Related
I have the following adding function, which appeared originally here.
add takes only one argument, but it may do so an 'infinite' number of times through the 'magic' of currying and closures.
function add (a) {
var f = b => add(a + b);
f.valueOf = () => a;
return f;
}
var add4 = add(2)(2);
var add6 = add4(2);
var add10 = add6(2)(2);
var add14 = add10(2)+2;
//var add16 = add14(2); no longer works because of type conversion above.
console.log(+add4, +add6, +add10, add14);
//logs 4, 6, 10, 14
You can see, above, that the function can keep creating functions with new a values that can go on taking additional arguments. The function can also act as a normal variable for the purpose of math operations, such as var sum = add(x)+y;.
However, once the type conversion takes place, the sum from the previous example ceases to be a function and is converted to a number.
Now that the background is out of the way, my questions is this: is there a (relatively easy) way to prevent the type coercion of the add function while still allowing it to be used in arithmetic operations? Or, in other words, is there a simple way to directly modify the valueOf (and/or a values) without adding much boilerplate (preferrably while maintaining the add(x)+y; structure)?
I think that the coercion to number you are trying to avoid does not relate to add() function, it is the way '+' operator of Javascript works. Therefore changing this behavior is not an 'easy' task. It could take changing the way javascript parser work.
The simplest workaround I can think of (not sure of course how exactly you are using this function) is to always wrap the result with extra add() call, e.g.:
add(2)(3) + 8; // 13, number
can be wrapped like this:
add( add(2)(3) + 8 ); // function with valueOf = 13
Again, not sure about your exact use case though.
This question already has answers here:
What does the construct x = x || y mean?
(12 answers)
Closed 6 years ago.
In JavaScript I recently realized you could use the OR || logical operator for assignment, and I want to know if it's considered bad practice.
In particular I have some functions that have optional array input, if the input is null or undefined I should just set it to an empty array [], if it has content it should take the content.
I found that using the assignment using the OR operator handles that perfectly in a single line, it's clean. However, it feels like the kind of thing that might be considered bad practice, or may have some horrible pitfalls I'm not considering.
Another approach is a simple if check, which is fairly safe in general.
I want to know if using the || approach seen below has any pitfalls I'm not considering, although it works in this scenario I would appreciate knowing if it works well to keep using this in the future, or to stop using it altogether.
https://jsbin.com/nozuxiwawa/1/edit?js,console
var myArray = ['Some', 'Strings', 'Whatever'];
// Just assign using OR
var pathOne = function(maybeAnArray) {
var array = maybeAnArray || [];
console.log(array);
}
// Assign using IF
var pathTwo = function(maybeAnArray) {
var array = [];
// Covers null and undefined
if (maybeAnArray != null) {
array = maybeAnArray;
}
console.log(array);
}
console.log('Path one:');
pathOne(myArray); // ['Some', 'Strings', 'Whatever']
pathOne(null); // []
console.log('\nPath two:');
pathTwo(myArray); // ['Some', 'Strings', 'Whatever']
pathTwo(null); // []
IMHO the use of the OR || for the purposes of assignment is perfectly valid and is good practice. We certainly use it in our projects and I've seen it used in lots of 3rd party projects that we use.
The thing you need to be aware of is how certain JavaScript objects can be coerced to be other values. So for example, if you're ORing values such as "", false or 0 then they are treated as false... this means that when you have the following:
function f(o) {
var x = o || -1;
return x;
}
Calling:
f(0)
...will return -1... but calling
f(1)
Will return 1 ... even though in both cases you passed a number - because 0 is treated as false -1 is assigned to x.
...that said, as long as you're aware of how the OR operator will treat the operands that you use with it - then it is good JavaScript practice to use it.
i prefer the first option, it's clear for my eyes, but when i need to share my code with others will think about to use second, will be more clear for any.
Now i'm using sonar, and prefer the second option too, will more easy to comprend for machine in inegration works.
Last idea is to use
if(maybeAnArray !== void(0))
Two reasons:
use cast and type conditionals
void(0) will works same for all browsers
Expect it helps yopu
When given the option, I prefer concise code (which must still be readable).
I would say || is common enough that it is considered good practice. Once one has seen it a few times it reads just fine.
In my opinion there are few reasons why you should rather use the second option:
First of all it's much more readable - new developers that are still learning can have problems with understanding notation like var myArray = someArrayArg || [];
If you are using some kind of code checkers like JSLint, they will return warnings and/or errors like Expected a conditional expression and instead saw an assignment. for the statement with var myArray = someArrayArg || [];
We already have something like var myArray = someArrayArg ? someArrayArg : []; that works pretty well
I'm currently looking into Haskell and i'm fascinated by some of its features, for example the end-recursive functions using an accumulator.
Questions:
Is there a construct in javascript similar to that? Or does it even
make sense regarding efficiency since javascript is not as
functional as Haskell?
Is there any library like ramda, lodash, ... that supports this way
of programming
And if so, how would you write this for example in javascript:
power_acc :: Double -> Int -> Double
power_acc x y = power_acc_h x y 1
power_acc_h :: Double -> Int -> Double -> Double
power_acc_h x 0 acc = acc
power_acc_h x y acc = power_acc_h x (y-1) (acc*x)
Is there a construct in javascript similar to that?
Yes, you can literally translate this to JS:
function power_acc(x, y) { // Double -> Int -> Double
y = y>>>0; // cast to positive int (avoiding nontermination)
return power_acc_h(x, y, 1);
}
function power_acc_h(x, y, acc) { // Double -> Int -> Double -> Double
return y == 0
? acc
: power_acc_h(x, y-1, acc*x);
}
Or does it even make sense regarding efficiency since javascript is not as functional as Haskell?
With ES6, tail recursion is fully supported in JS, and you'll get the same efficiency as with a loop (and possibly even better than haskell, as you don't create lazy multiplications).
Is there any library like ramda, lodash, ... that supports this way of programming
No library required. Although I'm sure there are libs that simplify type checking or offer nicer notation for pattern matching.
How would you write this for example in javascript?
You'd use a while loop. All accumulation functions in haskell are written this way because they can be directly optimised into a loop, and that's the notation you should use for this construct in JS (as most programmers are familiar with it):
function power_acc(x, y) { // Double -> Int -> Double
y = y>>>0; // cast to positive int (avoiding nontermination)
var acc = 1;
while (y != 0) {
acc *= x;
y -= 1;
}
return acc;
}
Mutating local variables is no harm, your function is still pure. If you're looking for an even shorter notation, use a for loop.
This is a direct translation of the Haskell code in javascript :
function power_acc(x, y) {
return aux(x,y,1);
function aux(x, y, acc) {
if (y == 0)
return acc;
else
return aux(x, y-1, acc*x);
}
}
Is there any library like ramda, lodash, ... that supports this
way of programming?
You don't need lodash or ramda for that. You can do that with your
plain javascript just as I have shown above. Also note that lodash is
an utility library providing a consistent API for operating with
collections in a functional way. It won't help you in these scenarios.
In addition to Sibi's answer, I'd like to point out that javascript (at least nodejs) actually allocates stack space. It works fine and fast up to exponents of about 13,000, then you'll get RangeError: Maximum call stack size exceeded. To carry out this experimant you need to set the base to a number close to 1 (e.g. 1.0001) or you'll get Infinity.
Haskell does not suffer from this problem. An exponent 1000 times as big (namely 13,000,000) still does not cause any space problems, though it does take a few seconds to run. This is because the recursion is a tail call, and these run in constant space in haskell.
So in a way Sibi's answer mimicks haskells expressiveness, but it still exhibits a different runtime behavior. I don't think there is anythining you can do about this.
I agree with all the answers in that a library is neither required nor particularly helpful. (I'm one of the authors of Ramda, BTW.)
Bergi's translation into JS is fine, although I think it's more idiomatic at least in browser-side JS, to embed the helper function inside a local closure, something a little closer to Sibi's answer.
The reason for the performance problem that Martin Drautzburg points out is that, although tail-call optimization is specified, it's barely implemented anywhere. One exception is Babel's support for direct recursion, so a Babel-transpiled version should get the expected performance benefit.
So if you want to do this because of the elegance and because you believe TCO will come along soon enough, and if you're not worried about current possible performance problems, then these responses are useful, and I'll even throw one more ES6 technique into the mix:
// Double -> Int -> Double -> Double
function powerAcc(x, y, acc = 1) {
return y == 0 ? acc : powerAcc(x, y - 1, acc * x);
}
powerAcc(2, 5); //=> 32
Default function parameters help replace some simple forms of pattern matching in this language, which doesn't have true pattern matching. This still relies on TCO, but makes for somewhat cleaner code. It should also run performantly in Babel.
I've been working for some time on a Javascript FP library called Ramda, and I'm having a slight problem with naming things. (You've heard the old line, right? "There are only two hard problems in Computer Science: cache invalidation, naming things, and off-by-one errors.")
In this library, (almost) every function of more than one parameter is automatically curried. And this works well for most use-cases. But there are some issues with a few functions which are non-commutative binary operators. The issue is that the English names often tend to imply something different than what happens when currying is applied. For example,
var div10 = divide(10);
sounds like it should be a function that divides its parameter by 10. But in fact it divides its parameter into 10, which is pretty clear if you look at the definition:
var divide = curry(function(a, b) {
return a / b;
});
So instead the expected:
div10(50); //=> 5 // NO!!
In fact, you get
div10(50); //=> 0.2 // Correct, but surprising!
We handle this by documenting the difference from people's possible expectations, and creating divideBy, which is just flip(divide) and subtractN, which is flip(subtract). But we haven't found a good equivalent for functions such as lt:
R.lt = curry(function(a, b) {
return a < b;
});
or its cousins lte, gt, and gte.
My own intuition would be that
map(lt(5), [8, 6, 7, 5, 3, 0, 9]);
//=> [false, false, false, false, true, true, false]
But of course, it actually returns
//=> [true, true, true, false, false, false, true]
So I'd like to do the same document-and-point-to-alternate-name routine for lt and its ilk. But I haven't been able to find a good name. The only real candidate has been ltVal and that doesn't really work when called with both arguments. We did discuss this issue, but had no good conclusions.
Have others dealt with this and come up with good solutions? Or even if not, any good suggestions for a name for the flipped versions of these functions?
Update
Someone suggested that this be closed because 'unclear what you were asking', and I guess the question really was lost a bit in the explanation. The simple question is:
What would be a good, intuitive name for a flipped version of lt?
First of all, kudos on the functional programming library that you are maintaining. I've always wanted to write one myself, but I've never found the time to do so.
Considering the fact that you are writing a functional programming library I'm going to assume that you know about Haskell. In Haskell we have functions and operators. Functions are always prefix. Operators are always infix.
Functions in Haskell can be converted into operators using backticks. For example div 6 3 can be written as 6 `div` 3. Similarly operators can be converted into functions using parentheses. For example 2 < 3 can be written as (<) 2 3.
Operators can also be partially applied using sections. There are two types of sections: left sections (e.g. (2 <) and (6 `div`)) and right sections (e.g. (< 3) and (`div` 3)). Left sections are translated as follows: (2 <) becomes (<) 2. Right sections: (< 3) becomes flip (<) 3.
In JavaScript we only have functions. There is no “good” way to create operators in JavaScript. You can write code like (2).lt(3), but in my humble opinion it is uncouth and I would strongly advise against writing code like that.
So trivially we can write normal functions and operators as functions:
div(6, 3) // normal function: div 6 3
lt(2, 3) // operator as a function: (<) 2 3
Writing and implementing infix operators in JavaScript is a pain. Hence we won't have the following:
(6).div(3) // function as an operator: 6 `div` 3
(2).lt(3) // normal operator: 2 < 3
However sections are important. Let's start with the right section:
div(3) // right section: (`div` 3)
lt(3) // right section: (< 3)
When I see div(3) I would expect it to be a right section (i.e. it should behave as (`div` 3)). Hence, according to the principle of least astonishment, this is the way it should be implemented.
Now comes the question of left sections. If div(3) is a right section then what should a left section look like? In my humble opinion it should look like this:
div(6, _) // left section: (6 `div`)
lt(2, _) // left section: (2 <)
To me this reads as “divide 6 by something” and “is 2 lesser than something?” I prefer this way because it is explicit. According to The Zen of Python, “Explicit is better than implicit.”
So how does this affect existing code? For example, consider the filter function. To filter the odd numbers in a list we would write filter(odd, list). For such a function does currying work as expected? For example, how would we write a filterOdd function?
var filterOdd = filter(odd); // expected solution
var filterOdd = filter(odd, _); // left section, astonished?
According to the principle of least astonishment it should simply be filter(odd). The filter function is not meant to be used as an operator. Hence the programmer should not be forced to use it as a left section. There should be a clear distinction between functions and “function operators”.
Fortunately distinguishing between functions and function operators is pretty intuitive. For example, the filter function is clearly not a function operator:
filter odd list -- filter the odd numbers from the list; makes sense
odd `filter` list -- odd filter of list? huh?
On the other hand the elem function is clearly a function operator:
list `elem` n -- element n of the list; makes sense
elem list n -- element list, n? huh?
It's important to note that this distinction is only possible because functions and function operators are mutually exclusive. It stands to reason that given a function it may either be a normal function or else a function operator, but not both.
It's interesting to note that given a binary function if you flip its arguments then it becomes a binary operator and vice versa. For example consider the flipped variants of filter and elem:
list `filter` odd -- now filter makes sense an an operator
elem n list -- now elem makes sense as a function
In fact this could be generalized for any n-arity function were n is greater than 1. You see, every function has a primary argument. Trivially, for unary functions this distinction is irrelevant. However for non-unary functions this distinction is important.
If the primary argument of the function comes at the end of the argument list then the function is a normal function (e.g. filter odd list where list is the primary argument). Having the primary argument at the end of the list is necessary for function composition.
If the primary argument of the function comes at the beginning of the argument list then the function is a function operator (e.g. list `elem` n where list is the primary argument).
Operators are analogous to methods in OOP and the primary argument is analogous to the object of the method. For example list `elem` n would be written as list.elem(n) in OOP. Chaining methods in OOP is analogous to function composition chains in FP[1].
The primary argument of the function may only be either at the beginning or at the end of the argument list. It wouldn't make sense for it to be anywhere else. This property is vacuously true for binary functions. Hence flipping binary functions makes them operators and vice-versa.
The rest of the arguments along with the function form an indivisible atom called the stem of the argument list. For example in filter odd list the stem is filter odd. In list `elem` n the stem is (`elem` n).
The order and the elements of the stem must remain unchanged for the expression to make sense. This is why odd `filter` list and elem list n don't make any sense. However list `filter` odd and elem n list make sense because the stem is unchanged.
Coming back to the main topic, since functions and function operators are mutually exclusive you could simply treat function operators differently than the way you treat normal functions.
We want operators to have the following behavior:
div(6, 3) // normal operator: 6 `div` 3
div(6, _) // left section: (6 `div`)
div(3) // right section: (`div` 3)
We want to define operators as follows:
var div = op(function (a, b) {
return a / b;
});
The definition of the op function is simple:
function op(f) {
var length = f.length, _; // we want underscore to be undefined
if (length < 2) throw new Error("Expected binary function.");
var left = R.curry(f), right = R.curry(R.flip(f));
return function (a, b) {
switch (arguments.length) {
case 0: throw new Error("No arguments.");
case 1: return right(a);
case 2: if (b === _) return left(a);
default: return left.apply(null, arguments);
}
};
}
The op function is similar to using backticks to convert a function into a operator in Haskell. Hence you could add it as a standard library function for Ramda. Also mention in the docs that the primary argument of an operator should be the first argument (i.e. it should look like OOP, not FP).
[1] On a side note it would be awesome if Ramda allowed you to compose functions as though it was chaining methods in regular JavaScript (e.g. foo(a, b).bar(c) instead of compose(bar(c), foo(a, b))). It's difficult, but doable.
We all know that naming in programming is serious business, particularly when it comes to functions in curried form. It is a valid solution to handle this issue with a programmatic approach as Aadit did in his response. However, I see two issues with his implementation:
it introduces function operators with left/right sections in Javascript, which are not part of the language
it requires a hideous placeholder or undefined hack to achieve that
Javascript has no curried operators and thus no left or right sections. An idiomatic Javascript solution should consider that.
The cause of the problem
Curried functions don't have a notion of arity, because every function invocation requires exactly one argument. You can either partially or completely apply curried functions without any helpers:
const add = y => x => x + y;
const add2 = add(2); // partial application
add(2)(3); // complete application
Usually the last argument of a function is its primarily one, because it is passed through function compositions (similar to objects that allow method chaining). Consequently when you partially apply a function, you want to pass its initial arguments:
const comp = f => g => x => f(g(x));
const map = f => xs => xs.map(x => f(x));
const inc = x => x + 1;
const sqr = x => x * x;
comp(map(inc)) (map(sqr)) ([1,2,3]); // [2,5,10]
Operator functions are special in this regard. They are binary functions that reduce their two arguments to a single return value. Since not every operator is commutative (a - b !== b - a) the argument order matters. For this reason operator functions don't have a primarily argument. But people are accustomed to read expressions with them in a certain way depending on the type of application:
const concat = y => xs => xs.concat(y);
const sub = y => x => x - y;
// partial application:
const concat4 = concat(4);
const sub4 = sub(4);
concat4([1,2,3]); // [1,2,3,4] - OK
sub4(3); // -1 - OK
// complete application:
concat([1,2,3]) (4); // [4,1,2,3] - ouch!
sub(4) (3); // -1 - ouch!
We defined concat and sub with flipped arguments, so that partial application works as expected. This evidently doesn't apply to complete application though.
A manual solution
const flip = f => y => x => f(x) (y);
const concat_ = flip(concat);
const sub_ = flip(sub);
concat_(xs) (4); // [1,2,3,4] - OK
sub_(4) (3); // 1 - OK
concat_ and sub_ correspond to left sections in Haskell. Please note that function operators like add or lt don't need a left section version because the former are commutative and the latter are predicates, which have logical counterparts:
const comp2 = f => g => x => y => f(g(x) (y));
const map = f => xs => xs.map(x => f(x));
const flip = f => y => x => f(x) (y);
const not = x => !x;
const notf2 = comp2(not);
const lt = y => x => x < y;
const gt = flip(lt);
const lte = notf2(gt);
const gte = notf2(lt);
map(lt(5)) ([8, 6, 7, 5, 3, 0, 9]);
// [false, false, false, false, true, true, false]
map(gte(5)) ([8, 6, 7, 5, 3, 0, 9]);
// [true, true, true, true, false, false, true]
Conclusion
We should solve this naming issue rather with a naming convention then with a programmatic solution which extends Javascript in a non-idiomatic way. Naming conventions are not ideal...well, just like Javascript.
What is the meaning of && in this JavaScript code?
function doIt(a) {
var b = a.parents(),
c = 1;
return b.each(function() {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
}
normally I would think this would be a logical operator AND, but I can't figure out what it does in this line.
The logical AND operator in this case is used in place of an IF-statement. It will set c to 0 if jQuery(this).hasClass("free-content") returns a truthy value.
It's equivalent to:
if (jQuery(this).hasClass("free-content")) {
c = 0;
}
You wondering what it means is actually the reason I dislike this type of coding and consider it a bad practice. It's hard to read and can create confusion, which in turn can create bugs.
It's also worth noting what logical AND returns, if you want to use the returned value:
(Logical AND) Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Here's an example showing, in my opinion, bad code since it's hard to follow:
var foo = bar && baz || qux;
The above code is equivalent to:
var foo;
if (bar && baz) {
foo = baz;
} else {
foo = qux;
}
Summary: Do not use logical operators as a nifty way to replace IF-statements or to save keystrokes. It will most likely come back and bite you or someone else in the ass.
I know there will be people arguing against me on this (usually the same people who doesn't want to use semicolon because ASI), but it's just a really bad idea to write code that only an expert would understand. There's no argument against it.
return b.each(function () {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
b.each loops over all entries in b, and checks whether the current element has the class free-content set. Only if that yields true, the second part of the expression is evaluated – because they are concatenated via &&, and JavaScript stops evaluating such an expression when the first part is false, because then the whole expression can’t become true any more.
So if there is an element with that class, the second part is evaluated – and thereby c is set to the value 0 (because that’s the assignment operator = there, and not a comparison).
And after that each loop is finished, the value of c is returned to the outside – because each() and c are connected via the comma operator , here, which evaluates its operands from left to right and then “returns” the second one.
JavaScript allows a lot of “fancy” coding like this, but as Marcus already said in his answer, that is hard to read, and there is no actual advantage here over, say
b.each(function() {
if(jQuery(this).hasClass("free-content")) {
c = 0;
return false;
}
});
return c;
I added the return false here inside the each loop, because once we found an element with that class, we don’t need to search the rest of them any more – that’s something that the person who came up with the original code forgot to do in all their “fancy-ness” … their loop will continue to iterate over all of b’s elements, not matter if it finds the element it is looking for in the first round already.