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.