I was reading this article about creating react/redux applications
and was a bit confused by the following section, specifically the part I've circled in red. What exactly is happening here? I'm not very familiar with the syntax being used, the double "=>" is not something I've seen before. If you are able to explain this block of code that would be much appreciated!
Thanks
Not sure how much you understand Redux yet but you create actions for each task you want to record in the store, these are processed using reducers.
The createAction function, as it's name suggests creates actions, so rather than having to re-write the same code over and over you can call it, passing the name of the action you want to create. In this example the action being created is called SET_USER_ID
The arrow function => is new syntax introduced with the latest javascript which is known as ES6. You can read about it here. Arrow functions allow you to define functions using shorter syntax and they also solve scoping issues.
The final line would be used within your react component to call the action. i.e.
<Button onClick={ () => dispatch(setUserId('abcd123')) } />
It took me a while to get my head around redux, if you haven't watched Dan Abramov's tutorials on it then I highly recommend them. He's the creator of redux. Also start building your own redux app, that's the best way to learn.
"the double "=>" is not something I've seen before."
This is called currying is the technique of translating the evaluation of a function that takes multiple arguments, in this particular example
type, (payload, meta). Here, the function accepts the first argument (type) and returns a function that accepts the second arguments (payload, meta) and so on.
example: const sum = x => y => x + y;
sum (2)(1); // returns 3
sum (2); // returns a function y => 2 + y
Currying is the process of taking a function with multiple arguments and turning it into a sequence of functions each with only a single argument - a fancy name of Partial Application
https://en.wikipedia.org/wiki/Partial_application
First you call createAction and pass a type(SET_USER_ID) then you call setUserId and pass a payload (id in this case). 'Meta' is optional argument.
It is hard to wrap your head around it at first.
You can also write it this way
const newOPfunction = (type) => {
const newFunc = (id) => {
return {type, id}
}
return newFunc;
}
but it doesn't look as pretty
Related
I am reading a book where it says one way to handle impure functions is to inject them into the function instead of calling it like the example below.
normal function call:
const getRandomFileName = (fileExtension = "") => {
...
for (let i = 0; i < NAME_LENGTH; i++) {
namePart[i] = getRandomLetter();
}
...
};
inject and then function call:
const getRandomFileName2 = (fileExtension = "", randomLetterFunc = getRandomLetter) => {
const NAME_LENGTH = 12;
let namePart = new Array(NAME_LENGTH);
for (let i = 0; i < NAME_LENGTH; i++) {
namePart[i] = randomLetterFunc();
}
return namePart.join("") + fileExtension;
};
The author says such injections could be helpful when we are trying to test the function, as we can pass a function we know the result of, to the original function to get a more predictable solution.
Is there any difference between the above two functions in terms of being pure as I understand the second function is still impure even after getting injected?
An impure function is just a function that contains one or more side effects that are not disenable from the given inputs.
That is if it mutates data outside of its scope and does not predictably produce the same output for the same input.
In the first example NAME_LENGTH is defined outside the scope of the function - so if that value changes the behaviour of getRandomFileName also changes - even if we supply the same fileExtension each time. Likewise, getRandomLetter is defined outside the scope - and almost certainly produces random output - so would be inherently impure.
In second example everything is referenced in the scope of the function or is passed to it or defined in it. This means that it could be pure - but isn't necessarily. Again this is because some functions are inherently impure - so it would depend on how randomLetterFunc is defined.
If we called it with
getRandomFileName2('test', () => 'a');
...then it would be pure - because every time we called it we would get the same result.
On the other hand if we called it with
getRandomFileName2(
'test',
() => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.charAt(Math.floor(25 * Math.random()))
);
It would be impure, because calling it each time would give a different result.
There's more than one thing at stake here. At one level, as Fraser's answer explains, assuming that getRandomLetter is impure (by being nondeterministic), then getRandomFileName also is.
At least, by making getRandomFileName2 a higher-order function, you at least give it the opportunity to be a pure function. Assuming that getRandomFileName2 performs no other impure action, if you pass it a pure function, it will, itself, transitively, be pure.
If you pass it an impure function, it will also, transitively, be impure.
Giving a function an opportunity to be pure can be useful for testing, but doesn't imply that the design is functional. You can also use dependency injection and Test Doubles to make objects deterministic, but that doesn't make them functional.
In most languages, including JavaScript, you can't get any guarantees from functions as first-class values. A function of a particular 'shape' (type) can be pure or impure, and you can check this neither at compile time nor at run time.
In Haskell, on the other hand, you can explicitly declare whether a function is pure or impure. In order to even have the option of calling an impure action, a function must itself be declared impure.
Thus, the opportunity to be impure must be declared at compile time. Even if you pass a pure 'implementation' of an impure type, the receiving, higher-order function still looks impure.
While something like described in the OP would be technically possible in Haskell, it would make everything impure, so it wouldn't be the way you go about it.
What you do instead depends on circumstances and requirements. In the OP, it looks as though you need exactly 12 random values. Instead of passing an impure action as an argument, you might instead generate 12 random values in the 'impure shell' of the program, and pass those values to a function that can then remain pure.
There's more at stake than just testing. While testability is nice, the design suggested in the OP will most certainly be impure 'in production' (i.e. when composed with a proper random value generator).
Impure actions are harder to understand, and their interactions can be surprising. Pure functions, on the other hand, are referentially transparent, and referential transparency fits in your head.
It'd be a good idea to have as a goal pure functions whenever possible. The proposed getRandomFileName2 is unlikely to be pure when composed with a 'real' random value generator, so a more functional design is warranted.
Anything that contains random (or Date or stuff like that). Will be considered impure and hard to test because what it returns doesn't strictly depends on its inputs (always different). However, if the random part of the function is injected, the function can be made "pure" in the test suite by replacing whatever injected randomness with something predictable.
function getRandomFileName(fileExtension = "", randomLetterFunc = getRandomLetter) {}
can be tested by calling it with a predictable "getLetter" function instead of a random one:
getRandomFileName("", predictableLetterFunc)
I'm working on wrapping a function in a customized one in TypeScript. For that, I want to correctly pass down the types.
I looked at similar questions like this one, but they all seem to answer the question on how to extract from a class but not a function.
I think en example is the easiest explanation:
// we have a given function like this:
function genericFunction<T extends object>(a: T) {
return a;
}
// we want to extract the T type to pass it down for smth like this:
type ExtractedT = typeof genericFunction<IWANTTHEGENERICTYPE>; // (THIS IS WHERE I DON'T KNOW HOW TO PROCEED);
function myGenericFunction<T extends ExtractedT>(a: T, b: string) {
console.log(b, "- is a newly introduced variable.")
genericFunction<T>(a);
}
Of course, the example is a highly abstracted example, but my goal should hopefully be clear.
I appreciate your answers!
EDIT:
I updated the example since it didn't really make sense before. My goal is to "dynamically" wrap a method from a framework i.e. (my sophisticated use case also extracts the Parameters<> types, but that's smth else.)
So I guess my goal is to have a way of detecting the generic types of a function and copying them over to my own function. But I start to think this that this blows the scope of TypeScript and just hovering over the generic types and importing / copy-pasting them for the wrapper function might be the better solution
I'm giving myself a bit of a crash course on JavaScript so that I can learn React. I haven't done any dev work for many years so this may be a facepalm moment.
I am reading a blog post on useState(). I understand that if the parameter passed to useState() is a function, the function is only executed on the first render execution.
(EDIT: blog post is here https://blog.logrocket.com/a-guide-to-usestate-in-react-ecb9952e406c/)
However, this confuses me:
const Message= () => {
const messageState = useState( () => expensiveComputation() );
/* ... */
}
In this example, why not just pass expensiveComputation to useState() like so?
const Message= () => {
const messageState = useState( expensiveComputation );
/* ... */
}
There are also some weird niggles about functions in Javascript that I don't think I'm understanding. For example, I've heard that arrow functions are executed when they are defined, but I've played with JSBin and I can't manage to prove that to myself in any way.
Thanks for the help!
I think these are the same in this particular case. The more general issue is the binding of this.
() => this.foo()
and
this.foo
are not the same, because "this" stays attached to the class in the first case and gets lost in the second case, so that when "foo()" is called in the second case, it won't be accessing the correct object as its "this".
It's generally regarded as a major design mistake of Javascript that this can be easily lost. The older-JS way to preserve this is with the bind method, i.e. this.foo.bind(this). But in language design, it's not possible to redefine the meaning of code without breaking everyone's existing applications. When lambdas with => were introduced, this was handled in the more modern, lexical way that preserves this.
I am building a simple application using Ramda.
I have run into a functional composition problem that I am not really sure how to address without creating what seems to be a needlessly absurd function.
The scenario:
I have an object being passed as a parameter. There are two attributes on this object, and some other stuff that isn't relevant to the problem other than that I'd like to not change it's state :
{locCode :<string>, LocationList : [<Location>], someOtherParams : ... }
I have a single arg function which can convert a locCode to a location:
fetchLocByCode
My desired result here would be to take the locCode value, pass it to fetchLocByCode, append LocationList with the result, and return a new object with the new LocationList without touching anything else on the object.
Something analagous to:
(Param)=>{
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
What I've ended up writing to do this seems extremely ridiculous and leads me to believe I have done something horribly wrong:
const locListLens = R.lens(R.prop('LocationList'),R.assoc('LocationList'))
const appendLocList = (i)=>R.compose(R.over(locListLens),R.append,fetchLocByCode,R.prop('locCode'))(i)(i)
This solution 'works' but it seems as if I've missed some fundamental idea.
Would anyone care to present a more 'canonical' way to address this scenario?
Let's start with your initial version:
Param => {
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
I very much hope the mutation is not required. Let's remove it:
Param =>
R.assoc('LocationList',
R.append(fetchLocByCode(Param.locCode), Param.LocationList),
Param)
We could use a lens to avoid accessing the LocationList property twice:
Param =>
R.over(R.lensProp('LocationList'),
R.append(fetchLocByCode(Param.locCode)),
Param)
Could we get rid of Param entirely? Let's start by using R.converge:
R.converge(R.over(R.lensProp('LocationList')),
[Param => R.append(fetchLocByCode(Param.locCode)),
R.identity])
Let's use R.compose to remove Param from the first branching function:
R.converge(R.over(R.lensProp('LocationList')),
[R.compose(R.append, fetchLocByCode, R.prop('locCode')),
R.identity])
Any time you find yourself writing R.converge(f, [g, R.identity]) you've discovered a use for the S combinator!
S.S(R.flip(R.over(R.lensProp('LocationList'))),
R.compose(R.append, fetchLocByCode, R.prop('locCode')))
Although this is neat, I think the R.assoc version is fine. Future readers would not enjoy having to make sense of S.S(R.flip(R.over(R.lensProp. ;)
I'm currently in the process of building out a VERY simple Observer class for a project I'm working on. I have successfully implemented the subscribe, unsubscribe, and notify methods. Everything works exactly as expected when using "regular" functions (i.e: var f = function()).
However, when I pass an anonymous function to the subscribe method and then try to unsubscribe passing the "same" anonymous function it (as expected) doesn't remove the function from my array (they are different, after all).
Here's my subscribe and unsubscribe methods:
this._subscribers = {};
subscribe: function(type, callback) {
if ( isUndefined(this._subscribers[type]) ) {
this._subscribers[type] = [];
}
this._subscribers[type].push(callback);
},
unsubscribe: function(type, callback) {
if ( this._subscribers[type] instanceof Array ) {
var index = this._subscribers[type].indexOf(callback);
if ( index >= 0 ) {
this._subscribers[type].splice(index, 1);
}
}
},
And here's the code I'm testing with:
var o = new gaf.events.Observable();
o.subscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent');
// Correct alerts 'Got It!'
o.unsubscribe('testEvent', function(event) { alert('Got It!'); });
o.notify('testEvent')
// Incorrectly alerts 'Got It!'
I know I could using an object (i.e.: _subscribers[event] = {}) and then when something subscribes I could add a new property equal to the callback and the value equal to the callback. This will cause Javascript to convert the callback to the string. I could then look it up (provided the methods passed in sub/unsub are exactly the same) using that string.
However, this is a mobile project and I'm very leery about storing strings that could be hundreds of characters long as properties as we could end up with a lot of subscribers.
Are there any other ways of doing this? Are there any SMALL (tiny, even) hashing libraries I can use to maybe hash the string value of the function and use that as the property? Would it be better to store the string value of the callback (so I can compare against it) in the array (rather then the actual callback) and use eval() on it?
EDIT
First, thanks all for the replies!
Per all the questions about "Why even pass anonymous" functions -
There really is no reason one COULDN'T use named functions. In fact, I agree with everyone that named functions are going to be the better solution. I'm simply gathering information and looking for a solution so that I can build out an implementation that handles the most scenarios as best as possible.
The other reason for this is what happens if a user (co-worker) of this Observable class passes it an anonymous function and then unsubscribes. That function won't actually be unsubscribed and therefore won't be cleaned up. I have a thing against orphaned data :)
Maybe another question I should as is, is it possible to test if the callback is anonymous or not? I'm going to assume no but doesn't hurt to ask.
There is nothing wrong with storing the entire string; premature optimization is evil.
However, this sounds like an incredibly bad idea.
If someone changes the function, but forgets to change the unsubscribed copy, the code will be subtly broken with no warning whatsoever.
Instead, you can require the user to store the anonymous function in a variable if they want to unsubscribe from it.
Alternatively, you can pass an optional name with each subscriber, then unsubscribe by that name.
the clients that use the Observer should store the reference to the function.
var obsCallback = function() {
}
o.subscribe('test', obsCallback);
....
o.unsubscribe('test', obsCallback);
in other words, keep a reference to the function around...
Perhaps a better solution is to modify the code using your library
var f = function() { alert('Got It!'); };
o.subscribe('testEvent', f);
o.notify('testEvent');
o.unsubscribe('testEvent', f);
o.notify('testEvent');
You could even return the function from the subscribe method
var f = o.subscribe('testEvent', function() { alert('Got It!'); });
// ...
then if you want to store a hash or some other identifier for subscribed functions, it is opaque to the calling code meaning that you just use the returned value to unsubscribe and the library hides the implementation detail.
What is the reason for passing in anonymous functions rather than named ones, or keeping references that you can use for unsubscribing later?
Alternatively you could allow for an optional 'id' argument but this would require unnecessarily complex bookkeeping to avoid duplicates.