[erlang-questions] Matthew Sackman's "cut" proposal

Erik Søe Sørensen <>
Mon Dec 16 18:47:24 CET 2013


Disclaimer 1: I haven't followed the "cut"/partial application discussion
up until now.
Disclaimer 2: Surface syntax bikeshed!

Anyway, what I'm really responding to is these parts:
"""
        fun F(A1, .., Am)/N.

1/ Should N be the arity of the resulting fun, or the arity of the
partially applied function with *all* its arguments included? That may be
confusing.
"""

by noticing that the confusion would (for most people) go away (at least in
the "inclusive or exclusive?" respect) if the syntax was

        fun F(A1, .., Am)+K

(in which case N=m+K, obviously).
I know that (as far as I'm aware) the plus sign has not hitherto been
associated with function syntax, and there may be any number of historical
reasons to not to it this way (of which RO'K perhaps can provide a few
:-)), but then again the slash also doubles as an arithmetic operator. New
meaning - new symbol - potential for less confusion overall.

/Erik


2013/12/16 Anthony Ramine <>

> A couple of days ago I had an idea of a syntax that may fit Erlang for
> partial application.
>
> 1/ I wanted something not like cuts, where you have to look very hard to
> determine the function arity (e.g. count the « _ » in « foo(X, _) ».
> 2/ I wanted to limit the partial application to trailing arguments, not
> pass them into arbitrary places like in Elixir where they do stuff like
> &(foo(&1, X)).
>
> My proposition is:
>
>         fun F(A1, .., Am)/N.
>
> Which compiles down to:
>
>         fun (Am+1, .., An) -> F(A1, .., Am, Am+1, .., An) end.
>
> This is loosely inspired from Prolog’s higher order predicates.
>
> Pros:
>
> 1/ There is an explicit ‘fun’ token which clearly shows a fun is produced
> here, compared with the implicit enclosing scope of foo(X, _).
> 2/ There is an explicit arity at the end, compared with the implicit arity
> of the number of holes in other cut proposals.
> 3/ It is inspired from the ancestor of Erlang.
> 4/ That may require a change to the AST, which would be a good occasion to
> unify the various ‘fun’ AST nodes.
> 5/ Implementation is *way more* straightforward than the original cut
> proposal.
>
> Cons:
>
> 1/ Should N be the arity of the resulting fun, or the arity of the
> partially applied function with *all* its arguments included? That may be
> confusing.
> 2/ That might require a change to the AST, breaking
> backwards-compatibility.
>
> I am posting this for people to tell me why I am wrong to think this is a
> good idea.
>
> Regards,
>
> --
> Anthony Ramine
>
> Le 12 juil. 2011 à 05:57, Richard O'Keefe <> a écrit :
>
> >
> > On 12/07/2011, at 1:15 PM, Tim Watson wrote:
> >>
> >>> As an occasional Haskell and SML programmer, I am certainly not
> >>> against Curried functions.  What I *am* against is an approach which
> >>> is ugly, confusing, and almost never applicable.
> >>>
> >>
> >> Can't disagree with you there.
> >>
> >>> If Erlang syntax were generalised to
> >>>
> >>>       ends_with(X)(Y) -> string:equal(string:right(Y, length(X)), X).
> >>>
> >>> we could eliminate those three tokens.
> >>>
> >>> What's more, we could do that *WITHOUT* any weird restrictions on
> >>> - whether pattern matching is allowed in the fun
> >>> - the form of the fun body
> >>> - where the arguments appear in the fun body
> >>> - the order in which the arguments appear in the fun body.
> >>> and *WITHOUT*
> >>> - any weird non-intention-revealing tokens, whether '_' or '?'
> >>>
> >>
> >> Yes but you have to admit, it does look a bit odd.
> >
> > Yes, but that is precisely because it looks just like other languages
> > that do Curried functions.
> >
> >       ends_with (x) (y) = rtake y (length x) == x
> >
> > is perfectly good Haskell, assuming an rtake function, and
> >
> >       fun ends_with (x) (y) =
> >               List.drop (y, length y - length x) = x
> >
> > is perfectly good SML, or would be if it didn't crash when y is
> > shorter than x.
> >
> >> Why can't I just
> >> use the variable 'Y' and let the compiler figure out that the function
> >> signature needs to change?
> >
> > Because it is only in toy examples that a compiler *could* figure out
> > *how* the function signature needs to change.
> >
> >>> If you want to do Haskell-like things, it doesn't make sense not
> >>> to do it in a Haskell-like way, and that is to say that
> >>>
> >>>       <name>(<args1>)(<args2>)...(<argsn>) -> <body>
> >>>
> >>> is equivalent to
> >>>
> >>>       <name>(<args1>) ->
> >>>           fun (<args2>) ->
> >>>               ...
> >>>               fun (<argsn>) ->
> >>>                   <body>
> >>>               end
> >>>               ...
> >>>           end
> >>>
> >>> *NO* new tokens!
> >>> *NO* weird restrictions!
> >>> Good consistency with the way Clean and ML and Haskell do it.
> >>> *NO* changes elsewhere in the language.
> >>>
> >>
> >> Great - is it going to get through the eep process? Do we need to vote
> >> on it, contribute (e.g., test proposed patches, etc) or whatever?
> >
> > I don't have time to write up an EEP today, but I'll see what I can do.
> > The nice thing about it is that it's entirely in the front end; the
> > rest of the compiler doesn't need to know anything about it.
> >
> >>
> >>> Let's see what we have to do now:
> >>>
> >>> c(F1, F2) -> fun (X) -> F2(F1(X)) end.
> >>> c(F1, F2, F3) -> fun (X) -> F3(F2(F1(X))) end.
> >>> c(F1, F2, F3, F4) -> fun (X) -> F4(F3(F2(F1(X)))) end.
> >>>
> >>> doodle(X) ->
> >>>   F = c(fun do_thing/1,
> >>>         fun calculate_next_thing/1,
> >>>         fun get_bored_of_typing_result_x,
> >>>         fun start_getting_annoyed_with_lazy_programmers/1),
> >>>   {ok, F(X)}.
> >>>
> >>> Nope, not hard.  Trivial, in fact.
> >>
> >> Boilerplate.
> >
> > No, library code, done *ONCE*.
> > The only "boilerplate" would be the
> > -import(compose, [c/4]). % plus any others you want
> > line.
> >
> > It would, in fact, have precisely the same status as function
> > composition in Haskell and SML.  Library code.
> >
> >>> The question is, in a language without static types, how do you
> >>> tell the difference between an intentional foo/2 meaning a function
> >>> and an erroneous foo/2 that should have been Foo/2, with Foo a
> >>> variable bound to a number.
> >>
> >> We're never going to get static types in Erlang, so I think the answer
> >> is that you'd end up with a failing unit or integration test case. Not
> >> sure how to do a "raised eyebrow" smiley.
> >
> > We *have* optional static types in Erlang, but you're right that they
> > will probably never be mandatory.
> >
> > Testing and static checking are complementary tools.
> > We need both.  Thank goodness we *have* both in Erlang.
> >
> >> The compiler knows full well that (<module>)<name>/<arity> evaluates
> >> to a fun!?
> >
> > Only if preceded by 'fun'.
> >
> >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20131216/6a0c399e/attachment.html>


More information about the erlang-questions mailing list