I need to implement a function that takes one or more expressions and executes those expressions in order.
This is what I have so far:
(define (foo exp0 exp1 ) exp0 exp1)
I need to implement a function that takes one or more expressions and executes those expressions in order.
This is what I have so far:
(define (foo exp0 exp1 ) exp0 exp1)
Assuming you have the following expression
(sequence form1 form2 form3)
and you want the forms to be evaluated in order, then you can't pass them to a function as Josuha explained. The easiest transformation would be to change the above to
((lambda () form1 form2 form3))
since the forms in a lambda expression are executed sequentially and the result is the value of the last form. Since this transformation has to be done at the source code level, you have to use a macro such as:
(define-syntax-rule (sequence form1 form2 ...)
((lambda () form1 form2 ...)))
which will transform an expression such as
(sequence (display "a") (display "b") (display "c"))
into
((lambda () (display "a") (display "b") (display "c")))
which will execute the forms in sequence.
Scheme doesn't specify any particular argument evaluation order. This means that if you have a display-and-return
function:
(define (display-and-return x)
(display x)
x)
and you then call, for instance,
(list (display-and-return 1) (display-and-return 2))
you're guaranteed to get the result (1 2)
, but you could see the output produced by display as either 12
or 21
. However, Scheme does specify that the arguments to a function will be evaluated before the body of the function is evaluated. So, you could sequence two expressions by making them arguments to functions:
((lambda (val1)
((lambda (val2)
(list val1 val2))
(display-and-return 2)))
(display-and-return 1))
In general, you could use a transformation like this to turn (seq exp1 exp2 ... expm expn)
into
((lambda (val1)
((lambda (val2)
...
((lambda (valm)
expn) ; or ((lambda (valn) valn) expn)
expm) ... )
exp2))
exp1)
You can define that sort of transformation using define-syntax-rule
.
You need something that takes 'one or more expressions' and then evaluates them and returns the last one. This could be defined with:
(define (sequence exp1 . exps)
(car (reverse (cons exp1 exps)))) ; (if (null? exps) exp1 ...)
You would then invoke it as:
> (sequence (+ 1 2) (* 1 2) 17)
17
Using define-syntax stuff isn't needed as standard function application will 'execute those expressions in order'
If you need the order to be guaranteed as left-to-right, then you'll need:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
(begin exp expos ...))))
but if you can't use begin
, but can use lambda
, then:
(define-syntax sequence
(syntax-rules ()
((sequence exp exps ...)
((lambda () exp exps ...)))))