Passing arguments as an array without .apply() - javascript

I am try to find out if there is a way to pass arguments to a javascript function as an array, without using the .apply method. The code would look something like this from a user's perspective:
var args = [1, 2, 3, 4];
doSomething(args);
Note that doSomething() will not always be the same function, so I cannot write it to use an array of arguments. Ideally, this should work for any function, and I guess what I am trying to do is essentially convert an array into an arguments-array-like object.
I was thinking that I may be able to set the functions arguments object like this:
function.arguments = otherArguments;
But I don't know when I would have to do that (wouldn't I have to somehow do it once the function started executing but before it actually did anything with its arguments?)
The reason I am trying to do this is because I am trying to write my own .apply function for learning purposes. Is this possible?

No, there is no way around. One tool for one functionality, and the one of choice is apply.
If you need to write your own function that does not use apply, you would need to use eval:
function apply(fn, thisObj, args) {
var obj = {fn: fn};
var str = "obj.fn(";
for (var i=0; i<args.length; i++)
str += (i?',':'') + "args["+i+"]";
str += ");";
return eval(str);
}

I am not recommending this at all, but if you wanted to be insane, you could probably dynamically generate a curry method for the arity of the function that you are invoking, and then invoke the resulting curry in a loop:
function func(a,b,c,d) {
console.log([a,b,c,d]);
return "Return Value";
}
// Using a static 4 argument curry.
function curry4(f) {
return function(a) {
return function(b) {
return function(c) {
return function(d) {
return f(a,b,c,d);
}
}
}
}
}
var args = [1,2,3,4];
for(var i=0,f=curry4(func);i<func.length;i++) { f = f(args[i]); }
console.log(f); // f is return value of `func`
See here for example that supports up to 12 optional arguments.
But this road probably leads to madness....

Just to mention:
if you use setTimeout you can pass params:
setTimeout( _function_name_, delay, param1,param2,param3...)
this way the params are passed to the function without using apply

Related

How can I access the result from a previous function in a currying function?

I have to write a currying function that takes a function, executes another function, then executes a second function by taking the last argument as the value to calculate with.
What I am struggling with: How can I access the first function and the value at the end at the same time?
So far I can access the first function by writing a function in the function syntax and accessing the this.
Function.prototype.foo = function(x) {
// can't make currying functions by using functions keyword
console.log(this, x);
};
(() => 10).foo(1);
When I write a currying function I can access the second (x) and third (y) function.
Function.prototype.bar = x => y => {
// but also can't access this like in function syntax
console.log(x, y);
}
// how would I access 10 in bar?
(() => 10).bar(1)(2);
The final Function would look something like that:
someFunc.then(someSecondFunc).then(someThirdFunc)(100)
Thank you so much for your help!
Not sure if it solves your problem, but you can make currying functions with the function keyword:
Function.prototype.bar = function(x) {
return function(y) {
console.log(x, y)
}
}
I wasn’t able to actually able to validate if this works:
(function() {return 10}).bar(1)(2)
In any case, ˋthisˋ would be the function, not the return value (10), since the function is not called.
By using currying functions and the function keyword, my answer looks like this:
Function.prototype.then = function(secondFct) {
const firstFct = this;
return function(value) {
return firstFct(secondFct(value));
}
}
Many thanks to buboh for the help.

Invoke a JavaScript function with parameter in a function

Today, I saw the following code below:
log_execution_time = require('./utils').log_execution_time;
var fib = function fib(n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
};
var timed_fib = log_execution_time(fib);
timed_fib(5);
>>> Execution time: 1.166ms
I am curious about function log_execution_time. I don't know how it is.
You can see the input of log_execution_time is a function. How can it call the function with parameter? But all of the methods from w3school need a parameter when calling a function. I assume:
var log_execution_time = function (input_function){
console.time("Execution time");
// input_function
console.timeEnd("Execution time");
}
Thanks and regards
I think the OP is specifically about how the 5 parameter gets passed to the function input_function
Functions are first class objects in JavaScript. You can set identifiers and pass their references around just the same as any other object.
log_execution_time(fib); does not invoke fib, it passes a reference to fib into the log_execution_time function as the first argument. This means the internals can reference fib
timed_fib is a function which can reference the closure from that invocation of log_execution_time due to when it was created, so it can hence invoke the reference to fib as desired
Here is a simple example;
function log(msg) {
console.log(msg);
}
function wrap(fn) {
return function () { // some anonymous function to be our wrapper
console.log('Wrapped:');
fn.apply(this, arguments); // this line invokes `fn` with whatever arguments
// that were passed into the anonymous function
};
}
var foo = wrap(log);
foo('Hello World'); // logs
// Wrapped:
// Hello World
We could also have used the more usual way to invoke fn, for example fn("fizz buzz");, instead of .apply but that would mean we needed to know more about how to invoke fn, which could have been anything
Useful stuff:
Function.prototype.apply
Function.prototype.call
This is known as function currying, in this case the function is being curried with a parameter that also happens to be a function. It may look something like this:
function logTime(f) {
return function() {
var s = new Date();
var r = f.apply(null, arguments);
var e = new Date();
console.log('Time taken ' + (e-s));
return r;
}
}
function numberlogger(n) {
console.log("logged number: " + n)
};
var timedlogger = logTime(numberlogger);
console.log(timedlogger(2));
We call logTime, passing in numberlogger as an argument. Functions in JavaScript are objects and can be passed around like anything else. The logTime function returns a different function that is then stored in timedlogger. When we invoke timedlogger, we're actually invoking the function that logTime returned. That uses a couple of variables to keep track of the start and end times for timing, but uses apply (which every function in js has) to call the original function (numberlogger) whilst passing in any arguments supplied.
I suggest reading up on Functions in Javascript. Here's a nice article from the Mozilla Developer Network (MDN) which is in my opinion, a much better resource than w3schools
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
To answer your question though, functions in javascript are first class citizens, and what that means is that you can think of them as any other object (string,boolean,number etc). They can be saved in variables and they can be passed as arguments into other functions.
In your example, log_execution_time will actually return a function which is essentially a wrapper around the fib function that gets passed to it
The code can be like this:
var log_execution_time = function (input_function){
var f=function(args)
{
var t1=new Date().getTime();
input_function(arguments);
console.warn("Execution time:" +(new Date().getTime()-t1).toString());
}
return f;
}

Understanding the syntax of a deferred execution chain

I'm getting around to learning JavaScript - really learning JavaScript. I come from a PHP background so some JavaScript concepts are still new to me, especially asynchronous programming. This question might have already been answered many times before but I have not been able to find an answer. It might be because I don't really even know how to ask the question other than by showing an example. So here it is:
When using the deferred package from npm, I see the following example:
delayedAdd(2, 3)(function (result) {
return result * result
})(function (result) {
console.log(result); // 25
});
They refer to this as chaining and it actually works as I'm currently using this code to check when a promise is resolved or is rejected. Even though they call it chaining, it reminds me of trailing closures like in Swift.
I don't really understand what type of chaining this is since we have a function invocation and then immediately after, an anonymous function enclosed in parentheses.
So I guess I have two questions.
What pattern is this?
How does it work? This may be a loaded question but I like to know how something works so when someone asks me about this I can give them a detailed explanation.
Here is the delayedAdd function:
var delayedAdd = delay(function (a, b) {
return a + b;
}, 100);
which uses the following function:
var delay = function (fn, timeout) {
return function () {
var def = deferred(), self = this, args = arguments;
setTimeout(function () {
var value;
try {
value = fn.apply(self, args));
} catch (e) {
def.reject(e);
return;
}
def.resolve(value);
}, timeout);
return def.promise;
};
};
It's actually really easy to understand. Let's look at what's going on here when the expression is evaluated:
First the delayedAdd(2, 3) function will be called. It does some stuff and then returns. The "magic" is all about its return value which is a function. To be more precise it's a function that expects at least one argument (I'll get back to that).
Now that we evaluated delayedAdd(2, 3) to a function we get to the next part of the code, which is the opening parenthesis. Opening and closing parenthesis are of course function calls. So we're going to call the function that delayedAdd(2, 3) just returned and we're going to pass it an argument, which is what gets defined next:
That argument is yet another function (as you can see in your example). This function also takes one argument (the result of the computation) and returns it multiplied by itself.
This function that was returned by the first call to delayedAdd(2, 3) returns yet another function, which we'll call again with an argument that is another function (the next part of the chain).
So to summarize we build up a chain of functions by passing our code to whatever function delayedAdd(2, 3) returned. These functions will return other functions that we can pass our functions again.
I hope this makes the way it works somewhat clear, if not feel free to ask more.
mhlz's answer is very clear. As a supplementary, here I compose a delayedAdd for your to better understand the process
function delayedAdd(a, b) {
var sum = a + b
return function(f1) {
var result1 = f1(sum)
return function(f2) {
f2(result1)
}
}
}
Where in your example code, the function you passed as f1 is:
function (result) {
return result * result
}
and f2 is:
function (result) {
console.log(result)
}
Functions are first-class citizens in JS - that means (among others), they can take the role of actual parameters and function return values. Your code fragment maps functions to functions.
The signatures of the functions in your chained call might look like this.
delayedAdd: number -> fn // returns function type a
a: fn ( number -> number) -> fn // returns function type b
b: fn ( number -> void ) -> void // returns nothing ( guessing, cannot know from your code portion )
General setting
Of course, JS is a weakly typed language, so the listed signatures are derived from the code fragment by guessing. There is no way to know whether the code actually does what is suggested above apart from inspecting the sources.
Given that this showed up in the context of 'chaining', the signatures probably rather look like this:
delayedAdd: number x number -> fn (( fn T -> void ) -> ( fn T -> void ))
Which means that delayedAdd maps two numbers to a function x, which maps functions of arbitrary signatures to functions of the same signature as itself.
So who would do anything like this ? And why ?
Imagine the following implementation of x:
//
// x
// Collects functions of unspecified (possibly implicit) signatures for later execution.
// Illustrative purpose only, do not use in production code.
//
// Assumes
function x ( fn ) {
var fn_current;
if (this.deferred === undefined) {
this.deferred = [];
}
if (fn === undefined) {
// apply functions
while ( this.deferred.length > 0 ) {
fn_current = this.deferred.shift();
this.accumulator = fn_current(this.accumulator);
}
return this.accumulator;
}
else {
this.deferred.push ( fn );
}
return this;
}
Together with a function delayedAdd that actually returns an object of the following kind ...:
function delayedAdd ( a1, a2) {
return x ( function () { a1 + a2; } );
}
... you'll effectively register a chain of functions to be executed at some later point of time (e.g. in a callback to some event).
Notes and reminders
JS functions are JS objects
The signatures of the registered functions may actually be arbitrary. Considering them to be unified just serves to keep this exposition simpler (well ...).
Caveat
I do not know whether the outlined codeis what node.js does (but it could be ... ;-))
To be fair this pattern can be either chaining or currying(or partial application). Depending how it's implemented. Note this is a theoretical answer to provide more information about the pattern and not your specific use case.
Chaining
There is nothing special here because we can just return a function that will be called again. Functions in javascript are first class citizens
function delayedAdd(x, y) {
// In here work with x and y
return function(fn) {
// In here work with x, y and fn
return function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
This make it unreadable in my opinion. There is a better alternative.
function delayedAdd(x, y) {
// In here work with x and y
return {
then: function(fn) {
// In here work with x, y and fn
return {
then: function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
}
}
This changes the way your functions are called from
delayedAdd(..)(..)(..); // 25
is transformed to
delayedAdd().then().then()
Not only is more readable when you are passing several callback functions but allows a distinction from the next pattern called currying.
Currying
The term cames after the mathematician Haskell Curry. The definition is this
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application). It was introduced by Moses Schönfinkel and later developed by Haskell Curry.
Basically what it does is take several arguments and merge with the subsecuents and apply them to the original function passed in the first argument.
This is a generic implementation of this function taken from Stefanv's Javascript Patterns.
{Edit}
I changed my previous version of the function to one which has partial application included to make a better example. In this version you must call the function with no argument to get the value returned or you will get another partially applied function as result. This is a very basic example, a more complete one can be found on this post.
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = [],
partial = function () {
if (arguments.length === 0){
return fn.apply(null, stored_args);
} else {
stored_args = stored_args.concat(slice.call(arguments));
return partial;
}
};
return partial;
}
This are the results of the application of this function
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
schonfinkelize(add)(1, 2, 3)(5, 5)(); ==> 16
Note that add (or in your case delayedAdd) can be implemented as the curying function resulting in the pattern of your example giving you this
delayedAdd(..)(..)(..); // 16
Summary
You can not reach a conclusion about the pattern just by looking at the way the functions are called. Just because you can invoke one after the other it doens't mean is chaining. It could be another pattern. That depends on the implementation of the function.
All excellent answers here, especially #mhlz and #Leo, I'd like to touch on the chaining part you've mentioned. Leo's example shows the idea of calling functions like foo()()() but only works for fixed number of callbacks. Here's an attempt to imlpement unlimited chaining:
delayedAdd = function da(a, b){
// a function was passed: call it on the result
if( typeof a == "function" ){
this.result = a( this.result )
}
else {
// the initial call with two numbers, no additional checks for clarity.
this.result = a + b;
}
// return this very function
return da;
};
Now you can chain any number of functions in () after the first call:
// define some functions:
var square = function( number ){ return number * number; }
var add10 = function( number ){ return number + 10; }
var times2 = function( number ){ return number * 2; }
var whatIs = function( number ){ console.log( number ); return number; }
// chain them all!
delayedAdd(2, 3)(square)(whatIs)(add10)(whatIs)(times2)(whatIs);
// logs 23, 35 and 70 in the console.
http://jsfiddle.net/rm9nkjt8/3/
If we expand this syntax logically we would reach something like this:
var func1 = delayedAdd(2, 3);
var func2 = function (result) {
return result * result
};
var func3 = function (result) {
console.log(result);
};
var res = func1(func2); // variable 'res' is of type 'function'
res(func3);

memoize continuation passing style function

I'm wondering if there is a way to implement a generic "memoize" functional (as in a function with a function as input and a function as output, as python's decorators) capable of handling also cps-style functions.
for a normal function (as in "the result value comes back by the return, the parameters are only for input!") a memoize function can be as simple as (in javascript)
function memoize(fun) {
var cache = {};
return function () {
var args = Array.prototype.slice.call(arguments);
if (args in cache)
return cache[args];
var ret = fun.apply(this, arguments);
cache[args] = ret;
return ret;
};
}
but a cps-style function cannot be memoized by my simple memoize function, cause I need to evaluate "again" the arguments of type function, knowing also the parameter to pass to them.
For example, given the function
function cps(param, next) {
var ret = param + 1;
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
maybe I can find that next is a function, but its signature (well... maybe, but it's tricky), and definitely not the parameters used in the function!
Can someone tell me I'm wrong? :D
I'm interested to be able to memoize an half dozen of cps-style functions and I don't want to mess with the logic inserting a "cache" in every one of them.
I'm new to CPS, but I think you'll have to construct your functions in a particular way.
Your CPS functions have the following structure (generalising from your example):
function cps(param, next) {
var ret = someFunctionOfParam(param);
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
So, you could use your standard memoizer, and construct the CPS function as well. Keeping this separate for the sake of it, first the CPS-maker (assumes the last argument for the functions is always the function to pass to):
function cpsMaker(transformFunc) {
return function() {
var args = Array.prototype.slice.call(arguments);
var next = args.pop(); // assume final arg is function to call
var ret = transformFunc.apply(this,args);
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
}
And then the memoizer can be used in conjunction with it:
function plusOne(val) {
return val+1;
}
var memoPlusOne = memoize(plusOne);
var cpsMemPlusOne = cpsMaker(memoPlusOne);
cpsMemPlusOne(3,function(n){console.log(n)});
The point is to separate the memoization of the transform from the CPS construction.
Thank you for introducing the idea of memoized CPS; even if this answer is rubbish, it has been an eye-opener for me!

overriding a javascript function's return statement

Assume I have a js function. From some other point in the program, I want to run its code, but not its return statement. In its place, I would like to run some other return statement that references the variables in the scope of the original function.
Is there a way to do this, other than loading up the function source, replacing the return, and using eval on the result? Minimal modification of the original is possible, though it should not affect the original's performance by adding e.g. an extra function call.
You could try something like this, but I'm not sure it meets your conditions.
Edit: Fixed to work in jsfiddle
// Modified to set all "shared" variables as "members" of the function.
var test = function() {
test.val = "one";
test.val2 = "two";
return 1;
}
// Using different result
function test2() {
test();
return test.val2;
}
Unless you're able to restructure your methods to accommodate a callback or introduce some other parameter-based logic-flow (not an option for 3rd party code), you're out of luck.
Here's a callback sample (fiddle, credit to dzejkej's answer)
function foo(callback) {
var x = 2;
// pass your values into the callback
return callback ? callback.call(this, x) : x * 2;
}
document.write(foo());
document.write("<hr/>");
// specify the parameters for your callback
document.write(foo(function(x){ return x * 4;}) );
You can introduce a callback function that will get called if available otherwise "standard" value will be returned.
function test(callback) {
// ...
return callback ? callback.call(this) : /* original value returned */ "xyz";
}
test(function() { /* "this" is same as in test() */ });
EDIT:
If you want to pass variables inside callback then you just list them in the .call() function.
Example:
function test(callback) {
var a = 4;
var b = 2;
// ...
return callback ? callback.call(this, a, b) : a * b;
}
test(); // 8
test(function(a, b) { return a + b; }); // 6
See this fiddle.
Provided that you would keep variables of the outer scope function within a single object, you could try something like the following:
function original(a, b, c, rep) {
var data = {};
// Do some fancy stuff but make sure to keep everything under data
data.a = a.replace(/foo/, 'bar');
...
if ( Object.prototype.toString.call(rep) === '[object Function]' )
return rep.call(data);
return data;
}
function replacement() {
return 'foo' + this.a;
}
// Now let's make use of both the original and the replacement ...
console.log(original('foo', x, y)); // => {a: "bar", b: ...}
console.log(original('foo', x, y, replacement)); // => {a: "foobar", b: ...}
Hope, it's what you where asking for.
cheers
I think you really misunderstand the concept of return statement. The return statement of a function will simply return a value, or an object, or undefined if there is no return parameter specified.
If all you're trying to do is execute a function but "not its return statement" than you would just invoke the function and not do anything with the returned value/object:
However, if what you mean is that you would like to execute a function but not execute the "parameter" to its return statement then that literally means to selectively execute an arbitrary portion of the body of a function. And as far as I know that is not possible (without using reflection to get the function definition, modify the definition, and then dynamically invoking the modified version - which you said you didn't want to do).

Categories

Resources