Возвращение переменной из другой среды - PullRequest
1 голос
/ 05 июня 2019

Я пытаюсь вернуть переменную в области видимости другой среды. Что у меня сейчас есть

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

, которая создает новую среду, когда вы вызываете ее из переводчика т.е. (определить env (make-empty-env))

Если я определю переменную "a" как 15 в "env", моя цель - вернуть это значение через функцию, вызываемую из user-initial-environment.

Что-то вроде

(apply-env env 'v) выводит -> значение переменной v в области действия env. v может быть неопределенным в user-initial-environment, но все равно будет возвращать значение, если переменная существует в env.

Я пробовал:

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

, который не работает, так как я передаю символ v при вызове функции. Моя главная проблема в том, что я не знаю, как передать символ и обработать его как переменную в функции. Это для домашней работы и подсказка для функции:

(применить-env v)

Возвращает значение переменной v в среде env.

Вот некоторые вызовы apply-env:

В тестовой среде a = 1, b = 2

(применить-env test-env 'a) 1

(применить-env test-env 'b) 2

Я относительно новичок в схеме, поэтому, возможно, мне не хватает каких-то фундаментальных основ, любые указатели или помощь будут очень благодарны.

Ответы [ 2 ]

1 голос
/ 01 июля 2019

Проблема в том, что добавление не организовано. Рассмотрим следующее с использованием квазиквотирования:

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

Квазиквотация эквивалентна (list '+ v 0).

1 голос
/ 01 июля 2019

Насколько я знаю, реализация проекта для вашей переменной среды зависит от вас.Так как это домашнее задание, я предполагаю, что вы можете делать это любым удобным для вас способом (я полагаю).

Итак, допустим, вы хотите сделать вашу переменную окружения в виде списка из 2 элементов.

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

E.g.

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

Теперь, когда вы хотите изначально «создать» свою среду, выпросто хотите вызвать функцию, которая возвращает начальную среду, которая является пустой .Теперь наша переменная окружения env - это просто пустой список '().Вы можете сделать такую ​​функцию

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

Теперь, чтобы добавлять, удалять и обновлять переменные в env, вы можете реализовать такие функции, как car и cdr и in-env? для базовой структуры данных


;;; 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))
        )
    )
)

Используя эти функции, вы можете относительно легко реализовать свои функции вставки, извлечения и обновления для 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) 
            )
        )
    )
)

ПРИМЕЧАНИЕ. Ваши реализации функций, аналогичных приведенным выше для env будет зависеть от того, как вы решите реализовать структуру данных, которая будет хранить ваши привязки переменных в env. Вы можете использовать любую структуру данных, которая вам нравится.Например, бинарное дерево.стек, очередь и т. д.

Надеюсь, это поможет!

...