All the code and such a big abstraction for the first example when it could have done like this: var result = []; paths.forEach(function (i, file){ fs.stat(file, function (err, data){ result.push(data); if (i === 0) { // Use stat size } if (result.length === paths.length) { // Use the stats } }); }); Fairly understandable, more efficient and without introducing logic patterns foreign to many. It also meet his require…
> without introducing logic patterns foreign to many Consider your use of the forEach() abstraction when you could have used a for() loop just as easily. (That said, I agree the article in general could do a better job of describing the "other" side)
Callbacks are imperative, promises are functional
31–40 of 154 posts
Re: Callbacks are imperative, promises are functional
#32If I wanted to compute the size of one file relative to a set, I’d probably do something like this:
queue()
.defer(fs.stat, "file1.txt")
.defer(fs.stat, "file2.txt")
.defer(fs.stat, "file3.txt")
.awaitAll(function(error, stats) {
if (error) throw error;
console.log(stats[0].size / stats.reduce(function(p, v) { return p + v.size; }, 0));
});
Or, if you prefer a list: var q = queue();
files.forEach(function(f) { q.defer(fs.stat, f); });
q.awaitAll(…); // as before
This uses my (shameless plug) queue-async module, 419 bytes minified and gzipped: https://github.com/mbostock/queueA related question is whether you actually want to parallelize access to the file system. Stat'ing might be okay, but reading files in parallel would presumably be slower since you'd be jumping around on disk. (Although, with SSDs, YMMV.) A nice aspect of queue-async is that you can specify the parallelism in the queue constructor, so if you only want one task at a time, it’s as simple as queue(1) rather than queue(). This is not a data dependency, but an optimization based on the characteristics of the underlying system.
Anyway, I actually like promises in theory. I just feel like they might be a bit heavy-weight and a lot of API surface area to solve this particular problem. (For that matter, I created queue-async because I wanted something even more minimal than Caolan’s async, and to avoid code transpilation as with Tame.) Callbacks are surely the minimalist solution for serialized asynchronous tasks, and for managing parallelization, I like being able to exercise my preference.
Re: Callbacks are imperative, promises are functional
#33Earlier quoted context omitted.
... and what does that haves to do with promises? And in such case you would only do this once outside the listeners of http/or-whatever connections so it would be done just once regardless of the number of concurrent activity.
The point is that a properly designed API wouldn't require any amount of scaffolding. You'd go: fs.statMany(filenames, function (stats) { ... }); or: var statsPromise = fs.statMany(filenames); And then in either case, you'd just use a for-loop or forEach or whatever your preference on the result. No thinking about how to preserve complex invariants or whatever is necessary. Hell, with ES6 generator-y expressions you…
Re: Callbacks are imperative, promises are functional
#34This is an interesting perspective. But to me, even having spent a year on a large node.js project, I just don't see how promises would have simplified things at all. If you have some crazy graph of dependencies, I can see how breaking out promises could help simplify things. But I don't feel like that's a super-common scenario. The author says: > * [Promises] are easier to think about precisely because we’ve delegat…
Re: Callbacks are imperative, promises are functional
#35I feel this is twisting the meaning of functional programming. Excel is not functional. It is declarative. You declare the relationships between the cells and Excel uses those to propagate changes. Just like a makefile is not functional but declarative. The dependency of the relationships are enforced to produce action. SQL is another example of declarative language and it is nowhere near as functional.
declarative is an orthogonal attribute to functional. The two attributes are not mutually exclusive. You may as well say something like: "A bicycle isn't a vehicle at all! A Bicycle is a metallic object!"
Re: Callbacks are imperative, promises are functional
#36I feel this is twisting the meaning of functional programming. Excel is not functional. It is declarative. You declare the relationships between the cells and Excel uses those to propagate changes. Just like a makefile is not functional but declarative. The dependency of the relationships are enforced to produce action. SQL is another example of declarative language and it is nowhere near as functional.
"Excel is not functional. It is declarative. You declare the relationships between the cells and Excel uses those to propagate changes." Whereas in functional languages, the functions declare relationships between values and the language uses the evaluation model to propagate the results between function evaluation. Where's the difference?
Re: Callbacks are imperative, promises are functional
#37Earlier quoted context omitted.
declarative is an orthogonal attribute to functional. The two attributes are not mutually exclusive. You may as well say something like: "A bicycle isn't a vehicle at all! A Bicycle is a metallic object!"
Following that logic, OO is an orthogonal attribute to functional. Both of them can define functions, and thus OO is functional.
Second, OO is an orthogonal attribute to functional.
Third, your argument commits a formal fallacy of this form:
All cats have whiskers
Cats can have stripes
Tony has stripes
therefore tony is a cat.
---The possibility of an attribute in X, and Y containing that attribute does not imply that Y is an X.
the point is that whether something is declarative has no bearing on whether it is functional or not. It's an irrelevant point to bring up. Whether something is OO is equally irrelevant. That is what "orthogonal" means. I would go on to define for you "functional" "declarative", "formal fallacy" "logic", but this seems like a bottomless rabbit hole. I can only hope you'll try and find out what these words actually mean yourself.
Re: Callbacks are imperative, promises are functional
#38Re: Callbacks are imperative, promises are functional
#39This is an interesting perspective. But to me, even having spent a year on a large node.js project, I just don't see how promises would have simplified things at all. If you have some crazy graph of dependencies, I can see how breaking out promises could help simplify things. But I don't feel like that's a super-common scenario. The author says: > * [Promises] are easier to think about precisely because we’ve delegat…
The point is promises free you from wanting or needing to know about the order that things happen in. I hear you saying you fear promises, because it means it would get in the way of your ability to know that. But the truth is once you embrace them, that need becomes unimportant. The idea that webservers are "all about side effects" gives me a chill. The whole architecture concept of HTTP is no side effects , so to c…
Using a Promises, as opposed to reducing a list of computations async-style, also limits you to the Promise object's interface, so you lose (or at least add cruft to) the flexibility and composability of using native lists. By sequencing computations with lists, if I want some insight into what's happening, I just List.map(apply compose, logFunc). With promises, I have some work to do.
Promises have their uses, but it's definitely a tradeoff, and for most HTTP servers, I'd argue that their utility does seem a bit limited. I'd similarly say that making a point of using FRP to build a server would probably be a bit overkill for the task.
Re: Callbacks are imperative, promises are functional
#40This is an interesting perspective. But to me, even having spent a year on a large node.js project, I just don't see how promises would have simplified things at all. If you have some crazy graph of dependencies, I can see how breaking out promises could help simplify things. But I don't feel like that's a super-common scenario. The author says: > * [Promises] are easier to think about precisely because we’ve delegat…
The point is promises free you from wanting or needing to know about the order that things happen in. I hear you saying you fear promises, because it means it would get in the way of your ability to know that. But the truth is once you embrace them, that need becomes unimportant. The idea that webservers are "all about side effects" gives me a chill. The whole architecture concept of HTTP is no side effects , so to c…
There's nothing incongruous about that. It is the case that side effects should only happen on POST, PUT, and DELETE methods (and the like), but almost all webservers are written because of a need to use these.
If your webserver is all GETs and HEADs, then it is either trivial and you would have used someone else's instead of writing your own, or its sole purpose is to repackage and serve existing data from other sources - a rare use case among all webservers.
If you were to take an inventory of all the webservers out there, you would doubtless find that almost all of them exist in large part in order to create side effects.