[英]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)
所以我真的不知道該怎么做。 提前致謝!
定義是在允許的“身體”背景下,像lambda
並let
等等。 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)
...
但那有點傻。
或者使用cond
並define
:
(cond [(list? code)
(define x '())
x]
...
最后一種方式 - 使用cond
和define
- 最接近當前的Racket風格指南推薦的方式。
或者你可以將表達式包裝在(開始)中,例如(開始(定義x 10)(定義y 100)(定義z 1000))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.