簡體   English   中英

在Racket中定義出錯

[英]Error with define in Racket

我幾天前剛剛發現了Racket,我試圖通過編寫一個生成圖像來表示使用#lang slideshow源代碼的#lang slideshow本來更加熟悉它。

我知道在使用函數范例進行編程時,最好用let創建幾乎所有變量,但我發現它引入了太多級別的嵌套,並且Racket的let有一個過於復雜的API,需要多余的括號。 我確信這是為了消除在更強大的方式下使用let時的歧義,但就我的目的來說,這只是一個煩惱。 因此,我正在使用define創建所有變量,並在需要時使用begin編寫塊(例如在if語句的主體中)。

問題是我一再得到看似非常神秘的錯誤。 我確定我只是犯了一些愚蠢的初學者的錯誤,對語言不熟悉,但我似乎無法找到投訴的來源。

這是有問題的代碼:

(define sub-code (foldr ht-append (rectangle 0 0) (map internal-style (rest code))))

雖然我們定義的sub-code似乎非常無關緊要。 如果我用它替換它

(define sub-code '())

我收到同樣的錯誤。 DrRacket說,在表達式上下文中使用了define 我理解這個錯誤通常意味着什么 - 當你編寫像(print (define x 10))這樣的代碼時它會引發IE,但是我看不到會在這里觸發什么。

如果有幫助,則此define位於if語句內的begin塊的開頭

(if (list? code)
    (begin
        (define sub-code '())
        ; a few more define statements and finally an expression ))

DrRacket正在打印的特定錯誤消息是

define: not allowed in an expression context in: (define sub-code (quote ()))

我認為也許在begin塊中不允許define ,但我檢查了文檔 ,其中一個示例為begin

(begin
    (define x 10)
    x)

所以我真的不知道該怎么做。 提前致謝!

定義是在允許的“身體”背景下,像lambdalet等等。 if的后續和替代條款不是身體背景; 它們是表達式上下文,因此不允許定義。

begin是特殊的 - 在body上下文中begin允許定義,但是begin表達式上下文begin禁止定義。 你的案子屬於后者。

例如:

(define (foo . args)     #| body context #|)
(define foo (lambda args #| body context |#))
(define (foo . args)
  (let (...)
    #| body context |#))

需要表達式的語法關鍵字: if, cond, case, and, or, when, unless, do, begin 查看任何Scheme報告中的正式語法(r {4,5,6,7} rs); 查找<body><sequence><command><expression>

此外,如果您需要表達式中的正文上下文,只需包含一個let語法表單,如下所示:

(if test
    (let ()
      (define foo 'foo)
      (list foo foo))
    alternate)

正如GoZoner所解釋的那樣,你不能在表達式上下文中使用define

你能做什么呢?

使用let

(if (list? code)
    (let ([x '()])
      x)
    ...

或者它可以使用“空” let define

(if (list? code)
    (let ()
      (define x '())
      x)
    ...

但那有點傻。

或者使用conddefine

(cond [(list? code)
       (define x '())
       x]
      ...

最后一種方式 - 使用conddefine - 最接近當前的Racket風格指南推薦的方式。

這里有更多細節,來自Racket文檔。

不同的上下文是必需的,因為宏必須以不同的方式擴展,具體取決於允許的語言形式。

正如其他人所說,表達式上下文中不允許定義(文檔中的“expr ...”),但在其他情況下也可以。

在其他doc條目中,“body ...”表示內部定義上下文( 指南引用 ),例如在lambda主體中,“form ...”表示所有非表達式上下文,如在begins文檔中。

或者你可以將表達式包裝在(開始)中,例如(開始(定義x 10)(定義y 100)(定義z 1000))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM