Code example below, `cond` is an example in their tutorial: 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=14695495In 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");
} function deriv(exp, variable) {
return if(is_number(exp))
0
else if(is_variable(exp))
if(is_same_variable(exp, variable))
1
else
0
else if(is_sum(exp))
make_sum(
deriv(addend(exp), variable),
deriv(augend(exp), variable)
)
else if(is_product(exp))
make_sum(
make_product(multiplier(exp), deriv(multiplicand(exp), variable)),
make_product(deriv(multiplier(exp), variable), multiplicand(exp))
)
else error(exp, "unknown expression type -- deriv");
} 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");
}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!)
Example
is_same_variable(exp, variable) ? 1 : 0
If is_same_variable returns a truthy value then return 1 else 0.
We can remove that and it will still follow the same while also being more readable
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.
JavaScript has a limited form of that via the comma operator.