I have the following function in lisp:
(defun F(F)
#'(lambda (n)
(if (zerop n)
(funcall F n)
(1+ (funcall (F F) (1- n))))))
How does this code behaves if I call:
(funcall (F #'(lambda (x) (+ 2 x))) 2)
I dont understand why the output is 4.
Thanks in advance
Since we know the argument, we can simplify the if statement in the function:
(funcall (F #'(lambda (x) (+ 2 x))) 2)
(1+ (funcall (F #'(lambda (x) (+ 2 x))) 1))
(1+ (1+ (funcall #'(lambda (x) (+ 2 x)) 0)))
(1+ (1+ 2))
4
The first 2 transformations replace (if false A B) with B, while the 3rd replaces (if true A B) with A.
First, untangle the two F:
(defun foo (fun)
#'(lambda (n)
(if (zerop n)
(funcall fun n)
(1+ (funcall (foo fun) (1- n))))))
Now, you call:
(funcall (foo #'(lambda (x) (+ 2 x))) 2)
We can give the inner lambda a name, I'll call it add-2.
(funcall (foo #'add-2) 2)
(Foo #'add-2) then returns the function
(lambda (n)
(if (zerop n)
(funcall #'add-2 n) ; n is always 0 here
(1+ (funcall (foo #'add-2) (1- n)))))
This gets called with 2, which is not zerop, so it is:
(1+ (funcall (foo #'add-2) 1))
We already know what (foo #'add-2) returns, and it gets called with 1 now, which still is not zerop:
(1+ (1+ (funcall (foo #'add-2) 0)))
Now the argument is 0, so we get to the base case:
(1+ (1+ (funcall #'add-2 0)))
We now can see that foo creates a function that adds n to the result of calling (fun 0).
Related
I've got an issue where I've got a macro, isentropic expansion which then calls solve-format replacing NIL in a list with 'x?, which then returns a valid expression can be passed to solve.
(isentropic-expansion 295 nil 1 4.2 1.4)
returns
(-
(expt
(/ 4.2 1)
(/
(- 1.4 1)
1.4))
(/ x\? 295))
which is the valid expression to then put into the solve function
but if I do the following (let's imagine I've set the output from the above command to the variable expr
(solve expr 2)
the macro doesn't replace the expression symbols with the value of expr, just expr the string, and I get
Wrong number of arguments: (lambda nil expr), 1
I think this is because I don't fully understand macros yet! Can anyone explain why this is please?
(defun newton-f (func x0)
"Solve the equation FUNC(x)=0 using Newton's method.
X0 is an initial guess."
(let* ((tolerance 1e-6)
(x x0)
(dx 1e-6)
fx fpx)
(while (> (abs (funcall func x)) tolerance)
(setq fx (funcall func x)
fpx (/ (- (funcall func (+ x dx)) (funcall func (- x dx))) (* 2 dx))
x (- x (/ fx fpx))))
x))
(defmacro solve (expression guess)
`(newton-f
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)
,guess))
(defun solve-format (exp)
(cond ((null exp) 'x?)
((atom exp) exp)
((list exp) (cons (solve-format (car exp))
(if (cdr exp)
(solve-format (cdr exp))
nil)))
(t (print "what"))))
(defmacro isentropic-expansion (t01 t02 p01 p02 gamma)
`(solve-format '(- (expt (/ ,p02 ,p01) (/ (- ,gamma 1) ,gamma)) (/ ,t02 ,t01))))
solve is also a macro:
(defmacro solve (expression guess) ...)
As macros do not automatically evaluate their arguments, when you use this:
(solve expr 2)
During the macro's expansion it has expression bound to the symbol expr and guess bound to the number 2.
The (lambda nil expr) in the error message is this call:
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)
The problem with flet is that the functions bound therein must be defined inline. In other words, there's no way to do this:
(new-flet ((a (lambda (f x)
(funcall f (* x 2))))
(b (function-generator)))
(a #'b 10))
I considered defining such a macro myself, but the problem is that flet seems to be the only way to set local function values. symbol-function always gets the global definition only, and function can't be used with setf. Anyone have an idea how this can be done fairly cleanly, if at all?
You can easily build a trampoline
(defun function-generator (x)
(lambda (y) (* x y)))
(let ((fg (function-generator 42)))
(flet ((a (f x) (funcall f (* x 2)))
(b (x) (funcall fg x)))
(a #'b 10)))
A macro implementation of new-flet with this approach is
(defmacro new-flet (bindings &body body)
(let ((let-bindings (list))
(flet-bindings (list))
(args (gensym)))
(dolist (binding bindings)
(let ((name (gensym)))
(push `(,name ,(second binding))
let-bindings)
(push `(,(first binding) (&rest ,args)
(apply ,name ,args))
flet-bindings)))
`(let ,(nreverse let-bindings)
(flet ,(nreverse flet-bindings)
,#body))))
that expands in your example case as
(macroexpand-1 '(new-flet ((a (lambda (f x) (funcall f (* x 2))))
(b (function-generator)))
(a #'b 10)))
==> (LET ((#:G605 (LAMBDA (F X)
(FUNCALL F (* X 2))))
(#:G606 (FUNCTION-GENERATOR)))
(FLET ((A (&REST #:G604)
(APPLY #:G605 #:G604))
(B (&REST #:G604)
(APPLY #:G606 #:G604)))
(A #'B 10)))
Is
(let* ((a (lambda (f x) (funcall f (* x 2))))
(b (function-generator)))
(funcall a b 10))
a fairly clean solution to your problem?
How about binding the variables with let, so that they're setfable, and then using an flet as the body of the let so that they're funcallable and (function …)-able, too. E.g., where I've given a silly little function instead of (generate-function):
(let ((a (lambda (f x)
(funcall f (* x 2))))
(b (lambda (&rest args)
(print (list* 'print-from-b args)))))
(flet ((a (&rest args)
(apply a args))
(b (&rest args)
(apply b args)))
(a #'b 10)))
We can wrap this up in a macro relatively easily:
(defmacro let/flet (bindings &body body)
(let ((args (gensym (string '#:args-))))
`(let ,bindings
(flet ,(loop :for (name nil) :in bindings
:collect `(,name (&rest ,args) (apply ,name ,args)))
,#body))))
Now
(let/flet ((a (lambda (f x)
(funcall f (* x 2))))
(b (lambda (&rest args)
(print (list* 'print-from-b args)))))
(a #'b 10))
expands into the first block of code. Note that you can also use (a b 10) in the body as well, since the binding of b is the same as the value of #'b. You can use setf on the variable as well:
(let/flet ((a (lambda (x)
(print (list 'from-a x)))))
(a 23)
(setf a (lambda (x)
(print (list 'from-new-a x x))))
(a 23))
prints
(FROM-A 23)
(FROM-NEW-A 23 23)
If anyone's interested in a labels equivalent, here it is:
(defmacro my-labels ((&rest definitions) &rest body)
(let ((gensyms (loop for d in definitions collect (gensym)))
(names (loop for d in definitions collect (car d)))
(fdefs (loop for f in definitions collect (cadr f)))
(args (gensym)))
`(let (,#(loop for g in gensyms collect (list g)))
(labels (,#(loop for g in gensyms for n in names
collect `(,n (&rest ,args) (apply ,g ,args))))
,#(loop for g in gensyms for f in fdefs
collect `(setf ,g ,f))
,#body))))
This is sort of like Scheme's letrec.
I'm trying to implement a Division function with clisp Lambda Calc. style
I read from this site that lambda expression of a division is:
Y (λgqab. LT a b (PAIR q a) (g (SUCC q) (SUB a b) b)) 0
These are TRUE and FALSE
(defvar TRUE #'(lambda(x)#'(lambda(y)x)))
(defvar FALSE #'(lambda(x)#'(lambda(y)y)))
These are conversion functions between Int and Church numbers
(defun church2int(numchurch)
(funcall (funcall numchurch #'(lambda (x) (+ x 1))) 0)
)
(defun int2church(n)
(cond
((= n 0) #'(lambda(f) #'(lambda(x)x)))
(t #'(lambda(f) #'(lambda(x) (funcall f
(funcall(funcall(int2church (- n 1))f)x))))))
)
This is my IF-THEN-ELSE Implementation
(defvar IF-THEN-ELSE
#'(lambda(c)
#'(lambda(x)
#'(lambda(y)
#'(lambda(acc1)
#'(lambda (acc2)
(funcall (funcall (funcall (funcall c x) y) acc1) acc2))))))
)
And this is my div implementation
(defvar division
#'(lambda (g)
#'(lambda (q)
#'(lambda (a)
#'(lambda (b)
(funcall (funcall (funcall (funcall (funcall IF-THEN-ELSE LT) a) b)
(funcall (funcall PAIR q)a))
(funcall (funcall g (funcall succ q)) (funcall (funcall sub a)b))
)))))
)
PAIR, SUCC and SUB functions work fine. I set my church numbers up like this
(set six (int2church 6))
(set two (int2church 2))
Then I do:
(setq D (funcall (funcall division six) two))
And I've got:
#<FUNCTION :LAMBDA (A)
#'(LAMBDA (B)
(FUNCALL (FUNCALL (FUNCALL (FUNCALL (FUNCALL IF-THEN-ELSE LT) A) B) (FUNCALL (FUNCALL PAR Q) A))
(FUNCALL (FUNCALL G (FUNCALL SUCC Q)) (FUNCALL (FUNCALL SUB A) B))))>
For what I understand, this function return a Church Pair. If I try to get the first element
with a function FRST (FRST works ok) like this:
(funcall frst D)
I've got
#<FUNCTION :LAMBDA (B)
(FUNCALL (FUNCALL (FUNCALL (FUNCALL (FUNCALL IF-THEN-ELSE LT) A) B) (FUNCALL (FUNCALL PAR Q) A))
(FUNCALL (FUNCALL G (FUNCALL SUCC Q)) (FUNCALL (FUNCALL SUB A) B)))>
If I try to get the int value with Church2int (Church2int works OK) like this:
(church2int (funcall frst D))
I've got
*** - +:
#<FUNCTION :LAMBDA (N)
#'(LAMBDA (F)
#'(LAMBDA (X)
(FUNCALL (FUNCALL (FUNCALL N #'(LAMBDA (G) #'(LAMBDA (H) (FUNCALL H (FUNCALL G F))))) #'(LAMBDA (U) X)) (LAMBDA (U) U))))>
is not a number
Where I expect to get 3
I think the problem is in DIVISION function, after the IF-THEN-ELSE, I tried to change it a little bit (I thought it was a nested parenthesis problem) but I got lots of errors.
Any help would be appreciated
Thanks
There are several problems with your definition.
DIVISION does not use the Y combinator, but the original definition does.
This is important, because the DIVISION function expects a copy of itself in the g
parameter.
However, even if you added the Y invocation, your code would still not work
but go into an infinite loop instead. That's because Common Lisp, like most of today's languages, is a call-by-value language. All arguments are evaluated before a function is called. This means that you cannot define conditional functions as elegantly as the traditional lambda calculus semantics would allow.
Here's one way of doing church number division in Common Lisp. I've taken the liberty of introducing some syntax to make this a bit more readable.
;;;; -*- coding: utf-8 -*-
;;;; --- preamble, define lambda calculus language
(cl:in-package #:cl-user)
(defpackage #:lambda-calc
;; note: not using common-lisp package
(:use)
(:export #:λ #:call #:define))
;; (lambda-calc:λ (x y) body)
;; ==> (cl:lambda (x) (cl:lambda (y) body))
(defmacro lambda-calc:λ ((arg &rest more-args) body-expr)
(labels ((rec (args)
(if (null args)
body-expr
`(lambda (,(car args))
(declare (ignorable ,(car args)))
,(rec (cdr args))))))
(rec (cons arg more-args))))
;; (lambda-calc:call f a b)
;; ==> (cl:funcall (cl:funcall f a) b)
(defmacro lambda-calc:call (func &rest args)
(labels ((rec (args)
(if (null args)
func
`(funcall ,(rec (cdr args)) ,(car args)))))
(rec (reverse args))))
;; Defines top-level lexical variables
(defmacro lambda-calc:define (name value)
(let ((vname (gensym (princ-to-string name))))
`(progn
(defparameter ,vname nil)
(define-symbol-macro ,name ,vname)
(setf ,name
(flet ((,vname () ,value))
(,vname))))))
;; Syntax: {f a b}
;; ==> (lambda-calc:call f a b)
;; ==> (cl:funcall (cl:funcall f a) b)
(eval-when (:compile-toplevel :load-toplevel :execute)
(set-macro-character #\{
(lambda (stream char)
(declare (ignore char))
`(lambda-calc:call
,#(read-delimited-list #\} stream t))))
(set-macro-character #\} (get-macro-character #\))))
;;;; --- end of preamble, fun starts here
(in-package #:lambda-calc)
;; booleans
(define TRUE
(λ (x y) x))
(define FALSE
(λ (x y) y))
(define NOT
(λ (bool) {bool FALSE TRUE}))
;; numbers
(define ZERO
(λ (f x) x))
(define SUCC
(λ (n f x) {f {n f x}}))
(define PLUS
(λ (m n) {m SUCC n}))
(define PRED
(λ (n f x)
{n (λ (g h) {h {g f}})
(λ (u) x)
(λ (u) u)}))
(define SUB
(λ (m n) {n PRED m}))
(define ISZERO
(λ (n) {n (λ (x) FALSE) TRUE}))
(define <=
(λ (m n) {ISZERO {SUB m n}}))
(define <
(λ (m n) {NOT {<= n m}}))
(define ONE {SUCC ZERO})
(define TWO {SUCC ONE})
(define THREE {SUCC TWO})
(define FOUR {SUCC THREE})
(define FIVE {SUCC FOUR})
(define SIX {SUCC FIVE})
(define SEVEN {SUCC SIX})
(define EIGHT {SUCC SEVEN})
(define NINE {SUCC EIGHT})
(define TEN {SUCC NINE})
;; combinators
(define Y
(λ (f)
{(λ (rec arg) {f {rec rec} arg})
(λ (rec arg) {f {rec rec} arg})}))
(define IF
(λ (condition if-true if-false)
{{condition if-true if-false} condition}))
;; pairs
(define PAIR
(λ (x y select) {select x y}))
(define FIRST
(λ (pair) {pair TRUE}))
(define SECOND
(λ (pair) {pair FALSE}))
;; conversion from/to lisp integers
(cl:defun int-to-church (number)
(cl:if (cl:zerop number)
zero
{succ (int-to-church (cl:1- number))}))
(cl:defun church-to-int (church-number)
{church-number #'cl:1+ 0})
;; what we're all here for
(define DIVISION
{Y (λ (recurse q a b)
{IF {< a b}
(λ (c) {PAIR q a})
(λ (c) {recurse {SUCC q} {SUB a b} b})})
ZERO})
If you put this into a file, you can do:
[1]> (load "lambdacalc.lisp")
;; Loading file lambdacalc.lisp ...
;; Loaded file lambdacalc.lisp
T
[2]> (in-package :lambda-calc)
#<PACKAGE LAMBDA-CALC>
LAMBDA-CALC[3]> (church-to-int {FIRST {DIVISION TEN FIVE}})
2
LAMBDA-CALC[4]> (church-to-int {SECOND {DIVISION TEN FIVE}})
0
LAMBDA-CALC[5]> (church-to-int {FIRST {DIVISION TEN FOUR}})
2
LAMBDA-CALC[6]> (church-to-int {SECOND {DIVISION TEN FOUR}})
2
since yesterday I've been trying to program a special case statement for scheme that would do the following:
(define (sort x)
(cond ((and (list? x) x) => (lambda (l)
(sort-list l)))
((and (pair? x) x) => (lambda (p)
(if (> (car p) (cdr p))
(cons (cdr p) (car p))
p)))
(else "here")))
instead of using all the and's and cond's statement, I would have:
(define (sort x)
(scase ((list? x) => (lambda (l)
(sort-list l)))
((pair? x) => (lambda (p)
(if (> (car p) (cdr p))
(cons (cdr p) (car p))
p)))
(else "here")))
What I could do so far, was this:
(define (sort x)
(scase (list? x) (lambda (l)
(sort-list l)))
(scase (pair? x) (lambda (p)
(if (> (car p) (cdr p))
(cons (cdr p) (car p))
p))))
with this code:
(define-syntax scase
(syntax-rules ()
((if condition body ...)
(if condition
(begin
body ...)))))
What I wanted to do now, is just allow the scase statement to have multiple arguments like this:
(scase ((list? (cons 2 1)) 'here)
((list? '(2 1)) 'working))
but I can't seem to figure out how I can do that. Maybe you guys could give me a little help?
Thanks in advance ;)
If this is an exercise in learning how to use syntax-rules, then disregard this answer.
I see a way to simplify your code that you are starting with.
(define (sort x)
(cond ((list? x)
(sort-list x))
((pair? x)
(if (> (car x) (cdr x))
(cons (cdr x) (car x))
x)))
(else "here")))
Since all the (and (list? x) x) => (lambda l ... does is see if x is a list, and then bind l to x, (since #f is not a list, and '() is not false, at least in Racket), you can just skip all that and just use x. You do not need to use => in case, and in this case it doesn't help. => is useful if you want to do an test that returns something useful if successful, or #f otherwise.
Now, if you want to use a macro, then you're going to need to clarify what you want it to do a bit better. I think that case already does what you want. Your existing macro is just if, so I'm not sure how to extend it.
I found the solution for my question, here it goes:
(define-syntax cases
(syntax-rules ()
((_ (e0 e1 e2 ...)) (if e0 (begin e1 e2 ...)))
((_ (e0 e1 e2 ...) c1 c2 ...)
(if e0 (begin e1 e2 ...) (cases c1 c2 ...)))))
Thank you all anyway :)
Here's a solution :
#lang racket
(require mzlib/defmacro)
(define-syntax scase
(syntax-rules (else)
((_ (else body1)) body1)
((_ (condition1 body1) (condition2 body2) ...)
(if condition1
body1
(scase (condition2 body2) ...)))))
(define (sort1 x)
((scase ((list? x) (lambda (l)
(sort l <)))
((pair? x) (lambda (p)
(if (> (car p) (cdr p))
(cons (cdr p) (car p))
p)))
(else (lambda (e) "here")))
x))
It works in DrRacket. I made three changes to your solution. First, i renamed your sort procedure to sort1 since sort is inbuilt in scheme ( I have used it inside sort1). Second, I have changed the sort1 itself so that the input given will be passed to the procedure returned by scase and you will directly get the sorted result. Third, I have modified the scase syntax extension, so that it will accept the else condition.
>(sort1 (list 3 1 2))
'(1 2 3)
> (sort1 (cons 2 1))
'(1 . 2)
> (sort1 'here)
"here"
I suggest you read "The Scheme Programming Language" by Kent Dybvig. There is an entire chapter on syntactic extensions.
I've a question, how to return a list without the nth element of a given list? E.g., given list: (1 2 3 2 4 6), and given n = 4, in this case the return list should be (1 2 3 4 6).
A simple recursive solution:
(defun remove-nth (n list)
(declare
(type (integer 0) n)
(type list list))
(if (or (zerop n) (null list))
(cdr list)
(cons (car list) (remove-nth (1- n) (cdr list)))))
This will share the common tail, except in the case where the list has n or more elements, in which case it returns a new list with the same elements as the provided one.
Using remove-if:
(defun foo (n list)
(remove-if (constantly t) list :start (1- n) :count 1))
butlast/nthcdr solution (corrected):
(defun foo (n list)
(append (butlast list (1+ (- (length list) n))) (nthcdr n list)))
Or, maybe more readable:
(defun foo (n list)
(append (subseq list 0 (1- n)) (nthcdr n list)))
Using loop:
(defun foo (n list)
(loop for elt in list
for i from 1
unless (= i n) collect elt))
Here's an interesting approach. It replaces the nth element of a list with a new symbol and then removes that symbol from the list. I haven't considered how (in)efficient it is though!
(defun remove-nth (n list)
(remove (setf (nth n list) (gensym)) list))
(loop :for i :in '(1 2 3 2 4 6) ; the list
:for idx :from 0
:unless (= 3 idx) :collect i) ; except idx=3
;; => (1 2 3 4 6)
loop macro can be very useful and effective in terms of generated code by lisp compiler and macro expander.
Test run and apply macroexpand above code snippet.
A slightly more general function:
(defun remove-by-position (pred lst)
(labels ((walk-list (pred lst idx)
(if (null lst)
lst
(if (funcall pred idx)
(walk-list pred (cdr lst) (1+ idx))
(cons (car lst) (walk-list pred (cdr lst) (1+ idx)))))))
(walk-list pred lst 1)))
Which we use to implement desired remove-nth:
(defun remove-nth (n list)
(remove-by-position (lambda (i) (= i n)) list))
And the invocation:
(remove-nth 4 '(1 2 3 2 4 6))
Edit: Applied remarks from Samuel's comment.
A destructive version, the original list will be modified (except when n < 1),
(defun remove-nth (n lst)
(if (< n 1) (cdr lst)
(let* ((p (nthcdr (1- n) lst))
(right (cddr p)))
(when (consp p)
(setcdr p nil))
(nconc lst right))))
That's elisp but I think those are standard lispy functions.
For all you haskellers out there, there is no need to twist your brains :)
(defun take (n l)
(subseq l 0 (min n (length l))))
(defun drop (n l)
(subseq l n))
(defun remove-nth (n l)
(append (take (- n 1) l)
(drop n l)))
My horrible elisp solution:
(defun without-nth (list n)
(defun accum-if (list accum n)
(if (not list)
accum
(accum-if (cdr list) (if (eq n 0) accum (cons (car list) accum))
(- n 1))))
(reverse (accum-if list '() n)))
(without-nth '(1 2 3) 1)
Should be easily portable to Common Lisp.
A much simpler solution will be as follows.
(defun remove-nth (n lst)
(append (subseq lst 0 (- n 1)) (subseq lst n (length lst)))
)