Programming style question: say I'm returning a value that is conditional on a flag, in JavaScript. Is it better to return a conditional value (return bool ? this : that) or conditionally return a value (bool ? return this : return that) and why do you think this?

@meredith_matthews Is the latter actually legal in JavaScript? In many C-family languages that isn't legal, because `return` is a statement and the '?:' ternary conditional requires expressions. Even if it's legal, of those two choices I'd still prefer `return c ? t : f` because I'd find it very confusing to have control-flow jump around in the middle of an expression. `if(c) return t; else return f;` is a different story though and sometimes I'd choose that over either of the other options.

@jamey @meredith_matthews it's probably legal in js, I haven't tested it. Actually... It's not, I just tried. And browser js isn't real thrilled with if-statement version either. My context is that you see the if- version in JS lot and it looks incorrect to me, and I shortened for tweet-brevity, but node doesn't seem to throw a syntax error reliably

@meredith_matthews I guess I'd usually choose something like the if-statement version, come to think of it.

My old college advisor described something he called "programming by successive strengthening of invariants" (which is a super awkward mouthful, but he's a CS prof and not an English major, so...)

The idea is that as you go through a function in order, it establishes more guarantees you can rely on. An if-statement checking for invalid input should return or throw, and then for the rest of the function you know the input is valid. At the end of a loop you might have proved that the sum of the elements of an array is in a particular variable, and you can rely on that for the rest of the function. etc

So I'd usually write an if statement that returns when there's something simple to report, and then, without any else, I'd return the thing that needs a more complicated computation.

Here's a Python example I wrote the other day:

@meredith_matthews On the other hand, ternary conditional can be great to make it clear that a variable always has some value assigned to it, and it's just a question of which value. I especially like that when I can then declare a variable to be constant/immutable, which some languages don't allow if you assign to the variable from multiple branches of an if statement. But that isn't usually a consideration for a return statement.

@jamey @meredith_matthews idiomatically in js, you want to declare your variables before an if statement, not inside it, to make the scope of the variable explicit (no block scoping means no private if-statement variables)

@meredith_matthews yeah, I had some vague sense of scoping issues there, but I am Not Good at JavaScript, especially not anything added to the language since it became ECMAScript, like `let` and `const` I guess? 😅

@jamey @meredith_matthews oh you'd like them though. Const is immutable and let is (mostly)block-scoped

@meredith_matthews haha, you're probably right! It's just that these are pretty much all of the JavaScript I've written in the last year or two, and they total maybe 150 lines, and I mostly wrote them by modifying sample code I found elsewhere. 😅 it's just that the language is C/Java/...-like enough that my preferences on this kind of control flow are pretty easy to apply there too...

@jamey @meredith_matthews to quote Crockford, it's basically a lisp in C's clothing, with all of the terrifying power and freedom that implies.

@grainloom @meredith_matthews Huh, I think that's a well-argued essay. I wasn't going to argue with calling JavaScript "a lisp in C's clothing" but it wasn't obvious to me what sense that might be true in. Countering with "sure, JS has things in common with Scheme, but so do most programming languages" makes a lot of sense to me. I've certainly seen people do very functional-style things in JavaScript but that doesn't say as much about the language as about some people's stubborn perversity. 😁

@jamey @meredith_matthews To be fair it's quite an old essay, since JS not has block scoped variables (with let), so it's possible it's closer to Scheme than it was at time of writing that.

@jamey @meredith_matthews (but "eval" is still not macros, so I still wouldn't call it one. but i'm sure there are at least 10 scheme based languages people tried to bolt onto it.)

@grainloom @jamey @meredith_matthews speaking of, my personal experience is with playing with Racket. I've yet to get the hang of metaprogramming, so maybe I don't even lisp, but I'm willing to buy the js-as-lisp meme simply because it feeeeels the same. Only those two languages give me the same gleeful anarchic joy of diving in, scattering some values around, frolicking through some proceedures and generally writing ridiculous code I refuse to be ashamed of. It's *fun*.

@meredith_matthews @jamey I think you can do similar things in Lua and Smalltalk (especially the latter) but that doesn't make them Lisps, just highly dynamic languages
(eg. Factor and other Forths are also very dynamic and Factor even has a cool hackable IDE, but it's definitely not a Lisp)

@grainloom @meredith_matthews Yeah, I dunno if metaprogramming is key to "the lisp experience" or whatever... but I think most languages that don't try to statically help you avoid bugs have some degree of that "gleeful anarchic joy" (which is a wonderful turn of phrase for this btw). Even just a Jupyter Notebook can be that kind of fun. Having a compile step that repeatedly tells me "no, this won't work, try again" is something I really value, but it can definitely be a buzz-kill. 😅

@grainloom @jamey @meredith_matthews that said, the argument in the essay is compelling. The whole thing is a little silly 😁

@jamey @meredith_matthews as @DMN alluded to, it's all about herding the side effects between here and the return statement

return b ? x : y;
says "Here's where I return something, and here's what it is: a ternary expression.".

The other option is just a minified `if...else`. Sometimes you need to return inside a conditional, but I'd prefer not to. Having a single place where you return (or as few as possible) is nice.

If there are side-effects of building either of the values, or if there's other stuff happening that depends on the same conditional, then returning from an if/else would make sense.
Also, situations might come up where it's difficult or opaque to build one of the values in-line. If the values don't already exist as variables, and can't be built in-line, then one'll probably use the if/else format.

@meredith_matthews I'd be guided by how lexically compact bool, this and that are. If the whole ?: can be read easily in one (or, maybe, three) line(s) then that seems preferable as it emphasises that there's always a value returned. Otherwise the if form.

Sign in to participate in the conversation
Mastodon for Tech Folks

This Mastodon instance is for people interested in technology. Discussions aren't limited to technology, because tech folks shouldn't be limited to technology either!