为什么在一个函数定义中它是合法的进行自我调用,但对于某个值是非法的? [英] Why is it legal in a function definition to make self-call but illegal for a value?

查看:180
本文介绍了为什么在一个函数定义中它是合法的进行自我调用,但对于某个值是非法的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

计算机程序的结构和解释(SICP)3.5.2引入了无限流:

 (定义了
(cons-stream 1 ones))

此代码在DrRacket中不起作用,错误如下:


ones:undefined;在其定义之前无法引用标识符


其他代码如下:

<$ p
(cons-stream n
(整数 - 从(+ n 1)开始)))
(整数 - 从n开始)

(定义整数(整数 - 从1开始))

产生错误: > b
$ b


禁用交互


(陷入无限循环?)



据我所知(SICP),实现无限流的关键点是延迟评估:

 (define(delay exp)
(lambda()exp))

(define(cons-stream ab)
利用
(延迟b)))

用于 cons-stream ,无限流仍然是非法的。

这种数据结构让我想起递归函数,其定义中的自我调用是合法的编译)有或没有执行机构l退出。



为什么一个值引用它本身是非法的?即使引用被延迟?

其他编程语言支持无限流吗?



如果不是,是它关于处理器处理汇编语言的方式?数据栈的东西?

解决方案

当你创建一个过程时,参数已经在开始过程体时被评估过。因此, delay 不会做任何事情,因为它已经在当时计算了。 cons-stream 需要是一个宏。

DrRacket不是一种语言实现。这是一个支持很多语言的IDE。其中之一是SICP兼容性语言。我使用DrRacket中的这段代码疯狂地运行代码,没有任何错误:


$ b

 <$ c (定义一个
(cons-stream 1个))

(define(整数 - 从n开始)
(cons-stream n
(整数开始自(+ n 1))))

(定义整数(整数 - 从1开始))

它就像一个魅力。 DrRacket中的默认语言<#!racket ,也有流,但名称不同:

#!racket

(define ones
(stream- (1))

(定义(从n开始的整数)
(stream-cons n
(整数从(+ n 1)开始)))

(定义整数(整数 - 从1开始))

然而对于Scheme,你应该使用SRFI-41,你可以使用#!racket (使用(require srfi / 41))和#!r6rs (和R7RS - 当它结束时很大)
$ b

(stream-cons 1 ones))$ b $(
$ s
$ s

(定义(整数 - 从n开始)
(stream-cons n
(integer-starting-from(+ n 1))))

(定义整数(整数 - 从1开始))
#!racket 和<$ c中滚动自己的SICP流$ c>#!r6rs 您可以使用 define-syntax

 (define-syntax stream-cons 
(syntax-rules()
((_ ad)(cons a(delay d)))))

请注意RSFI-41和球拍拥有自己的流媒体库#!racket stream-cons 中延迟了这两个值,而不仅仅是在SICP版本中的尾部。


Structure and Interpretation of Computer Programs (SICP) 3.5.2 introduces infinite streams:

(define ones
  (cons-stream 1 ones))

This code doesn't work in DrRacket, with the error:

ones: undefined; cannot reference an identifier before its definition

Other code like this:

(define (integers-starting-from n)
  (cons-stream n
               (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))

produce error:

Interactions disabled

(fall in infinite loop?)

So far as I read(SICP), the key point of implementing an infinite stream is delayed evaluation:

(define (delay exp)
  (lambda () exp))

(define (cons-stream a b)
  (cons a
        (delay b)))

With this used in cons-stream, infinite stream still illegal.

Such data structure reminds me of recursive function in whose definition self-call is legal (in compiling) within or without an actual exit.

Why is it illegal for a value to reference itself? Even the reference has been delayed?

Could infinite stream supported by other programming language?

If not, is it about the way processor deal with assembly language? The data stack stuff?

解决方案

When you make a procedure the arguments are already evaluated when you start the body of the procedure. Thus delay would not do anything since it's already computed at that time. cons-stream need to be a macro.

DrRacket is not one language implementation. It's an IDE that supports lots of languages. One of them is a SICP compatibility language. I mananged to run your code without errors using this code in DrRacket:

#!planet neil/sicp

(define ones
  (cons-stream 1 ones))

(define (integers-starting-from n)
  (cons-stream n
               (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))

It works like a charm. The default language in DrRacket, #!racket, has streams too, but the names are different:

#!racket 

(define ones
  (stream-cons 1 ones))

(define (integers-starting-from n)
  (stream-cons n
               (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))

However for Scheme you should use SRFI-41 that you can use from both #!racket (using (require srfi/41)) and #!r6rs (and R7RS-large when it's finished)

(import (rnrs)
        (srfi :41))

(define ones
  (stream-cons 1 ones))

(define (integers-starting-from n)
  (stream-cons n
               (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))

To roll your own SICP streams in both #!racket and #!r6rs you can use define-syntax

(define-syntax stream-cons 
  (syntax-rules ()
    ((_ a d) (cons a (delay d)))))

Note that RSFI-41 and rackets own stream library for #!racket delays both values in a stream-cons and not just the tail as in SICP version here.

这篇关于为什么在一个函数定义中它是合法的进行自我调用,但对于某个值是非法的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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