you still have to say "return (val)" at the end of functions
We have a bunch of code that compiles to both Common Lisp and Javascript, and those nasty "return" statements are one of the two biggest mismatches between the two languages (the other being Javascript's weird semantics around null, false, 0, and ""). One of these days I intend to try inserting them all automatically.
Indeed. It's surprising how deeply eliminating return changes the language semantics.
I've postponed learning Javascript until recently, because my work hasn't usually been web-oriented, but it's interesting how similar Javascript and Lua are. They seem to have been aimed at the same target, but for historical reasons Javascript's development got frozen early, while Lua had time to iron out many similar design flaws.
(In Lua, undefined and null are both nil, nil and false are "false-y", and everything else, including 0 and "", are truthy.)
I think you hit the nail on the head earlier. It isn't "return" as such, it's expressions vs. statements. Backus got it right. What's surprising is that the superior way gets the tiny minority of usage. (Not so surprising if you know the historical reasons.)
JS is not so bad. We're lucky that what we're doing (writing high-level FP code that compiles to JS and runs in pretty much every web browser in the world) is doable at all.
JS even has its own version of progn: "(a,b,c)" evaluates to c (after evaluating a and b). We use that pretty heavily. Alas, it has two problems: there are some things you can't do inside the block (like declare new variables or have for loops), and it makes the JS harder to read and debug. Otherwise we'd probably just compile everything that way.
Can you get around (at least some of) those restrictions by wrapping things in function expressions? Here's a for loop:
((function(){ for(x in [1,2,3]){print(x)} })(), 42)
Yes, and we have some macros that do just that (a Greenspunned version of half of CL's LOOP comes to mind). But it's not great as a general solution because of what it makes you give up in performance and readability. Also, it doesn't solve the problem of declaring new variables.
Every now and then we hit upon a new abstraction that lets us remove another chunk of ugliness from our code (while still generating acceptable JS) and I'm hoping that the trend will continue, especially if we can get rid of all those "return"s.
We have a bunch of code that compiles to both Common Lisp and Javascript, and those nasty "return" statements are one of the two biggest mismatches between the two languages (the other being Javascript's weird semantics around null, false, 0, and ""). One of these days I intend to try inserting them all automatically.