Implementing a map using foldr in Emacs Lisp

I am starting to learn Emacs Lisp and as an exercise that I am trying to implement using foldr. The code is as follows:

(defun foldr (f z l)
   (if (null l)
       z
       (funcall f (car l)
                  (foldr f z
                           (cdr l)))))

(defun map (f l)
   (foldr (lambda (x z)
            (cons (funcall f x) z))
          nil
          l))

However, when I try to evaluate, for example,

(map (lambda (x) (+ x 1)) '(1 2 3 4 5))

in Emacs with eval-last-sexp (after evaluating both foldr and the map), the result is as follows:

Debugger entered--Lisp error: (wrong-number-of-arguments (lambda (x z) (cons (funcall f x) z)) 1)
  (lambda (x z) (cons (funcall f x) z))(5)
  funcall((lambda (x z) (cons (funcall f x) z)) 5)
  (cons (funcall f x) z)
  (lambda (x z) (cons (funcall f x) z))(5 nil)
  funcall((lambda (x z) (cons (funcall f x) z)) 5 nil)
  (if (null l) z (funcall f (car l) (foldr f z (cdr l))))
  foldr((lambda (x z) (cons (funcall f x) z)) nil (5))
  (funcall f (car l) (foldr f z (cdr l)))
  (if (null l) z (funcall f (car l) (foldr f z (cdr l))))
  foldr((lambda (x z) (cons (funcall f x) z)) nil (4 5))
  (funcall f (car l) (foldr f z (cdr l)))
  (if (null l) z (funcall f (car l) (foldr f z (cdr l))))
  foldr((lambda (x z) (cons (funcall f x) z)) nil (3 4 5))
  (funcall f (car l) (foldr f z (cdr l)))
  (if (null l) z (funcall f (car l) (foldr f z (cdr l))))
  foldr((lambda (x z) (cons (funcall f x) z)) nil (2 3 4 5))
  (funcall f (car l) (foldr f z (cdr l)))
  (if (null l) z (funcall f (car l) (foldr f z (cdr l))))
  foldr((lambda (x z) (cons (funcall f x) z)) nil (1 2 3 4 5))
  map((lambda (x) (+ x 1)) (1 2 3 4 5))
  eval((map (function (lambda (x) (+ x 1))) (quote (1 2 3 4 5))) nil)
  eval-last-sexp-1(nil)
  #[257 "\204\303!\207  \303!\n)B\211A  =\204\211A\211@\207" [eval-expression-debug-on-error eval-last-sexp-fake-value debug-on-error eval-last-sexp-1] 4 2471606 "P"](nil)
  ad-Advice-eval-last-sexp(#[257 "\204\303!\207 \303!\n)B\211A  =\204\211A\211@\207" [eval-expression-debug-on-error eval-last-sexp-fake-value debug-on-error eval-last-sexp-1] 4 2471606 "P"] nil)
  apply(ad-Advice-eval-last-sexp #[257 "\204\303!\207   \303!\n)B\211A  =\204\211A\211@\207" [eval-expression-debug-on-error eval-last-sexp-fake-value debug-on-error eval-last-sexp-1] 4 2471606 "P"] nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

I don’t understand why this does not work when the following super similar implementation in Haskell works fine:

foldr f z l = if (null l)
              then z
              else f (head l) (foldr f z (tail l))

map f l = foldr (\ x z -> (:) (f x) z) [] l

So why aren't Lisp and Haskell equivalent? What is the nature of the problem in the implementation of Lisp, i.e. Why does the card not work?

+4
source share
1 answer
(setq lexical-binding t)

fis a free variable in the form of a lambda that you pass to foldr.

:

(map (lambda (x) (+ x 1)) '(1 2 3 4 5)) ; ==> (2 3 4 5 6)
+3

Source: https://habr.com/ru/post/1608394/


All Articles