Подтвердить что ты не робот

Как переопределить переменную в Схеме?

Как переопределить переменную в Схеме? Возможно ли это?

4b9b3361

Ответ 1

В схеме переменные определяются либо лямбдой, либо одним из различных разрешений. Если вы хотите, чтобы один из них был "undefined", все, что вам нужно сделать, это оставить область видимости, в которой они находятся. Разумеется, это не означает, что они действительно не определяют их, это просто, что переменная больше не привязана к ее предыдущей определение.

Если вы делаете определения верхнего уровня, используя (define), то технически вы определяете функцию. Поскольку схема функциональна, функции никогда не исчезают. Я полагаю, что технически он где-то хранится в какой-то среде, поэтому, если вы были знакомы с вашей реализацией (и это не защищено каким-то образом), вы, вероятно, могли бы переписать ее своим собственным определением среды globabl. Если не считать этого, я бы сказал, что лучше всего будет переопределить функцию, чтобы вернуть нулевой список, который действительно пуст, как вы получаете.

Ответ 2

Вы касаетесь нерва здесь. В схеме нет четкого стандартного представления о том, как работают среды верхнего уровня. Зачем? Поскольку стандарты Схемы представляют собой компромисс между двумя группами людей с очень разными идеями о том, как должна работать схема:

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

Вопрос "как я могу определить неопределенность переменной" имеет смысл только в первой модели.

Обратите внимание, что интерпретирующая модель, в которой привязки верхнего уровня программы зависят от того, какие коды кода используются, значительно упрощает сборку кода схемы по многим причинам. Например, как компилятор Scheme встраивает вызов процедуры, если имя процедуры является привязкой верхнего уровня, которая может не просто изменяться во время выполнения, но даже исчезает в ничто?

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

Ответ 3

(set! no-longer-needed #f)

Достигает ли это того, что вы хотите? Вы также можете использовать define на верхнем уровне.

guile> (define nigel "lead guitar")
guile> nigel
"lead guitar"
guile> (define nigel #f)
guile> nigel
#f
guile> 

Тогда вы могли бы переделать переменную. Все это зависит от объема переменных, конечно: см. Greg answer.

Ответ 4

Вы не можете развязать переменную в стандартной схеме. Вы можете установить! переменная в 'undefined, я думаю, или вы могли бы написать metainterpreter, который обновляет среды, позволяя вам представить свое собственное представление о неопределяемых переменных.

Ответ 5

Я думаю, если вы хотите сделать эквивалент "бесплатно" или "отложить", тогда вам не очень повезло. вы не можете выделить выделение переменной. вы можете переопределить его на что-то маленькое, например #f, но как только вы это сделаете (определите foo), переменная foo будет существовать в некоторой форме, пока вы не закончите программу.

С другой стороны, если вы используете let, или letrec, конечно, имя существует только до соответствующего закрытого...

Ответ 6

Я думаю, что ваш вопрос не глуп. В AutoLISP есть переменная (undefined) apriori supposted значение "nil" (даже если переменная не существует в памяти - это означает - если она не находится в таблице переменных), тогда значение равно "nil" - "false" "). Это означает также ложь. И это также пустой список. Если вы программируете какую-то функцию обработки списка, достаточно сделать начальный тест только:

(if input-list ....)

Если вы хотите явно отключить любую переменную, вы можете сделать это:

(setq old-var nil); or: (setq old-var ())

Мне это нравится. Ключевое слово "setq" означает "define". Что лучше на ограничивающих и неограничивающих переменных в других диалектах? Вы должны проверить, существуют ли они, если они являются списками, вам нужен сборщик мусора, вы не можете переопределять переменную, чтобы явно освободить память. Следующая команда не может быть записана, если переменная "my-list" не определена:

(define my-list (cons 2 my-list))

Итак, я думаю, что путь AutoLISP для программирования намного лучше. Возможности, которые я написал, вы можете использовать там. К сожалению, AutoLISP работает только в некоторых графических системах CAD.

Ответ 7

Как указано в других ответах, нет стандартного способа манипулирования пространством имен в Схеме. Для конкретной реализации может быть решение.

В Racket переменные верхнего уровня хранятся в пространстве имен. Вы можете удалить переменную с помощью namespace-undefined-variable.

Невозможно удалить локальную переменную.

http://docs.racket-lang.org/reference/Namespaces.html?q=namespace#%28def.%28%28quote.~23 ~ 25kernel% 29._namespace-Undefine переменной% 21% 29% 29

Ответ 8

Схема (R7RS) не имеет стандартного способа удаления привязки верхнего уровня.

Если вы оцениваете несуществующую переменную, вы получите сообщение об ошибке:

(eval 'a)
; => ERROR: undefined variable: a

Если вы определяете его, переменная добавляется в среду верхнего уровня.

(define a 1)
(eval 'a)
; => 1

Теперь, независимо от того, что вы делаете, вы не получите ошибку, если вы получите доступ к переменной.

Если вы установите значение false, вы получите false:

(set! a #f)
(eval 'a)
; => #f

Даже если вы установите его на что-то неопределенное, маловероятно, что вы получите сообщение об ошибке:

(set! a (if #f #t))
(eval 'a)
; =>

Но У схем может быть нестандартный способ удаления привязки верхнего уровня. MIT Scheme предоставляет функцию unbind-variable.