Earlier quoted context omitted.
Well that is a fair enough concern, and I notice I used the word "Monadic" to describe jquery carelessly, to mean "Monad-like" though that isn't really what "Monadic" means. For the case in hand though, you can get to almost but not quite really technically a monad, and still cure most of the nested callback headaches. One way I think about monads is they are a strategy for turning nested functions into sequentially…
I just don't think it's useful to use the word monad to describe the strategy you're suggesting. I'm not criticizing your suggestion, I just don't think it has anything to do with monads. More to the point, I don't understand why we (HN and the JS community at large) keep having this discussion. Coroutines have been around since the 60s. This is a solved problem.
Kal – a clean JavaScript alternative without callbacks
121–130 of 130 posts
Re: Kal – a clean JavaScript alternative without callbacks
#122Earlier quoted context omitted.
I am not sure if I followed entirely. But let me give you an example, again with Q.nfcall. MultiplyAndSquare = (a, b, cb) -> Multiply a, b, (err, product) -> Square product, (err, square) -> cb null, square #ignore errors for now. nonCallbackVersion = (a, b) -> Q.nfcall(MultiplyAndSquare, a, b) result = yield nonCallbackVersion(10, 20)
You see how the caller has to be aware of how what he's calling is a generator. You're dragging generators all the way trough the call chain as soon as anything deep down in the call chain is a generator, and you'd want to use generators to acomplish asynchronicity. Let's say you write some code A, which uses some other code B, which uses some other code C. C is also used by various other pieces of code like X, Y, Z,…
MultiplyAndSquare = (a, b, cb) ->
Multiply a, b, (err, product) ->
Square product, (err, square) ->
cb(null, square) #ignore errors for now.
C = (a, b, cb) ->
MultiplyAndSquare(a, b, cb)
ABDEXY = (a, b, cb) ->
#Calls C
C(a, b, cb)
callersOfABDEXY = (a, b) ->
#Calls ABDEXY
ABDEXY a, b, (err, result) ->
Console.WriteLine(result)
#Refactored C. Returns a promise instead.
refactoredC = (a, b) ->
(Q.async ->
result = yield Q.nfcall(MultiplyAndSquare, a, b)
return result)()
#Refactored ABDEXY.
refactoredABDEXY = (a, b, cb) ->
#Change needed here, since C now returns a promise
refactoredC(a, b).then (result) ->
cb(null, result)
#No need to refactor callersOfABDEXYRe: Kal – a clean JavaScript alternative without callbacks
#123Re: Kal – a clean JavaScript alternative without callbacks
#124Beautiful work. The `for parallel` notation is a really interesting way of writing it. It seems like a number of folks in this thread have expressed interest in your process -- both of designing the feature set, and of gradually bootstrapping it away from CoffeeScript to become self-hosting. I'd love to hear more, if not here, then in a blog post, perhaps...
Re: Kal – a clean JavaScript alternative without callbacks
#125The title is kinda funny to the russian ear because kal means feces in Russian :)
That is really unfortunate... I chose it because it in Hebrew it roughly means something like easy/simple/BASIC. edit: More importantly, does that make you more or less likely to use it?
Re: Kal – a clean JavaScript alternative without callbacks
#126Does anyone know if there is a JS dialect out there that adds support for callback-less async code without also adding a bunch of other coffeescripty syntax changes at the same time?
http://onilabs.com/stratifiedjs (disclosure: I work at Oni Labs)
It does extend JS with some additional syntax as well (new concurrency constructs as well as some syntactic sugar), but it doesn't alter existing JS syntax.
Re: Kal – a clean JavaScript alternative without callbacks
#127Re: Kal – a clean JavaScript alternative without callbacks
#128Yay, another JavaScript super-set language that solves one problem.
On the one hand, this comment has the kernel of a legitimate criticism in it, and gets across why I probably won't use this language in a real project. On the other hand, that's so rude! Not every project has to be the next CoffeeScript to be interesting and worthy of appreciation. If you don't like it, just click on a different story instead of cutting down someone who chose to make something cool and share it with…
Re: Kal – a clean JavaScript alternative without callbacks
#129For the curious, the equivalent example from the OP using promises[1]: function getUserFriends(userName) { return db.users.findOne({ name: userName }).then(function (user) { return db.friends.find({ userId: user.id }); }); } [1]: http://promises-aplus.github.io/promises-spec/
Re: Kal – a clean JavaScript alternative without callbacks
#130It's remarkable how similar this code looks to the monadic way of doing it. For this Kal code... task getUserFriends(userName) wait for user from db.users.findOne {name:userName} wait for friends from db.friends.find {userId:user.id} if user.type is 'power user' for parallel friend in friends wait for friendsOfFriend from db.friends.find friend for newFriend in friendsOfFriend friends.push newFriend unless newFriend…