Returning variable from a different environment

 ̄綄美尐妖づ 提交于 2020-01-05 21:25:16

问题


I'm attempting to return a variable in the scope of a different environment. What I have currently is

(define make-empty-env
   (lambda()
      (make-top-level-environment)
   )
)

which creates a new environment when you call it from the interpreter i.e. (define env (make-empty-env))

If I define the variable "a" as 15 in "env", my goal is to return this value through a function called from the user-initial-environment.

Something along the lines of

(apply-env env 'v) outputs -> value of variable v in scope of env. v can be undefined in user-initial-environment but would still return a value if the variable exists in env.

I've tried:

(define apply-env
   (lambda (env v)
       (eval (+ v 0) env)
   )
)

which doesn't work since I'm passing a symbol 'v when I call the function. My main problem is that I don't know how to pass a symbol and treat it like a variable in the function. This is for a homework and the prompt for the function is:

(apply-env env v)

Returns the value of variable v in environment env.

Here are some calls to apply-env:

In test-env, a = 1, b = 2

(apply-env test-env 'a) 1

(apply-env test-env 'b) 2

I'm relatively new to scheme so I'm probably missing some fundamental basics, any pointers or help would be very much appreciated.


回答1:


As far as I know the design implementation for your environment variable is up to you. Since its a homework question I'm assuming that you can go about it any way you like (I assume).

So lets say you want to make your environment variable as a that is a list of list of 2 elements.

env -> ((var1,val1),(var2,val2),......,(varn.valn))

E.g.

env -> ((a,1),(b,2),(c,3))

Now when you want to "create" your environment initially, you simply want to call a function which returns the initial environment which is empty. Now our environment variable env is just an empty list '(). You could make a function like this

(define (make-empty-env)
    (lambda ()
        '()
    )
)

Now to add, remove and update variables in env you can implement function like car and cdr and in-env? for the underlying data structure


;;; cdr like function for env
(define (cdr-env env)
    (cdr env)
)

;;; car like function for env
(define (car-env)
    (list (car env))
)

;;; Returns boolean for v in env
(define (in-env? env)
    (cond
        ((null? env)    ; If env is empty then v doesnt exist in env
            #f
        )
        ((equal? v (car (car env))) ; If first element of the first list in env matches with v 
            #t
        )
        (else       ; Recursive step to find if v is in the remaining enviornment env
            (in-env? v (cdr env))
        )
    )
)

Using these functions you can relatively easily implement your insertion, retrieval and updation functions for env.


;;; Update the value variable v to val in env. This function assumes that you are calling it in the insert-env function
(define (update-env v val env)
    (cond 
        ((null? env)
            '()
        )
        ((equal? v (car (car env)))
            (append (cdr env) (list (list v val)))
        )
        (else
            (append 
                (update-env v val (cdr env)) 
                (list (list (car (car env)) (car (cdr (car env)))))
            )
        )
    )
)


;;; add a variable-value pair (v,val) to env, also checks if variable already exists in pair. If so then updates it
(define (insert-env v val env)
    (cond 
        ((in-env? v env)
            (update-env v val env)
        )
        (else  ; Add to env the 2 element list (v val)
            (append env (list (list v val)))
        )
    )
)

;;; Gets the value of variable v or returns an error message
(define apply-env
    (lambda (env v)
        (cond 
            ((null? env)    ; If env is empty then no variablles exist for the name v
                (error "appply-env: found empty enviroment")
            )
            ((equal? (car (car env)) v) ; First element of the first list is v [matching var found in env]
                (car (cdr (car env))) ; Second element of that list is value of v
            )
            (else       ; Else look for v in the rest of the env list
                (apply-env (cdr env) v) 
            )
        )
    )
)

NOTE: Your implementations of functions like above for env will depend on how you choose to implement the data structure that will store your variable bindings in env You can use any data structure you like. E.g. Binary tree. stack, queue, etc

Hope this helps!




回答2:


The issue is that the addition isn't staged. Consider the following using quasiquotiation:

(define apply-env
   (lambda (env v)
       (eval `(+ ,v 0) env)
   )
)

The quasiquotation is equivalent to (list '+ v 0).



来源:https://stackoverflow.com/questions/56452832/returning-variable-from-a-different-environment

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!