Promises and Lisp
lisper.in
lisper.in
Indeed, and that is why I am personally not really that bullish on promises, at least not how they are currently implemented. When you're debugging you want access to the implicit state-machine that the promise statement constructed, but at least in JS such state is hidden away in the `then()` function.
A good compromise (which I'm currently exploring in JS) is to make the state-machine navigable from the root, giving you the ability to examine it and mutate it explicitly during a debug session.
Alternatively you can use the yield-spawn method of getting rid of then() altogether. Then you get code that looks sequential as well, and the browser gives you nice stack traces.
This doesn't help with modifying values during debugging as you mentioned, but it does solve the problem of seeing the "caller" stack frames.
You might also want to check out the JS library q, which has support for stack traces that span async jumps if a promise errors out https://github.com/kriskowal/q#long-stack-traces
http://common-lisp.net/project/cl-monad-macros/monad-macros....
There are some people in the CL community who mention why CL users might not appreciate monads like those in other languages and/or programming styles/disciplines.
(Original) http://marijnhaverbeke.nl/monad.html
(HN Discussion) https://news.ycombinator.com/item?id=7651175
As far as your Lisp implementation goes, since promises are really just syntactical sugar around continuation passing (not in a bad way), and since both the continuation and the callback are first class, it should be trivial to land on a syntax that is as easy or easier to read than the JavaScript implementation. I think your final implementation hides a bit too much.
I actually mention this in a footnote, but I will do what you have suggested to be clearer still.
> it should be trivial to land on a syntax that is as easy or easier to read than the JavaScript implementation. I think your final implementation hides a bit too much.
Can you elaborate how this syntax might look?
Also: I'm not sure it's a good idea to give these macros the same names as the CL builtins. This will require users to do 'shadowing-import' if they want to use them without the package prefix, and then when they want to reference the builtins (in performance-sensitive code, perhaps) they'll have to use an explicit 'cl:'. At the very least, I'd suggest exporting a second set of names also, which are prefixed with "p-" or some such, so people can import them without shadowing.
That's nice. I had initially defined LET/LET* using a similar function, but then removed it to keep the macro definitions simpler.
> Also: I'm not sure it's a good idea to give these macros the same names as the CL builtins.
I gave this some thought, and came to the conclusion that using P-LET* is not very different from using PCL:LET*. So the way I envisioned this is that you don't import symbols from the PCL package; just use them with the package prefix. Though not everyone would prefer things this way, so if this was not a toy project I might have done what you suggested.