Related
A piece of code I'm working on at the moment would benefit, potentially more from a semantic point of view, from the ability to have a call to 'just an object' return something other than the whole object. This may sound confusing so I shall elaborate with code.
If I had an Object constructor 'rectangle' defined as:
function Rectangle(side1, side2) {
this.area = side1 * side2;
}
What I'd then like to be able to do is call an instance of that object and then get a return value for it like so:
var foo = new Rectangle(1, 2);
return foo;
As it stands the return value will be something like a key:value pair. However, what I want is the return value to be something like "Hi Dave". I have read through various documentations on the Internet and have failed to find anything suitable.
Whilst I'm aware I could assign a property name to the "Hi Dave" statement and call that instead; for my application that does not make semantic sense. I am also aware that 'this' is not a variable and thus I can't just assign to that.
Any help would be much appreciated.
EDIT: Made an adjustment over what I want returned to avoid confusion.
I think the closest you can come to this is to override the .prototype.valueOf and .prototype.toString methods. This doesn't give you exactly what you wanted, which is being able to get a different return value, but, it will give you the desired value when used with strings.
class StringRectangle {
constructor(val1, val2) {
this.area = val1 * val2;
this.__proto__.valueOf = () => 'My area is: ' + this.area;
this.__proto__.toString = () => 'My area is: ' + this.area;
}
}
const stringRect = new StringRectangle(2, 3);
// This is where the above fails for what you want
stringRect; // StringRectangle {area: 6}
// But, maybe these are good enough, since you're displaying strings?
// Uses valueOf
'My area is: ' + stringRect + '!'; // My area is: 6!
// Uses toString
`My area is: ${stringRect}!` // My area is: 6!
Looking further into your ideal solution, I don't think there is any way to do it cross browser, if at all. The value of references is stored at the machine level. Ex: what does console.log actually do? I have no idea without looking into the V8 code:
console.log(console.log); // function log() { [native code] }
It's that native code bit that's the limiting part here. If you want to delve into the native code, start here for the V8 console.log.
Thanks for the learning here; haven't delved this much into prototypes in a while.
You can define a static method on the class
class Rectangle {
constructor(side1, side2) {
this.area = side1 * side2;
}
static whoAmI() {return "I am a rectangle"}
}
var foo = new Rectangle(1, 2);
Rectangle.whoAmI();
I'm learning to use Ramda and have come across compose. But I can't grasp the purpose of it
let value = R.compose( calledThird, calledSecond, calledFirst('hello') );
// vs
let value = calledThird( calledSecond( calledFirst('hello') ) );
Is it purely to allow currying? Perhaps...
let curried = R.compose( calledThird, calledSecond, calledFirst );
curried('hello');
Is there any other purpose?
Your second example is exactly the reason for it, although this in fact has nothing to do with currying.
Functional composition allows you to build more sophisticated functions out of simpler ones.
Imagine you have some datatype that you need to sort, let's say a collection of appointments. Given that you already have a sortByDate function and a reverse function, you can write sortByDateDescending as
var sortByDateDescending = function(appointments) {
return reverse(sortByDate(appointments));
}
or in ES6:
const sortByDateDescending = appointments => reverse(sortByDate(appointments));
There is nothing wrong with this. But if you were to write it with a compose helper, it has several advantages:
var sortByDateDescending = compose(reverse, sortByDate);
First of all, it's clearly shorter, and the difference will grow more substantial as you add more functions, especially with pre-es6 code.
But more importantly, this allows you to focus on what's meaningful. You are combining functions here; the data that will eventually be passed through is the goal, but while you're building the new function, it's mostly a distraction.
By writing it this way, you get to focus on what's going on: you are sorting the list by date, and then you are reversing the result.
Languages more closely focused on functional programming make this simpler still, with an unobtrusive operator rather than a function like compose. In Haskell, the equivalent would look like
sortByDateDescending = reverse . sortByDate
But Javascript does not offer that elegance. The best we can do is create functions like compose (or its order-reversed twin, pipe.)
My introduction to Ramda post offers many more examples of working in this style.
Currying, by the way, is a different beast altogether. It is one technique that makes it much easier to reuse functions in such compositions. But it's mostly a distraction here. If you're interested, I also have a post on the issue.
Scott's answer is great - just wanted to add some more real-life examples.
You can identify places to improve code when you see a lot of this sort of pattern, where you're constantly massaging some data with passthrough functions:
var list = [3, 4, 1, 2];
list = filterOutEvens(list);
list = sort(list);
list = prependFoo(list);
You may be tempted to do something like this instead:
[3, 4, 1, 2].filterOutEvens().sort().prependFoo();
But then you remember that to make that possible, you'd have to add stuff to Array.prototype, which is definitely a no-no.
R.compose gives you the next best thing (remember that it works right-to-left):
var processList = R.compose(prependFoo, sort, filterOutEvens);
processList([3, 4, 1, 2]);
Here's the full example if you want to play around with it:
function filterOutEvens(list) {
return list.filter(function(item) {
return item % 2 !== 0;
});
}
function sort(list) {
// More cleanly use R.sort here instead of native Array.prototype.sort, which operates in-place.
var diff = function(a, b) { return a - b; };
return R.sort(diff, list);
}
function prependFoo(list) {
return list.map(function(item) {
return 'foo-' + item;
});
}
var processList = R.compose(prependFoo, sort, filterOutEvens);
var result = processList([3, 4, 1, 2]);
// -> ["foo-1", "foo-3"]
// Display Stackoverflow snippet output.
document.body.innerHTML = JSON.stringify(result, null, 2);
<script src="//cdn.jsdelivr.net/ramda/0.19.1/ramda.min.js"></script>
I'm wondering which of these is better and why. I often encounter situations in my daily work where I'm like "This algorithm works so long as the input isn't empty" or something like that. I usually just return early because, for some reason, the idea of wrapping almost the entirety of a function in an if conditions seem wrong to me. However, I know that some religions don't believe in early return statements.
Example:
(1)
function combine ( strings , separator )
{
if ( strings.length > 0 )
{
retstring = strings[0];
for ( var i = 1; i < strings.length; ++ i )
retstring += (separator + strings[i]);
}
return retstring;
}
(2)
function combine ( strings , separator )
{
if (strings.length === 0) return undefined;
retstrings = strings[0];
for ( var i = 1; i < strings.length; ++ i )
retstring += (separator + strings[i]);
return retstring;
}
So which is better to go with in such situations?
I'd say that neither is "better"; it's subjective.
And, unlike many subjective programming choices, this one isn't just a matter of personal preference. Rather, I think a good programmer will use both patterns, choosing which one based on what they want to express.
Pattern #1 says "if X do Y". Pattern #2 says "If !X, don't do anything else." Admittedly, those two are equivalent to any browser running your code.
But, to a human reading your code (eg. such as a co-worker who has to modify it) each pattern suggests different things about what is going on. Thus, my recommendation would be to try and determine which of the two patterns best describes what you are trying to communicate, and use that.
For instance, many functions have "if this isn't relevant logic", and that is best expressed with pattern #2:
function doStuffIfLoggedIn(user) {
if (!user.isLoggedIn()) return;
doStuff();
}
But it's also fairly common to do something if a particular option is provided, and that fits better with the first pattern:
function format(word, capitalize) {
if (capitalize) {
word = string.toUpperCase();
}
returns word;
}
If either is equally valid (and I find this happens fairly often) then it does come down to a matter of preference. Personally, in those "either is valid" cases I opt for #2; all else being equal it results in less indentation, which I (subjectively) find easier to read.
But really, the important thing (IMHO) is to think about how your code will look to the person who comes after (and that might even be you, a year later when you've forgotten why you wrote it that way). The browser doesn't care either way, and your co-workers will be able to understand either one, but using the one that best represents the situation can offer a critical clue about the code's function to whoever reads it later.
EDIT
To your point about:
some religions don't believe in early return statements
I think the idea there is that multiple return statements can make the code more complicated. When your function has lots of ways of exiting it can become hard to understand its logic, because to interpret a latter part, you have to reason through whether any of the earlier parts prevented you from getting there.
However, the Stack Overflow consensus is that, while it's a good idea to avoid excessive return statements, using a few properly can make your code more readable, and thus are a good idea.
See:
Should a function have only one return statement?
There is a built-in array method that does what your functions do: join()
function combine(strings, separator) {
return strings.join(separator);
}
console.log(combine(['this','is','a','test'], '...')); //this...is...a...test
But if join() didn't exist, I'd recommend a variation on your first code. You don't have to explicitly return undefined. If you don't include a return statement, the function will automatically return undefined:
function combine(strings, separator) {
if (strings.length) {
var retstring = strings[0];
for (var i = 1; i < strings.length; ++i)
retstring += (separator + strings[i]);
return retstring;
}
}
console.log(combine(['this','is','a','test'], '...')); //this...is...a...test
console.log(combine([], '...')); //undefined
I've such an input array that every element of the array is a dictionary {x:a_int, y:a_int}. Now I need to extract all y values and create a new array, so that it can be used to calculate the maximum of all y-values. Here is my current code:
var inputArray = [{x:1,y:100},{x:2,y:101},{x:3,y:103}];
function extractY(data) {
var result = [];
data.forEach(function (item) {
result.push(item.y);
});
return result;
}
// Test code
var yArray = extractY(inputArray);
console.log(Math.max.apply(Math, yArray));
I want to make code shorter. As I'm new to javascript, I'd like to know, if it possible to shorten the function extractY(). My imagination is to have a transformation function. The code should not rely on jQuery and does not have to consider old browser compatibility.
You can simply use Array.prototype.map, which will create a new Array with the values returned by the function passed to it, like this
function extractY(data) {
return data.map(function (item) {
return item.y;
});
}
Or you can simply write the same as
console.log(Math.max.apply(Math, inputArray.map(function(item) {
return item.y;
})));
Using reduce, you can get the maximum y value directly:
inputArray.reduce(function(prev, curr) {
return prev.y > curr.y ? prev : curr;
}).y
With underscore:
_.max(_.pick(inputArray, 'y'))
With d3:
d3.max(inputArray, function(d) { return d.y; })
Note in response to #AmitJoki's comment: Yes, I know this question was not tagged underscore. If you don't want to use underscore, feel free to ignore this answer. Having said that, underscore is a highly useful utility toolbelt that is perfect for solving problems such as this, among many other things. It's exhaustively tested and robust and efficient and handles all the edge cases correctly. Unlike certain other bloated libraries, it's quite lightweight and is well worth learning.
I doubt if it falls within the realm of common sense to imply that the failure to mark a question "underscore" means that underscore-based answers are somehow not acceptable, considering that it's easy to imagine that in many cases the OP may not even be aware of that option and might welcome a suggestion about how to write more compact code, while learning a useful tool in the process.
I have a list of methods I am calling in a method, as follows:
this.doOneThing();
someOtherObject.doASecondThing();
this.doSomethingElse();
When this is synchronous, they are executed one after the other, which is required. But now I have someOtherObject.doASecondThing() as asynchronous, and I might turn doOneThing as async too. I could use a callback and call that.doSomethingElse from inside the callback:
var that = this;
this.doOneThing( function () {
someOtherObject.doASecondThing(function () {
that.doSomethingElse();
});
});
However, because the sequence is growing, it seems a little messy to have callbacks call each other, for some reason it makes the sequence not look as obvious as before, and the indentation might grow with the number of methods called in the sequence.
Is there a way to make this look better? I could use the observer pattern also but it doesn't make things very obvious either, in my opinion.
Thanks,
Continuations, and why they're causing callback spaghetti
Writing in callbacks forces you to write in sometime akin to "continuation-passing style" (CPS), an extremely powerful but difficult technique. It represents a total inversion of control, literally turning a computation "upside-down". CPS makes your code's structure explicitly reflect the control flow of your program (sometimes a good thing, sometimes a bad thing). In effect, you are explicitly writing down the stack out of anonymous functions.
As a prerequisite for understanding this answer, you may find this useful:
http://matt.might.net/articles/by-example-continuation-passing-style/
For example this is what you are doing:
function thrice(x, ret) {
ret(x*3)
}
function twice(y, ret) {
ret(y*2)
}
function plus(x,y, ret) {
ret(x+y)
}
function threeXPlusTwoY(x,y, ret) {
// STEP#1
thrice(x, // Take the result of thrice(x)...
function(r1) { // ...and call that r1.
// STEP#2
twice(y, // Take the result of twice(y)...
function(r2) { // ...and call that r2.
// STEP#3
plus(r1,r2, // Take r1+r2...
ret // ...then do what we were going to do.
)
}
)
}
)
}
threeXPlusTwoY(5,1, alert); //17
As you've complained about, this makes for fairly indented code, because closures are the natural way to capture this stack.
Monads to the rescue
One way to unindent CPS is to write "monadically" like in Haskell. How would we do that? One nice way of implementing monads in javascript is with the dot-chaining notation, similar to jQuery. (See http://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/ for an amusing diversion.) Or we can use reflection.
But first we need a way to "write down the plumbing", and THEN we can find a way abstract it away. Tragically it's sort of hard to write a generic monad syntax in javascript, so I will use lists to represent computations.
// switching this up a bit:
// it's now 3x+2x so we have a diamond-shaped dependency graph
// OUR NEW CODE
var _x = 0;
var steps = [
[0, function(ret){ret(5)},[]], //step0:
[1, thrice,[_x]], //step1: thrice(x)
[2, twice,[_x]], //step2: twice(x)
[3, plus,[1, 2]] //step3: steps[1]+steps[2] *
]
threeXPlusTwoX = generateComputation(steps);
//*this may be left ambiguous, but in this case we will choose steps1 then step2
// via the order in the array
That's kinda ugly. But we can make this UNINDENTED "code" work. We can worry about making it prettier later (in the last section). Here our purpose was to write down all the "necessary information". We'd like an easy way to write each "line", along with a context we can write them in.
Now we implement a generateComputation which generates some nested anonymous functions which would perform the above steps in-order if we executed it. This is what such an implementation would look like:
function generateComputation(steps) {
/*
* Convert {{steps}} object into a function(ret),
* which when called will perform the steps in order.
* This function will call ret(_) on the results of the last step.
*/
function computation(ret) {
var stepResults = [];
var nestedFunctions = steps.reduceRight(
function(laterFuture, step) {
var i = step[0]; // e.g. step #3
var stepFunction = step[1]; // e.g. func: plus
var stepArgs = step[2]; // e.g. args: 1,2
console.log(i, laterFuture);
return function(returned) {
if (i>0)
stepResults.push(returned);
var evalledStepArgs = stepArgs.map(function(s){return stepResults[s]});
console.log({i:i, returned:returned, stepResults:stepResults, evalledStepArgs:evalledStepArgs, stepFunction:stepFunction});
stepFunction.apply(this, evalledStepArgs.concat(laterFuture));
}
},
ret
);
nestedFunctions();
}
return computation;
}
Demonstration:
threeXPlusTwoX = generateComputation(steps)(alert); // alerts 25
sidenote: reduceRight semantics implies the steps on the right will be more deeply nested in functions (further in the future). FYI for those not familiar, [1,2,3].reduce(f(_,_), x) --> f(f(f(0,1), 2), 3), and reduceRight (due to poor design considerations) is actually equivalent to [1.2.3].reversed().reduce(...)
Above, generateComputation made a bunch of nested functions, wrapping them in one another in preparation, and when evaluated with ...(alert), unpeeled them one-by-one to feed into the computation.
sidenote: We have to use a hack because in the previous example, we used closures and variable names to implement CPS. Javascript does not allow sufficient reflection to do this without resorting to crafting a string and evaling it (ick), so we eschew functional style temporarily and opt for mutating an object that keeps track of all parameters. Thus the above more closely replicates the following:
var x = 5;
function _x(ret) {
ret(x);
}
function thrice(x, ret) {
ret(x*3)
}
function twice(y, ret) {
ret(y*2)
}
function plus(x,y, ret) {
ret(x+y)
}
function threeXPlusTwoY(x,y, ret) {
results = []
_x(
return function(x) {
results[0] = x;
thrice(x, // Take the result of thrice(x)...
function(r1) { // ...and call that r1.
results[1] = r1;
twice(y, // Take the result of twice(y)...
function(r2) { // ...and call that r2.
results[2] = r2;
plus(results[1],results[2], // Take r1+r2...
ret // ...then do what we were going to do.
)
}
)
}
)
}
)
}
Ideal syntax
But we still want to write functions in a sane way. How would we ideally like to write our code to take advantage of CPS, but while retaining our sanity? There are numerous takes in the literature (for example, Scala's shift and reset operators are just one of the many ways to do so), but for sanity's sake, let's just find a way to make syntactic sugar for regular CPS. There are some possible ways to do it:
// "bad"
var _x = 0;
var steps = [
[0, function(ret){ret(5)},[]], //step0:
[1, thrice,[_x]], //step1: thrice(x)
[2, twice,[_x]], //step2: twice(x)
[3, plus,[1, 2]] //step3: steps[1]+steps[2] *
]
threeXPlusTwoX = generateComputation(steps);
...becomes...
If the callbacks are in a chain, we can easily feed one into the next without worrying about naming. These functions only have one argument: the callback argument. (If they didn't, you could curry the function as follows on the last line.) Here we can use jQuery-style dot-chains.
// SYNTAX WITH A SIMPLE CHAIN
// ((2*X) + 2)
twiceXPlusTwo = callbackChain()
.then(prompt)
.then(twice)
.then(function(returned){return plus(returned,2)}); //curried
twiceXPlusTwo(alert);
If the callbacks form a dependency tree, we can also get away with jQuery-style dot-chains, but this would defeat the purpose of creating a monadic syntax for CPS, which is to flatten the nested functions. Thus we won't go into detail here.
If the callbacks form a dependency acyclic graph (for example, 2*x+3*x, where x is used twice) we would need a way to name the intermediate results of some callbacks. This is where it gets interesting. Our goal is to try to mimic the syntax at http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style with its do-notation which "unwraps" and "rewraps" functions into and out of CPS. Unfortunately the [1, thrice,[_x]] syntax was the closest we could easily get to that (and not even close). You could code in another language and compile to javascript, or using eval (queue the ominous music). A bit overkill. Alternatives would have to use strings, such as:
// SUPER-NICE SYNTAX
// (3X + 2X)
thriceXPlusTwiceX = CPS({
leftPart: thrice('x'),
rightPart: twice('x'),
result: plus('leftPart', 'rightPart')
})
You can do this with only a few tweaks to the generateComputation I described. First you adapt it to use logical names ('leftPart', etc.) rather than numbers. Then you make your functions actually lazy objects which behave like:
thrice(x).toListForm() == [<real thrice function>, ['x']]
or
thrice(x).toCPS()(5, alert) // alerts 15
or
thrice.toNonCPS()(5) == 15
(You would do this in an automated way with some kind of decorator, not manually.)
sidenote: All your callback functions should follow the same protocol about where the callback parameter is. For example if your functions begin with myFunction(callback, arg0, arg1, ...) or myFunction(arg0, arg1, ..., callback) they might not be trivially compatible, though if they aren't presumably you could do a javascript reflection hack to look at the source code of the function and regex it out, and thus not have to worry about it.
Why go through all that trouble? This allows you to mix in setTimeouts and prompts and ajax requests without suffering from "indent hell". You also get a whole bunch of other benefits (like being able to write a 10-line nondeterministic-search sudoku solver, and implementing arbitrary control-flow operators) which I will not go into here.