Scheme中表达式后的函数定义

Scheme中表达式后的函数定义,scheme,Scheme,我知道我不能在表达式中定义函数,但在同一嵌套函数中的表达式之后定义函数会出错。我将R5RS与DrScheme一起使用 例如,这会引发一个错误,“define:表达式上下文中不允许”: 您可以在另一个定义中使用define。但是,有些方案不允许在没有else部分的情况下使用if。这对我很有用: (define (cube x) (if (= x 0) 0 1) ; just for example, no reason to do this (define (square x) (* x

我知道我不能在表达式中定义函数,但在同一嵌套函数中的表达式之后定义函数会出错。我将R5RS与DrScheme一起使用

例如,这会引发一个错误,“define:表达式上下文中不允许”:

您可以在另一个定义中使用
define
。但是,有些方案不允许在没有
else
部分的情况下使用
if
。这对我很有用:

(define (cube x)
  (if (= x 0) 0 1) ; just for example, no reason to do this
  (define (square x) (* x x))
  (* x (square x)))
你一开始就试过定义吗?这可能是您的解释器的问题。

您可以在另一个定义中使用
define
。但是,有些方案不允许在没有
else
部分的情况下使用
if
。这对我很有用:

(define (cube x)
  (if (= x 0) 0 1) ; just for example, no reason to do this
  (define (square x) (* x x))
  (* x (square x)))

你一开始就试过定义吗?这可能是您的解释器的问题。

在R5R中,您只能在相当特定的位置使用
定义
:特别是,您可以在具有
的表单的开头(仅)使用它。第5.2.2节对此进行了描述。这特别意味着,内部
定义
永远不能出现在任何其他表达式之后,即使在
中也是如此


原生球拍(或者无论你用什么合适的名字来称呼
#lang Racket
)在这方面都更加灵活:你想要做的事情(除了单臂
if
)合法使用球拍。

在R5R中,您只能在相当特定的位置使用
定义
:特别是,您可以在具有
的表单开头(仅)使用它。第5.2.2节对此进行了描述。这特别意味着,内部
定义
永远不能出现在任何其他表达式之后,即使在
中也是如此


在这方面,Native Racket(或者无论您从
#lang Racket
获得什么正确的名称)更加灵活:您试图做的事情(除了单臂
,如果
)在Racket中是合法的。

在过程体中定义
(包括所有程序的语法糖形式,如
let
let*
、和
letrec
)只在其他表达式之前合法,不在第一个表达式之后合法,并且不能是最后一个形式

你的例子没有说明为什么你想在定义之前有一个表达式的真正原因。除了将所有
define
移到最开始,你没有别的办法了。例如

(define (cube x)
  ;; define moved to top
  (define (square x) (* x x))
  ;; dead code moved under define and added missing alternative
  (if (= x 0) 0 'undefined) 
  (* x (square x)))
如果代码没有死。例如,这是尾部表达式,您可以使用
let
创建一个新的主体:

(define (cube x)
  (if (= x 0) 
      0
      (let ()
        ;; this is top level in the let
        (define (square x) (* x x))
        ;; required expression
        (* x (square x)))))

我想也许我们需要一个例子,在这个例子中,您认为应该在表达式后面加上define,我们将很高兴地展示如何设计它。

define
在一个过程体中(包括所有程序的语法糖形式,如
let
let*
、和
letrec
)只在其他表达式之前合法,不在第一个表达式之后合法,并且不能是最后一个形式

你的例子没有说明为什么你想在定义之前有一个表达式的真正原因。除了将所有
define
移到最开始,你没有别的办法了。例如

(define (cube x)
  ;; define moved to top
  (define (square x) (* x x))
  ;; dead code moved under define and added missing alternative
  (if (= x 0) 0 'undefined) 
  (* x (square x)))
如果代码没有死。例如,这是尾部表达式,您可以使用
let
创建一个新的主体:

(define (cube x)
  (if (= x 0) 
      0
      (let ()
        ;; this is top level in the let
        (define (square x) (* x x))
        ;; required expression
        (* x (square x)))))

我想也许我们需要一个例子,在这个例子中,您认为有必要在表达式之后定义,我们很乐意展示如何设计它。

实际上,您可以在表达式中定义函数,而不是使用
define
语法,该语法只能在某些上下文中使用,而是使用
let
,例如:
(+2(let((平方)(λ(x)(*x)))(平方4)))
这个问题的重点是它不在表达式内部。lambda语法也会出现同样的错误。有几个很好的答案可以解释这里发生了什么。实际上,您可以在表达式内部定义函数,而不是使用
define
语法,该语法只能在某些上下文中使用,但与
语法一起使用>let
,例如:
(+2(let((平方)(λ(x)(*x)))(平方4)))
这个问题的重点是它不在表达式内部。lambda语法也会出现同样的错误。有几个很好的答案可以解释这里发生了什么。R5RS和R7RS都只指定内部定义可以位于所有表达式之间()。我不认为允许它们出现在任何地方都是不符合规范的,但我认为Racket的实现会尝试快速失败,并尽可能少地解释规范。这显然超出了R5RS规范。在
lambda
的主体和派生形式的开头,您可能有本地定义。这两者都不是和c显然不是一致的方案代码。就像比规范有更多绑定的实现一样,如果它碰巧在特定的实现中工作也没关系,因为它不会破坏方案代码,但是这样做会导致实现特定的锁定,而不是标准一致的代码。实际上我提到了我专门使用的解释器o@AlexisKing是正确的。是的,@Sylwester,我想这或多或少就是我所说的,尽管措辞更清楚一些。:)R5RS和R7RS都只指定内部定义可以出现在所有表达式之间()。我不认为允许它们出现在任何地方都是不符合规范的,但我认为Racket的实现会尝试快速失败,并尽可能少地解释规范。这显然超出了R5RS规范。在
lambda
的主体和派生形式的开头,您可能有本地定义。这两者都不是和c显然不是共振的方案代码。就像比规范有更多绑定的实现一样,如果它碰巧在特定的环境中工作,也没关系