函数

每个功能强大的编程语言都应该具有函数这个特性。

幸运的是我们可以很容易地添加一个fun语言构造,fun将最后一个参数当作函数体,将之前的所有名称用作函数参数。

  1. specialForms.fun = (args, scope) => {
  2. if (!args.length) {
  3. throw new SyntaxError("Functions need a body");
  4. let body = args[args.length - 1];
  5. let params = args.slice(0, args.length - 1).map(expr => {
  6. if (expr.type != "word") {
  7. throw new SyntaxError("Parameter names must be words");
  8. }
  9. return expr.name;
  10. });
  11. return function() {
  12. if (arguments.length != argNames.length) {
  13. throw new TypeError("Wrong number of arguments");
  14. }
  15. let localScope = Object.create(scope);
  16. for (let i = 0; i < arguments.length; i++) {
  17. localScope[params[i]] = arguments[i];
  18. }
  19. return evaluate(body, localScope);
  20. };
  21. };

Egg 中的函数可以获得它们自己的局部作用域。 fun形式产生的函数创建这个局部作用域,并将参数绑定添加到它。 然后求解此范围内的函数体并返回结果。

  1. run(`
  2. do(define(plusOne, fun(a, +(a, 1))),
  3. print(plusOne(10)))
  4. `);
  5. // → 11
  6. run(`
  7. do(define(pow, fun(base, exp,
  8. if(==(exp, 0),
  9. 1,
  10. *(base, pow(base, -(exp, 1)))))),
  11. print(pow(2, 10)))
  12. `);
  13. // → 1024