схема и набор!

Как я могу изменить значение переменной с помощью функции, которая использует лямбда-параметр? То есть:

;;definitions
(define test "fails")
(define (experiment input) (set! input "works"))

;;interactions
> test
"fails"
> (experiment test)
> test
"fails"

Кажется, это не удается.

С Уважением


person Hellnar    schedule 10.11.2009    source источник


Ответы (2)


Вы не можете -- Scheme передает все значения "по значению", поэтому в приведенном выше примере функция experiment просто изменяет свой собственный входной аргумент. Чтобы что-то подобное работало, вы можете использовать поле, которое является явно изменяемым контейнером значений:

(define test (box "fails"))
(define (experiment input) (set-box! input "works"))
(unbox test)
(experiment test)
(unbox test)

Если вы действительно хотите изменить значение переменной, вы можете использовать макрос:

(define-syntax-rule (experiment input) (set! input "works"))

Это создает experiment как макрос, что означает, что каждая форма (experiment foo) переписывается в (set! foo "works"). Это может иметь тонкие последствия, поэтому не рекомендуется использовать это, если вы не знаете, что делаете. (Например, (experiment 2) потерпит "интересный" сбой.) Написание макросов в Scheme легко, но написать хорошие макросы по-прежнему сложнее, чем написать новое определение функции.

[Обратите внимание, что я предполагаю, что в этом ответе вы используете схему PLT. Но обе части могут быть переведены в «стандартную» схему, если это необходимо — например, используйте изменяемую ячейку cons для первой и используйте define-syntax с syntax-rules для второй.]

person Eli Barzilay    schedule 10.11.2009
comment
Это также можно сделать с помощью параметров: srfi.schemers.org/srfi-39/ srfi-39.html - person Jonathan Arkell; 10.11.2009
comment
Да, параметры — это еще один изменяемый вид контейнера (а в PLT их несколько больше, например thread-cell). Но их семантика может немного отличаться от простой глобальной. Например, параметр имеет уникальное значение для каждого потока (точнее, уникальное значение для каждого продолжения). - person Eli Barzilay; 11.11.2009

Возможно, было бы разумнее, если бы вы рассмотрели тот же код на Python:

test = "fails"
def experiment(input):
  input = "works"

>>> test
'fails'
>>> experiment(test)
>>> test
'fails'
person newacct    schedule 10.11.2009
comment
Как это отвечает на вопрос? - person Vijay Mathew; 11.11.2009