Is there a way of shortening fat-arrow functions?
Use Recursion
I've found that recursion is (almost) always shorter than eval
+for
. The general way to convert from for to eval is:
for(a=n;b;c);d
(f=a=>b?f(c):d)(n)
So let's see your example:
b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}
We can first simplify it to:
for(m=b,a=1;~-m;--m,a*=m*m)a%b;
What did we do here? Well we simply moved everything inside the for
statement, this helps us reduce the amount of semicolons which is not directly better but almost always leads to some golf.
Let's put this in eval and compare it to the recursion version:
b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}
b=>eval('for(m=b,a=1;~-m;--m,a*=m*m)a%b')
b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)
The first part of the for loop (a=n
), we can start that off by passing those variables in as arguments. The condition is simply: b?(c,f(a)):d
where d
is the return value. Usually c
just modifies a
so it can be merged into it. So we can golf it even more using what I've mentioned:
b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)
b=>(f=a=>~-m?f(a*=--m*m):a%b)(1,m=b) // --m moved into a*=
b=>(f=a=>--m?f(a*=m*m):a%b)(1,m=b) // --m moved to condition
That said, as noted by @Niel is simplifying your algorithm. An algorithm golfy in one language may not be golfy in another so make sure to try different algoriths and compare them.
Abuse eval.
It's simple. Instead of:
f=n=>{for(i=c=0;i<n;i++)c+=n;return c}
Use
f=n=>eval("for(i=c=0;i<n;i++)c+=n;c")
Eval returns the last evaluated statement. In this case, since the last evaluated statement would be c+=n
, we would be left with c
anyhow, saving two bytes.
f=n=>eval("for(i=c=0;i<n;i++)c+=n")
In general:
f=n=>eval("code;x")
is shorter than this, by a byte:
f=n=>{code;return x}
As a note, using graves to call eval to possibly save bytes doesn't work, since:
eval`string`
is equivalent to
["string"]
Helpful for obfuscation! Not so much for code golf.