我有一种情况,我想做一些像......
(define (def a b)
(store a b) ; store the definition of 'a' somewhere
(define-global a b)) ; also define 'a' so that its definition
; is accessible later in the program
这有可能吗?据我所知define-global
不存在,所以程序中的define
语句仅适用于本地环境。
这是为了在方案中为嵌入式DSL创建'def'过程,因此除了定义之外,我还需要将定义存储在我自己的符号表中。最终我想“拦截”符号查找以应用我自己的转换,返回符号查找的表达式,而不是实际执行它。
我正在使用Gambit-C Scheme。
感谢。
答案 0 :(得分:4)
不,至少没有任何Gambit特定的低级别钩子。但这是有充分理由的:你所建议的将无法进行有效的编译,因为绑定可以随时改变。
如果您的目标是实现DSL,那么将值保存在您自己的表中,并在DSL中实现变量查找的代码中进行查找非常有意义。此外,它自然会引导您实现DSL在其自己的世界中的实现,与实现它的代码分开。 (例如,如果你有上述内容,那么当DSL中的代码定义了一个名为def
的变量时,你会发生什么?)
答案 1 :(得分:1)
可能有办法解决这个问题。我正在寻找一种在玩具计划中实现这一目标的方法,并且在特定环境中进行定义。如果gambit具有eval的环境选项,那么您应该能够通过调用(interaction-environment)来获取父作用域中的环境。将其保存在全局环境中或通过参数传递。你可以做类似的事情:
(定义全球环境(互动环境))
;; ;;其他代码和体面的调用栈
(eval(cons'define(cons symbol-a(cons value'())))global-environment)
这应该使用传入的环境评估表达式并获得您想要的内容。如果一切正常。它取决于获得对全局环境的引用的调用以及可以将环境作为参数的eval。
答案 2 :(得分:0)
;; It's always possible to create a global variable ;; (assigned to #f so you know if it's been assigned to yet) ;; and just use it later. (define *some-global-var* #f) ;; then later on... (set! *some-global-var* 234234) ;; or w/e you want (if *some-global-var* ;; it's been assigned (do-something *some-global-var*)) ;; But in your case, a (hash) table is definitely ;; much better than unorganized free variables. ;; Gambit-C has hash tables built in. So, you can ;; define the hash table early on... (define *globals* (make-table)) ;; And assign to it later. Use the "variable name" ;; for the key. (table-set! *globals* 'x 3) (table-set! *globals* 'y 4) ;; Whenever you want you plan to access ;; a lot, it's best to use a "let" (let ((x (table-ref *globals* 'x)) (y (table-ref *globals* 'y))) (println "The sum of " x " and " y " is " (+ x y) ".")) The sum of 3 and 4 is 7. ;; Gambit also has structures, and they too are useful ;; for organizing data (*kind of* like C structs). ;; Note that it's possible to assign structures to hash ;; tables -- just like anything else -- and sometimes ;; it's *very* useful to do so. (define-structure person name age) (define jy (make-person "jyaan" 9000)) (person-name jy) "jyaan" (person-age-set! jy 25) (println jy) #<person #3 name: "jyaan" age: 25>