球拍中的定义错误 [英] Error with define in Racket

查看:78
本文介绍了球拍中的定义错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前我刚刚发现了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.

如果有帮助,此defineif语句内的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,但是我检查了

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'上下文中允许定义,例如lambdalet等. 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)

这篇关于球拍中的定义错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆