Thank you for your valuable comments and putting this into a historical context, Chris.
Am Di., 23. Jan. 2024 um 01:10 Uhr schrieb Chris Hanson < c...@chris-hanson.org>: > On 1/22/24 02:06, Marc Nieper-Wißkirchen wrote:> More and more, I have > come to the conclusion that the > > addition of the local defines to Scheme added a wart to the language > > long ago. > Speaking for GJS and Hal, I'll point out that the reason for local > defines is pedagogical. The similarity between top-level and local > defines makes it easy for students to grasp the concept without having > to explain yet another binding mechanism. And since LETREC didn't exist > at that time, it was a sensible choice. > > I'd argue that it's still valuable. It's also something that both GJS > and I use regularly and I generally find preferable to LETREC. > I also use them regularly (primarily for internal procedure definitions), and I don't mean to say they are useless. For most warts in a programming language, there was a good reason to introduce it. My point is that there should be a better way to achieve what internal defines achieve without making the Scheme language more complicated. For example, a simpler syntax for `letrec' when specialized to procedures would already help. With the current tools, (lambda () (define (f) 1) (define (g) 2) (define (h) (+ (f) (g))) (h)) would have to be replaced by (lambda () (letrec ((f (lambda () 1)) (g (lambda () 2)) (h (lambda () (+ (f) (g)))) (h))) which has more boilerplate and has inferior indentation behaviour (for longer or more complicated procedures). A better (but not yet optimal) tool could be something like a, say, `labels' macro, e.g. as in: (lambda () (labels ((f) 1) ((g) 2) ((h) (+ (f) (g))) (h))) I also don't find the argument about continuation behavior particularly > compelling. I have been using internal definitions for 40 years without > once running into an issue with it; although admittedly I rarely use > internal definitions for anything other than procedure definitions. It > might be simpler to restrict what kinds of values can be used in those > definitions than worrying about reused continuations. > Internal defines, as specified in R[4567]RS, have no more problems with continuations than `letrec' does. Questionable behaviour shows up when local definitions are added after expressions because these can alter the semantics of the earlier expressions. SRFI 245's deviation from R6RS program body semantics was an attempt to fix this, but it doesn't. I don't mean the continuation behaviour when saying that local defines may constitute a wart in the language. One of the selling points of the Scheme language is its simplicity, in particular, that it doesn't have to distinguish between statements and expressions. Everything is an expression. With local definitions, however, we now have to distinguish between expressions and definitions. This complicates reasoning about and writing macros (not a problem in R4RS); see what Racket all had to add in functionality to give macro writers sufficient power. We wouldn't have to discuss topics like splicing or non-splicing behaviour or where bodies instead of expressions may appear if there weren't local defines. Marc