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)

Re: SRFI 232: An advanced currying form Wolfgang Corcoran-Mathe 13 Jan 2022 22:37 UTC

I'm re-ordering the quotations in this response to put what seems
like the most important topic first.

> You can introduce a form that creates procedures taking up to the
> number of formal arguments and always returns a procedure. And it is a
> mistake if more than the number of formal arguments are given.
>
> A second form is needed (and should really be separate) for the second
> case. Here, a procedure is created that takes at least the number of
> formal arguments and always applies the access arguments to the
> result. And it is a mistake if less than the number of formal
> arguments are given.

Let's consider what these would look like.  I'll just call them
λc and λx ("lambda curry" and "lambda extra").  λc is much like the
current lambda*, except that it always returns a procedure and it
raises an exception when applied to too many arguments:

    ;; One list argument for simplicity.
    (define fold-c
      (λc (kons knil xs)
        (fold kons knil xs)))

    (fold-c * 1 '(1 2 3))   => #<procedure>
    ((fold-c * 1 '(1 2 3))) => 6
    (fold-c * 1 '(1 3 5) '(2 4 6))  ; exception: arity mismatch

    (let ((product-maker (fold-c * 1))
          (sum-maker (fold-c + 0))
          (ns '(2 4 6)))
      (list ((product-maker ns))
            ((sum-maker ns))))

      => (48 12)

λx, on the other hand, only handles the "extra-arguments case":

    (define sum-div
      (λx (ns)
        (lambda (d)
          (/ (fold + 0 (append extra ns)) d))))

    (sum-div '(2 4 6) 3) => 4
    (sum-div)             ; exception: arity mismatch
    (sum-div '(2 4) 4 5)  ; exception: arity mismatch

I'm sorry if these examples seem a bit dumb.  Hopefully this is
something like what you had in mind.  Assuming these forms are
correct: they're consistent, but I don't like them very much.  Having
to apply the thunk returned by λc seems clumsy and pedantic, and makes
the form very tricky to use in compositions; applying the thunk is
also something you'll probably forget to do.  λx looks OK, but not
exactly thrilling.

One compromise that I've considered is removing the
extra-argument-passing semantics of lambda*; it's simply an error to
pass surplus arguments, as with λc above.  This retains the useful
behavior of lambda* and eliminates what is probably the biggest
source of bugs.  There is still the ambiguity of what is returned
when the expected number of arguments is provided, though.  (I still
think it makes good practical sense to apply at that point.)

Opinions?

> As Scheme nowadays usually supports Unicode, schönfinkel or
> шейнфинкель would be better than curry. But certainly not optimal. :)
>
> I would postpone this discussion (which is bike-shedding at this
> point) until the semantics of the new form(s) have been fixed.

Fine.  Let's hold off on naming.  Keep thinking of catchy names,
though.

> > I agree that I'd like to see useful examples of lambda*, and I believe
> > that the sum/product example given in the SRFI is one, though it's
> > tiny.
>
> I think the sum and product examples are just examples coincidentally
> because the fold procedure happens to take the list as its last
> argument. They would better serve as motivating examples for SRFI 26.

Perhaps so, and, of course, cut is more flexible.  But I think there's
a major brevity advantage to being able to do simple "ordered" partial
application.  Consider this short snippet adapted from SICP Section
2.2.3, as written with lambda*-style currying:

    (compose (map make-pair-sum)
             (filter prime-sum?)
             (append-map pair-over-interval))

With SRFI 26 instead:

    (compose (cut map make-pair-sum <>)
             (cut filter prime-sum? <>)
             (cut append-map pair-up <>))

(What the functions do isn't important here.) This is a simple example
and the difference isn't huge, but I think it's clear that the first
version is easier to read and contains less extraneous information.

> Again, citing ML and Haskell here is not the right thing for Scheme
> because ML and Haskell are strongly typed.

Yes, there are serious differences and I don't mean to conflate what
those languages do and SRFI 232.  I've been referring to them in a
broader, cultural (!) sense: In these languages, partial application
is common and considered ["by whom?"] idiomatic.  Regardless of the
theoretical background, it's easy to write "curried procedures" in,
say, Haskell without explicit lambda abstraction or fancy syntax.
I suggest that it is nice to be able to do the same in Scheme, though
the foundations of the idiom are very different in a dynamically-typed
language.

> What would be the semantics of a hypothetical +* in Scheme be?

Good question.  I'm mildly worried about the semantic loophole this
introduces; a +* (or any other "omniadic") procedure would be an
operational paradox, since the point of evaluation would be
completely arbitrary.  ("How many arguments does it take before
they're added and the value returned?")  The good news is that
there doesn't seem to be a way to express such a procedure with
lambda* (or λc or λx).

--
Wolfgang Corcoran-Mathe  <xxxxxx@sigwinch.xyz>

"Most learning is not the result of instruction.  It is rather the
result of unhampered participation in a meaningful setting."
--Ivan Illich