SRFI 232: An advanced currying form
Arthur A. Gleckler
(08 Jan 2022 02:21 UTC)
|
Re: SRFI 232: An advanced currying form
Dr. Arne Babenhauserheide
(08 Jan 2022 17:24 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(08 Jan 2022 18:26 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(09 Jan 2022 18:45 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(09 Jan 2022 21:56 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(13 Jan 2022 22:37 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(14 Jan 2022 07:24 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(18 Jan 2022 19:30 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(19 Jan 2022 00:44 UTC)
|
Re: SRFI 232: An advanced currying form
John Cowan
(16 Jan 2022 18:29 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(16 Jan 2022 18:52 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(16 Jan 2022 19:01 UTC)
|
Re: SRFI 232: An advanced currying form
John Cowan
(20 Jan 2022 06:21 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(18 Jan 2022 18:28 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(18 Jan 2022 18:38 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(18 Jan 2022 19:00 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(18 Jan 2022 21:22 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(18 Jan 2022 22:18 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(19 Jan 2022 07:47 UTC)
|
Re: SRFI 232: An advanced currying form Marc Nieper-Wißkirchen (19 Jan 2022 20:55 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(24 Jan 2022 23:08 UTC)
|
Re: SRFI 232: An advanced currying form
Marc Nieper-Wißkirchen
(26 Jan 2022 13:29 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(31 Jan 2022 21:42 UTC)
|
Re: SRFI 232: An advanced currying form
Dr. Arne Babenhauserheide
(09 Jan 2022 01:35 UTC)
|
Re: SRFI 232: An advanced currying form
John Cowan
(16 Jan 2022 18:15 UTC)
|
Re: SRFI 232: An advanced currying form
Wolfgang Corcoran-Mathe
(09 Jan 2022 18:47 UTC)
|
If you think the backward-compatible extension of lambda à la (lambda (x y z | w . r) ...) to make it currying with fine control about the point of actual application is a viable option, I can provide you with a sample implementation. Marc PS Coincidentally, with the same approach, we could extend lambda with keyword arguments but without the need for an extra keyword type. Am Mi., 19. Jan. 2022 um 08:46 Uhr schrieb Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de>: > > So... a more regular, more expressive, and not hard-to-use version of > lambda* would look like > > (lambda** (<var> ...) (<var> ... . <var*>) > <body>) > > If this form is applied to no more than as many arguments as there are > variables between the first set of parentheses, a procedure is > returned. If there are more actual arguments, any excess arguments are > distributed over the second set of formals (and it is an error if > there are not enough excess arguments) and then the body is evaluated. > > (The name "lambda**" is just to distinguish it from the current "lambda*".) > > With these semantics, we have that > > (lambda (<var> .... . <var*>) <body)) > > is equivalent to > > (lambda** () (<var> ... . <var*>) <body>) > > and > > (lambda* (<var1> ... <var2> . <var*>) <body>) > > is equivalent to > > (lambda** (<var1> ...) (<var2> . <var*>) <body>) > > As one can see from this translation, it becomes clear why lambda* > with zero formal arguments would be the odd one out. > > Using the more expressive lambda**, we can then define other useful > versions of fold: > > (define fold** > (lambda** (proc seed lst1) lst* > (apply fold proc seed lst1 lst*))) > > (fold** proc seed lst1) => evaluates to a procedure that takes an > arbitrary number of lists and folds them together with lst1. > > There is another possible syntax for lambda** besides the one I gave > that has two formal argument lists and which may be more convenient: > > (lambda*** (a b c | d e . f) <body>) > > would be (lambda** (a b c) (d e . f) <body>), where "|" is some > keyword-like datum. > > The nice thing about lambda*** is that it is backward-compatible > (including error checking for too few arguments) with lambda! If you > leave out the "|", you get back lambda. And if you place "|" just > before the last argument, you get lambda*. > > So the name lambda*** (and lambda*) can be ditched and just replaced by lambda. > > Only one thing remains to be solved, namely what "|" is supposed to > be. If it is an identifier and treated as auxiliary syntax, lambda*** > can easily be implemented portably, but it would not be able to rebind > that identifier. (So the invariant that no identifier has special > status amongst the formals would be breached.) If it was a proper > keyword disjoint from identifiers, that problem would go away but we > haven't decided upon some keyword system yet. It could also be some > datum that otherwise cannot appear in formals like "" or #(), but that > may be considered ugly. > > The drawback of the choice that "|" is an identifier (which is > otherwise the most portable and most aesthetic appealing approach) can > be mitigated by reusing the with-ellipsis trick of Guile and SRFI 211 > to remove the special status of the ellipsis in syntax-rules/-case > macros: We could add a special form (with-currier <id> <body>) that is > equivalent to the evaluation of <body> but in which <id> takes over > the role of "|". 99.999% of the time, with-currier wouldn't be used, > but it would help to persuade purists like me that the approach is a > good one. > > Marc > > PS We can't use the literal "|", of course, because that's not an identifier. > > > > > > Am Di., 18. Jan. 2022 um 23:18 Uhr schrieb Marc Nieper-Wißkirchen > <xxxxxx@nieper-wisskirchen.de>: > > > > Am Di., 18. Jan. 2022 um 22:23 Uhr schrieb Wolfgang Corcoran-Mathe > > <xxxxxx@sigwinch.xyz>: > > > > > > On 2022-01-18 19:59 +0100, Marc Nieper-Wißkirchen wrote: > > > > Haskell has no thunks (and needs no thunks), but Scheme has. Giving > > > > them a special status in Scheme versus procedures with more than zero > > > > arguments goes against basic principles. An even more basic principle > > > > is that, if , the number 1, and not the number 0, should be given > > > > special status in the domain of the non-negative integers. > > > > > > Theoretically I agree that we should not treat 0 as a special case. > > > But nullary procedures *are* a special case, I argue, in Scheme > > > practice. They aren't isomorphic to constants, and we only tend to > > > use them as a way to get a body expression evaluated with a certain > > > continuation or in a certain environment. Deriving a thunk from a > > > positive-ary procedure is, I think, rarely useful for this reason. > > > In Scheme programming, "nullary" isn't just the predecessor-ary of > > > "unary", but a different beast. > > > > For practical programming, yes, we don't need most such thunks that > > would be generated; but the regularity that would be won could still > > make reasoning about programs easier. > > > > But I'm still thinking of how to make it both practical and regular. > > > > > > ... that's why I have > > > > been asking about compelling use cases that can't be solved with > > > > standard Scheme, with cut, or with something like my "!". > > > > > > I've tried to explain why I find lambda* compelling (brevity of > > > notation and ease of use, especially compared to cut, convenience in > > > composition, etc.), and I know you haven't been similarly excited. We > > > can't talk about "compelling use cases" without reference to whom is > > > feeling compelled. Would you be willing to suggest the kind of > > > example which you'd be happy to see? > > > > If something is theoretically appealing (which lambda* isn't, > > unfortunately, for the reasons discussed), its elegance may be enough > > to make it part of Scheme. > > > > If not, it should at least be helpful in practice. What I am looking > > for is thus an example that can't be expressed similarly concisely > > with what we already have, including cut and abbreviations to cut > > (like !). Can you give me an example that is more than a toy example > > and doesn't look like the direct translation of some, say, Haskell > > demonstration code. > > > > > > PS Another difference to Haskell is that Haskell has a static type > > > > system that gives early errors. In Scheme, we don't have much ad-hoc > > > > overloading so the dynamic type system can catch errors early. The > > > > lambda* goes in a different direction. > > > > > > I'm also a bit concerned about the possibility that arity mistakes > > > will be harder to catch. But variadic procedures already cause plenty > > > of confusion here; accidentally over-apply map or some other variadic > > > form and you probably won't see the mistake until the program runs. > > > > With Scheme, you usually only see errors when the program runs; that's > > true, but especially because of that you should try hard so that the > > error is raised early and near where you made it. Otherwise > > (especially because of Scheme's inferior tooling environment compared > > with mainstream languages), debugging can be a nightmare. > > > > To give an example: One can argue that there shouldn't be length, > > vector-length, and string-length but just a polymorphic length. > > Barring questions of efficiency, this will make programs dealing with > > vectors and strings shorter (because there is less to type), but it > > will detect fewer type errors early. In a statically-typed language, > > this is no problem. In a dynamically typed language, you should be > > explicit and write what you mean. It also serves as a documentation. > > As you only write code once, brevity is certainly not the most > > important goal. > > > > > The bottom line is that arity can be tricky to keep track of with > > > variadic procedures, whether created with lambda* or not. > > > > This suggests defining only very few procedures with lambda*. > > > > > > Marc