Evaluate list in Racket with parameters - list

I am generating lists such as the following, with operators, numbers and parameters:
'(* (+ 3 param1) param2)
That I want to evaluate and test with different parameters. But reading around it doesn't look like I can change those values at runtime if I use the eval procedure.
Is there a clean way to do this?

Here's an alternative, using quasiquoting:
(eval `(* (+ 3 ,param1) ,param2))
In the above line, the two parameters will get evaluated at runtime before the call to eval. For example:
(define param1 42)
(define param2 43)
(eval `(* (+ 3 ,param1) ,param2))
=> 1935

Note that
> (eval '(let ([param1 42]
[param2 43])
(* (+ 3 param1) param2)))
1935
So wrap your expression in a let before you evaluate it.

If you want to manage explicitly the binding of values to the variables in the expression, in order to evaluate the expression with different values, you could create and manipulate an explicit “environment”.
; create an empty environment
(define (make-env)
'())
; create a new environment extending env with a new bind (var . value)
(define (bind var value env)
(cons (cons var value) env))
; lookup var in env, if present returns the value, otherwise returns itself
(define (lookup var env)
(cond ((null? env) var)
((eq? (caar env) var) (cdar env))
(else (lookup var (cdr env)))))
(define (myEval exp env)
(define (substitute exp env)
(cond ((null? exp) '())
((number? exp) exp)
((symbol? exp) (lookup exp env))
(else (cons (substitute (car exp) env) (substitute (cdr exp) env)))))
(eval (substitute exp env)))
(myEval '(* (+ 3 param1) param2) (bind 'param1 10 (bind 'param2 20 (make-env))))
The function myEval substitutes all the variables inside the expression with the corresponding value inside the environment, then call the predefined function eval. Note that the definition of an environment is the first step in defining your own eval function.

Related

define: not allowed in an expression context

I've just started learning Racket.
I have written this procedure:
#lang racket
(define split
(lambda (list)
(define plus-list '())
(define minus-list '())
(cond ((null? list) '())
(else
(do ([i (length list) (- i 1)])
((zero? i))
(define l (list-ref list i))
(define item (last-element-on-list l))
(cond ((= (cdr l '+)) (set! plus-list (cons list plus-list)))
((= (cdr l '-)) (set! minus-list (cons list minus-list))))
)
(cons plus-list minus-list)
)
)
)
)
And instead of using (list-ref lst i) inside de do I have defined a variable l:
(define (list-ref lst i) l)
But it seems that I cann't do that, because I get the error:
define: not allowed in an expression context in: (define l (list-ref
lst i))
But there are a lot of define inside the do.
If I remove all the define inside the do, I have to write a lot of code and it is not easier to read and understand:
(define split
(lambda (list)
(define plus-list '())
(define minus-list '())
(cond ((null? list) '())
(else
(do ([i (length list) (- i 1)])
((zero? i))
(cond ((= (cdr (last-element-on-list (list-ref list i)) '+)) (set! plus-list (cons (list-ref list i) plus-list)))
((= (cdr (last-element-on-list (list-ref list i)) '-)) (set! minus-list (cons (list-ref list i) minus-list))))
)
(cons plus-list minus-list)
)
)
)
)
How can I define a variable inside a do?
Reading your other question I see why you write the bolded expressions -
…
(cond ((= (cdr (last-element-on-list (list-ref list i)) '+))
(set! plus-list
(cons (list-ref list i) plus-list)))
((= (cdr (last-element-on-list (list-ref list i)) '-))
(set! minus-list
(cons (list-ref list i) minus-list))))
…
Your input list shown there is –
(define lst
'((n 25 f +)
(s 25 m +)
(ll 20 no -)))
Your split is inspecting the contents of each element of l. split has overstepped its boundaries and now it only works for lists containing elements of this particular structure. Along with set!, lack of else in a cond is typically an indication you're doing something wrong. You also call (cdr (last-element-of-list ...)). If last-element-of-list returns an atom, cdr would throw an error here.
Consider designing split in a more generic way –
(define (split proc l)
(define (loop l true false)
(cond ((null? l)
(cons true false))
((proc (car l))
(loop (cdr l)
(cons (car l) true)
false))
(else
(loop (cdr l)
true
(cons (car l) false)))))
(loop l '() '()))
(split (lambda (x) (> x 5))
'(1 5 3 9 7 0 8 3 2 6 4))
;; '((6 8 7 9) 4 2 3 0 3 5 1)
If our list contains different elements, we can still use the same split procedure –
(split (lambda (x) (eq? '+ (cadr x)))
'((1 +) (1 -) (2 +) (3 +) (2 -) (3 -) (4 +)))
;; '(((4 +) (3 +) (2 +) (1 +)) (3 -) (2 -) (1 -))
I think it's never too early to start learning continuation passing style. Below, return represents our continuation and defaults to cons, the same procedure we used to return the final result in our original implementation. Intuitively, a continuation represents "the next step" of the computation –
(define (split proc l (return cons)) ;; `return` is our continuation
(if (null? l)
;; base case: list is empty, return empty result
(return '() '())
;; inductive case: at least one `x`
(let* ((x (car l))
(bool (proc x)))
(split proc ;; tail recur with our proc
(cdr l) ;; ... a smaller list
(lambda (t f) ;; ... and "the next step"
(if bool ;; if `(proc x)` returned true
(return (cons x t) ;; ... cons the `x` onto the `t` result
f) ;; ... and leave the `f` the same
(return t ;; otherwise leave `t` the same
(cons x f)))))))) ;; ... and cons the `x` onto the `f` result
If we run our split procedure, you'll notice we get the same exact output as above. At first glance it looks like we made a mess of a nice program, however there's one distinct advantage of this implementation. Because the continuation is user-configurable, instead of cons, we could decide an entirely different fate for our two lists, t and f –
(split (lambda (x) (eq? '+ (cadr x)))
'((1 +) (1 -) (2 +) (3 +) (2 -) (3 -) (4 +))
(lambda (plus minus)
(printf "plus: ~a, minus: ~a\n" plus minus)))
;; plus: ((1 +) (2 +) (3 +) (4 +)), minus: ((1 -) (2 -) (3 -))
Note how plus and minus were given the respective results. We didn't have to pick apart an intermediate cons result. More intuitively, we want printf to be "the next step", but we only need to specify the first argument –
(split (lambda (x) (eq? '+ (cadr x)))
'((1 +) (1 -) (2 +) (3 +) (2 -) (3 -) (4 +))
(curry printf "plus: ~a, minus: ~a\n"))
;; plus: ((1 +) (2 +) (3 +) (4 +)), minus: ((1 -) (2 -) (3 -))
Now we've scratched the surface of functional style :D
do loops are not idiomatic Racket. They are inherited from Scheme, and for whatever reason, they don’t permit internal definitions. I have never once used a do loop in Racket, since the for comprehensions are more functional, and they’re just generally easier to work with. Plus, since they originate in Racket, not in Scheme, they support internal definitions as you’d expect.
You could write your split function using for/fold instead of do, which has the added advantage of not needing to use set! (and avoiding the quadratic access time of using list-ref instead of iterating through the list). I’m not completely sure what your split function is supposed to do, as even with the internal definition removed, it does not compile, but here’s my best guess at what you might be attempting to do:
(define (split lst)
(for/fold ([plus-lst '()]
[minus-lst '()])
([l (in-list lst)])
(define item (last l))
(cond
[(equal? item '+)
(values (cons l plus-lst) minus-lst)]
[(equal? item '-)
(values plus-lst (cons l minus-lst))]
[else
(values plus-lst minus-lst)])))
Aside from the obvious restructuring to use for/fold instead of do, this code also makes the following changes over your code:
It uses the built-in last function from racket/list to get the last element of a list.
It uses equal? instead of = to compare symbols, since = is specifically for comparing numbers.
It indents things properly and puts close parentheses in idiomatic locations.
I fixed your code using let, read documentation about let it's heavily used in Scheme/Racket. I haven't used Scheme lately so I couldn't explain it as well as it is in documentation.
Shortly it's local symbol definition/redefinition, and you can use symbol with value only in let body.
Short example on let
(define x 5)
(let ((x 10))
(display x)) # => 10
(display x) # => 5
(let ((y 1))
(display y)) # => 1
(display y) # = => (error) y: undefined
Your code fixed using let
(define split
(lambda (list)
(let ((plus-list '())
(minus-list '()))
(cond ((null? list) '())
(else
(do ([i (length list) (- i 1)])
((zero? i))
(let ((l (list-ref list i))
(item (last-element-on-list l)))
(cond ((= (cdr l '+)) (set! plus-list (cons list plus-list)))
((= (cdr l '-)) (set! minus-list (cons list minus-list))))))
(cons plus-list minus-list))))))

In list, how can I make modifications to a list through a function which takes the list as a parameter?

I was writing a program in Lisp to put the common elements from two lists into a new one. Here is my code.
(defun test (a b)
(let ((alist nil) (blist nil))
(progn
(join a b alist blist)
(print blist))))
(defun join (a b alist blist)
(cond
((and (null a) (null b))
(setf blist (cons alist blist)))
((equal (car a) (car b))
(setf alist (cons (list (car a) (car b)) alist)))
(t (join (cdr a) (cdr b) alist blist))))
But the output of the function is alwaysnil. Then I looked up something on Internet and found out that when I try to use setf, it no longer points to the original list, instead it points to a new one. So if I cannot use setf, what else can I use to implement this?
(defun test (a b)
(let ((alist nil) (blist nil)) ; two variables initialized to NIL
(progn ; this PROGN is not needed
(join a b alist blist) ; you call a function, but ignore the
; return value? Why?
(print blist)))) ; since blist was never modified, this
; can only be the initial value, NIL
(defun join (a b alist blist) ; four new local variables
(cond
((and (null a) (null b))
(setf blist (cons alist blist))) ; why do you set the variable BLIST?
; you never use it later
((equal (car a) (car b))
(setf alist (cons (list (car a) (car b)) alist)))
; why do you set the variable ALIST?
; you never use it later
(t (join (cdr a) (cdr b) alist blist))))
; the only recursive call of JOIN
You can only change variables, which are lexically reachable.
Don't use "output" arguments in Lisp. Better return the result from the function.
Also, there is a function 'intersection' in CL which does what you want, so please use it unless it is an exercise (then you can look up its implementation).

Scheme equivalent of print function in Clojure

I'm looking at Scheme (Dr-Scheme) coming from Clojure.
In Clojure I can type
(print 'a 'b 'c)
and the print function figures out that this is an arbitrary number of non-string arguments and prints them out separated by a space.
In Scheme the print function expects a single argument.
Is there a way to get the equivalent of Clojure's print function in Scheme?
Interesting... you can roll one of those pretty easily, but I'm not sure I see the need for it. For instance:
#lang racket
(define (print-many . args)
(display
(apply
string-append
(add-between (map print-to-string args) " "))))
(define (print-to-string arg) (format "~v" arg))
(print-many 3 4 5 'b '(3 3 4))
In general, though, I'm thinking that if you're generating output for a user, you're going to want better control over the output, and if you're not generating output for a user, you're just as happy slapping a pair of parens around it and making it into a list.
What's the use case for this?
Perhaps you are looking for trace ?
#lang racket
(define (foo x y)
(+ x y))
(define (bar x)
(+ (foo 1 x)
(foo 2 (+ x 1))))
(require racket/trace)
(trace foo)
And then in the interaction window:
> (bar 3)
>(foo 1 3)
<4
>(foo 2 4)
<6
10
I use this set of definitions to print multiple arguments separated by new line:
(define (println x) (display x) (newline))
(define (printlist l) (begin
(println (car l))
(if (not (null? (cdr l))) (printlist (cdr l)))))
(define (multiprint . args) (begin
(if (not (null? args)) (printlist args)
(println "Error: multiprint requires at least one argument"))))

Scheme: Return all elements of an expression that can be obtained using any combination of car and cdr

I'm trying to write a procedure in Scheme (R5RS) of my CS class that takes an expression (either a symbol or a list) as an argument and returns a list of (1) all the possible expression that can be formed by using car and cdr on the expression and (2) and an expression demonstrating how each of these components of the original expression were obtained. If a piece can be obtained in more than one way, it should be returned more than once.
Examples
(pieces '()) => ((() x))
(pieces 'apple) => ((apple x))
(pieces '(apple)) => (((apple) x) (apple (car x)) (() (cdr x)))
(pieces '(a (b c))) =>
(((a (b c)) x)
(a (car x))
(((b c)) (cdr x))
((b c) (car (cdr x)))
(b (car (car (cdr x))))
((c) (cdr (car (cdr x))))
(c (car (cdr (car (cdr x)))))
(() (cdr (cdr (car (cdr x)))))
(() (cdr (cdr x))))
Since we've just started with Scheme, we're limited to fairly basic syntax for this assignment. Here's what I have so far:
(define pieces
(lambda (exp)
(cond
((symbol? exp)
(list exp 'x))
((null? exp)
(list '() 'x))
((list? exp)
(let ((b (pieces (car exp))) (c (pieces (cdr exp))))
(list exp 'x b c))))))
(pieces '()) => (() x)
(pieces 'apple) => (apple x)
(pieces '(apple)) => ((apple) x (apple x) (() x))
(pieces '(a (b c))) => ((a (b c)) x (a x) (((b c)) x ((b c) x (b x) ((c) x (c x) (() x)))
(() x)))
The procedure returns all of the proper elements, but each recursion causes the components to be nested in an additional list. Is there any way to prevent that?
Also, I have no idea where to start for the second part of the problem (showing how each element was obtained from the original using car and cdr). I've tried a million different approaches, and none of them have even been close to working. If anyone has any hints or suggestions on how to implement that feature, I'd really appreciate it. Thanks a ton.
(pieces 'apple) => (apple x)
But it should be ((apple x)), right? You should get a list where the first and only element is the list (apple x).
The cond clauses that terminate recursion (exp is a symbol or null) return items that should go in the list, while the clause that recurs on car and cdr attempts to create a list of items. As pieces can return both items and lists of items it's kind of hard to make a list of items out of the values that are returned from it: when you do (list exp 'x b c) you don't know if b and c are items that should go into the list or lists of items.
If you make sure that pieces always returns a list of items (e.g. (list (list exp 'x))) it gets a lot easier. When you recur on car and cdr you want to do something like append the lists a and b and add the "current" ((list exp 'x)) item to that list (maybe with cons or something).
For the second part, pieces must know how it got to the current item. You can make pieces take a the "path" to the current item as a (maybe optional) parameter. If the path is a list, then when you call pieces on (car exp) you can add a car symbol to the path you're sending as argument, and for (cdr exp) you can add the symbol cdr. And then you use the path to create something nice to substitute for 'x in (list exp 'x).
I know it's not Scheme, but maybe looking at similar language would help. I did this more to practice myself, so take it with a drip of salt, yet it seems to be doing exactly what you're after:
(defun parse-list (whatever)
(labels ((pieces (expression &optional path)
(cond
((null expression)
`((,path . nil)))
((listp expression)
(append (list
`(,path . ,expression))
(pieces (car expression)
(cons 'car path))
(pieces (cdr expression)
(cons 'cdr path))))
(t `((,path . ,expression))))))
(dolist (output (pieces whatever))
(format t "path ~a => result ~a~&"
(car output) (cdr output)))))
(parse-list '(a (b c)))
Which then produces this output:
path NIL => result (A (B C))
path (CAR) => result A
path (CDR) => result ((B C))
path (CAR CDR) => result (B C)
path (CAR CAR CDR) => result B
path (CDR CAR CDR) => result (C)
path (CAR CDR CAR CDR) => result C
path (CDR CDR CAR CDR) => result NIL
path (CDR CDR) => result NIL
Sorry, I couldn't get SO's code formatting better than this :)

LISP Need some helps to solve one exsercise with LIST

This is what I must do! I have a lot of list and I must return list without integer.
(functInt '(f 3 (v) (((7))) n ()))
-------->
(f (v) ((())) n ())
This is my code:
(defun functInt (list)
(cond ((atom list) (if (not(integerp list)) list))
((null (cdr list)) (functInt (car list)))
(T (cons (functInt (car list)) (functInt (cdr list))))))
But what I get is (F NIL V NIL N)
How can I correct my code to get the output that I want?
One of the problems is that
(if (not (integerp list)) list)
returns nil when list is an integer, so you're replacing integers with nil.
I think the only way to get this right is by assuming that no-one will ever call your function on a non-list value. Then you can rewrite it in the form
(defun functInt (x)
(cond ((atom x) x)
((integerp (car x)) FOO)
(t BAR)))
where I leave the expressions to substitute for FOO and BAR as exercises. (functInt 3) will still return 3, but that violates the function's contract.
Note that (atom nil) is true, so you don't need a special case for (null x).
It might be helpful to not try to do all this in a single function, but use a higher-order function to solve the general case and then only fill in a very simple function for the specific case. This is one suitable higher-order function:
(defun tree-mapcan (function tree)
(if (listp tree)
(list (mapcan (lambda (elt) (tree-mapcan function elt))
tree))
(funcall function tree)))