Lambda Function

We can now add a builtin for our lambda function. We want it to take as input some list of symbols, and a list that represents the code. After that it should return a function lval. We’ve defined a few of builtins now, and this one will follow the same format. Like in def we do some error checking to ensure the argument types and count are correct (using some newly defined Macros). Then we just pop the first two arguments from the list and pass them to our previously defined function lval_lambda.

  1. lval* builtin_lambda(lenv* e, lval* a) {
  2. /* Check Two arguments, each of which are Q-Expressions */
  3. LASSERT_NUM("\\", a, 2);
  4. LASSERT_TYPE("\\", a, 0, LVAL_QEXPR);
  5. LASSERT_TYPE("\\", a, 1, LVAL_QEXPR);
  6. /* Check first Q-Expression contains only Symbols */
  7. for (int i = 0; i < a->cell[0]->count; i++) {
  8. LASSERT(a, (a->cell[0]->cell[i]->type == LVAL_SYM),
  9. "Cannot define non-symbol. Got %s, Expected %s.",
  10. ltype_name(a->cell[0]->cell[i]->type),ltype_name(LVAL_SYM));
  11. }
  12. /* Pop first two arguments and pass them to lval_lambda */
  13. lval* formals = lval_pop(a, 0);
  14. lval* body = lval_pop(a, 0);
  15. lval_del(a);
  16. return lval_lambda(formals, body);
  17. }

Where did LASSERT_NUM and LASSERT_TYPE come from? I took the liberty of improving the error reporting macros for this chapter. This task was suggested in the bonus marks of the previous chapter. It makes the code so much cleaner that it was hard to ignore! If you were planning on completing this task yourself, now might be a good time to do it. Otherwise you can look at the reference code for this chapter to see what approach I took, and integrate that into your code.

Let’s register this with the other builtins.

  1. lenv_add_builtin(e, "\\", builtin_lambda);