问题描述
几天前我刚刚发现了Racket,我试图通过编写一个小的脚本来使用#lang slideshow
生成代表源代码的图像的脚本来使它更加舒适.
I just discovered Racket a few days ago, and I'm trying to get more comfortable with it by writing a little script that generates images to represent source code using #lang slideshow
.
我知道,在功能范例中进行编程时,最好使用let
创建几乎所有变量,但是我发现它引入了太多的嵌套层次,而Racket的let有一个过于复杂的API,需要使用多余的括号.我确信这是为了以更强大的方式使用let
消除歧义,但是就我的目的而言,这只是一个烦人.因此,我将使用define
创建所有变量,并在需要时使用begin
编写块(例如,在if
语句的正文中).
I know that when programming in a functional paradigm it's good practice to create almost all your variables with let
, but I find that it introduces too many levels of nesting and that Racket's let has an overcomplicated API which requires superfluous parentheses. I'm sure this is to remove ambiguity when using let
in more powerful ways, but for my purposes it's just an annoyance. Consequently, I'm creating all my variables with define
, and writing blocks with begin
if I need to (such as in the body of an if
statement).
问题是我一再遇到似乎非常神秘的错误.我确定我只是在犯一些愚蠢的初学者错误,因为它是该语言的新手,但我确实似乎找不到抱怨的根源.
The problem is that I've repeatedly been getting what seem to be very mysterious errors. I'm sure I'm just making some silly beginner's mistake, being new to the language, but I really can't seem to find the source of the complaint.
这是令人讨厌的代码:
(define sub-code (foldr ht-append (rectangle 0 0) (map internal-style (rest code))))
尽管我们将sub-code
定义为似乎无关紧要.如果我将其替换为
although what we're defining sub-code
to seems pretty irrelevant. If I replace it with
(define sub-code '())
我收到相同的错误. DrRacket表示define
在表达式上下文中使用.我理解此错误的一般含义-IE在您编写(print (define x 10))
之类的代码时会引发该错误,但我看不到是什么会触发此错误.
I receive the same error. DrRacket is saying that define
is being used in an expression context. I understand what this error would normally mean - IE that it would raise when you write code like (print (define x 10))
, but I can't see what would trigger it here.
如果有帮助,此define
在if
语句内的begin
块的开头
If it helps, this define
is at the beginning of a begin
block, inside an if
statement
(if (list? code)
(begin
(define sub-code '())
; a few more define statements and finally an expression ))
DrRacket正在打印的特定错误消息是
The specific error message DrRacket is printing is
define: not allowed in an expression context in: (define sub-code (quote ()))
我认为begin
块中可能不允许define
,但是我检查了文档和begin
的示例之一是
I thought maybe define
isn't allowed in begin
blocks, but I checked the docs and one of the examples for begin
is
(begin
(define x 10)
x)
所以我真的不知道该怎么办.预先感谢!
So I don't really know what to do. Thanks in advance!
推荐答案
在'body'上下文中允许定义,例如lambda
和let
等. if
的后继子句不是主体上下文;它们是表达式上下文,因此不允许定义.
Definitions are allowed in a 'body' context, like in lambda
and let
among others. The consequent and alternate clauses of if
are not body contexts; they are expression contexts and therefore definitions are not allowed.
begin
是特殊的-主体上下文中的begin
允许定义,但表达式上下文中的begin
禁止定义.您的情况属于后来者.
begin
is special - begin
in a body context allows definitions, but begin
in an expression contexts forbids definitions. Your case falls in to the later.
例如:
(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>
.
Syntactic keywords that requires expressions: if, cond, case, and, or, when, unless, do, begin
. Check out the formal syntax in any Scheme report (r{4,5,6,7}rs); look for <body>
, <sequence>
, <command>
, and <expression>
.
此外,如果需要在表达式中包含主体上下文,则只需包装let
语法形式,如下所示:
Also, if you need a body context in an expression, just wrap a let
syntactic form, as such:
(if test
(let ()
(define foo 'foo)
(list foo foo))
alternate)
这篇关于球拍中的定义错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!