Control of assessment according to the scheme (trick)

This seems like a simple matter; perhaps it is so simple that it is difficult to find a search that will find the answer. In Scheme (specifically, the implementation of Guile, if that matters), how can I evaluate something that has been pointed out?

Here is what I am trying to do.

I basically need to make sure that the function that I define gets its arguments evaluated in a certain order, because the side effects caused by evaluating one argument depend on evaluating the other arguments. However, the diagram says that the arguments can be evaluated in any order, so I want to manually force it by specifying the arguments, and then manually evaluating them in the order in which it is necessary.

It looks like "eval" should do what I want, but it has two problems:

  • Its use is discouraged, so I feel that there must be a better way to accomplish what I want to do here.
  • The diagram shows that eval takes a second parameter, which is the environment. It bothers me. I want it to appear in the same environment in which the operator appears, so why do I need a second parameter? Is it possible? I played with eval a bit, and it seems that some implementations require different parameters (for example, mit-scheme does not even know what it is (interaction environment) !!!)

I tried other tricks, like building lambda:

(list 'lambda '() '(car (bc))) 

but it looks like it would have to be evaluated to create a procedure. I also tried:

 (list lambda '() '(car (bc))) 

but this returns a "primitive inline macro" that doesn't work either.

Edit: It looks like the macro will work to control the evaluation order: (defmacro test1 (ab) `(begin, b, a))

+6
source share
3 answers

eval is a completely wrong tool for simply changing the order of evaluation of arguments. Create a macro instead:

 ;; (my-fun e1 e2) ;; Just calls my-real-fun, but evaluates e2 before e1 (define-syntax my-fun (syntax-rules () [(my-fun e1 e2) ;; let* has guaranteed order of evaluation (let* ([y e2] [x e1]) (my-real-fun xy))])) (define (my-real-fun xy) ....) 

Or use defmacro if necessary.

+8
source

If you need to evaluate the structure of the list (nested lists with quotes that represent the text of the Scheme program), then you should use eval . For the circuit, you need to pass the environment as the second argument, even if it is the current environment:

 (eval '(+ xy) (interaction-environment)) 

If you just need to do the calculations in a specific order, you can provide a way to evaluate side effects using begin , let or just the body of the function. They determine the sequence of ratings:

 (let ((x 42)) ; eval with effects #1 (display x) ; eval with effects #2 (display (+ x 1))) 

Edit: If you need to have a parameterized block of code in which you can pass undefined expressions and then force them to be evaluated in a specific order, you can use one of these methods:

  • Macro (as you mentioned, for completeness only):

     > (defmacro test1 (ab) `(begin ,b ,a)) > (test1 (display 2) (display 3) 32 
  • Delayed computation (special schema syntax for lazy evaluation):

     > (define (test1 ab) (begin (force b) (force a))) > (test1 (delay (display 2)) (delay (display 3))) 32 
  • Regular abstraction and use of lambda

     > (define (test1 ab) (begin (b) (a))) > (test1 (lambda () (display 2)) (lambda () (display 3))) 32 
+1
source

You were on the right track with passing in lambdas. if you have

 (define (fxyz) ...) 

... then you can call it like this:

 (f (lambda () a) (lambda () b) (lambda () c)) 

This will cause f with all arguments ( a , b , c ) in unvalued form. Inside f , you have every opportunity to choose the order that you rate them. The only difference is that you must explicitly call (x) , (y) and (z) and write their values ​​inside define or let statements. This ensures that side effects occur only once.

No macros are needed here at all. By the way, don't worry about using a lot of lambda everywhere; they are very cheap.

0
source

Source: https://habr.com/ru/post/892369/


All Articles