Как оценить символ, возвращаемый функцией в Scheme?

Я заново знакомлюсь со Scheme и столкнулся с проблемой, которая, вероятно, отражает фундаментальное непонимание с моей стороны.

Скажем, я делаю следующее в Scheme (используя Guile в этом случае, но то же самое в Chicken):

> (define x 5)
> x
5
> (string->symbol "x")
x
> (+ 5 (string->symbol "x"))
<unnamed port>:45:0: In procedure #<procedure 1b84960 at <current input>:45:0 ()>:
<unnamed port>:45:0: In procedure +: Wrong type: x
> (symbol? (string->symbol "x"))
#t
> (+ 5 x) ; here x is dereferenced to its value 5
10
> (+ 5 'x) ; here x is not dereferenced
<unnamed port>:47:0: In procedure #<procedure 1c7ba60 at <current input>:47:0 ()>:
<unnamed port>:47:0: In procedure +: Wrong type: x    

Я понимаю, что string->symbol возвращает символ x, который фактически заключен в кавычки. Однако я не могу понять, как использовать символ, возвращаемый string->symbol, в любом более позднем контексте. Как я могу заставить Scheme оценить этот символ?

Чтобы дать представление о том, почему я хочу это сделать, я пишу программу на C со встроенным Guile. Я хотел бы иметь возможность доступа к символам, определенным в Guile, по имени из C, используя, например, scm_from_*_symbol или scm_string_to_symbol. Причины, по которым эти функции не работают так, как я думал, связаны с моим основным вопросом выше. Возможно, есть лучший способ сделать то, что я хочу сделать с Гайлом, но это другой вопрос. Прямо сейчас меня интересует фундаментальный вопрос выше.


person Community    schedule 01.06.2013    source источник


Ответы (3)


Вам следует прочитать главу fly-evaluation руководства Guile. документация.

Вы хотите eval и, возможно, interaction-environment

Я рекомендую прочитать знаменитый SICP и Маленькие кусочки lisp

person Basile Starynkevitch    schedule 01.06.2013
comment
eval сделал именно то, что я хотел. Странно, потому что я пробовал это раньше, но я думаю, что сначала сделал это неправильно. Спасибо! - person ; 01.06.2013

Вам нужно вычислить символ (а не "разыменовывать" его). Я думаю, это то, что вы имели в виду:

(define x 5)
(+ 5 (eval 'x (interaction-environment)))
=> 10

Дополнительные сведения см. в документации.

person Óscar López    schedule 01.06.2013
comment
Это не работает с Guile 2.0, потому что его eval требует два аргумента (вещь для оценки и окружение....) - person Basile Starynkevitch; 01.06.2013
comment
Разве в этом примере нет бесполезной оценки числа? x оценивается как 5 перед применением eval. - person Sylwester; 02.06.2013

В этом смысле символы не являются чем-то особенным, то есть их не легче вычислять, чем обычные строки.

Symbol очень похож на строку, только не заключен в кавычки. Ну и принципиальное отличие, конечно, не в отсутствии кавычек, а в том, что символы интернированы. Это означает, что строки "x" и "x" являются двумя разными строками (хотя они и равны), а символы 'x и 'x на самом деле являются одним и тем же объектом.

person kirelagin    schedule 01.06.2013
comment
Хм, тогда это фундаментальное недоразумение. Я исправил заголовок своего вопроса, указав разыменование, что я и имел в виду. - person ; 01.06.2013
comment
@BrandonInvergo Опять же, вы действительно можете подумать, что символы представляют собой строку без кавычек. (+ 5 "x") не имеет смысла, как и (+ 5 'x). - person kirelagin; 01.06.2013
comment
Если вы хотите оценить содержимое строки как код схемы, вам не нужны символы, вам нужна функция eval-string. - person kirelagin; 01.06.2013
comment
На самом деле да, можно вычислить символ. - person Óscar López; 01.06.2013
comment
@ ÓscarLópez Верно, я изменил формулировку в своем ответе, чтобы быть более точным. - person kirelagin; 01.06.2013