How to convert string to variable-name in scheme

落花浮王杯 提交于 2020-01-21 05:26:10

问题


How can I achieve below in Scheme REPL? Create a variable name from a string.

=>(define (string->variable-name "foo") 12)

=>foo

12

=>(+ foo 8)

20

In Common Lisp, this should be

=> (set (intern "ANY-TEXT") 5)

=> ANY-TEXT

5

How do I build a #procedure like "string->variable-name" (and "variable-name->string") ?

Thanks a lot.


回答1:


If what you're passing to string->variable-name is always a string literal (i.e., not a variable that contains a string), you can do that using a syntax-case macro that transforms the string literal to an identifier:

(define-syntax string->variable-name
  (lambda (stx)
    (syntax-case stx ()
      ((_ str)
       (string? (syntax->datum #'str))
       (datum->syntax #'str (string->symbol (syntax->datum #'str)))))))

and conversely, a variable-name->string macro could look like this:

(define-syntax variable-name->string
  (lambda (stx)
    (syntax-case stx ()
      ((_ id)
       (identifier? #'id)
       (datum->syntax #'id (symbol->string (syntax->datum #'id)))))))

However, remember: this will only work if you are working with string (in case of string->variable-name) or identifier (in case of variable-name->string) literals.


If, on the other hand, you want the ability to reflect on names in your current Scheme environment, this is not supported by standard Scheme. Some implementations, like Guile or Racket, do have this capability.

Here's a Guile example:

> (module-define! (current-module) 'foo 12)
> foo
12
> (define varname 'bar)
> (module-define! (current-module) varname 42)
> bar
42

and a Racket example:

> (namespace-set-variable-value! 'foo 12)
> foo
12
> (define varname 'bar)
> (namespace-set-variable-value! varname 42)
> bar
42



回答2:


Forgetting the syntax for a moment:

(define string->variable-name string->symbol)

(define name->value-mapping '())

(define (name-set! name value)
  (set! name->value-mapping
        (cons (cons name value)
              name->value-mapping))
  value)

(define (name-get name)
  (cond ((assoc name name->value-mapping) => cdr)
        (else 'unbound)))

Sure you can't do (+ 5 <my-named-value>) without some other help...



来源:https://stackoverflow.com/questions/21176956/how-to-convert-string-to-variable-name-in-scheme

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