Repository: source-academy/js-slang
Pull request #183 (2019-02-26 07:40:48)

[NATIVE #2] Nice function strings
Stringifying of functions should work nicely now.

# Features:

- [x] Native!
- [x] Builtins work! 
- [x] Can store constants and letiables (repl works)
- [x] Proper tail calls (Iterative processes are iterative)
- [ ] Enforcing of strict types (`'' * ''` still works)
- [x] Error handling (basic ones only)
- [x] stringifying functions (should be same as interpreter now) 

# How to use: 

Change 

```typescript
const DEFAULT_OPTIONS: IOptions = {
  scheduler: 'async',
  steps: 1000,
  isNativeRunnable: false //change to true
}
```
in `src/index.ts` 

# Please help try and break it!

You can assume member access `obj['string']` is not going to work once strict types are enforced. Find some other way to reach eval, or to break the transpiler. In particular, managing to access the global variable $$NATIVE_STORAGE in Source would break it, as all the functions inside can be switched out.

coveralls: ## Pull Request Test Coverage Report for [Build 719](https://coveralls.io/builds/21850467)

* **137** of **139**   **(98.56%)**  changed or added relevant lines in **8** files are covered.
* **1** unchanged line in **1** file lost coverage.
* Overall coverage increased (+**0.5%**) to **91.575%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [src/index.ts](https://coveralls.io/builds/21850467/source?filename=src%2Findex.ts#L72) | 21 | 23 | 91.3%
<!-- | **Total:** | **137** | **139** | **98.56%** | -->

|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [src/utils/properTailCalls.ts](https://coveralls.io/builds/21850467/source?filename=src%2Futils%2FproperTailCalls.ts#L17) | 1 | 91.11% |
<!-- | **Total:** | **1** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/21850467/badge)](https://coveralls.io/builds/21850467) |
| :-- | --: |
| Change from base [Build 696](https://coveralls.io/builds/21814562): |  0.5% |
| Covered Lines: | 1468 |
| Relevant Lines: | 1599 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/src/transpiler.ts b/src/transpiler.ts
index fc34af8b..1d4f9dbd 100644
--- a/src/transpiler.ts
+++ b/src/transpiler.ts
@@ -1,14 +1,11 @@
 import { simple } from 'acorn-walk/dist/walk'
 import { generate } from 'astring'
 import * as es from 'estree'
-import { RawSourceMap } from 'source-map'
-import * as sourceMap from 'source-map'
+import { RawSourceMap, SourceMapGenerator } from 'source-map'
 import { GLOBAL, GLOBAL_KEY_TO_ACCESS_NATIVE_STORAGE } from './constants'
-// import * as constants from "./constants";
 import * as errors from './interpreter-errors'
 import { AllowedDeclarations, Value } from './types'
 import * as create from './utils/astCreator'
-// import * as rttc from "./utils/rttc";
 
 /**
  * This whole transpiler includes many many many many hacks to get stuff working.
@@ -132,13 +129,30 @@ function createStatementsToStoreCurrentlyDeclaredGlobals(program: es.Program) {
   return statements
 }
 
-function transformFunctionDeclarationsToArrowFunctions(program: es.Program) {
+function generateFunctionsToStringMap(program: es.Program) {
+  const map: Map<es.Node, string> = new Map()
+  simple(program, {
+    ArrowFunctionExpression(node: es.ArrowFunctionExpression) {
+      map.set(node, generate(node))
+    },
+    FunctionDeclaration(node: es.FunctionDeclaration) {
+      map.set(node, generate(node))
+    }
+  })
+  return map
+}
+
+function transformFunctionDeclarationsToArrowFunctions(
+  program: es.Program,
+  functionsToStringMap: Map<es.Node, string>
+) {
   simple(program, {
     FunctionDeclaration(node) {
       const { id, params, body } = node as es.FunctionDeclaration
       node.type = 'VariableDeclaration'
       node = node as es.VariableDeclaration
       const asArrowFunction = create.blockArrowFunction(params as es.Identifier[], body)
+      functionsToStringMap.set(asArrowFunction, functionsToStringMap.get(node)!)
       node.declarations = [
         {
           type: 'VariableDeclarator',
@@ -164,13 +178,19 @@ function transformFunctionDeclarationsToArrowFunctions(program: es.Program) {
  * to allow for iterative processes to take place
  */
 
-function wrapArrowFunctionsToAllowNormalCallsAndNiceToString(program: es.Program) {
+function wrapArrowFunctionsToAllowNormalCallsAndNiceToString(
+  program: es.Program,
+  functionsToStringMap: Map<es.Node, string>
+) {
   simple(program, {
     ArrowFunctionExpression(node) {
       const originalNode = { ...node }
       node.type = 'CallExpression'
       const transformedNode = node as es.CallExpression
-      transformedNode.arguments = [originalNode as es.ArrowFunctionExpression]
+      transformedNode.arguments = [
+        originalNode as es.ArrowFunctionExpression,
+        create.literal(functionsToStringMap.get(node)!)
+      ]
       transformedNode.callee = create.identifier(globalIds.wrap)
     }
   })
@@ -352,7 +372,7 @@ function splitLastStatementIntoStorageOfResultAndAccessorPair(
     }
   }
   const uniqueIdentifier = getUniqueId('lastStatementResult')
-  const map = new sourceMap.SourceMapGenerator({ file: 'lastline' })
+  const map = new SourceMapGenerator({ file: 'lastline' })
   const lastStatementAsCode = generate(lastStatement, { lineEnd: ' ', sourceMap: map, version: 3 })
   const uniqueDeclarationToStoreLastStatementResult = create.constantDeclaration(
     uniqueIdentifier,
@@ -378,11 +398,12 @@ export function transpile(untranformedProgram: es.Program, id: number) {
   if (statements.length === 0) {
     return { transpiled: '' }
   }
+  const functionsToStringMap = generateFunctionsToStringMap(program)
   transformReturnStatementsToAllowProperTailCalls(program)
   transformCallExpressionsToCheckIfFunction(program)
   transformTernaryIfAndLogicalsToCheckIfBoolean(program)
-  transformFunctionDeclarationsToArrowFunctions(program)
-  wrapArrowFunctionsToAllowNormalCallsAndNiceToString(program)
+  transformFunctionDeclarationsToArrowFunctions(program, functionsToStringMap)
+  wrapArrowFunctionsToAllowNormalCallsAndNiceToString(program, functionsToStringMap)
   const statementsToPrepend = getStatementsToPrepend()
   const statementsToAppend = getStatementsToAppend(program)
   const lastStatement = statements.pop() as es.Statement
@@ -400,7 +421,7 @@ export function transpile(untranformedProgram: es.Program, id: number) {
   ])
   program.body = [...getDeclarationsToAccessTranspilerInternals(), wrapped]
 
-  const map = new sourceMap.SourceMapGenerator({ file: 'source' })
+  const map = new SourceMapGenerator({ file: 'source' })
   const transpiled = generate(program, { sourceMap: map })
   const codeMap = map.toJSON()
   return { transpiled, codeMap, evalMap }
diff --git a/src/utils/properTailCalls.ts b/src/utils/properTailCalls.ts
index 39f4ba41..b1473b3f 100644
--- a/src/utils/properTailCalls.ts
+++ b/src/utils/properTailCalls.ts
@@ -47,8 +47,10 @@ export const callIteratively = (f: any, ...args: any[]) => {
   }
 }
 
-export const wrap = (f: (...args: any[]) => any) => {
+export const wrap = (f: (...args: any[]) => any, stringified: string) => {
   const wrapped = (...args: any[]) => callIteratively(f, ...args)
   wrapped.transformedFunction = f
+  wrapped[Symbol.toStringTag] = () => stringified
+  wrapped.toString = () => stringified
   return wrapped
 }


Test patch:
diff --git a/src/__tests__/__snapshots__/allowed-syntax.ts.snap b/src/__tests__/__snapshots__/allowed-syntax.ts.snap
index 387632d3..127543f8 100644
--- a/src/__tests__/__snapshots__/allowed-syntax.ts.snap
+++ b/src/__tests__/__snapshots__/allowed-syntax.ts.snap
@@ -841,7 +841,7 @@ const wrap = native.properTailCalls.wrap;
           };
         }
       }
-    });
+    }, \\"function name(a, b) {\\\\n  const sum = a + b;\\\\n  if (sum > 1) {\\\\n    return sum;\\\\n  } else {\\\\n    if (a % 2 === 0) {\\\\n      return -1;\\\\n    } else if (b % 2 === 0) {\\\\n      return 1;\\\\n    } else {\\\\n      return a > b ? 0 : -2;\\\\n    }\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(name, 15, 0, 1, 2);\\");
     native.globals.set(\\"name\\", {
       kind: \\"const\\",
@@ -938,7 +938,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(wrap(() => ({   isTail: false,   value: true })), 1, 0);\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(wrap(() => ({   isTail: false,   value: true }), \\\\\\"() => true\\\\\\"), 1, 0);\\");
     return lastStatementResult;
   })();
 })();
@@ -1156,7 +1156,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(wrap((x, y) => {   return {     isTail: false,     value: x + y   }; }), 1, 0, 1, 2);\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(wrap((x, y) => {   return {     isTail: false,     value: x + y   }; }, \\\\\\"(x, y) => {\\\\\\\\n  return x + y;\\\\\\\\n}\\\\\\"), 1, 0, 1, 2);\\");
     return lastStatementResult;
   })();
 })();
diff --git a/src/__tests__/__snapshots__/block-scoping.ts.snap b/src/__tests__/__snapshots__/block-scoping.ts.snap
index 61da8737..bd5e44a4 100644
--- a/src/__tests__/__snapshots__/block-scoping.ts.snap
+++ b/src/__tests__/__snapshots__/block-scoping.ts.snap
@@ -206,7 +206,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function test() {\\\\n  const x = true;\\\\n  if (true) {\\\\n    const x = false;\\\\n  } else {\\\\n    const x = false;\\\\n  }\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 10, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -248,7 +248,7 @@ const wrap = native.properTailCalls.wrap;
         z[x] = wrap(() => ({
           isTail: false,
           value: x
-        }));
+        }), \\"() => x\\");
       }
       return {
         isTail: true,
@@ -257,7 +257,7 @@ const wrap = native.properTailCalls.wrap;
         line: 6,
         column: 9
       };
-    });
+    }, \\"function test() {\\\\n  let z = [];\\\\n  for (let x = 0; x < 10; x = x + 1) {\\\\n    z[x] = () => x;\\\\n  }\\\\n  return z[1]();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 8, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -299,7 +299,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function test() {\\\\n  let x = true;\\\\n  for (let x = 1; x > 0; x = x - 1) {}\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 7, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -348,7 +348,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function test() {\\\\n  let x = true;\\\\n  if (true) {\\\\n    let x = false;\\\\n  } else {\\\\n    let x = false;\\\\n  }\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 10, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -393,7 +393,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function test() {\\\\n  const x = true;\\\\n  {\\\\n    const x = false;\\\\n  }\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 8, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -440,7 +440,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function test() {\\\\n  let x = true;\\\\n  while (true) {\\\\n    let x = false;\\\\n    break;\\\\n  }\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 9, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/__snapshots__/index.ts.snap b/src/__tests__/__snapshots__/index.ts.snap
index 7596c850..1cf6325a 100644
--- a/src/__tests__/__snapshots__/index.ts.snap
+++ b/src/__tests__/__snapshots__/index.ts.snap
@@ -135,7 +135,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: variable
       };
-    });
+    }, \\"function test() {\\\\n  let variable = false;\\\\n  variable = true;\\\\n  return variable;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(test, 6, 0);\\");
     native.globals.set(\\"test\\", {
       kind: \\"const\\",
@@ -374,7 +374,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(apply_in_underlying_javascript, 1, 0, wrap((a, b, c) => ({   isTail: false,   value: a * b * c })), callIfFuncAndRightArgs(list, 1, 55, 2, 5, 6));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(apply_in_underlying_javascript, 1, 0, wrap((a, b, c) => ({   isTail: false,   value: a * b * c }), \\\\\\"(a, b, c) => a * b * c\\\\\\"), callIfFuncAndRightArgs(list, 1, 55, 2, 5, 6));\\");
     return lastStatementResult;
   })();
 })();
diff --git a/src/__tests__/__snapshots__/interpreter-errors.ts.snap b/src/__tests__/__snapshots__/interpreter-errors.ts.snap
index 1fbccd7f..740a72cf 100644
--- a/src/__tests__/__snapshots__/interpreter-errors.ts.snap
+++ b/src/__tests__/__snapshots__/interpreter-errors.ts.snap
@@ -271,14 +271,14 @@ const wrap = native.properTailCalls.wrap;
     const g = wrap(() => ({
       isTail: false,
       value: 1
-    }));
+    }), \\"() => 1\\");
     const f = wrap(x => ({
       isTail: true,
       function: g,
       arguments: [x],
       line: 2,
       column: 15
-    }));
+    }), \\"x => g(x)\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 3, 0, 1);\\");
     native.globals.set(\\"g\\", {
       kind: \\"const\\",
@@ -368,7 +368,7 @@ const wrap = native.properTailCalls.wrap;
     const f = wrap(x => ({
       isTail: false,
       value: x
-    }));
+    }), \\"x => x\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 2, 0);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -454,7 +454,7 @@ const wrap = native.properTailCalls.wrap;
     const f = wrap(x => ({
       isTail: false,
       value: x
-    }));
+    }), \\"x => x\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 2, 0, 1, 2);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -540,7 +540,7 @@ const wrap = native.properTailCalls.wrap;
     const f = [wrap(x => ({
       isTail: false,
       value: x
-    }))];
+    }), \\"x => x\\")];
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f[0], 2, 0, 1, 2);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -632,7 +632,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function f(x) {\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 4, 0);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -724,7 +724,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function f(x) {\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 4, 0, 1, 2);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/__snapshots__/return-regressions.ts.snap b/src/__tests__/__snapshots__/return-regressions.ts.snap
index edbc40de..48015a4c 100644
--- a/src/__tests__/__snapshots__/return-regressions.ts.snap
+++ b/src/__tests__/__snapshots__/return-regressions.ts.snap
@@ -34,7 +34,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const f = wrap(() => {
       for (let i = 0; i < 100; i = i + 1) {
         return {
@@ -49,7 +49,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 12, 6);
-    });
+    }, \\"function f() {\\\\n  for (let i = 0; i < 100; i = i + 1) {\\\\n    return i + 1;\\\\n    unreachable();\\\\n  }\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -101,7 +101,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const f = wrap(() => {
       if (boolOrErr(true, 6, 6)) {
         return {
@@ -116,7 +116,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 12, 6);
-    });
+    }, \\"function f() {\\\\n  if (true) {\\\\n    return 1;\\\\n    unreachable();\\\\n  } else {}\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -168,7 +168,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const f = wrap(() => {
       while (true) {
         return {
@@ -183,7 +183,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 12, 6);
-    });
+    }, \\"function f() {\\\\n  while (true) {\\\\n    return 1;\\\\n    unreachable();\\\\n  }\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -232,7 +232,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const f = wrap(() => {
       return {
         isTail: false,
@@ -244,7 +244,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 9, 6);
-    });
+    }, \\"function f() {\\\\n  return 1;\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 11, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -336,13 +336,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       for (let i = 0; i < 100; i = i + 1) {
         return {
@@ -354,7 +354,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 0
       };
-    });
+    }, \\"function f() {\\\\n  for (let i = 0; i < 100; i = i + 1) {\\\\n    return id(i + 1) + id(i + 2);\\\\n  }\\\\n  return 0;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -413,13 +413,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       if (boolOrErr(true, 9, 6)) {
         return {
@@ -434,7 +434,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 15, 6);
-    });
+    }, \\"function f() {\\\\n  if (true) {\\\\n    return id(1) + id(2);\\\\n    unreachable();\\\\n  } else {}\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 17, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -493,13 +493,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       while (true) {
         return {
@@ -514,7 +514,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 15, 6);
-    });
+    }, \\"function f() {\\\\n  while (true) {\\\\n    return id(1) + id(2);\\\\n    unreachable();\\\\n  }\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 17, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -570,13 +570,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       return {
         isTail: false,
@@ -588,7 +588,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 12, 6);
-    });
+    }, \\"function f() {\\\\n  return id(1) + id(2);\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -647,13 +647,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       for (let i = 0; i < 100; i = i + 1) {
         return {
@@ -671,7 +671,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 15, 6);
-    });
+    }, \\"function f() {\\\\n  for (let i = 0; i < 100; i = i + 1) {\\\\n    return id(i + 1);\\\\n    unreachable();\\\\n  }\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 17, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -730,13 +730,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       if (boolOrErr(true, 9, 6)) {
         return {
@@ -754,7 +754,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 15, 6);
-    });
+    }, \\"function f() {\\\\n  if (true) {\\\\n    return id(1);\\\\n    unreachable();\\\\n  } else {}\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 17, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -813,13 +813,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       while (true) {
         return {
@@ -837,7 +837,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 15, 6);
-    });
+    }, \\"function f() {\\\\n  while (true) {\\\\n    return id(1);\\\\n    unreachable();\\\\n  }\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 17, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
@@ -893,13 +893,13 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 1 < true
       };
-    });
+    }, \\"function unreachable() {\\\\n  return 1 < true;\\\\n}\\");
     const id = wrap(x => {
       return {
         isTail: false,
         value: x
       };
-    });
+    }, \\"function id(x) {\\\\n  return x;\\\\n}\\");
     const f = wrap(() => {
       return {
         isTail: true,
@@ -914,7 +914,7 @@ const wrap = native.properTailCalls.wrap;
         value: 0
       };
       callIfFuncAndRightArgs(unreachable, 12, 6);
-    });
+    }, \\"function f() {\\\\n  return id(1);\\\\n  unreachable();\\\\n  return 0;\\\\n  unreachable();\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 14, 4);\\");
     native.globals.set(\\"unreachable\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/__snapshots__/stdlib.ts.snap b/src/__tests__/__snapshots__/stdlib.ts.snap
index 10f78e85..e1675895 100644
--- a/src/__tests__/__snapshots__/stdlib.ts.snap
+++ b/src/__tests__/__snapshots__/stdlib.ts.snap
@@ -550,7 +550,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(is_function, 1, 0, wrap(x => ({   isTail: false,   value: x })));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(is_function, 1, 0, wrap(x => ({   isTail: false,   value: x }), \\\\\\"x => x\\\\\\"));\\");
     return lastStatementResult;
   })();
 })();
@@ -582,7 +582,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: x
       };
-    });
+    }, \\"function f(x) {\\\\n  return x;\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(is_function, 4, 0, f);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -1035,7 +1035,7 @@ const wrap = native.properTailCalls.wrap;
           value: true
         };
       }
-    });
+    }, \\"function repeatUntilDifferentTime() {\\\\n  if (start === runtime()) {\\\\n    return repeatUntilDifferentTime();\\\\n  } else {\\\\n    return true;\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(repeatUntilDifferentTime, 9, 0);\\");
     native.globals.set(\\"start\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/__snapshots__/stringify.ts.snap b/src/__tests__/__snapshots__/stringify.ts.snap
index a32d87e8..145bb325 100644
--- a/src/__tests__/__snapshots__/stringify.ts.snap
+++ b/src/__tests__/__snapshots__/stringify.ts.snap
@@ -10,6 +10,25 @@ stringify(xs);",
   "parsedErrors": "",
   "result": "[1, \\"true\\", true, () => x]",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const xs = [1, 'true', true, wrap(() => ({
+      isTail: false,
+      value: x
+    }), \\"() => x\\")];
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 2, 0, xs);\\");
+    native.globals.set(\\"xs\\", {
+      kind: \\"const\\",
+      value: xs
+    });
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
@@ -24,6 +43,25 @@ stringify(f);",
   "parsedErrors": "",
   "result": "(x, y) => z",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const f = wrap((x, y) => ({
+      isTail: false,
+      value: z
+    }), \\"(x, y) => z\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 2, 0, f);\\");
+    native.globals.set(\\"f\\", {
+      kind: \\"const\\",
+      value: f
+    });
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
@@ -136,6 +174,27 @@ stringify(f);",
   return z;
 }",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const f = wrap((x, y) => {
+      return {
+        isTail: false,
+        value: z
+      };
+    }, \\"function f(x, y) {\\\\n  return z;\\\\n}\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 4, 0, f);\\");
+    native.globals.set(\\"f\\", {
+      kind: \\"const\\",
+      value: f
+    });
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
@@ -423,6 +482,25 @@ stringify(xs);",
   "parsedErrors": "",
   "result": "[1, \\"true\\", [true, () => x, [[]]]]",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const xs = [1, 'true', [true, wrap(() => ({
+      isTail: false,
+      value: x
+    }), \\"() => x\\"), [[]]]];
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 2, 0, xs);\\");
+    native.globals.set(\\"xs\\", {
+      kind: \\"const\\",
+      value: xs
+    });
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
@@ -616,6 +694,17 @@ Object {
  ...  ... \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}} ...},
 null ...]",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 1, 0, callIfFuncAndRightArgs(parse, 1, 10, 'x=>x;'), ' ... ');\\");
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
@@ -670,6 +759,17 @@ Object {
 ....................\\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}}.........},
 null.........]",
   "resultStatus": "finished",
+  "transpiled": "const native = $$NATIVE_STORAGE;
+const boolOrErr = native.operators.get(\\"itselfIfBooleanElseError\\");
+const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArgumentsElseError\\");
+const wrap = native.properTailCalls.wrap;
+(( <globals redacted> ) => {
+  return (() => {
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(stringify, 1, 0, callIfFuncAndRightArgs(parse, 1, 10, 'x=>x;'), '.................................');\\");
+    return lastStatementResult;
+  })();
+})();
+",
   "visualiseListResult": Array [],
 }
 `;
diff --git a/src/__tests__/__snapshots__/tailcall-return.ts.snap b/src/__tests__/__snapshots__/tailcall-return.ts.snap
index 60bb12f8..99b60b92 100644
--- a/src/__tests__/__snapshots__/tailcall-return.ts.snap
+++ b/src/__tests__/__snapshots__/tailcall-return.ts.snap
@@ -37,7 +37,7 @@ const wrap = native.properTailCalls.wrap;
           column: 11
         };
       }
-    });
+    }, \\"function f(x, y) {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return f(x - 1, y + 1);\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 8, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -88,7 +88,7 @@ const wrap = native.properTailCalls.wrap;
           column: 20
         });
       }
-    });
+    }, \\"function f(x, y) {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return false || f(x - 1, y + 1);\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 8, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -131,7 +131,7 @@ const wrap = native.properTailCalls.wrap;
         line: 2,
         column: 22
       };
-    });
+    }, \\"function f(x, y) {\\\\n  return x <= 0 ? y : f(x - 1, y + 1);\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 4, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -177,7 +177,7 @@ const wrap = native.properTailCalls.wrap;
         isTail: false,
         value: 'unreachable'
       };
-    });
+    }, \\"function f(x, y) {\\\\n  return x <= 0 ? y : false || x > 0 ? f(x - 1, y + 1) : 'unreachable';\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 4, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -228,7 +228,7 @@ const wrap = native.properTailCalls.wrap;
           column: 11
         };
       }
-    });
+    }, \\"(x, y) => {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return f(x - 1, y + 1);\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 8, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -267,7 +267,7 @@ const wrap = native.properTailCalls.wrap;
       arguments: [x - 1, y + 1],
       line: 1,
       column: 33
-    });
+    }, \\"(x, y) => x <= 0 ? y : f(x - 1, y + 1)\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 2, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -318,7 +318,7 @@ const wrap = native.properTailCalls.wrap;
           column: 11
         };
       }
-    });
+    }, \\"function f(x, y, z) {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return f(x - 1, y + f(0, z, 0), z);\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 8, 0, 5000, 5000, 2);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -358,7 +358,7 @@ const wrap = native.properTailCalls.wrap;
       arguments: [x - 1, y + 1],
       line: 1,
       column: 33
-    });
+    }, \\"(x, y) => x <= 0 ? y : g(x - 1, y + 1)\\");
     const g = wrap((x, y) => boolOrErr(x <= 0, 2, 20) ? {
       isTail: false,
       value: y
@@ -368,7 +368,7 @@ const wrap = native.properTailCalls.wrap;
       arguments: [x - 1, y + 1],
       line: 2,
       column: 33
-    });
+    }, \\"(x, y) => x <= 0 ? y : f(x - 1, y + 1)\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 3, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
@@ -430,7 +430,7 @@ const wrap = native.properTailCalls.wrap;
           column: 11
         };
       }
-    });
+    }, \\"function f(x, y) {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return g(x - 1, y + 1);\\\\n  }\\\\n}\\");
     const g = wrap((x, y) => {
       if (boolOrErr(x <= 0, 9, 2)) {
         return {
@@ -446,7 +446,7 @@ const wrap = native.properTailCalls.wrap;
           column: 11
         };
       }
-    });
+    }, \\"function g(x, y) {\\\\n  if (x <= 0) {\\\\n    return y;\\\\n  } else {\\\\n    return f(x - 1, y + 1);\\\\n  }\\\\n}\\");
     const lastStatementResult = eval(\\"callIfFuncAndRightArgs(f, 15, 0, 5000, 5000);\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/__snapshots__/transpiled-code.ts.snap b/src/__tests__/__snapshots__/transpiled-code.ts.snap
index e9f3c436..4b5a6d70 100644
--- a/src/__tests__/__snapshots__/transpiled-code.ts.snap
+++ b/src/__tests__/__snapshots__/transpiled-code.ts.snap
@@ -107,7 +107,7 @@ const wrap90 = native.properTailCalls.wrap;
       wrap7;
       wrap8;
       wrap9;
-    });
+    }, \\"function f(callIfFuncAndRightArgs) {\\\\n  let wrap = 2;\\\\n  wrap0;\\\\n  wrap1;\\\\n  wrap2;\\\\n  wrap3;\\\\n  wrap4;\\\\n  wrap5;\\\\n  wrap6;\\\\n  wrap7;\\\\n  wrap8;\\\\n  wrap9;\\\\n}\\");
     const lastStatementResult = eval(\\"native;\\");
     native.globals.set(\\"f\\", {
       kind: \\"const\\",
diff --git a/src/__tests__/stringify.ts b/src/__tests__/stringify.ts
index 15bbeb5b..738f8c6c 100644
--- a/src/__tests__/stringify.ts
+++ b/src/__tests__/stringify.ts
@@ -28,12 +28,15 @@ test('String representation of booleans are nice', () => {
 })
 
 test('String representation of functions are nice', () => {
-  return expectResult(stripIndent`
+  return expectResult(
+    stripIndent`
   function f(x, y) {
     return z;
   }
   stringify(f);
-  `).toMatchInlineSnapshot(`
+  `,
+    { native: true }
+  ).toMatchInlineSnapshot(`
 "function f(x, y) {
   return z;
 }"
@@ -41,10 +44,13 @@ test('String representation of functions are nice', () => {
 })
 
 test('String representation of arrow functions are nice', () => {
-  return expectResult(stripIndent`
+  return expectResult(
+    stripIndent`
   const f = (x, y) => z;
   stringify(f);
-  `).toMatchInlineSnapshot(`"(x, y) => z"`)
+  `,
+    { native: true }
+  ).toMatchInlineSnapshot(`"(x, y) => z"`)
 })
 
 test('String representation of arrays are nice', () => {
@@ -53,7 +59,7 @@ test('String representation of arrays are nice', () => {
   const xs = [1, 'true', true, () => x];
   stringify(xs);
   `,
-    { chapter: 3 }
+    { chapter: 3, native: true }
   ).toMatchInlineSnapshot(`"[1, \\"true\\", true, () => x]"`)
 })
 
@@ -63,7 +69,7 @@ test('String representation of multidimensional arrays are nice', () => {
   const xs = [1, 'true', [true, () => x, [[]]]];
   stringify(xs);
   `,
-    { chapter: 3 }
+    { chapter: 3, native: true }
   ).toMatchInlineSnapshot(`"[1, \\"true\\", [true, () => x, [[]]]]"`)
 })
 
@@ -482,7 +488,7 @@ test('String representation with custom indent', () => {
     stripIndent`
   stringify(parse('x=>x;'), ' ... ');
   `,
-    { chapter: 4 }
+    { chapter: 4, native: true }
   ).toMatchInlineSnapshot(`
 "[... {... \\"tag\\": \\"function_definition\\",
  ...  ... \\"parameters\\":
@@ -507,7 +513,7 @@ test('String representation with long custom indent gets trimmed to 10 character
     stripIndent`
   stringify(parse('x=>x;'), '.................................');
   `,
-    { chapter: 4 }
+    { chapter: 4, native: true }
   ).toMatchInlineSnapshot(`
 "[.........{.........\\"tag\\": \\"function_definition\\",
 ....................\\"parameters\\":
diff --git a/src/stdlib/__tests__/__snapshots__/list.ts.snap b/src/stdlib/__tests__/__snapshots__/list.ts.snap
index e3a906cb..79f29936 100644
--- a/src/stdlib/__tests__/__snapshots__/list.ts.snap
+++ b/src/stdlib/__tests__/__snapshots__/list.ts.snap
@@ -15,7 +15,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(accumulate, 1, 0, wrap((curr, acc) => ({   isTail: false,   value: curr + acc })), 0, callIfFuncAndRightArgs(list, 1, 41, 2, 3, 4, 1));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(accumulate, 1, 0, wrap((curr, acc) => ({   isTail: false,   value: curr + acc }), \\\\\\"(curr, acc) => curr + acc\\\\\\"), 0, callIfFuncAndRightArgs(list, 1, 41, 2, 3, 4, 1));\\");
     return lastStatementResult;
   })();
 })();
@@ -401,7 +401,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(build_list, 1, 6, 5, wrap(x => ({   isTail: false,   value: x * x }))), callIfFuncAndRightArgs(list, 1, 33, 0, 1, 4, 9, 16));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(build_list, 1, 6, 5, wrap(x => ({   isTail: false,   value: x * x }), \\\\\\"x => x * x\\\\\\")), callIfFuncAndRightArgs(list, 1, 33, 0, 1, 4, 9, 16));\\");
     return lastStatementResult;
   })();
 })();
@@ -497,7 +497,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(filter, 1, 6, wrap(x => ({   isTail: false,   value: x <= 4 })), callIfFuncAndRightArgs(list, 1, 26, 2, 10, 1000, 1, 3, 100, 4, 5, 2, 1000)), callIfFuncAndRightArgs(list, 1, 72, 2, 1, 3, 4, 2));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(filter, 1, 6, wrap(x => ({   isTail: false,   value: x <= 4 }), \\\\\\"x => x <= 4\\\\\\"), callIfFuncAndRightArgs(list, 1, 26, 2, 10, 1000, 1, 3, 100, 4, 5, 2, 1000)), callIfFuncAndRightArgs(list, 1, 72, 2, 1, 3, 4, 2));\\");
     return lastStatementResult;
   })();
 })();
@@ -528,7 +528,7 @@ const wrap = native.properTailCalls.wrap;
     let sum = 0;
     callIfFuncAndRightArgs(for_each, 2, 0, wrap(x => {
       sum = sum + x;
-    }), callIfFuncAndRightArgs(list, 4, 3, 1, 2, 3));
+    }, \\"x => {\\\\n  sum = sum + x;\\\\n}\\"), callIfFuncAndRightArgs(list, 4, 3, 1, 2, 3));
     const lastStatementResult = eval(\\"sum;\\");
     native.globals.set(\\"sum\\", {
       kind: \\"let\\",
@@ -661,7 +661,7 @@ const callIfFuncAndRightArgs = native.operators.get(\\"callIfFunctionAndRightArg
 const wrap = native.properTailCalls.wrap;
 (( <globals redacted> ) => {
   return (() => {
-    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(map, 1, 6, wrap(x => ({   isTail: false,   value: 2 * x })), callIfFuncAndRightArgs(list, 1, 22, 12, 11, 3)), callIfFuncAndRightArgs(list, 1, 40, 24, 22, 6));\\");
+    const lastStatementResult = eval(\\"callIfFuncAndRightArgs(equal, 1, 0, callIfFuncAndRightArgs(map, 1, 6, wrap(x => ({   isTail: false,   value: 2 * x }), \\\\\\"x => 2 * x\\\\\\"), callIfFuncAndRightArgs(list, 1, 22, 12, 11, 3)), callIfFuncAndRightArgs(list, 1, 40, 24, 22, 6));\\");
     return lastStatementResult;
   })();
 })();