Imagine you have a function addTogether that can take any number of parameters, and adds them all after the last parameter. I know this could be done ridiculously easily with a List, but I'm just trying out a concept here. I think I remember being able to do so in JavaScript by accessing the arguments object (here). Would it be possible to implement an argument object monad in haskell that translates the arguments applied to a native function (syntactically, so you don't have to explicitly use >>=) into a list of arguments?
http://chris-taylor.github.io/blog/2013/03/01/how-haskell-printf-works/ - a good link "Polyvariadic Functions and Printf"
Related
I was wondering about how functions work in javascript, I noticed in some cases, things like array.sort, array.filter, and event listeners the code that calls (not declares) the function (not using functionless or inline), usually FunctionName have parenthesis with the arguments in there (FunctionName(arg1, arg2, arg3...)). Are parameters “automatically” passed into the function?
Now I understand, looking wikipedia's article on callback looking at the alert, it looks like it first calls "calculate" first, supplies the 2 numbers and the function (that function name only, without the open and then closing parenthesis), and THEN uses the parameters for callbackFunction. So without the parenthesis on the function name is like without using bracket on an array name.
Minimal example: Say I have the higher-order function
const my_fn = (a) => (b) => a + b
that, when called like so:
my_fn(42)
returns the function (b) => 42 + b.
Would it be correct to refer to my_fn as a "template function"?
I know that, in languages such as C++, the word "template" has a very specific technical meaning.
But in JavaScript, there is (AFAIK) no built-in template in syntax in the way that there is in C++.
I don't want to abuse terminology.
Is it correct to refer to higher-order functions in JS as template functions, and vice-versa?
(related, optional question: is there a difference between skillfully using higher-order functions in JS and doing "generic programming" in this language?)
I wouldn't call this a “template” function, though I might call this function a “function factory.” To me, the word “template” in languages like C++ implies the specific goal of applying one function to a range of different data types.
A function like the example you gave doesn’t really accomplish anything new in terms of “generic programming” because it's not designed to produce functions that operate on different types of values. Javascript is not strict about types, so you can pass a value of any type to your function and the language will do its best to work with it. You don't have to do anything additional to make a function apply to different types of objects; every function accepts every kind of object unless the programmer adds explicit typechecking logic.
Coming from Python into some JavaScript-based APIs I'm confused by some of the syntax. And I can't find an answer in all of the noise of random information about declaring functions.
In Python, you can mix specifying arguments to a function base on the order and based on the name:
np.arange(1,5,step = 5)
Can you do something like that in Javascript?
If there is a function like:
ee.List.sequence(start,end, step, count)
and it only needs three out of the four arguments I can really easily specify the start, end, step, like so:
ee.List.sequence(1,100,2)
But, do I have to use the object notation to specify the count?
ee.List.sequence({start=1,end=100, count=50})
Is there a shorthand, like in Python, such as:
ee.List.sequence(1,100,{count=50})
or
ee.List.sequence(1,100,,50)?
It seems that what you are really asking is less about JavaScript as a language and more about specific APIs. So, here's some things to know:
In JavaScript, all arguments are optional. In other words, there is no way to enforce that a function is called with the proper amount or order of arguments. It's up to the caller to know the signature of the function its calling and call it appropriately. It's also up to the creator of the function to be prepared for some or all of the arguments to not be passed. There is an arguments array-like object that all functions have that can assist with this, but checking the inputs is also pretty easy. Here's an example:
// Here's an example of a function that does not explicitly declare any arguments
function foo1(){
// However, arguments might still be passed and they can be accessed
// through the arguments object:
console.log("Arguments.length = ", arguments.length);
console.log(arguments);
}
foo1("test", "boo!"); // Call the function and pass args even though it doesn't want any
// ***********************************************
// Here's an example of a function that needs the first arg to work,
// but the seond one is optional
function foo2(x, y){
if(y){
console.log(x + y);
} else {
console.log(x);
}
}
foo2(3);
foo2(4, 5);
In JavaScript, your functions can take any valid primitive or object. Again, it's up to the caller to know what the API is and call it correctly:
function foo1(string1, number1, object1, string2){
console.log(arguments);
}
foo1("test", 3.14, {val:"John Doe"}, "ing");
I've found the answer in this JavaScript tutorial.
In general, yes, the default JavaScript function can take anything as an argument. But any well-written API function, with specified arguments (and default values), will not allow this to happen.
So the two options are
Supply the arguments in order, without naming them.
`ee.List.sequence(1,100,2)`
Pass them in a named object (where suddenly order doesn't matter)
`ee.List.sequence({start=1,end=100, count=50})`
There is no mixed notation like Python has
ee.List.sequence(1,100,{count=50})
BUT there is a workaround for 1
In case you want to use a different combination of arguments, one can supply null values to the arguments that are omitted. So the following can be used:
`ee.List.sequence(1,100,null,50)`
I tried googling but couldn't find a precise answer, so allow me to try and ask here. If the question does not seem proper, please let me know and I'll delete it.
In JS you've got three different way of writing certain build in functionalities:
str.length
str.toString()
parseInt(str)
I wonder if there is a reason behind these different ways of writing. As a new user I don't grasp why it couldn't be streamlined as: length(str) / toString(str) / parseInt(str) or with dot formulation.
I however think if I do know the reason behind these differences, it would give me a better understanding of JavaScript.
Length is one of the attributes of string in JavaScript. Hence you use string.length to get the length of the string.
toString is a function for string objects, hence we use stringobj.toString().
parsInt(str) is a global function which takes string as a parameter.
JavaScript is object-oriented, so there are functions or procedures which require first an object to use as this in their bodies. str.length is a property, both syntactically and semantically. It doesn't require any parameters and represents some quality of the object. obj.toString() is a method (a function attached to an object), which doesn't represent any characteristics of the object, but rather operates on its state, computes some new values, or changes the state of the object a lot. parseInt(str) is a "global" function, which represents an operation not attached to any type or object.
Under the hood, these three ways may be well implemented with just calling a function, passing this as the first parameter (like C# does, for example). The semantic difference is the important one.
So why not use just the third syntax, like for example PHP does? First, it doesn't bloat the global environment with lots of functions which only work for one specific case and type, allowing you to specify any new function you want without breaking the old functionality. Second, it ecourages you to use object-oriented concepts, because you can already see working objects and methods in the language, and can try to make something similar.
And why isn't parseInt a method? It can as well be str.toInt() without any issues, it's just the way JavaScript designers wanted it to be, although it seems also a bit logical to me to make it a static method Number.parseInt(str), because the behaviour of the function is relevant more to the Number type than the String type.
JavaScript is based around objects. Objects have properties (e.g. a User object may have name and age properties). These are what define the user and are related to the user. Properties are accessed via dot-notation or brackets notation (to access Eliott’s age, we’ll use either eliott.age or eliott['age'] — these are equivalent).
These properties can be of any type — String, Number, Object, you name it — even functions. Now the proper syntax to call a function in JS is to put round brackets: eliott.sayHello(). This snippet actually fetches Eliott’s sayHello property, and calls it right away.
You can see Eliott as a box of properties, some of which can be functions. They only exist within the box and have no meaning out of the box: what would age be? Whose age? Who’s saying hello?
Now some functions are defined at the global level: parseInt or isNaN for instance. These functions actually belong to the global box, named window (because legacy). You can also call them like that: window.parseInt(a, 10) or window.isNaN(a). Omitting window is allowed for brevity.
var eliott = {
name: 'Eliott',
age: 32,
sayHello: function () { console.log('Hello, I’m Eliott'); }
};
eliott.name; // access the `name` property
eliott.age; // access the `age` property
eliott.sayHello; // access the `sayHello` property
eliott.sayHello(); // access the `sayHello` property and calls the function
sayHello(eliott); // Reference error: `window.sayHello` is undefined!
Note: Some types (String, Number, Boolean, etc.) are not real objects but do have properties. That’s how you can fetch the length of a string ("hello".length) and reword stuff ("hello, Eliott".replace("Eliott", "Henry")).
Behaviour of these expressions is defined in ECMAScript grammar. You could read the specification to understand it thoroughly: ECMAScript2015 specification. However, as pointed out by Bergi, it's probably not the best resource for beginners because it doesn't explain anything, it just states how things are. Moreover I think it might be too difficult for you to be able to grasp concepts described in this specification because of the very formal language used.
Therefore I recommend to start with something way simpler, such as a very basic introduction to JavaScript: JavaScript Basics on MDN. MDN is a great resource.
But to answer your question just briefly:
str.length is accessing a property of the str object.
parseInt(str) is a function call
str.toString() is a call of a function which is a property of the str object. Such functions are usually named methods.
Functions and methods are in fact very similar but one of the differences (except for the obvious syntax difference) is that methods by default have context (this) set to refer to the object which they're part of. In this case inside of toString function this equals to str.
Note: Accessing a property (as in str.length) could in effect call a getter function but it depends on how the object is defined, and is in fact transparent for the user.
I've always passed arguments to a function like so:
setValue('foo','#bar')
function setValue(val,ele){
$(ele).val(val);
};
Forgive the silly example. But recently I have been working on a project that has some functions that take a lot of arguments. So I started passing the arguments through as an object (not sure if that's the correct way to put that), like so:
setValue({
val:'foo',
ele:'#bar'
});
And then in the function:
function setValue(options){
var value = options.val;
var element = options.ele;
$(element).val(value);
};
My question is, is there a better way to do that? Is it common practice (or okay) to call these 'options'? And do you typically need to 'unpack' (for lack of a better term) the options and set local vars inside the function? I have been doing it this way in case one of them was not defined.
I'm really looking to not create bad habits and write a bunch of code that is ugly. Any help is appreciated and + by me. Thanks.
I do the exact same thing, except I don't declare a new variable for each option inside the function.
I think options is a good name for it although I shorten it to opts.
I always have a "default" object within the function that specify default values for each available option, even if its simply null. I use jQuery, so I can just use $.extend to merge the defaults and user-specified options like this: var opts = $.extend({}, defaults, opts);
I believe this is a great pattern. I've heard an options object like this referred to as a "builder object" in other languages (at least in the context of object creation). Here are some of the advantages:
Users of your function don't have to worry about what order the parameters are in. This is especially helpful in cases like yours where the method takes a lot of arguments. It's easy to get those mixed up, and JavaScript will not complain!
It's easy to make certain parameters optional (this comes in handy when writing a plugin or utility).
There are some pitfalls though. Specifically, the user of your function could not specify some of the options and your code would choke (note that this could also happen with a normal JS function: the user still doesn't have to supply the correct arguments). A good way for handling this is to provide default values for parameters that are not required:
var value = options.val || 0;
var element = options.ele || {};
$(element).val(value);
You could also return from the function immediately or throw an exception if the correct arguments aren't supplied.
A good resource for learning how to handle builder objects is to check out the source of things like jQueryUI.
I realize this question is a year old, but I think the cleanest way to pass an arbitrary number of arguments to a JavaScript function is using an array and the built in apply method:
fun.apply(object, [argsArray])
Where fun is the function, object is your scope/context in which you want the function to be executed and the argsArray is an array of the arguments (which can hold any number of arguments to be passed.
The current pitfall right now is that the arguments must be an array (literal or object) and not an array-like object such as {'arg' : 6, 'arg2' : "stuff"}. ECMAScript 5 will let you pass array-like objects, but it only seems to work in FireFox at the moment and not IE9 or Chrome.
If you look at the jQuery implementation, it uses an options class to handle most of the arbitrary-number-of-parameters functions, so I think you are in good company.
The other way is to test for arguments.length, but that only works if your arguments are always in the same order of optionality.
It's worth remembering that all functions have a bonus parameter called arguments that is an object very much like a JS array (it has length but none of the array functions) that contains all the parameters passed in.
Useful if you want to pass in a range of parameters (e.g.
function Sum() {
var i, sum = 0;
for (i=0; i < arguments.length; i++){
sum+=arguments[i];
}
return sum;
};
If this isn't the case and you just have a lot of parameters, use the params object as you've described.
Nothing wrong with that practice.
"Options" seems like as good a name as any.
You don't need to "unpack" them, but if you'll be accessing the same item several times, it will be a little more efficient to reference them in local variables because local variable access is generally quicker than property lookups.