8 ms·
The tragedy of JS if blocks being statements not expressions is made explicit here
by akavi 3y ago
The tragedy of JS if blocks being statements not expressions is made explicit here
- code_biologist 3y agoThere was a library adding macros to JS that was a thing long ago. I always thought that `cond` would make JSX way better, though JS + macros sounds terrifying in general. Code example below, `cond` is an example in their tutorial: https://www.sweetjs.org/doc/tutorial.html#sweet-cond https://www.sweetjs.org/doc/tutorial.html#sweet-cond let realTypeof = cond { case x === null: 'null' case Array.isArray(x): 'array' case typeof x === 'object': 'object' default: typeof x } Discussed in 2017 on HN: https://news.ycombinator.com/item?id=14695495 https://news.ycombinator.com/item?id=14695495
- 3cats-in-a-coat 3y agoWhat's wrong with ternary?
- vorticalbox 3y agoNothing but when you nest them a whole bunch they are far harder to read and understand that if/else.
- pipeline_peak 3y ago(is(((it any) harder than) this?))
- freilanzer 3y agoYes, since Lisp isn't hard to read.
- leodag 3y agoYou'd be surprised at how readable Lisp is for people who actually learn it instead of just saying "look, weird language ha-ha!"
- 3cats-in-a-coat 3y agoI frankly find it hard to imagine an expression form of if...else that's more readable than either the JS or Scheme versions of the code. In fact, I believe the problem with the JS example's readability is the formatting. Here's how I'd format the same code, and I find this quite readable: function deriv(exp, variable) { return is_number(exp) ? 0 : is_variable(exp) ? is_same_variable(exp, variable) ? 1 : 0 : is_sum(exp) ? make_sum( deriv(addend(exp), variable), deriv(augend(exp), variable) ) : is_product(exp) ? make_sum( make_product(multiplier(exp), deriv(multiplicand(exp), variable)), make_product(deriv(multiplier(exp), variable), multiplicand(exp)) ) : error(exp, "unknown expression type -- deriv"); }
- 6510 3y agoJust for looksies. function deriv(exp,v){ //v = variable; if(is_number(exp) ){ return 0 } if(is_variable(exp){ return is_same_variable(exp,v) * 1 } if(is_sum(exp)){ a = deriv(addend(exp),v); return make_sum(a,a) } if(is_product(exp)){ m = multiplier(exp); c = multiplicand(exp); a = make_product(m,deriv(c,v)); b = make_product(deriv(m,v),c)); return make_sum(a,b) } return error(exp, "unknown expression type -- deriv"); }
- MrJohz 3y agoI'd possibly make it even more syntactically simple by removing the braces for one-line if statements. I know this can be a bit controversial, but for cases like this where the block consists only of a return statement, and where that statement fits on a single line (and where you have a formatter and a linter that will prevent you from writing indentation that doesn't match the semantics), it's very useful for removing visual clutter. That said, this is pretty much how I'd write it, and seems a lot simpler than the heavily nested ternary (and I say that as a fan of nested ternaries!)
- lmm 3y ago
- paulddraper 3y agoThey are, but you use ?-: instead of if-else
- Akronymus 3y agoThat still doesn't make all blocks expressions. In f# everything is an expression and it simplifies the language a lot. The last value in a block is considered the value "return" value of the whole block, which has the knockon effect of getting rid of most returns, allows you to check an if/else to return the same type and such. This also works in conjunction with the type inference, so you get an error when you try to return a string in one branch and an int in another.
- paulddraper 3y agoI understand. Scala is the same. JavaScript has a limited form of that via the comma operator.