When `let y = x`, is it possible for `y !== x` - javascript

Is there any case where
let x = y;
console.log(y !== x) //=> true
So far, no case has worked, neither object nor symbol
?

Oh, I just found out.
Using getters and setters.
If y is a global getter and returns a different value each time, this is possible.
// Defining y.
((i) => {
Object.defineProperty(this, "y", {
get: () => i++
})
})(0)
// y is going to be one more than the previous value it gave,
// but is starts with 1.
// The magical testing...
let x = y;
console.log(x === y); // It returns `false`!
// Even y is not y.
console.log(y === y);

Related

Why does Object.assign behave differently from regular references?

If I have a simple reference to an object as in the first example, the way I understand it is x.a and y.a point to the same address which holds the value 1. When I change the value at that address to 2, the value changes in both x and y.
But in the second example, I use Object.assign to create y. x and y are different references, but x.a and y.a both point to the same address. So why is it that when I change x.a, y.a is not changed in this case?
// simple reference
var x = {a:1};
var y = x;
console.log(x === y); // true
console.log(x.a === y.a) // true
x.a = 2;
console.log(y.a); // 2
console.log('end first example');
// same example but with Oject.assign
var x = {a:1};
var y = Object.assign({}, x);
console.log(x === y); // false
console.log(x.a === y.a); // true, x.a and y.a point to the same address
x.a = 2;
console.log(y.a); // 1, I was expecting this to be 2

Printing curried function doesn't show the captured parameter

If I define a curried function like this:
const gt = x => y => y > x
I would expect gt(5) returns y => y > 5
but gt(5) (or gt(5).toString()) returns y => y > x
How do I get the captured parameter?
I would expect gt(5) returns y => y > 5
That isn't how JavaScript works. The code of the function returned by gt(5) is y => y > x, it's just that that code executes in an environment where the identifer x resolves to a binding that has the value 5 because it's a closure over that environment. toString on functions returns a string version of the source code of the function (or a function declaration around the [ native code ]) (spec), so you still see y => y > x. The string returned by toString doesn't include the environment in which that code runs.
See also:
How do JavaScript's closures work? - here on SO
Closures are not complicated - on my old anemic blog (uses some outdated terminology, I should probably fix that)
As #VLAZ points out in a comment, you can override the default toString on a function to give it the behavior you want. If you don't mind duplication (which almost inevitably leads to maintenance issues):
const gt = x => {
const fn = y => y > x;
fn.toString = () => `y => y > ${x}`;
return fn;
};
console.log(String(gt(5)));
...or if you want to define toString with the same enumerability, etc., as the version on the prototype:
Object.defineProperty(fn, "toString", {
value: () => `y => y > ${x}`,
writable: true,
configurable: true,
});
Doing that in the general case requires a proper JavaScript parser to do the substitution.
It's not possible to just print a variable captured in a closure, however there is a workaround for curry. I will be referring to Brian Lonsdorf's article on Medium Debugging Functional which goes into more details about curry and compose. I heartily recommend reading the article itself, as I will only use the essentials.
Brian Lonsdorf proposes a custom implementation of a general curry function. The original version is taken from an article by Erin Swenson-Healy.
Here is the modified version:
function fToString(f) {
return f.name ? f.name : `(${f.toString()})`;
}
function curry(fx) {
var arity = fx.length;
function f1() {
var args = Array.prototype.slice.call(arguments, 0);
if (args.length >= arity) return fx.apply(null, args);
function f2() {
return f1.apply(null, args.concat(Array.prototype.slice.call(arguments, 0)));
}
f2.toString = function() {
return fToString(fx)+'('+args.join(', ')+')';
}
return f2;
};
f1.toString = function() { return fToString(fx); }
return f1;
}
const gt = curry((x, y) => y > x);
const sum3 = curry((x, y, z) => x + y + z);
const ltUncurried = (x, y) => y < x;
const lt = curry(ltUncurried);
console.log(gt(1)); // ((x, y) => y > x)(1)
console.log(sum3(1)); // ((x, y, z) => x + y + z)(1)
console.log(sum3(1, 2)); // ((x, y, z) => x + y + z)(1, 2)
console.log(sum3(1)(2)); // ((x, y, z) => x + y + z)(1, 2)
console.log(lt(1)); // ltUncurried(1)
(I have modified fToString() to include brackets around f.toString() for better readability)
This is quite flexible as it allows currying any function but also provides better logging of said function. The toString implementation can be modified if required for whatever you deem are the most important details.
const gt = x => y => y > x
gt(1);
If you had pass only 1 argument like gt(1) and if you Check in console, x = 1, y is not available at this time. So the execution context (call stack) will show only the x argument and for the gt() method it will only show the code (y > x).
And here below gives us a hint that gt(1) will first bind x to 1, and return a new function f(y) = y > x = y > 1
You didn't second pass second argument, It means now the function f(y) = 1 + y is executed, and this time, it will check for the y where y is not available at that time. And the argument x’s value 1 is still preserved in the context via Closure.
It's look like same as below closure function :-
function add(x) {
return function (y) {
return y > x
}
}
var d = add(1)(2); ===>>>> true

How to refactor the method in react?

T want to divide a method into two, so that it can be used by two methods with different arguments.
What am I trying to do?
I have a method named convert_point that takes values x and y based on a click on a canvas and then converts that to x, y and z values as an array.
add_point_at = (x, y) => {
this.props.convert_point([x, y]).then(converted_point => {
let next;
let some_var = this.state.some_var;
if (some_var === undefined) {
this.method1();
next = this.add(this.props.drawings);
some_var = next.paths.length - 1;
this.setState({
some_var: some_var,
draft_point: {x: x, y: y},//seems like this x and y values
needs to replaced as well...
});
} else {
next = this.props.drawings;
this.setState({
some_var: undefined,
});
}
const variable = next.paths[some_var];
next_drawings = this.add_path(
next, converted_point[0], converted_point[1],
converted_point[2]);
this.props.on_drawings_changed(next_drawings);
}).catch(some_method_called);
};
The above method accepts x and y values, so basically it is called by another function like below. Here x and y are, say, 20 and 30 and when given to this.props.convert_point method in add_point_at, the output is say [11.2, -13, 45], so basically converted_point given to the then method is [11.2, -13, 45]:
handle_click = (x, y) => {
this.add_point_at(x,y);
}
This works fine. Now there is a situation where I have x, y and z values already and want to call the add_point_at method… So I divided the add_point_at method as below:
add_point_at = (x, y) => {
this.props.convert_point([x,
y]).then(this.call_another_method).catch(some_method_called);
call_another_method = (converted_point) => {
let next;
let some_var = this.state.some_var;
if (some_var === undefined) {
this.method1();
next = this.add(this.props.drawings);
some_var = next.paths.length - 1;
this.setState({
some_var: some_var,
draft_point: {x: x, y: y},// x and y values are unknown
});
console.log("last statement in if");
} else {
next = this.props.drawings;
this.setState({
some_var: undefined,
});
}
console.log("first statement after else");
const variable = next.paths[some_var];
next_drawings = this.add_path(
next, converted_point[0], converted_point[1],
converted_point[2]);
this.props.on_drawings_changed(next_drawings);
};
So if I have x, y and z values already, I directly call:
this.call_another_method(converted_point);
If I have only x and y values, I call
this.add_point_at(x, y);
…so that this converts x, y to x, y, z values using the this.props.convert_point method.
But after dividing the method, it doesn't work. I don't see any console error. To debug, I tried to add console statements as seen in code above, but it is not logged to the console. Not sure why.
Could someone help me understand where the problem is?
EDIT: i realised that the problem is with the x and y values undefined in the splitted method...how can i refactor this method such that x and y values are replaced with something.

Which parameter order with operators as pre-curried functions and composition in Javascript?

Given is a simple, mathematically curried function to subtract numbers:
function sub(x) {
return function (y) {
return x - y;
};
};
sub(3)(2); // 1
The function signature reads exactly as the obtained result. The situation changes as soon as function composition is involved:
function comp(f) {
return function (g) {
return function (x) {
return f(g(x));
};
};
};
function gte(x) {
return function (y) {
return x >= y;
};
};
comp(gte(2))(sub(3)) (4); // true
With function composition, the last parameter of each function involved is crucial, as it is fed respectively with the value returned by the previously applied function. The composition in the above example reads therefore as: 4 - 3 >= 2 which would yield false. In fact, the computation behind the composition is: 2 >= 3 - 4, which yields true.
I can rewrite sub and gte easily to get the desired result:
function sub(y) {
return function (x) {
return x - y;
};
};
function gte(y) {
return function (x) {
return x >= y;
};
};
comp(gte(2))(sub(3)) (4); // false
But now the return values of directly called functions are different than expected:
sub(3)(2); // -1 (but reads like 1)
gte(2)(3); // true (but reads like false)
I could switch the arguments for each call or define a partial applied function for each case:
function flip(f) {
return function (x) {
return function (y) {
return f(y)(x);
};
};
}
flip(gte)(2)(3); // false
var gteFlipped = flip(gte);
gteFlipped(2)(3); // false
Both variants are obviously cumbersome and neither more readable.
Which parameter order is preferable? Or is there a mechanism to use both, depending on the respective requirements (like Haskell's left/right sections for partially applied operators)?
A possible solution must take into account, that I use unary functions only!
So you want to partially apply operators without having to write code like:
var gte2 = function (x) { return x >= 2; };
That's a reasonable use case, “to partially apply operators”.
The answer is simple. Just write a curried function. For example:
// var gte = y => x => x >= y; // ES6 syntax
var gte = function (y) {
return function (x) {
return x >= y;
};
};
var gte2 = gte(2);
Unfortunately, there are two ways we can partially apply binary operators:
Partially apply the operator to the left argument.
Partially apply the operator to the right argument.
This raises two important questions:
Which argument should the operator be partially applied to by default?
How do we partially apply the operator to the other argument?
Fortunately, we can agree on one thing: it makes no sense to provide both arguments to the operator.
// Why write the following:
add(2)(3)
// When you can write the following:
2 + 3
The reason we are creating curried operator functions in the first place is for partial application.
Hence, it makes no sense to provide both arguments to the function “at once”.
What are the ramifications of this restriction? It means that:
We can choose any argument order we want.
// This is correct:
var sub = x => y => x - y;
// So is this:
var sub = y => x => x - y;
It only needs to make sense given one argument.
// Consider this operator function:
var sub = y => x => x - y;
// This makes sense:
sub(1) // means (x => x - 1)
// However, this doesn't make sense:
sub(2)(3) // expected (2 - 3) but actually (3 - 2)
// But that's OK because it only needs to make sense given one argument.
Now, keeping this in mind which is the best argument order? Well, it depends.
For commutative operations the argument order doesn't matter.
For example, both addition and multiplication are commutative. Hence, a + b = b + a for addition and a * b = b * a for multiplication.
For non-commutative operations the right-to-left argument order is generally better because it allows the partial application to be read out loud.
For example, the expression lt(2) generally means x => x < 2 and not x => 2 < x.
Why is this the general case? Well, in JavaScript function names come before the argument. Hence, name(arg) naturally reads as x => x name arg instead of x => arg name x.
However, there are some exceptions to the second rule. Most prominently, division:
div(10) // is read out loud as divide 10 by x
// it is not read out loud as divide x by 10
Of course, the correct argument order for such edge cases is a matter of debate but in my humble opinion the left-to-right argument order seems more natural.
So, here are a bunch of curried operator functions:
// Commutative operators:
var add = x => y => x + y;
var mul = x => y => x * y;
// Right-to-left operators:
var lt = y => x => x < y;
var gt = y => x => x > y;
var lte = y => x => x <= y;
var gte = y => x => x >= y;
var sub = y => x => x - y;
// Left-to-right operators:
var div = x => y => x / y;
Now, the second question is how do we partially apply the operators to “other” argument?
The only way to do so it to create a new function with the flipped argument order.
Fortunately, we don't need to create a new function for every operator:
For commutative operators the argument order doesn't matter. Hence:
flip(add) = add
flip(mul) = mul
For relational operators we don't need to create extra functions:
flip(lt) = gt
flip(gt) = lt
flip(lte) = gte
flip(gte) = lte
We only need to create flipped operator functions for sub and div:
var subFrom = x => y => x - y; // subFrom(5) means (y => 5 - y)
var divBy = y => x => x / y; // divBy(10) means (x => x / 10)
All things considered, I would say that you should use your common sense.
Here's how I read your composition:
comp(gte(2))(sub(3)) (4);
gte(2) = function(y) { return 2 >= y; } // (x = 2)
sub(3) = function(y) { return 3 - y; } // (x = 3)
// Therefore:
comp(gte(2))(sub(3)) = function(x) {
var f = function(y) { return 2 >= y; };
var g = function(y) { return 3 - y; };
return f(g(x));
};
// Now call with (x = 4):
x = 4
g(4) = 3 - 4 = -1
f(-1) = (2 >= -1) = true
So in short, it seems that your expectations are wrong. Maybe you do indeed have something backwards, but I honestly can't tell what. I do, however, think that this is not a good way to work in JavaScript and you're overcomplicating things, but that's just my opinion.
This response is based on the reply from Aadit.
There is actually a need for fully applied curried operator functions in Javascript - when used as First Class Citizens:
function between(ops) {
return function (left) {
return function (right) {
return function (n) {
// At this point one should use the native Javascript operators
// but they can't be passed to the function, since operators are not First Class.
return ops[0](left)(n) && ops[1](right)(n);
};
};
};
}
function lte(y) { return function (x) { return x <= y; }; }
function gt(y) { return function (x) { return x > y; }; }
between([gt, lte])(2)(4)(4); // true
// is evaluated as: gt(2)(4) && lte(4)(4) === true; (confusing)
between may be nonsense, but it serves as proof that fully applied curried operator functions make sense in Javascript. There are likely even other use cases.
Nevertheless Aadit is right that something like sub(2)(3) contradicts the very purpose of currying!
So how could a solution look like?
all curried operator functions must have a right-to-left argument order
a function is introduced, which explicitly indicates the unusual usage when passing all arguments to a curried function at once
Here is uncurryOp:
// intended for all operator functions
function uncurryOp(f) {
return function (x, y) {
return f(y)(x);
};
}
uncurryOp(gt)(2, 4); // false (intuitive)
This is not really an adequate solution. I think there is no, due to lack of First Class and partially applicable operators in Javascript.

Why is the U variable set to NULL in this interesting Javascript code fragment?

i have a javascript code fragment as
var u = {};
var x = y = z = {"cvalue":"cell", "call":function(){alert(this.cvalue);}};
(function(){u=x;/*change all cvalue in x,y, z, u*/ u.cvalue = "notcell";})();
if(u == x && x == y && y == z && z == u){
u.call();
}
//only u goes to null
u = null;
//x,y,z stay same
alert(x.cvalue);
wondering why u = null only applies for u?
Variables don't actually hold an object, but simply hold a reference to one. By assigning u to null, you're dropping the reference that u had to the object.
A more basic example:
var x = { 'name': 'Bob' };
var y = x;
console.log(x); // Object { name="Bob"}
console.log(y); // Object { name="Bob"}
y.name = 'Jack';
console.log(x); // Object { name="Jack"}
console.log(y); // Object { name="Jack"}
x = null;
console.log(x); // null
console.log(y); // Object { name="Jack"}
Note how our object isn't held in x. It's held somewhere in memory, and x is referring to it. When we do y = x, we copy the reference to y, and therefore y begins to refer to the same object. Setting x to null simply drops the reference that x holds to the object, leaving the actual object unaffected. If we were to set y to null, or to anything else, the garbage collector would eventually pick up the object for destruction.
Daniel is right, but you have to be careful because in Javascript you are sometimes dealing with a copy, and othertimes dealing with the original. For example...
var a = new Object();
a.foo = new function(){alert("I exist")};
var b = a;
b.foo = null;//this erases the function from both a and b (technically, there is only one since a and b point to the same place in memory).
a.foo();//this now fails since there is no longer a function called foo
b = null;//this does NOT affect a in any way as per Daneiel Vassallo's explanation.
You are assigning the exact same object to x, y and z, not a copy of it's value, but the exact same object.
In pseudo code:
var u = OBJECT_A // u points to OBJECT_A
var x = y = z = OBJECT_B // x y and z points to OBJECT_B
(function(){
u=x; // Drop reference to OBJECT_A and point to OBJECT_B
/*change all cvalue in x,y, z, u*/
u.cvalue = "notcell"; //Changes the cvalue in OBJECT_B
// Remember x,y,z, and u points to OBJECT B
// so x.cvalue, y.cvalue, z.cvalue and u.cvalue is the same
})();
if(u == x && x == y && y == z && z == u){
u.call();
}
//only u goes to null
u = null; // Drop reference to OBJECT_B and point to NULL.
//x,y,z still points to OBJECT_B
alert(x.cvalue);

Categories

Resources