|
The underscore
Marc Nieper-Wißkirchen
(26 Oct 2025 12:04 UTC)
|
|
Re: The underscore Daphne Preston-Kendal (25 Nov 2025 13:25 UTC)
|
|
Re: The underscore
Daphne Preston-Kendal
(09 Dec 2025 10:31 UTC)
|
On 26 Oct 2025, at 13:04, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > Binding constructs in Scheme generally do not care about the current binding of a variable that is to be bound. [etc.] Marc and I had a discussion about this thread which ended up being off-list because I forgot to reply-all to his first message. With his permission, here is a record of what was said: On 26 Oct 2025, at 13:17, Daphne Preston-Kendal <xxxxxx@nonceword.org> wrote: > The main practical issue here is that you can’t bind a variable called _ with the pattern matcher. I don’t consider this a major flaw. In fact, not being able to rebind the underscore avoids accidentally overriding an important auxiliary syntax keyword. > > So if this is a problem at all, I would prefer (what I understand to be) your second idea. > > Racket provides a (var <<identifier>>) pattern which will bind <<identifier>> even if it is the underscore. This might be the best option of all. Apart from the ability to rebind underscore, though, it has no uses as far as I can tell. I consider it also mostly a hangover from an attempt to fix the misfeatures of the Wright pattern matcher, from which the Racket matcher historically evolved. > > It may be useful for strict correctness in implementing macros which use ‘match’ as an implementation detail, though. Without it, an identifier which is passed from a use of such a macro into a place which is supposed to bind a variable from a pattern may surprisingly not be bound if it is the underscore. > > > Daphne > > PS Incidentally, if we did Scheme over from scratch, I would probably make the underscore not an identifier at all but a non-self-evaluating special object much like the empty list. So I consider this to be all patches on top of patches. On 26 Oct 2025, at 13:38, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > Am So., 26. Okt. 2025 um 13:18 Uhr schrieb Daphne Preston-Kendal <xxxxxx@nonceword.org>: >> The main practical issue here is that you can’t bind a variable called _ with the pattern matcher. I don’t consider this a major flaw. In fact, not being able to rebind the underscore avoids accidentally overriding an important auxiliary syntax keyword. > > I don't think that the latter applies to modern Scheme, which allows rebinding lambda, let, etc. > >> So if this is a problem at all, I would prefer (what I understand to be) your second idea. >> >> Racket provides a (var <<identifier>>) pattern which will bind <<identifier>> even if it is the underscore. This might be the best option of all. Apart from the ability to rebind underscore, though, it has no uses as far as I can tell. I consider it also mostly a hangover from an attempt to fix the misfeatures of the Wright pattern matcher, from which the Racket matcher historically evolved. >> > If Racket already provides `var', it makes sense to reuse it (which is simpler than what I intended to suggest). >> It may be useful for strict correctness in implementing macros which use ‘match’ as an implementation detail, though. Without it, an identifier which is passed from a use of such a macro into a place which is supposed to bind a variable from a pattern may surprisingly not be bound if it is the underscore. >> > It is not only useful, it is necessary for correctness. >> PS Incidentally, if we did Scheme over from scratch, I would probably make the underscore not an identifier at all but a non-self-evaluating special object much like the empty list. So I consider this to be all patches on top of patches. >> > We are back to keywords (in the style of Racket). :) > > Until we have them, the underlying flaw is trying to emulate them by looking at bindings of identifiers that would be bound. (My first suggestion basically is to remove this flaw so no patch at all is needed.) On 27 Oct 2025, at 10:32, Daphne Preston-Kendal <xxxxxx@nonceword.org> wrote: > On 26 Oct 2025, at 13:38, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > >> Am So., 26. Okt. 2025 um 13:18 Uhr schrieb Daphne Preston-Kendal <xxxxxx@nonceword.org>: >> >>> The main practical issue here is that you can’t bind a variable called _ with the pattern matcher. I don’t consider this a major flaw. In fact, not being able to rebind the underscore avoids accidentally overriding an important auxiliary syntax keyword. >> >> I don't think that the latter applies to modern Scheme, which allows rebinding lambda, let, etc. > > I meant *accidental* rebinding. See my recent conversation with Arne where he was surprised to learn that doing something like (lambda (_) …) to create a procedure of one argument (where the argument is not relevant to the code) would in fact break syntax-case, syntax-rules etc. within the lambda. > >>> It may be useful for strict correctness in implementing macros which use ‘match’ as an implementation detail, though. Without it, an identifier which is passed from a use of such a macro into a place which is supposed to bind a variable from a pattern may surprisingly not be bound if it is the underscore. >> >> It is not only useful, it is necessary for correctness. > > That’s rather stretched. Such a macro could change its implementation to use its own variable name in the pattern, then rebind it with ‘let’. > > In any case, ‘var’ also wouldn’t free one from having to think about this problem and would not fix this sharp edge (for the authors of macros using ‘match’ within their definition) so much as codify it. The question is then rather of which style I wish to encourage more: macros which use match in their definition and make match patterns available for the convenience of their users; or macros which use match in their definition and make it purely an implementation detail not apparent to users of the macro. I think I prefer the former. > > Racket’s ‘var’ pattern does not seem to be used much in practice. These results are mostly irrelevant: <https://github.com/search?q=language%3ARacket+%2F%5C%28var%2F+%2F%5C%28match%2F&type=code>. > (This isn’t much of an argument against it – if I didn’t include things just because people don’t seem to use them very often, I wouldn’t include ‘match-letrec’. But it’s a data point.) > > > Daphne On 27 Oct 2025, at 11:17, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > Am Mo., 27. Okt. 2025 um 10:33 Uhr schrieb Daphne Preston-Kendal <xxxxxx@nonceword.org>: > On 26 Oct 2025, at 13:38, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote: > >> > Am So., 26. Okt. 2025 um 13:18 Uhr schrieb Daphne Preston-Kendal <xxxxxx@nonceword.org>: >> > >> >> The main practical issue here is that you can’t bind a variable called _ with the pattern matcher. I don’t consider this a major flaw. In fact, not being able to rebind the underscore avoids accidentally overriding an important auxiliary syntax keyword. >> > >> > I don't think that the latter applies to modern Scheme, which allows rebinding lambda, let, etc. >> >> I meant *accidental* rebinding. See my recent conversation with Arne where he was surprised to learn that doing something like (lambda (_) …) to create a procedure of one argument (where the argument is not relevant to the code) would in fact break syntax-case, syntax-rules etc. within the lambda. >> > We should encourage people to actually understand the language they are writing code in. :) > > Of course, such misunderstandings happen regularly, in any language, and by every programmer. But the result should be a deeper understanding and not an encouragement to muddle actually simple and clear language semantics. >> >> It may be useful for strict correctness in implementing macros which use ‘match’ as an implementation detail, though. Without it, an identifier which is passed from a use of such a macro into a place which is supposed to bind a variable from a pattern may surprisingly not be bound if it is the underscore. >> > >> > It is not only useful, it is necessary for correctness. >> >> That’s rather stretched. Such a macro could change its implementation to use its own variable name in the pattern, then rebind it with ‘let’. >> > Right, but this would be very taxing to the macro author it seems. >> In any case, ‘var’ also wouldn’t free one from having to think about this problem and would not fix this sharp edge (for the authors of macros using ‘match’ within their definition) so much as codify it. The question is then rather of which style I wish to encourage more: macros which use match in their definition and make match patterns available for the convenience of their users; or macros which use match in their definition and make it purely an implementation detail not apparent to users of the macro. I think I prefer the former. >> > It seems that the "var" approach is as taxing to the macro author as the renaming one (because user-supplied input has to be parsed and scanned as well). In this light, my first suggestion (of my earlier post) looks better. > > Marc