Path: csiph.com!weretis.net!feeder6.news.weretis.net!news.misty.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: George Neuner Newsgroups: comp.compilers Subject: Re: Scheme is not another C-like language? was Compilers :) Date: Thu, 12 Jan 2023 02:54:37 -0500 Organization: A noiseless patient Spider Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <23-01-046@comp.compilers> References: <23-01-001@comp.compilers> <23-01-002@comp.compilers> <23-01-003@comp.compilers> <23-01-008@comp.compilers> <23-01-016@comp.compilers> <23-01-029@comp.compilers> <23-01-033@comp.compilers> <23-01-038@comp.compilers> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="12037"; mail-complaints-to="abuse@iecc.com" Keywords: Scheme Posted-Date: 12 Jan 2023 13:38:52 EST X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:3314 On Wed, 11 Jan 2023 11:02:56 -0000 (UTC), Kaz Kylheku <864-117-4973@kylheku.com> wrote: >It seems that Scheme, with its ugly (define ...) that can be used inside >block scopes, [disallows name redefinition]! Agree it's ugly: I never use internal defines in my own code. Unfortunately some people love them. >I tried (lambda () (define x 42) (define x 43)) in a Scheme >implementation and got an error about the duplicate variable. > >That's completely silly since it breaks the idea that the block scoped >define can just be desugared to nested lets. Unfortunately the experience varies by version: From R3RS to R5RS, a series of internal defines is treated AS IF they all are part of a single 'letrec' with the scope being the whole body. 'letrec', of course, does not permit multiple bindings to the same name. In R6RS and R7RS, a series of internal defines is treated as a 'letrec*' [note trailing *]. letrec* is equivalent to nested letrec and so does permit rebinding to the same name ... which will shadow any previous bindings. from R5RS 5.2.2 Internal Definitions ... The variable defined by an internal defnition is local to the body. That is, variable is bound rather than assigned, and the region of the binding is the entire body. For example, (let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) (foo (+ x 3))) => 45 A body containing internal definitions can always be converted into a completely equivalent letrec expression. For example, the let expression in the above example is equivalent to (let ((x 5)) (letrec ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3)))) Just as for the equivalent letrec expression, it must be possible to evaluate each expression of every internal definition in a body without assigning or referring to the value of any variable being defined. From R6RS 11.3 Bodies The of a lambda, let, let*, let-values, let*-values, letrec, or letrec* expression, or that of a definition with a body consists of zero or more definitions followed by one or more expressions. ... ... Each identifier defined by a definition is local to the . That is, the identifier is bound, and the region of the binding is the entire (see section [5.2]). Example: (let ((x 5))   (define foo (lambda (y) (bar x y)))   (define bar (lambda (a b) (+ (* a b) a)))   (foo (+ x 3)))               =>  45 When begin, let-syntax, or letrec-syntax forms occur in a body prior to the first expression, they are spliced into the body; see section [11.4.7]. Some or all of the body, including portions wrapped in begin, let-syntax, or letrec-syntax forms, may be specified by a macro use (see section [9.2]). An expanded (see chapter [10]) containing variable definitions can always be converted into an equivalent letrec* expression. For example, the let expression in the above example is equivalent to (let ((x 5))   (letrec* ((foo (lambda (y) (bar x y)))             (bar (lambda (a b) (+ (\* a b) a))))     (foo (+ x 3))))