[Lisp] Functions vs. Macros 08-31-2015, 11:56 PM
#1
There are 2 somewhat equivalent "def" functions in Lisp: defun and defmacro.
The difference between these two is macros are used for defining syntax extension to Common Lisp or Domain Specific Languages (DSLs). These languages are embedded right within your existing Lisp code.
As a more concrete example, Python has list comprehensions built-in the language. This gives a simple syntax for a common case [1] gives the numbers from 0 to 9 that are divisible by two. Back in Python 1.5 there was no such syntax, and that would have expressed as:
[1]
The above examples are functionally equivalent, yes?
In Lisp you could write the following:
Instead of doing all that messy garbage, we can define a macro called lcomp (short for list comprehension). It's syntax will be exactly like the python that we used in the example.
Both programs give the same output.
Lisp:
Python:
Huge props to gte525u and Slomojo from StackOverflow for reference on this topic. If you're confused as hell after reading this, go read this.
The difference between these two is macros are used for defining syntax extension to Common Lisp or Domain Specific Languages (DSLs). These languages are embedded right within your existing Lisp code.
As a more concrete example, Python has list comprehensions built-in the language. This gives a simple syntax for a common case [1] gives the numbers from 0 to 9 that are divisible by two. Back in Python 1.5 there was no such syntax, and that would have expressed as:
Code:
divisibleByTwo = []
for x in range( 10 ):
if x % 2 == 0:
divisibleByTwo.append( x )[1]
Code:
divisibleByTwo = [x for x in range(10) if x % 2 == 0]The above examples are functionally equivalent, yes?
In Lisp you could write the following:
Code:
;; the first two functions are a clone of Python's "range"
(defun range-helper (x)
(if (= x 0)
(list x)
(cons x (range-helper (- x 1)))))
(defun range (x)
(reverse (range-helper (- x 1))))
;;equal to divisibleByTwo = []
(setq divisibleByTwo nil)
(loop for x in (range 10)
if (= (mod x 2) 0)
do (setq divisibleByTwo (append divisibleByTwo (list x))))Instead of doing all that messy garbage, we can define a macro called lcomp (short for list comprehension). It's syntax will be exactly like the python that we used in the example.
Code:
(defmacro lcomp (expression for var in list conditional conditional-test)
(let ((result (gensym)))
`(let ((,result nil))
(loop for ,var in ,list
,conditional ,conditional-test
do (setq ,result (append ,result (list ,expression))))
,result)))
;; we need a variable for our macro to take in this case
(setq l '(0 1 2 3 4 5 6 7 8 9)) ;; ' for literal definition
(write (lcomp x for x in l if (= (mod x 2) 0)))Both programs give the same output.
Lisp:
Code:
(0 2 4 6 8)Code:
[0, 2, 4, 6, 8]Huge props to gte525u and Slomojo from StackOverflow for reference on this topic. If you're confused as hell after reading this, go read this.
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.
don't have much in the first place, who feel the new currents and ride them the farthest.

















![[+]](https://sinister.li/images/modern/collapse_collapsed.png)













