-
-
Save wolfspider/662908fd629262ace94dbc647898f5c5 to your computer and use it in GitHub Desktop.
using Underscores | |
using Transducers | |
using WebAssemblyCompiler | |
function fpwasm(f) | |
z = Iterators.countfrom() |> Map(x -> 2x) |> TakeWhile(x -> x < 10) | |
j = reduce(+, z) | |
return j | |
end | |
compile((fpwasm, Float64); filepath = "fpwasm.wasm", validate = true, optimize = false) | |
Lets go ahead, using W2C2, and now translate this from WebAssembly into C (and of course do some hand edits for legibility). You can even run this on godbolt:
#include <stdio.h>
int fp(int l0) {
int l1=0;
int l2=0;
int l3=0;
int l4=0;
int l5=0;
int l6=0;
int l7=0;
int l8=0;
int si0;
int sj0,sj1;
sj0=2ULL;
l1=sj0;
sj0=2ULL;
l2=sj0;
L2:;
goto L1;
L1:;
L4:;
{
sj0=l2;
sj1=1ULL;
sj0+=sj1;
l4=sj0;
sj0=2ULL;
sj1=l2;
sj0*=sj1;
l5=sj0;
sj0=l5;
sj1=10ULL;
si0=(int)((int)sj0<(int)sj1);
l8=si0;
L6:;
si0=l8;
if(si0){
sj0=l1;
sj1=l5;
sj0+=sj1;
l6=sj0;
si0=0U;
l7=si0;
sj0=l6;
l3=sj0;
goto L5;
}else{
si0=1U;
l7=si0;
goto L5;
}
L7:;
return 0;
L5:;
L9:;
si0=l7;
if(si0){
goto L3;
}else{
goto L8;
}
L10:;
return 0;
L8:;
sj0=l3;
l1=sj0;
sj0=l4;
l2=sj0;
goto L4;
}
return 0;
L3:;
sj0=l1;
goto L0;
L0:;
return sj0;
}
int main() {
int f = fp(3);
printf("Output: %d", f);
return f;
}
The really cool thing is we get the right answer. Now, keep in mind that we need to "reduce" the answer each time. There is no direct translation to a function which eventually executes in terms of writing the IR. The answer is always 20. So now with the marvel of AI we can ask it to simplify the code and make it more readable. After doing this then we get this:
#include <stdio.h>
int fp(int l0) {
int l1 = 2;
int l2 = 2;
int l3 = 0;
int l4, l5, l6;
int l7 = 0;
int l8;
while (1) {
l4 = l2 + 1;
l5 = l2 * 2;
l8 = l5 < 10;
if (l8) {
l6 = l1 + l5;
l7 = 0;
l3 = l6;
} else {
l7 = 1;
}
if (l7) {
return l1;
} else {
l1 = l3;
l2 = l4;
}
}
return l1; // This return is technically unreachable
}
int main() {
int f = fp(3);
printf("Output: %d\n", f);
return f;
}
After working with FP for a while now I am thrilled that this can be done in such a straightforward way. Truly, without any extra library imports or anything we can see what the machine sees. We see the "while" in TakeWhile and we see the 2x in there as well as the countfrom(). In terms of authoring your own FP language this could be really useful if you do not want to implement everything in a higher level language but want the same guarantees.
Translating FP into something which can be usable elsewhere can be challenging but with WebAssembly we can now do some things which weren't possible before. Normally, this block of code which is a simple example from the Julia forums regarding libraries which can utilize functional and clojure-like features outputs the following in the REPL: