What is this pattern f(a)(b)(c) called? - javascript

function setStyle(x) {
with (x.style) {
padding = '10px'
marginBottom = '10px'
width = '100%'
}
return setStyle
}
setStyle(account)(password)(login)
I often use the above pattern, but when I need to talk about it, I have no idea what is it called? How to refer to this kind of approach in the conversation?
UPDATE:
Someone closed this question as duplicate, but I cannot see why is that a duplicate. Other question is about some framework, the poster is trying to understand the code. I do not try to understand the code, I am asking about an English term for a known pattern. Even though the discussed concept is the same, the question is different. It is like saying that "Who was the youngest in Jasckson's Five" and "Whose album is Thriller" both are the same question, only because it happens to be about the same person. But those are different questions, not the same.

This pattern is not "function chaining", because chained (=composed, pipelined) functions work by passing result of one function as an argument to the next one. For example, if you have something like:
str = removeBadChars(str)
str = makeLowerCase(str)
str = convertToURL(str)
you can rewrite this more concisely as
str = chain(removeBadChars, makeLowerCase, convertToURL)(str)
(Exercise: write chain()).
Your pattern doesn't appear to have a name, probably because it's fairly useless. Mr. Crockford coined the term retursion,
but it doesn't seem to be used widely.
Note that this pattern is essentially anti-functional, because in functional programming we prefer to work with pure functions, while a "retursive" function can only do anything useful as a side effect.
UPD: this reasoning applies to functions that just blindly return itself, like in your example, however, the f()()() syntax can also be used with functions that return something else on each invocation. In this case, the "root" function accepts a hidden parameter ("accumulator") used to carry state around. A good example of such approach would be chain() like above, but written in the applicative style: chain(func1)(func2)(func3):
function chain(f, fun) {
fun = fun || function(x) { return x };
if(typeof f != "function")
return fun(f);
return function(x) {
return chain(x, function(y) { return f(fun(y)) })
}
}
// Example:
makeLowerCase = function(str) { return str.toLowerCase() };
removeBadChars = function(str) { return str.replace(/\W/g, "") };
makeURL = function(str) { return "http://" + str };
funcs = chain(makeLowerCase)(removeBadChars)(makeURL);
x = funcs('!!! HELLO ???');
alert(x);
In this case, this syntax is used to implement "partial application", because we return a closure which calls the root function yet again, with a predefined second argument.

Related

Confused with input/type validation and monads

I just got to know better functional programming and how many stuff we have in javascript that I did not know it was actually functional.
So I think I understood the idea of the monad and functors. The thning I don't get is,e specificaly in javascript, how validating type/inputs with libs like monet or validate, makes any of the code cleaner than just return an Either with its value being the error value?
I like this talk because it explains in way I can better understand the idea behind fp and composition at least, but the implementations that I have seem in javascript does not help with readabitlity.
Just to give an example let say I have the following code:
function Just(aValue) {
this.v = function () {
return aValue;
}
}
function Invalid(anError) {
Just.call(this, anError); //call the parent because this function does nothing but change the instance type.
this.prototype = Object.create(Just.prototype); //we set the prototype to the function we want to inherit.
this.constructor = Invalid; // we set back the constructor to the this function so it gets its instance type.
}
function Title (aTitle) {
//cant be blank
if (aTitle == '') {
return new Invalid ('Title can\'t be blank');
}
//cant be bigger than
if (aTitle.length > 45) {
return new Invalid ('Title can\'t be bigger then 45 chars');
}
return new Just(aTitle);
}
function Description (aDescription) {
if (aDescription) {
//cant have more than 3 lines and
if (aDescription.split(/\r\n|\r|\n/).length > 3) {
return new Invalid ('not more than 3 lines');
}
//line cant be bigger than 65 chars
for (var index = 0; index < aDescription.split(/\r\n|\r|\n/).length; index++) {
if (aDescription[index].length > 65) {
return new Invalid ('lines cant be bigger than 65 chars');
}
}
}
function Item(aTitle, aDescription) {
this.Title = new Title(aTitle),
this.Description = new Description(aDescription)
}
var validItem = new Item('ValidTitle', 'ValidDesc');
//returns {Title:Just<ValidTitle>,Description:Just<ValidDesc>}
var InvalidItem = new Item('','');
//returns {Title:Invalid<'Title cant be empty'>,Just<''>}
This will return an Item object with errors or not, which I believe can be easily be retrieved by checking the types of the Item obj literal returned. Let's say this gets way bigger or whatever reasons gets more complicated than that. How can the "monad" validation help me? Any examples in javascript similar to the talk would be great.
The example code is just me trying to grasp the idea in practice. No idea id that is a proper implementation or not. FIY it is the way it is on purpose, I know es6 has proper classes and etc. This is all for the sake of understanding the concepts.
Thank you all.

Generalizing two functions which act inversely on two properties

I have these two functions, and I feel there must be an elegant functional way to generalize them.
$scope.togglePick = function(){
let targetPhoto = $scope.photoImport.data[indexService.current];
targetPhoto.pick = !targetPhoto.pick;
if(targetPhoto.reject && targetPhoto.pick) {
targetPhoto.reject = false;
}
}
$scope.toggleReject = function() {
let targetPhoto = $scope.photoImport.data[indexService.current];
targetPhoto.reject = !targetPhoto.reject;
if (targetPhoto.reject && targetPhoto.pick) {
targetPhoto.pick = false;
}
}
I suppose I could pass in string params togglePick = toggle('pick', 'reject') and use [] notation in the toggle function, but this feels like magic strings... even though they're property names, I'm uncertain. I could also have:
function toggle(magicFlag){
let primary = magicFlag ? 'pick' : 'reject';
let secondary = magicFlag ? 'reject' : 'pick';
...
targetPhoto[primary] = !targetPhoto[primary];
...
}
Again, ick, magic flag. Is there a more elegant way to do this than longhand in each function?
The amount of code in these functions and the slight differences makes them fine the way they are. Without working the property string weirdness, I don't see how you really make this generic while remaining readable. Sometimes it's okay not to have the most generic code you possibly can. That line in the sand has to be drawn somewhere.

Better method of checking a bunch of conditions

I'm new to javascript and still coming to terms with the language's nuances.
I have a piece of code where I have to check a set of conditions on a particular variable.
if (a=="MAIN_DOMAINNAME" || a=="DOMAIN_SERIAL" || a=="DOMAIN_REFRESH" || a=="DOMAIN_RETRY" || a=="DOMAIN_EXPIRE" || a=="DOMAIN_NEGTTL" || a=="MAIN_NS") {
Is there a better way to do this conditional check, like say:
if a is one of ("DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH" ) {?
Assuming a relatively modern browser, you can use Array.indexOf (spec)
if (["DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH"].indexOf(a) !== -1)
Note - you can easily shim it for older browsers (see the mdn link on how).
A regex would be shorter and works everywhere :
if ( /^(MAIN_DOMAINNAME|DOMAIN_SERIAL|DOMAIN_REFRESH|..)$/.test(a) ) {
// do stuff
}
FIDDLE
var ars = ["DOMAIN_SERIAL", "MAIN_DOMAINNAME", "DOMAIN_REFRESH"];
if(ars.some(function(ar){ return a === ar; })){
// do smth
}
Should mention the switch statement as it should be working fine with the example given in the question.
switch(a) {
case('MAIN_DOMAINAME'):
case('DOMAIN_SERIAL'):
case('DOMAIN_REFRESH'):
case('DOMAIN_RETRY'):
console.log('Go wild.');
break;
}
Not as lightweight as the other answers, but it's readable and matches (a === b).
I prefer the regex solution already provided by adeneo, but if you want something that matches the
if a is one of (...
wording from the question reasonably closely you can do this:
if (a in list("MAIN_DOMAINNAME", "DOMAIN_SERIAL", "DOMAIN_REFRESH", "DOMAIN_RETRY")) {
// do something (rest of list omitted to avoid scrolling)
}
by providing a helper function to turn the list into an object:
function list() {
var o={}, i;
for (i=0; i < arguments.length; i++) o[arguments[i]] = true;
return o;
}
Of course you can omit the helper function and just use an object literal, but that's ugly:
if (a in {"MAIN_DOMAINNAME":1, "DOMAIN_SERIAL":1, "DOMAIN_REFRESH":1}) {

Shorthand for if sentence

Why I am asking
I have been having a lot of trouble understanding the shorthand for the if sentence in JavaScript, and I haven't found an article or tutorial that described it well. And that's why I am stuck opitimizing my little code. And I am new to JavaScript, so if someone could give me a basic understanding of the shortning of this code, I would very much appreciate you telling me the magic behind the code.
What I need help with
I am going to use the exact same code in a lot of functions. Therefore, I want to optimize it and make it shorter version of the code.
function welcomemessage() {
if (br == 1) {
hello();
}
else {
hey();
}
}
Use the ternary operator.
function welcomemessage() {
(br == 1) ? hello() : hey();
}
The ternary operator is useful, and not difficult to understand. here's how it works.
(condition) ? (true) : (false)
Edit:
Since JS treats functions as first class objects, it is possible to create a wrapper. Something like below (not tested though)
function ternaryWrapper(br, functionTrue, functionFalse){
return (br == 1) ? functionTrue : functionFalse;
}
//call it
ternaryWrapper(2,hello, hey);
Even shorter:
function welcomemessage(br){
[hello,hey][br-1](); //This will work.
}
welcomemessage(1); //hello();
welcomemessage(2); //hey();
Fun Fact:1
To make your script hard to read for someone else, do it like this:
function welcomemessage(){
return br==1 && (hello(),1) || (hey(),1); //This will work too.
}
1 Totally not related to the answer.
Update
var something = ( (br == 1) ? hello() : hey() );
something will be the value hello() or hey() returned.
Or:
var msgfuncs = [ hey, hello ];
function welcommessage() { msgfuncs[br](); }
(assumes that when "br" isn't 1 it's 0, which of course may be an invalid assumption.)
If the choice is made with different functions, just put the array directly in the surrounding function:
function welcomemessage() {
[ hey, hello ][br]();
}
If you want to make the decision and save the function to call later, you can do this:
var messageFunction = [ hey, hello ][ br ];
then any time later:
messageFunction();
In case br is always be numeric, the xbonez answer can be optimized a little bit by using strict comparison === (because it is a little bit faster):
function welcomemessage() {
(br === 1) ? hello() : hey();
}
And another interesting option is:
function welcomemessage() {
(br - 1) ? hey() : hello();
}
This last function works because when br is 1, it will turn to 0 (which is a falsish value) and evaluate to false, triggering hello(), and for the rest it will trigger hey()

Expressing Y in term of SKI-Combinators in JavaScript

I was fiddling with combinators in JavaScript and was being proud of (hopefully) getting S to work when I stumbled upon Wikipedia saying: "The Y combinator can be expressed in the SKI-calculus as: Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))", so I had to try that:
var I = function (x) {
return x;
};
var K = function (x) {
return function(){
return x;}
};
var S = function (x) {
return function (y) {
return function (z) {
return x(z)(y(z));
}
}
};
var Y = S (K(S(I)(I))) (S(S(K(S))(K)) (K(S(I)(I))));
Y; //evals to:
//function (z) {return x(z)(y(z));}
//And this (lifted from Crockford's Site):
var factorial = Y(function (fac) {
return function (n) {
return n <= 2 ? n : n * fac(n - 1);
};
}); //fails:
//RangeError: Maximum call stack size exceeded
What am I doing wrong? Am I not translating that expression correctly? Is there something wrong with how I'm going about this? Does it even make sense? Most of what's to be read about stuff like this just makes my brain want to explode, so the point of this exercise for me was mainly to see if I understood the notation (and would thus be able to translate it to JavaScript).
Oh, and, by the way: what got me reading & fiddling again was that what prototype.js implements as Prototype.K is actually the I combinator. Has anyone noticed?
The problem here is that you are using a strictly evaluated programming language. The Y-combinator, pretty much like any other fixed point combinator, will only work properly when your functions are called by need, or 'lazily evaluated'.
I know of a way to work around this (one of my professors looked into it a while ago), but it will make your code completely unreadable.
Below I've shown what's going on exactly, hoping you can see why JavaScript can't handle a straightforward implementation of SKI-calculus.
This is what Y looks like after JavaScript evaluated your SKI-expression:
var Y = function (q) {
return (function(p){return q(p(p))})(function(p){return q(p(p))});
};
Now let's see what happens if you feed it your function function (fac) { ... }. Let's call that function f:
var factorial = (function(p){return f(p(p))})(function(p){return f(p(p))});
Since the first anonymous function is applied to an argument, it will be evaluated into this:
var factorial = f(
(function(p){return f(p(p))})(function(p){return f(p(p))})
);
In a lazily evaluated language, the argument to f would now be left alone, and f itself would be evaluated. However, because JavaScript is a strictly evaluated language (or 'call-by-value'), it wants to know what argument it needs to pass to function f before actually running that function. So let's evaluate that argument, shall we?
var factorial = f(f(
(function(p){return f(p(p))})(function(p){return f(p(p))})
)
);
I guess now you're starting to see now where things go wrong, and how the Y-combinator actually works. In any case, your JavaScript machine will run out of stack space, because it's trying to build an infinite stack of calls to f.

Categories