While looking through the d3 source code, I found this snippet:
scale.unknown = function(_) {
return arguments.length ? (unknown = _, scale) : unknown;
};
This implements the pattern here: https://bost.ocks.org/mike/chart/. Here's a minimal example that works, with the above code adapted:
function closure() {
let mult
function my(t) {
return t * mult
}
my.mult = function(_) {
return arguments.length ? (mult = _, my) : mult
}
return my
}
Afterwards, you can use it like this:
fn = closure()
fn.mult(2)
console.log(fn(3)) // 6
fn.mult(4)
console.log(fn(3)) // 12
What I don't understand in my above example is this line:
return arguments.length ? (mult = _, my) : mult
This checks if there are arguments, and assigns the parameter to mult if there are, or returns mult if there aren't.
But what does the parentheses mean in (mult = _, my)? What does putting the returned function at the very end do?
I believe you have actually two different questions here.
The first one is about the parenthesis: Bostock (D3 creator) did that to take advantage of the comma operator, which he commonly uses in his codes. In short, this...
return arguments.length ? (mult = _, my) : mult
Translates to: does the function has any passed argument? If no, return the value of mult; if yes, return the my function AND assign the passed parameter to mult.
Then you have a second question:
What does putting the returned function at the very end do?
Not much, because that's not necessary. The test of argument.length is just to use a getter, that is, returning the stored value if no argument is passed. It could be just:
return arguments.length ? mult = _ : mult;
You can check this here:
function closure() {
let mult
function my(t) {
return t * mult
}
my.mult = function(_) {
return arguments.length ? mult = _ : mult;
}
return my
}
fn = closure()
fn.mult(2)
console.log(fn(3))
fn.mult(4)
console.log(fn(3))
console.log("stored value: " + fn.mult())
Related
why is it necessary to add return statement before ternary operator in recursive function to return function output?
// This dose not work
function rec(n) {
n == 1 ? n : n + rec(n - 1);
}
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}
// If you would like to do this in one line then correct solution would be:
let rec = n => n == 1 ? n : n + rec(n - 1);
// Now you dont need to add the return keyword before
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}
A recursive function is function which calls itself during the execution. The ternary operator decides if the function need to call itself. So the return statement call the same function.
In the example n == 1 ? n : n + rec(n - 1); if n=1 then the function should return the value of n if not then the function will call itself with new value that is n-1.
You need a return because of
n + rec(n - 1);
where the rec(n-1) call needs to return a value to be able to calculate n + rec(n - 1), and that goes for each call to rec() until n reaches 1 when it just returns 1.
return is never default in ternary operation.
return is default in Arrow-function but it not default in normal function deceleration.
to return a output from a normal function execution it is always necessary to add return statement, but it is optional in case of Arrow-function.
function x() { 5;}
console.log(x()); // Opuput: undefined
let y = () => 5;
console.log(y()); // Output: 5
A conditional expression (often called a ternary) is simply an expression. It yields a value, but it doesn't do anything with it. In fact, unless it has side-effects, it's totally useless unless you either:
return it from a function,
assign its result to a variable, or
nest it in another expression in which you do one of these things
You may be confused by the fact that arrow functions with single-expression bodies return the result of that expression. It's still being returned by the function, even though you don't explicitly use return. And because of this simplicity, conditional expressions are often used as the body of arrow function.
But it should be no more surpising that you have to have return here than that you have to have it in
function add (x, y) {
return x + y;
}
If you took out the return there, the addition will still happen when the function is invoked, but it won't yield any value. It's the same thing in your original.
I just stumbled upon an interesting example of recursive lambdas and I don't really understand why it works in this manner.
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
print(f(10))
Same in javascript.
var rec = function(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
}
var f = rec
rec = function(a) {
return a + 1;
}
console.log(f(10));
To my surprise both of these print 100 instead of 10! (as I would expect).
Why does the reassignment of rec change the behavior of the f function? When the rec variable is captured in lambda, doesn't it refer to the lambda itself?
Edit.
As most of the answers explain what is going on, let me rephrase the question because I am looking for a more in depth explanation.
So at the moment of the declaration of the function rec in the first line why doesn't the rec in the body of the function bind to itself?
For example if you take JavaScript and rewrite the first line in a seemingly "same" way as suggested in one of the answers you get:
var rec =function rec(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function (a) {
return a + 1;
}
console.log(f(10));
This one prints out 10! as one would expect.
So in this case the "inner rec"(in the function body) binds to the rec of the function-name instead of looking at rec variable and the reassignment of the variable rec didn't change the behavior.
So what I am really asking is the mechanism by which those languages decide what to bind the variables in the lambdas.
I am writing an interpreter myself for a class project and I came across to the same question of when and where to bind those variables. So I wanted to understand how this works in popular languages to implement something similar.
I will address it for python because that is what i am familiar with.
First, this behaviour is only possible because python (and looks like javascript i presume) follows late-binding for their closures. further read
Late binding is when the names within a closure are looked up at runtime (unlike early binding where the names are looked up at compile time.)
What this allows is to mutate behaviours at run time, by rebinding variables that are being looked up at runtime(such as functions like rec).
The last step then is just converting the lambda functions into equivalent def syntax so the real behaviour is clearer.
The code:
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
print(f(10))
Can be equivalent to:
First:
def somefunc(x):
return 1 if x==0 else rec(x-1)*x
Note, python will not complain about rec not existing even on a clean session/kernel because it does not look the value up during function definition. late binding means unless this function is called, python does not care about what rec is.
Then:
rec = somefunc
f = rec
def someotherfunc(x):
return x + 1
f(10) #3628800
Now we change the rec function
rec = someotherfunc
And observe that subsequent function calls of f will use the late-bound rec, that is looked up on the function call.
f(10) #100
PS. Complete code added below:
def somefunc(x):
return 1 if x==0 else rec(x-1)*x
rec = somefunc
f = rec
def someotherfunc(x):
return x + 1
f(10) #3628800
rec = someotherfunc
f(10) #100
You could add some console.log and view, that first f is called with 10, then rec with 9 and the result is 10 * 10.
var rec = function(a) {
console.log('f', a);
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function(a) {
console.log('rec', a);
return a + 1;
}
console.log(f(10));
Keeping rec.
var rec = function rec(a) {
console.log('f', a);
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function(a) {
console.log('rec', a);
return a + 1;
}
console.log(f(10));
These 3 statements can sum up to a single statement
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
from 1 & 2
f = lambda x : 1 if x==0 else rec(x-1)*x
from above & 3
f = lambda x : 1 if x==0 else x*x
I will suggest to use variable names properly, here you don't need reassignment
why it uses second rec not the first one ?
well your function call is happening after reassignment of rec so you have the latest value in rec as
rec = function(a) {
return a + 1;
}
var f = function(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
}
var rec = function(a) {
return a + 1;
}
console.log(f(10));
Is there a way to print out the [ith] element of the array with the [ith] function's argument? for example, print out the returned value of 2nd element of the array with input (3) as function's argument
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
It's not exactly clear what you are looking for. I assume that you want to call the ith function passing j as an argument.
To access the ith element of an Array, you use the square brackets post-around-fix indexing operator [] and pass the index inside the square brackets, which looks like this: ary[idx]. To call a function, you use the round parentheses post-around-fix function call operator () and pass the argument inside the round parentheses, which looks like this: func(arg).
Like this:
puzzlers[2](3);
There's really nothing puzzling about this, if you understand what an array is and what a function is.
It sounds like you're looking for this, but the question is a bit cryptic.
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
var secondFunction = puzzlers[1];
var result = secondFunction(3);
alert(result);
//or short
alert(puzzlers[1](3));
I am learning function programming in JavaScript, currently I have the following code.
I would like to combine this two functions in another function which alllow an user to pass a value in and having the result equal to the value passed plus 10 multiply 3 using the following functions.
Pseudo code example:
const myFormulat= add(10).multiply(3);
How can I write this function using only vanilla JS ES6?
function add(x){
return function(y){
return y + x;
};
}
function multiply(x){
return function(y){
return y * x;
};
}
// my calculation
// get x add 10 and after multiply by 3
Bear traps and landmines
This answer exists solely to demonstrate why this is not such a great idea – complexity is thru the roof with basically no gain. Note we must tell our function when to end, so i've added a special function call so our expressions will look like this
.add(3).mult(4).call(x)
// where x is the input for the entire function chain
One last change is our library of functions add, mult, et al must be wrapped in some scope that limits the reach of our proxy. This scope tells us exactly where the functions we wish to chain exist.
Oh and if the title of this section wasn't a warning enough, we use a Proxy too.
// helpers
const identity = x => x
const comp = f => g => x => f(g(x))
// magic wand
const using = scope => {
let acc = identity
let p = new Proxy({
call: x => acc(x),
}, {
get: (target, name) => {
if (name in target)
return target[name]
else if (name in scope)
return x => {
acc = comp (scope[name](x)) (acc)
return p
}
else
throw Error(`${f} is not undefined in ${scope}`)
}
})
return p
}
// your functions wrapped in a scope
const math = {
add: x => y => x + y,
mult: x => y => x * y
}
// chain it up
const main = using(math).add(3).mult(4).add(5).mult(6).call
console.log(main(2))
// (((2 + 3) * 4) + 5) * 6
// ((5 * 4) + 5) * 6
// (20 + 5) * 6
// 25 * 6
// 150
Function composition
But seriously, don't do that. Pushing everything through the . operator is unnatural given your starting point and you should be looking for more effective means to combine functions.
We can effectively do the same thing using a slightly different notation – the biggest difference here is complexity is almost zero
const compose = (f,...fs) => x =>
f === undefined ? x : compose (...fs) (f(x))
const add = x => y => x + y
const mult = x => y => x * y
const main = compose (add(3), mult(4), add(5), mult(6))
console.log(main(2)) // => 150
Functors
Maybe you don't like traditional function composition, and that's fine, because we have yet another way to tackle this problem using Functors – simply put, a Functor is a container with a map function.
Below we have a Box function which puts values in our container. The map function accepts a function and creates a new Box with the return value of the user-specified function. Lastly, we have a fold function which allows us to take our value out of the box
Again, it changes up the way we write the code a little bit, but the reduction is complexity is tremendous (compared to the Proxy example)
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x)
})
const add = x => y => x + y
const mult = x => y => x * y
const main = Box(2).map(add(3)).map(mult(4)).map(add(5)).map(mult(6)).fold
main(console.log) // 150
See: http://scott.sauyet.com/Javascript/Talk/Compose/2013-05-22/
function add(x){
return function(y){
return y + x;
};
}
function multiply(x){
return function(y){
return y * x;
};
}
Function.prototype.compose = function(g) {
var fn = this;
return function() {
return fn.call(this, g.apply(this, arguments));
};
};
var f = multiply(3).compose(add(10));
console.log(f(5));
If i understand you correctly you are trying to figure out function chaining in JavaScript
Function Chaining or Method chaining is a common pattern in JS world.
one of the methods in which you can achieve chaining is by creating a class and returning this operator or current object reference back
You can find interesting tutorial regarding this in following URL
https://www.bennadel.com/blog/2798-using-method-chaining-with-the-revealing-module-pattern-in-javascript.htm
For example, addEventListener's 2-nd argument has a "e" or "evt" or "event" or "..." parameter. How can I add parameters to a function argument without calling it (without using arguments object). Is it possible?
Sorry for my bad english :)
You are looking for partial functions.
You can create functions with arguments and not provide them. For example,
function add(x, y) {
return x + y;
}
console.log(add(1, 2)); // 3
console.log(add(2)); // NaN (2 + undefined)
console.log(add(0)); // NaN (undefined + undefined)
If you don't want the function to return value like NaN, you can write this:
function add2(x, y) {
x = x || 0;
y = y || 0;
return x + y;
}
console.log(add2(1, 2)); // 3
console.log(add2(2)); // 2
console.log(add2(0)); // 0