Racket - Match Function - match

I'm learning how to use the "match" function in Racket but I'm not really sure how it can work in certain contexts.
For example, a problem I have is to use match to replace every occurrence of lambda in a program with the word "lumbda".
> (lambda->lumbda '(lambda (lambda) lambda))
(lumbda (lambda) lambda)
It should only change the function "lambda" to "lumbda", not any variables. I have no clue how to go about this.

Try this:
(define (lambda->lumbda exp)
(match exp
[(list 'lambda args body) (list 'lumbda args body)]
[_ (error "unknown expression")]))
For example:
(lambda->lumbda '(lambda (lambda) lambda))
=> (lumbda (lambda) lambda)

Related

Racket: How do you use the value of an argument as a symbol?

I'm new to Racket, and am struggling to find the right words to explain what I'm trying to do. The best I can come up with is this: How do I use the value of an argument as a symbol, without calling the function which has the same name as the value of the argument, and without just quoting the name of the argument?
Here is a minimal example to show this.
There is a function called ul which does something.
There is another function called make-list which has a single parameter, list-type.
There is a third function, make-ul, which calls make-list with an argument ul.
In the true branch, the function ul is applied. Good so far.
In the false branch, I want to be able to use the value of the argument, which in this case is 'ul, as a symbol. In effect, this line of code would run (λ args (list* 'ul args)). How do I achieve this?
#lang racket
(define (ul . xs) `(div ,#xs))
(define (make-list list-type)
(if (equal? 'something 'something-else)
(λ args (apply list-type args)) ; true branch: call the function "ul"
(λ args (list* list-type args)))) ; false branch: how to use `ul without calling the "ul" function?
(define make-ul (make-list ul))
If your goal is to write good Racket code, then the best answer is don't.
Add a separate argument to take the symbol, like this:
;; make-list : Procedure Symbol -> Any ... -> Any
(define (make-list proc tag-sym)
(if ....
proc ;; (λ args (apply proc args)) simplifies to just proc
(λ args (list* tag-sym args))))
(define make-ul (make-list ul 'ul))
Or if the branch is independent of args, you could just have a single argument of type (U Procedure Symbol) instead:
;; make-list : (U Procedure Symbol) -> Any ... -> Any
(define (make-list list-type)
(cond [(procedure? list-type)
;; (λ args (apply list-type args))
list-type]
[(symbol? list-type)
(λ args (list* list-type args))]))
(define make-ul (make-list ul))
(define make-li (make-list 'li))
If you want to explore Racket features, there are two main ways to do it.
You can make a macro that takes a procedure name and uses it both as a reference and quotes it as a symbol. For example, using the first version of make-list above:
(define-syntax-rule (make-list* proc-name) (make-list proc-name (quote proc-name)))
(define make-ul (make-list* ul)) ;; => (define make-ul (make-list ul 'ul))
You can call object-name on a procedure to ask what Racket thinks its name is. For example, (object-name list) returns 'list, and (object-name ul) should return 'ul. But (object-name make-ul) will not return 'make-ul, because Racket tracks names at compile time, not at run time. (I would advise against writing code that depends on object-name; it makes your code very fragile.)

Call several functions with the same value

I have various functions and I want to call each function with the same value. For instance,
I have these functions:
(defun OP1 (arg) ( + 1 arg) )
(defun OP2 (arg) ( + 2 arg) )
(defun OP3 (arg) ( + 3 arg) )
And a list containing the name of each function:
(defconstant *OPERATORS* '(OP1 OP2 OP3))
So far, I'm trying:
(defun TEST (argument) (dolist (n *OPERATORS*) (n argument) ) )
I've tried using eval, mapcar, and apply, but these haven't worked.
This is just a simplified example; the program that I'm writing has eight functions that are needed to expand nodes in a search tree, but for the moment, this example should suffice.
Other answers have provided some idiomatic solutions with mapcar. One pointed out that you might want a list of functions (which *operators* isn't) instead of a list of symbols (which *operators* is), but it's OK in Common Lisp to funcall a symbol. It's probably more common to use some kind of mapping construction (e.g., mapcar) for this, but since you've provided code using dolist, I think it's worth looking at how you can do this iteratively, too. Let's cover the (probably more idiomatic) solution with mapping first, though.
Mapping
You have a fixed argument, argument, and you want to be able to take a function function and call it with that `argument. We can abstract this as a function:
(lambda (function)
(funcall function argument))
Now, we want to call this function with each of the operations that you've defined. This is simple to do with mapcar:
(defun test (argument)
(mapcar (lambda (function)
(funcall function argument))
*operators*))
Instead of operators, you could also write '(op1 op2 op3) or (list 'op1 'op2 'op3), which are lists of symbols, or (list #'op1 #'op2 #'op3) which is a list of functions. All of these work because funcall takes a function designator as its first argument, and a function designator is
an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself).
Iteratively
You can do this using dolist. The [documentation for actually shows that dolist has a few more tricks up its sleeve. The full syntax is from the documentation
dolist (var list-form [result-form]) declaration* {tag | statement}*
We don't need to worry about declarations here, and we won't be using any tags, but notice that optional result-form. You can specify a form to produce the value that dolist returns; you don't have to accept its default nil. The common idiom for collecting values into a list in an iterative loop is to push each value into a new list, and then return the reverse of that list. Since the new list doesn't share structure with anything else, we usually reverse it destructively using nreverse. Your loop would become
(defun test (argument)
(let ((results '()))
(dolist (op *operators* (nreverse results))
(push (funcall op argument) results))))
Stylistically, I don't like that let that just introduces a single value, and would probably use an &aux variable in the function (but this is a matter of taste, not correctness):
(defun test (argument &aux (results '()))
(dolist (op *operators* (nreverse results))
(push (funcall op argument) results)))
You could also conveniently use loop for this:
(defun test2 (argument)
(loop for op in *operators*
collect (funcall op argument)))
You can also do somewhat succinctly, but perhaps less readably, using do:
(defun test3a (argument)
(do ((results '() (list* (funcall (first operators) argument) results))
(operators *operators* (rest operators)))
((endp operators) (nreverse results))))
This says that on the first iteration, results and operators are initialized with '() and *operators*, respectively. The loop terminates when operators is the empty list, and whenever it terminates, the return value is (nreverse results). On successive iterations, results is a assigned new value, (list* (funcall (first operators) argument) results), which is just like pushing the next value onto results, and operators is updated to (rest operators).
FUNCALL works with symbols.
From the department of silly tricks.
(defconstant *operators* '(op1 op2 o3))
(defun test (&rest arg)
(setf (cdr arg) arg)
(mapcar #'funcall *operators* arg))
There's a library, which is almost mandatory in any anywhat complex project: Alexandria. It has many useful functions, and there's also something that would make your code prettier / less verbose and more conscious.
Say, you wanted to call a number of functions with the same value. Here's how you'd do it:
(ql:quickload "alexandria")
(use-package :alexandria)
(defun example-rcurry (value)
"Calls `listp', `string' and `numberp' with VALUE and returns
a list of results"
(let ((predicates '(listp stringp numberp)))
(mapcar (rcurry #'funcall value) predicates)))
(example-rcurry 42) ;; (NIL NIL T)
(example-rcurry "42") ;; (NIL T NIL)
(defun example-compose (value)
"Calls `complexp' with the result of calling `sqrt'
with the result of calling `parse-integer' on VALUE"
(let ((predicates '(complexp sqrt parse-integer)))
(funcall (apply #'compose predicates) value)))
(example-compose "0") ;; NIL
(example-compose "-1") ;; T
Functions rcurry and compose are from Alexandria package.

Error during expansion of macro in Chicken Scheme

I'm learning how the macro system in Scheme works and I'm trying to make my code look more JavaScript-y. So I thought I would start with the function macro. This is how I want a function definition to look:
(function id (x) x)
It should expand to the following:
(define (id x) x)
So I write a macro as follows:
(define-syntax function
(lambda (name args . body)
`(define (,name ,#args) ,#body)))
However when I use it I get the following error (in Chicken Scheme):
Error: during expansion of (define ...) - in `define' - lambda-list expected: (define ((function id (x) x) . #<procedure (rename sym1348)>) #<procedure (compare s11400 s21401)>)
Call history:
<syntax> (function id (x) x)
<eval> (##sys#cons (##core#quote define) (##sys#cons (##sys#cons name args) body))
<eval> (##sys#cons (##sys#cons name args) body)
<eval> (##sys#cons name args) <--
Where am I going wrong? In addition how do I read such error messages to be able to debug the program myself?
In Scheme, using syntax-rules():
(define-syntax function
(syntax-rules ()
((function name (args ...) body ...)
(define (name args ...) body ...))))
The error you are seeing is that apparently Chicken Scheme's compiler expects the second form of define-syntax to be a macro expansion procedure - they typically require arguments for renaming and comparing identifiers. The lambda in your macro doesn't produce a suitable function - syntax-rules does.
The above is guaranteed hygienic.
The way you have defined the macro is not correct as per Chicken documentation. Your code seems to be more inspired by Common Lisp macros. Check out the doc here for define-syntax with transformer function:
The macro should be defined as:
(define-syntax function
(lambda (expr inject compare)
`(define (,(cadr expr) ,#(caddr expr)) ,(cadddr expr))))
expr is the whole macro expression i.e (function id (x) x) and inject and compare are special utility functions passed to the macro while perfoming macro expand.

Renaming lambda in Common Lisp

I started learning Common Lisp recently, and (just for fun) decided to rename the lambda macro.
My attempt was this:
> (defmacro λ (args &body body) `(lambda ,args ,#body))
It seems to expand correctly when by itself:
> (macroexpand-1 '(λ (x) (* x x)))
(LAMBDA (X) (* X X))
But when it's nested inside an expression, execution fails:
> ((λ (x) (* x x)) 2)
(Λ (X) (* X X)) is not a function name; try using a symbol instead
I am probably missing something obvious about macro expansion, but couldn't find out what it is.
Maybe you can help me out?
edit:
It does work with lambda:
> ((lambda (x) (* x x)) 2)
4
edit 2:
One way to make it work (as suggested by Rainer):
> (set-macro-character #\λ (lambda (stream char) (quote lambda)))
(tested in Clozure CL)
In Common Lisp LAMBDA is two different things: a macro and a symbol which can be used in a LAMBDA expression.
The LAMBDA expression:
(function (lambda (x) (foo x)))
shorter written as
#'(lambda (x) (foo x))
An applied lambda expression is also valid:
((lambda (x) (+ x x)) 4)
Above both forms are part of the core syntax of Common Lisp.
Late in the definition of Common Lisp a macro called LAMBDA has been added. Confusingly enough, but with good intentions. ;-) It is documented as Macro LAMBDA.
(lambda (x) (+ x x))
expands into
(function (lambda (x) (+ x x))
It makes Common Lisp code look slightly more like Scheme code and then it is not necessary to write
(mapcar #'(lambda (x) (+ x x)) some-list)
With the LAMBDA macro we can write
(mapcar (lambda (x) (+ x x)) some-list)
Your example fails because
((my-lambda (x) (* x x)) 2)
is not valid Common Lisp syntax.
Common Lisp expects either
a data object
a variable
a function call in the form (function args...)
a function call in the form ((lambda (arglist ...) body) args...)
a macro form like (macro-name forms...)
a special form using one of the built-in special operators like FUNCTION, LET, ...
defined in the list of special operators in Common Lisp
As you can see a syntax of
((macro-name forms...) forms...)
is not a part of Common Lisp.
It is possible to read the character λ as LAMBDA:
(defun λ-reader (stream char)
(declare (ignore char stream))
'LAMBDA)
(set-macro-character #\λ #'λ-reader)
Example:
CL-USER 1 > ((λ (x) (* x x)) 3)
9
CL-USER 2 > '(λ (x) (* x x))
(LAMBDA (X) (* X X))
You might also think of LAMBDA as an operator which, given a term and a list of free variables, returns a function. This p.o.v. takes LAMBDA out of the family of basic functions and elementary macros -- at least as far as the interpreter is concerned.
(defun lambda-char (stream char)
"A lambda with only ONE arg _"
(declare (ignore char))
(let ((codes (read stream nil)))
`(lambda (_) ,codes)))
(set-macro-character #\λ #'lambda-char t)
λ(+ 1 2 _) ; => (lambda (_) (+ 1 2 _))
Maybe this is more concise, with ONLY ONE arg of _

LISP functions that perform both symbolic and numeric operations on expressions using +, -, *, and /

I'm currently working on a LISP exercise for a small project and need severe help. This may be more or less of a beginner's question but I'm absolutely lost on writing a certain function that takes in two unevaluated functions and spits out the result dependent on if the variables were given an assignment or not.
An example would be
(setq p1 '(+ x (* x (- y (/ z 2)))))
Where
(evalexp p1 '( (x 2) (z 8) ))
returns (+ 2 (* 2 (- y 4)))
My goal is to write the evalexp function but I can't even think of where to start.
So far I have
(defun evalexp (e b) )
.. not very much. If anyone could please help or lead me in a good direction I'd be more than appreciative.
Here's a full solution. It's pretty straightforward, so I'll leave out a full explanation. Ask me in the comments if there's anything you can't figure out yourself.
(Using eval to do the actual evaluation might not be what you want in your exercise/project. Look up "meta-circular interpreter" for another way.)
(defun apply-env (exp env)
(reduce (lambda (exp bdg) (subst (cadr bdg) (car bdg) exp))
env :initial-value exp))
(defun try-eval (exp)
(if (atom exp)
exp
(let ((exp (mapcar #'try-eval exp)))
(if (every #'numberp (cdr exp))
(eval exp)
exp))))
(defun evalexp (exp env)
(try-eval (apply-env exp env)))
Here's a hint, this is how you might do it (in pseudocode):
function replace(vars, list):
for each element of list:
if it's an atom:
if there's an association in vars:
replace atom with value in vars
else:
leave atom alone
else:
recursively apply replace to the sublist
There will certainly be some details to work out as you convert this to Lisp code.