Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Higher Order Function Syntax in Common Lisp

I'm teaching myself Common Lisp using Norvig's Paradigms of AI Programming and came across something I didn't understand and he didn't explain.

(defun mappend (fn the-list)
  (apply #'append (mapcar fn the-list)))

What is the difference between calling a higher order function as follows, higherOrderFunc #'funcName funcArg and what he does when calling mapcar without #'? Is #' necessary when calling a higher order function?

like image 664
vrume21 Avatar asked Apr 10 '13 21:04

vrume21


2 Answers

Common Lisp has different namespaces for functions and variables.

(defun mappend (fn the-list)
   (apply #'append (mapcar fn the-list)))

Above MAPPEND gets defined with two local variables fn and the-list

APPLY gets passed the function value of APPEND.

MAPCAR gets passed the variable value of FN.

Similar see this:

CL-USER 129 >  (flet ((add-something (number)
                       (+ number 17)))
                (let ((add-something (lambda (number)
                                       (+ number 42))))
                  (list
                   (mapcar #'add-something '(1 2 3))
                   (mapcar add-something '(1 2 3)))))

->

((18 19 20) (43 44 45))

LET creates local variables, FLET creates local functions.

The first mapcar uses the function namespace and the second uses the variable namespace.

Common Lisp uses a special function namespace because it was thought to be more efficient (slightly easier to implement a fast Lisp) and to allow functions and variables to have the same name.

In Common Lisp we can write:

(defun list-me (list)
  (list list))

In Scheme, which does not have separate namespaces one would write something like this:

(define (list-me lst)
  (list lst))
like image 175
Rainer Joswig Avatar answered Sep 30 '22 19:09

Rainer Joswig


#' is syntactic sugar for function: #'foo is read as (function foo).

Function is a special operator that returns the function value bound to the name given. If you pass a function as a parameter, that parameter (in your case, fn) has its value bound to the function. To pass it on to another function, you can simply put the variable name into the call form. However, to get the function value of a name, you need to access it with function.

like image 35
Svante Avatar answered Sep 30 '22 21:09

Svante