Writing a test function leveraging two namespaces in lisp - scheme

I started to learn Lisp and using Lispworks personal edition 6.1.1 and I hit on problem when evaluating basic functions. I am able to get them right in Scheme but they are not working when I try to evaluate them in Lisp.
I know in Lisp that every symbol has two namespaces. So I tried to write simple procedure for composing two procedures. It is working perfectly in Scheme but in Lisp there is a problem with evaluation.
Code in scheme it is working perfectly and return 2
(define (comp a b)
(lambda (x)
(a (b x))))
(define test (comp car cdr))
(test '(1 2 3))
Same code rewritten in Lisp
(defun comp (a b)
(lambda (x)
(funcall a (funcall b x))))
(defun test (comp #'car #'cdr))
(funcall test '(1 2 3))
Error in lispworks is:
Trying to bind a non-symbol, (FUNCTION CAR).
so when I try to evaluate (defun test (comp #'car #'cdr)) in listener I get
Non-symbol (FUNCTION CAR) used as variable name in function TEST.
I do not understand why it is not working written like that. I would aprreciate any help

defun is used to define a function with parameters:
defun function-name lambda-list [[declaration* | documentation]] form*
so it requires a lambda list after the function name, but you have written:
(defun test (comp #'car #'cdr))
which does not respect this syntax. If you want to define a variable that contains the function resulting from composing two functions you have several possibilities:
Use a special variable:
(defvar test (comp #'car #'cdr))
Use a local variable inside a form:
(let ((test (comp #'car #'cdr)))
(funcall test '(1 2 3))
You can even assign it to a global function name, like in:
(setf (symbol-function 'test) (comp #'car #'cdr)
and in this case you can use the name as a regular function name, without funcall:
(test '(1 2 3))

(defun test (comp #'car #'cdr))
DEFUN expects a lambda-list after the name, and here your lambda-list is malformed since #'car is not a symbol but reads as (function car).
What you probably wanted to do is to define the function test as the composition of car and cdr; (comp ...) would return the appropriate function object but defun does not allow to have a value in place of the lambda-list.
You could do:
(setf (symbol-function 'test)
(comp #'car #'cdr))

With local functions:
CL-USER 1 > (flet ((comp (a b)
(lambda (x)
(funcall a (funcall b x)))))
(let ((test (comp #'car #'cdr)))
(flet ((test (x)
(funcall test x)))
(test '(1 2 3)))))
2
CL-USER 2 > (labels ((comp (a b)
(lambda (x)
(funcall a (funcall b x))))
(test (x)
(funcall (comp #'car #'cdr) x)))
(test '(1 2 3)))
2

Another suggestion:
(defun comp (a b)
(lambda (x)
(funcall a (funcall b x))))
(defun mytest (x &key test) ;; a "test" key is common
(funcall test x))
(mytest '(1 2 3) :test (comp #'car #'cdr))
or
(defun comp (x a b)
(funcall a (funcall b x)))
(defun test (x a b)
(comp x a b))
(test '(1 2 3) #'car #'cdr)

Related

scheme: order of internal definition

It's a problem in SICP book ch4,here is the code
(let ((a 1))
(define (f x)
(define b (+ a x))
(define a 5)
(+ a b))
(f 10))
the error message is “a: undefined; cannot use before initialization”,if I use lambda expression
((lambda (a)
(define (f x)
(define a 5)
(define b (+ a x))
(+ a b))
(f 10)) 1)
still dont work,but if I write this as procedure define,like this
(define (f a)
(define (g x)
(define b (+ a x))
(+ a b))
(g 10))
(f 1)
it runs without error,but these two are basically the same right? why the let and lambda expression failed? thanks.
Because it refers to the inner a, not the one in the let:
(let ((a 1))
(define (f x)
(define b (+ a x)) ; `a` here refers to
(define a 5) ; **this one**
(+ a b))
(f 10))
Internal defines are all placed in one shared scope. It is done so we can define mutually recursive functions.
If you switch the order of the two defines it'll work (put a definition above the b definition) because then a will be initialized before being used in the b initialization, but only if you use #lang racket.
In #lang sicp the following works:
(let ((a 1))
(define (f x)
(define a 5)
(define b (lambda () (+ a x)))
(+ a (b)))
(f 10))

Unusual Scheme `let` binding, what is `f`?

In "The Scheme Programming Language 4th Edition" section 3.3 Continuations the following example is given:
(define product
(lambda (ls)
(call/cc
(lambda (break)
(let f ([ls ls])
(cond
[(null? ls) 1]
[(= (car ls) 0) (break 0)]
[else (* (car ls) (f (cdr ls)))]))))))
I can confirm it works in chezscheme as written:
> (product '(1 2 3 4 5))
120
What is 'f' in the above let? Why is the given ls being assigned to itself? It doesn't seem to match what I understand about (let ...) as described in 4.4 local binding:
syntax: (let ((var expr) ...) body1 body2 ...)
If 'f' is being defined here I would expect it inside parenthesis/square brackets:
(let ([f some-value]) ...)
This is 'named let', and it's a syntactic convenience.
(let f ([x y] ...)
...
(f ...)
...)
is more-or-less equivalent to
(letrec ([f (λ (x ...)
...
(f ...)
...)])
(f y ...))
or, in suitable contexts, to a local define followed by a call:
(define (outer ...)
(let inner ([x y] ...)
...
(inner ...)
...))
is more-or-less equivalent to
(define (outer ...)
(define (inner x ...)
...
(inner ...)
...)
(inner y ...))
The nice thing about named let is that it puts the definition and the initial call of the local function in the same place.
Cavemen like me who use CL sometimes use macros like binding, below, to implement this (note this is not production code: all its error messages are obscure jokes):
(defmacro binding (name/bindings &body bindings/decls/forms)
;; let / named let
(typecase name/bindings
(list
`(let ,name/bindings ,#bindings/decls/forms))
(symbol
(unless (not (null bindings/decls/forms))
(error "a syntax"))
(destructuring-bind (bindings . decls/forms) bindings/decls/forms
(unless (listp bindings)
(error "another syntax"))
(unless (listp decls/forms)
(error "yet another syntax"))
(multiple-value-bind (args inits)
(loop for binding in bindings
do (unless (and (listp binding)
(= (length binding) 2)
(symbolp (first binding)))
(error "a more subtle syntax"))
collect (first binding) into args
collect (second binding) into inits
finally (return (values args inits)))
`(labels ((,name/bindings ,args
,#decls/forms))
(,name/bindings ,#inits)))))
(t
(error "yet a different syntax"))))
f is bound to a procedure that has the body of let as a body and ls as a parameter.
http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.16
Think of this procedure:
(define (sum lst)
(define (helper lst acc)
(if (null? lst)
acc
(helper (cdr lst)
(+ (car lst) acc))))
(helper lst 0))
(sum '(1 2 3)) ; ==> 6
We can use named let instead of defining a local procedure and then use it like this:
(define (sum lst-arg)
(let helper ((lst lst-arg) (acc 0))
(if (null? lst)
acc
(helper (cdr lst)
(+ (car lst) acc)))))
Those are the exact same code with the exception of some duplicate naming situations. lst-arg can have the same name lst and it is never the same as lst inside the let.
Named let is easy to grasp. call/ccusually takes some maturing. I didn't get call/cc before I started creating my own implementations.

Why is it returning this?

I am trying to use lambda, but when I test it in the console, it returns #<procedure:...esktop/Lab 4.rkt:105:2>.
My code is
(define (comp f g)
(lambda (x) (f (g x))))
And my test code is
(comp (lambda (x) (+ x 1)) 3)
For some reason, lambda is deferring the evaluation. Can someone please help?
comp takes two function arguments and returns a new function - their
composition:
(define (comp f g)
(lambda (x) (f (g x))))
;Value: comp
To test it, one has to call it on a number:
((comp (lambda (x) (+ x 1))
(lambda (x) (+ x 2)))
3)
;Value: 6

How to write a macro that maintains local state?

This seems to work, it's a macro that expands to successive integers depending on how many times it has been expanded.
;; Library (test macro-state)
(library
(test macro-state)
(export get-count incr-count)
(import (rnrs))
(define *count* 0)
(define (get-count) *count*)
(define (incr-count) (set! *count* (+ *count* 1)))
)
;; Program
(import (rnrs) (for (test macro-state) expand))
(define-syntax m
(lambda (x)
(syntax-case x ()
((m) (begin (incr-count) (datum->syntax #'m (get-count)))))))
(write (list (m) (m) (m)))
(newline)
;; prints (1 2 3)
But it's clumsy to me because the macro state *count* and the macro m itself are in different modules. Is there a better way to do this in r6rs, preferably one that doesn't split the implementation over two modules?
EDIT
I should make it clear that although this example is just a single macro, in reality I'm looking for a method that works when multiple macros need to share state.
You can make the state local to the macro transformer:
(define-syntax m
(let ()
(define *count* 0)
(define (get-count) *count*)
(define (incr-count) (set! *count* (+ *count* 1)))
(lambda (x)
(syntax-case x ()
((m) (begin (incr-count) (datum->syntax #'m (get-count))))))))
Edited to add: In Racket, you can also do this:
(begin-for-syntax
(define *count* 0)
(define (get-count) *count*)
(define (incr-count) (set! *count* (+ *count* 1))))
(define-syntax m
(lambda (x)
(syntax-case x ()
((m) (begin (incr-count) (datum->syntax #'m (get-count)))))))
But I don't think R6RS has anything that corresponds to begin-for-syntax.

curry in scheme

I have this curry function:
(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))
I think it's like (define curry (f a b)).
my assignment is to write a function consElem2All using curry,which should work like
(((consElem2All cons) 'b) '((1) (2 3) (4)))
>((b 1) (b 2 3) (b 4))
I have wrote this function in a regular way:
(define (consElem2All0 x lst)
(map (lambda (elem) (cons x elem)) lst))
but still don't know how to transform it with curry. Can anyone help me?
thanks in advance
bearzk
You should begin by reading about currying. If you don't understand what curry is about, it may be really hard to use it... In your case, http://www.engr.uconn.edu/~jeffm/Papers/curry.html may be a good start.
One very common and interesting use of currying is with functions like reduce or map (for themselves or their arguments).
Let's define two currying operators!
(define curry2 (lambda (f) (lambda (arg1) (lambda (arg2) (f arg1 arg2)))))
(define curry3 (lambda (f) (lambda (arg1) (lambda (arg2) (lambda (arg3) (f arg1 arg2 arg3))))))
Then a few curried mathematical functions:
(define mult (curry2 *))
(define double (mult 2))
(define add (curry2 +))
(define increment (add 1))
(define decrement (add -1))
And then come the curried reduce/map:
(define creduce (curry3 reduce))
(define cmap (curry2 map))
Using them
First reduce use cases:
(define sum ((creduce +) 0))
(sum '(1 2 3 4)) ; => 10
(define product (creduce * 1))
(product '(1 2 3 4)) ; => 24
And then map use cases:
(define doubles (cmap double))
(doubles '(1 2 3 4)) ; => (2 4 6 8)
(define bump (cmap increment))
(bump '(1 2 3 4)) ; => (2 3 4 5)
I hope that helps you grasp the usefulness of currying...
So your version of curry takes a function with two args, let's say:
(define (cons a b) ...)
and turns that into something you can call like this:
(define my-cons (curry cons))
((my-cons 'a) '(b c)) ; => (cons 'a '(b c)) => '(a b c)
You actually have a function that takes three args. If you had a curry3 that managed 3-ary functions, you could do something like:
(define (consElem2All0 the-conser x lst) ...)
(like you did, but allowing cons-like functions other than cons to be used!)
and then do this:
(define consElem2All (curry3 consElem2All0))
You don't have such a curry3 at hand. So you can either build one, or work around it by "manually" currying the extra variable yourself. Working around it looks something like:
(define (consElem2All0 the-conser)
(lambda (x lst) ...something using the-conser...))
(define (consElem2All the-conser)
(curry (consElem2All0 the-conser)))
Note that there's one other possible use of curry in the map expression itself, implied by you wrapping a lambda around cons to take the element to pass to cons. How could you curry x into cons so that you get a one-argument function that can be used directly to map?...
Perhaps better use a generalized version:
(define (my-curry f)
(lambda args
(cond ((= (length args) 1)
(lambda lst (apply f (cons (car args) lst))))
((>= (length args) 2)
(apply f (cons (car args) (cdr args)))))))
(define (consElem2All0 x lst)
  (map ((curry cons) x) lst))

Resources