Use try-// instead of if-then-else
if A then B else C end
The conditional expression is very lengthy and almost never1 worth it. Depending on your condition
A and the values
C there might be short alternatives based on indexing or arithmetic, but a general solution is to use
try is part of the try-catch exception handler, and returns
empty for faulty code if the
catch part is omitted.
// is the alternative operator which returns the left hand side if it evaluates to a truthy2 value, and the right hand side otherwise.
Putting these two together we can rewrite the conditional expression as:
C is a number or a string, for lists you might need
+ instead and if C is a stream of multiple values, this gets a bit trickier. The outer parentheses can be removed in some cases.
The idea is that
true*1 throws an error, which is caught by
This can be shortened further by using
EXP ?, which should be a shorthand for
try EXP, though it seems like it does a lot more stuff, for example causing all subsequent filters to not throw errors. In this case
(1?*(A//C)//B) works, but you might need to do some trial and error in your specific situation.
?// is its own operator since 1.6, so you need to add a space there.
Practical example: Fibonacci
A recursive filter using a conditional expression comes in at 41 bytes:
def f:if.<2then. else[.-1,.-2|f]|add end;
Applying the general approach gets this to 39 bytes:
In this case
add can be used to throw an error in the truthy case, 35 bytes:
? instead of
try for 33 bytes:
1 If you have a practical example where this is not the case, I'd like to see it.
2 Falsy values are
empty, everything else is truthy.