球拍 "eval" 一个数据

Racket "eval" a datum

我正在尝试提高 Racket 中的元编程水平,但我意识到我不知道如何获取数据并简单地对其进行“评估”。

如果我有

  (for ((x '(("Five" (+ 2 3))
             ("Twelve" (* 6 2))
             ("Three" (- (/ 21 3) 4)))))
    (displayln (format "~s: ~s" (first x) (second x))))

我明白了

: "Five": (+ 2 3)
: "Twelve": (* 6 2)
: "Three": (- (/ 21 3) 4)

这实际上不是我想要的 - 我想实际评估该列表以获得答案。

我确定这很简单(也许我需要涉及语法?)但我现在只是缺少图片。我该怎么做?

编辑: 我想在显示之前评估 s-exp,而不是在初始列表中。这就是为什么我认为我可能需要语法,因为我(我认为)必须注入当前语法上下文。

backquoteunquote一起使用,即

;; backquote: ` 
;; unquote: ,
;; there is also splice list: ,@

(for ((x `(("Five" ,(+ 2 3))
           ("Twelve" ,(* 6 2))
           ("Three" ,(- (/ 21 3) 4)))))
  (displayln (format "~s: ~s" (first x) (second x))))

;; "Five": 5
;; "Twelve": 12
;; "Three": 3

Eval 几乎总是错误的选择,但 eval 正是您要找的:

#lang racket

(define base-ns (make-base-namespace))
(for ((x '(("Five" (+ 2 3))
           ("Twelve" (* 6 2))
           ("Three" (- (/ 21 3) 4)))))
  (displayln (format "~s: ~s" (first x) (eval (second x) base-ns))))

备选方案 1:Lambda / thunks

(for ((x `(("Five" ,(thunk (+ 2 3)))
           ("Twelve" ,(thunk (* 6 2)))
           ("Three" ,(thunk (- (/ 21 3) 4))))))
  ;; notice double parentheses to call the thunk
  (displayln (format "~s: ~s" (first x) ((second x)))))

thunk 只是没有参数的 lambda 的语法糖。 我已经尝试了一些可以打印其源代码的程序。因此,您可以制作自己的 thunk ,其具有原始结构作为我用我的视觉 lambda 演示的结构:

(struct proc (src obj)
  #:property prop:procedure (struct-field-index obj)
  #:transparent
  #:methods gen:custom-write
  [(define (write-proc x port mode)
     ((case mode
        [(#t) write]
        [(#f) display]
        [else pretty-print])
      (proc-src x)
      port))])

(define-syntax lambda*
  (syntax-rules ()
    ((_ . rest)
     (proc '(lambda* . rest) (lambda . rest)))))

(define test (lambda* (x y) (+ x y)))

test                  ; ==> #(struct:closure (lambda* (x y) (+ x y)) #<procedure>)
(proc-src test)       ; ==> (lambda* (x y) (+ x y))
(proc-obj test)       ; ==> #<procedure>
((proc-obj test) 1 2) ; ==> 3
(test 1 2)            ; ==> 3
(display test)        ; prints (lambda* (x y) (+ x y))