Naming variables using variables in Racket?

2019-08-09 18:04发布

问题:

If I have two variables, for example

(define x 10)
(define y 20)

And I want to create a new variable, using the values of x and y to create the name, how would I go about doing so?

For example let's say I want to make a new variable called variable-x-y

(define variable-x-y "some-value")

In this case, x would be 10 and y would be 20.

Basically to summarize everything, I want to be able to enter variable-10-20 and have it return "some-value"

I'm sorry if this sounds like a novice question. I'm quite new to Racket.

EDIT: Also, how would I go about retrieving the values if just given the values of x and y (within the program)?

For example, let's say that somehow I was able to define the following:

(define variable-10-20 "some-value")

(define x 10)
(define y 20)

Is there a way for me to write variable-x-y and get back "some-value"?

EDIT 2 Here is the simplified code of what I'm trying to implement. What it does is it recursively reads each individual element into a local variable which can then be used after it's all been "read in". I'm sure if you tweak the code using the method found here it should work just fine.

(define (matrix->variables matrix)
  (local [(define (matrix2->variables/acc matrix2 x y)
            (cond
              [;; the entire matrix has "extracted" it's elements into variables
               (empty? matrix2)
               #|This is where the main program goes for using the variables|#]
              [;; the first row has "extracted" it's elements into variables
               (empty? (first matrix2))
               (matrix2->variables/acc (rest matrix2) 0 (add1 y))]
              [else (local [(define element-x-y "some-value")]
                      ;; Here is where I got stuck since I couldn't find a way to
                      ;; name the variable being created (element-x-y)
                      (matrix2->variables/acc
                       (cons (rest (first matrix2)) (rest matrix2))
                       (add1 x) y))]))]
    (matrix2->variables/acc matrix 0 0)))

回答1:

I think you're misunderstanding how variable definition works. When you create a variable name, you have to know how to call it, you can't define names dynamically.

Perhaps a hash table for storing bindings will be useful, it's somewhat similar to what you ask and simulates having dynamically defined variables - but still I'm not sure why you want to do this, sounds more like an XY problem to me. Try this:

(define (create-key var1 var2)
  (string->symbol
   (string-append 
    "variable-"
    (number->string var1)
    "-"
    (number->string var2))))

; create a new "variable"
(define x 10)
(define y 20)
(create-key x y)
=> 'variable-10-20

; use a hash for storing "variables"
(define vars (make-hash))

; add a new "variable" to hash
(hash-set! vars (create-key x y) "some-value")

; retrieve the "variable" value from hash
(hash-ref vars 'variable-10-20)
=> "some-value"


回答2:

Contrary to what Mr. López said, variable names can be decided at runtime, but only at the top-level or module level. To do it in a module:

(compile-enforce-module-constants #f)
(eval `(define ,(string->symbol "foo") 'bar) (current-namespace))

Whether this is the right or wrong thing to do is a separate question entirely.

You'll run into the same problem when you try to access these variables, so you'll have to use eval there, too. You cannot export these variables with provide.