Callbacks are imperative, promises are functional
111–120 of 154 posts
Re: Callbacks are imperative, promises are functional
#112Earlier quoted context omitted.
> (it also makes it look very "mathematical") Has that ever been an advantage?
For people that like math, sure, why not. When implementing mathematical concepts, if you squint at Haskell code you can see the original formulas, which should make it easier for people used to this way of thinking. EDIT: I'm not implying it's useful just for programming "math stuff", after all, everything can be reduced to a mathematical problem - including game engines[1], web application frameworks[2], etc. [1] h…
Re: Callbacks are imperative, promises are functional
#113Earlier quoted context omitted.
For people that like math, sure, why not. When implementing mathematical concepts, if you squint at Haskell code you can see the original formulas, which should make it easier for people used to this way of thinking. EDIT: I'm not implying it's useful just for programming "math stuff", after all, everything can be reduced to a mathematical problem - including game engines[1], web application frameworks[2], etc. [1] h…
And it's probably one of the most significant things limiting adoption of Haskell.
Re: Callbacks are imperative, promises are functional
#114Earlier quoted context omitted.
do f1 Or, if you prefer a list do fs And that seems to be one small example of why you may have already invented monads. I've been loving the impact of Javascript—modify and immediately see it on the browser—but every time I'm not using Haskell I miss it dearly.
Please use more readable names in your code. Use of names like 'fs' in key places makes it unreadable.
In Haskell, if you see a short name, look up and down 3 lines for the definition. If you can't find it then complain.
Re: Callbacks are imperative, promises are functional
#115Earlier quoted context omitted.
do f1 Or, if you prefer a list do fs And that seems to be one small example of why you may have already invented monads. I've been loving the impact of Javascript—modify and immediately see it on the browser—but every time I'm not using Haskell I miss it dearly.
Please use more readable names in your code. Use of names like 'fs' in key places makes it unreadable.
Re: Callbacks are imperative, promises are functional
#116Earlier quoted context omitted.
A tyrannical dichotomy. Functional programming is declarative. Especially when it's lazy and the program's instantaneous state is abstracted out. One of the motivating goals in functional programming is to be able to define a computation once, in terms of other computations, and have that relationship be maintained with minimal regard to the state of the program or its order of execution. Which is what it seems like…
I'm not saying his design sense is wrong. I'm saying his characterization of promises as functional is so close to being right that it's the worst kind of wrongness. It's worse to say, "The capital of Kenya is Nairobi Central" than to say "The capital of Kenya is London." It is worse because errors that are only slightly wrong and maybe even partially correct are more deceptive, durable, and confusing. A promise is n…
If you insist on setting up semantic games: if Oleg hacking Haskell isn't functional programming then nothing meaningfully is.
----
> Functions return immutable values. Declarations make promises. Under the hood there may be similarities but no one made any claims to the contrary.
What does `foldr (+)` return? What about `const 1`?
Re: Callbacks are imperative, promises are functional
#117Earlier quoted context omitted.
I can speak your comment, since my side project is a Node.js server that talks to several APIs, a database, and N web clients. Like you, I've worked more than a year on it, but I had a positive experience with Q [1] and jQuery promises. Promises make async code easy to manage, even at scale. Each API request gets its own promise. What happens inside that promise doesn't matter, as long as it returns a result or an er…
In other words, promises allow us to separate concerns. Document retrieval is one concern, collation another. Other programming languages have this too. They're called a 'METHOD'. Sorry, couldn't resist. On a serious note, look at your code in here: https://github.com/fruchtose/muxamp/blob/master/lib/playlist... And look at your 'playlistCount' function on line 39 (which for no apparent reason you've made a variable)…
I'm thinking of something like the below as a dbHelper class.
Note I'm passing the error messages into the deferred reject method rather than using console logging. I'm not sure if the q API supports that as you don't, but if it doesn't that seems like a bit of an odd design decision by the library authors, how else are you supposed to pass errors back? Unless I'm misunderstanding promises. If you want to have console logging of failed defers I would recommend either editing the source of Q or monkey patching the reject method to do it automatically.
It's also worth noting I am deliberately not checking rows length, etc. You should let exceptions do what they're supposed to do as something very serious has gone wrong if rows.length == 0 or rows[0] is null or rows[0]['count'] doesn't exist. A SELECT COUNT should always return 1 row and if you've named the column it should definitely be there.
//this is totally untested code to show the idea of
//how you should abstract the boilerplate from your code
var dbHelper = function() {
var db = require('./db'),
Q = require('q');
var dbHelperInner = {
query : function(query, onComplete) {
var dfd = Q.defer();
try {
var cmd = new DbCommand(dfd);
cmd.execute(query, onComplete);
} catch(e) {
dfd.reject(e);
}
return dfd.promise;
}
}
function DbCommand(dfd) {
if (!db.canRead()) {
throw "db unavailable";
}
this.dfd = dfd;
}
DbCommand.prototype.execute = function(query, onComplete) {
var self = this;
dbConnectionPool.acquire(function(acquireError, connection) {
if (acquireError) {
self.dfd.reject(acquireError);
return;
}
connection.query(query, function(queryError, rows) {
if (queryError) {
self.dfd.reject(queryError);
} else {
try {
self.dfd.resolve(
onComplete(rows));
} catch (e) {
self.dfd.reject(e);
}
}
dbConnectionPool.release(connection);
});
});
}
return dbHelperInner;
}();
//and then you could use it like this
//which is almost identical to the code I posited above
function playlistCount(){
return dbHelper.query('SELECT COUNT(id) AS count FROM Playlists;', function(rows) {
return parseInt(rows[0]['count']);
});
}Re: Callbacks are imperative, promises are functional
#118Earlier quoted context omitted.
do f1 Or, if you prefer a list do fs And that seems to be one small example of why you may have already invented monads. I've been loving the impact of Javascript—modify and immediately see it on the browser—but every time I'm not using Haskell I miss it dearly.
Have to admit that has also been my reaction to some of these javascript async frameworks based on promises or deferreds. Congratulations, you've reimplemented a quirky ad-hoc variant on the continuation and error monads. Perhaps people don't spot the link as easily because monads are usually explained in terms of a type system, and javascript is untyped? (Or perhaps just because Monad is a very abstract abstraction…
Re: Callbacks are imperative, promises are functional
#119Not to focus too myopically on the given example, but I can’t help but wonder why it’s a requirement that the first file be handled specially? A less contrived example would make the argument more convincing. If 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(functi…
do f1 Or, if you prefer a list do fs And that seems to be one small example of why you may have already invented monads. I've been loving the impact of Javascript—modify and immediately see it on the browser—but every time I'm not using Haskell I miss it dearly.
Re: Callbacks are imperative, promises are functional
#120Earlier quoted context omitted.
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…
> 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 claim that it's all about side effects seems odd. It should only be the case for POST PUT or DELETE methods, and only in very specific ways. 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),…
A cache gets refreshed or added to. A user's viewcount is incremented. A new statistic is calculated and then stored. An item is marked as viewed. And these are all just on a GET.
On complex sites with a logged-in user, side effects are pretty much the norm.