Lambda the Ultimate

inactiveTopic Larry Wall: Apocalypse 6
started 3/11/2003; 12:39:21 PM - last post 3/14/2003; 2:38:04 PM
Ehud Lamm - Larry Wall: Apocalypse 6  blueArrow
3/11/2003; 12:39:21 PM (reads: 2051, responses: 15)
Larry Wall: Apocalypse 6
(via Keith Devens)

This is the Apocalypse on Subroutines. In Perl culture the term "subroutine" conveys the general notion of calling something that returns control automatically when it's done. This "something" that you're calling may go by a more specialized name such as "procedure", "function", "closure", or "method". In Perl 5, all such subroutines were declared using the keyword sub regardless of their specialty. For readability, Perl 6 will use alternate keywords to declare special subroutines, but they're still essentially the same thing underneath. Insofar as they all behave similarly, this Apocalypse will have something to say about them.

Language design in action.

As this Apocalypse covers many issues, I will not try to give a summary. Go read the whole thing (or at least skim through it), so we can discuss specific constructs in the comments.


Posted to general by Ehud Lamm on 3/11/03; 12:39:51 PM

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 12:44:11 AM (reads: 1130, responses: 0)
"The important thing is that we're adding a generalized type system to Perl. Let us begin by admitting that it is the height of madness to add a type system to a language that is well-loved for being typeless.

But mad or not, there are some good reasons to do just that. First, it makes it possible to write interfaces to other languages in Perl. Second, it gives the optimizer more information to think about. Third, it allows the S&M folks to inflict strongly typed compile-time semantics on each other. (Which is fine, as long as they don't inflict those semantics on the rest of us.) Fourth, a type system can be viewed as a pattern matching system for multi-method dispatch.

Which basically boils down to the notion that it's fine for Perl to have a type system as long as it's optional. It's just another area where Perl 6 will try to have its cake and eat it too."

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 2:56:11 AM (reads: 1122, responses: 0)
"Perl 6 still allows you to access the arguments via @_ if you like, but in general you'll want to hoist the metadata up into the declaration. Perl 6 still fully supports the distinction between positional and variadic data--you just have to declare them differently. In general, variadic items must follow positional items both in declaration and in invocation."

It's about time, wouldn't you say?

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 2:58:31 AM (reads: 1122, responses: 0)
"A macro is a function that is called immediately upon completion of the parsing of its arguments. Macros must be defined before they are used--there are no forward declarations of macros, and while a macro's name may be installed in either a package or a lexical scope, its syntactic effect can only be lexical, from the point of declaration (or importation) to the end of the current lexical scope.

Every macro is associated (implicitly or explicitly) with a particular grammar rule that parses and reduces the arguments to the macro. The formal parameters of a macro are special in that they must be derived somehow from the results of that associated grammar rule. We treat macros as if they were methods on the parse object returned by the grammar rule, so the first argument is passed as if it were an invocant, and it is always bound to the current parse tree object, known as $0 in Apocalypse 5."

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 8:16:47 AM (reads: 1083, responses: 1)
"Currying is done with the .assuming method. It works a bit like the .wrap method, except that instead of wrapping in place, it returns a new function to you with a different signature, one in which some of the parameters are assumed to be certain values:

    my &say ::= &*print.assuming(handle => $*TERM);
"

Dan Shappir - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 8:43:12 AM (reads: 1202, responses: 0)
Syntax is sort of similar to what we use in BeyondJS. To bind argument 'goo' of the function 'bar' in put the new function in variable 'foo':

var foo = bar.curry({goo : "hello world"});

If goo happens to be the first argument you can also write:

var foo = bar.curry("hello world");

and if it happens to be the last argument:

var foo = bar.curry({-1 : "hello world"});

Binding to the second argument:

var foo = bar.curry({2 : "hello world"});

Or, you can use the fact that curry() also accepts an array as the list of values to bind to so you write:

var foo = bar.curry([,"hello world"]);

The first array element in this case is empty so its not bound to.

Binding to several arguments can be done as:

var foo = bar.curry("hello").curry("world");

or simply:

var foo = bar.curry("hello", "world");

In addition we also provide the using() method which is similar to curry() but handles binding of functions differently. If bar and goo are functions:

var foo = bar.curry(goo);

binds a reference to the function goo to the first argument. OTOH:

var foo = bar.using(goo);

binds an invocation of the function goo to this first argument. That is, whenever foo is called, goo is also called automatically and its return value is assigned to bar's first argument.

Finally writing:

var foo = bar.andThen(goo);

is equivalent to writing:

var foo = goo.using(bar);

First bar is activated and then its return value is passed along to go.

water - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 3:28:56 PM (reads: 1002, responses: 1)

The first thing that occurs to me is that Larry could acheive a boost in performance and cut down on his development time by years by simply providing a translation layer from Perl 6 grammar to a language that has mature compilers which implement nearly all of the functionality desired in a single package.

I say this because the RFI's taken together create a feature-set almost resembling that of Common Lisp. No, I'm not meaning to troll, but this is a very ambitious set of goals.

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 11:05:02 PM (reads: 1006, responses: 0)
this is a very ambitious set of goals.

I agree. What I am most interested in is Larry's design approach (backward compatability vs. new features) and his unique approach to syntax in general and syntactic sugar in particular.

The integration of the new features into Perl5, which is a mature language with a large base of users is the important thing here. The language features themselves are for the most part not original.

water - Re: Larry Wall: Apocalypse 6  blueArrow
3/12/2003; 11:09:58 PM (reads: 974, responses: 3)
The use of relative specification of precedence instead of numerical levels of precedence caught my eye the most about that. I've not seen that mentioned in any other language design. Is that specific to Perl 6?

Noel Welsh - Re: Larry Wall: Apocalypse 6  blueArrow
3/13/2003; 8:54:47 AM (reads: 931, responses: 1)

I find it impossible to read to the end of any of Larry Wall's writing, so I'll just note I find the specification mind-bogglingly complex. I also don't think the complexity is necessary as other languages offer the same features without the syntactic obfuscation.

More interesting to me is the way Larry Wall writes:

Third, it allows the S&M folks to inflict strongly typed compile-time semantics on each other. (Which is fine, as long as they don't inflict those semantics on the rest of us.)

The same point could be made without the value judgement but stating the point in this was is implicitly defining the values of the Perl community, and stating who is in and who is out. I conjecture that this style of writing helps to unify the Perl community by enforcing their shared values. I wonder if this is important in the development of an open-source language? Having a cause to unite behind is certainly a good way to gather converts.

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/13/2003; 9:47:28 AM (reads: 961, responses: 0)
Sure. A Larry's humour is an essential part of Perl culture.

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/13/2003; 1:02:11 PM (reads: 924, responses: 0)
The use of relative specification of precedence instead of numerical levels of precedence caught my eye. Is that specific to Perl 6?

No other language comes to mind.

Carl Witty - Re: Larry Wall: Apocalypse 6  blueArrow
3/14/2003; 10:16:00 AM (reads: 839, responses: 0)
The MetaPRL proof assistant (http://www.metaprl.org/) uses a relatively fixed input grammar, but has a built-in highly customizable pretty printer. The pretty printer requires relative specification of precedence. You declare a new named precedence level; then later (perhaps even in another file) you declare the relationships between these named precedence levels.

Aaron Ucko - Re: Larry Wall: Apocalypse 6  blueArrow
3/14/2003; 12:07:46 PM (reads: 862, responses: 0)
IIRC, Cecil goes one step further, by allowing operators to specify multiple precedence relationships with other operators (yielding a partial ordering). I don't think I've the version in A6 anywhere else; it's somewhat weaker (as it forces a total ordering) but still much better than arbitrary numeric levels IMNSHO.

Bryn Keller - Re: Larry Wall: Apocalypse 6  blueArrow
3/14/2003; 1:28:37 PM (reads: 867, responses: 0)
CamlP4 does something like this I believe.

(From http://caml.inria.fr/camlp4/manual/manual005.html)

Syntax of a position

A position can be:

* FIRST: The extension is inserted at the beginning of the precedence levels. * LAST: The extension is inserted as the end of the precedence levels. * BEFORE label: The extension is inserted before the precedence level so labelled. * AFTER label: The extension is inserted after the precedence level so labelled. * LEVEL label: The extension is inserted at the precedence level so labelled.

Only the case LEVEL extends already existing levels: the other cases create new levels.

Ehud Lamm - Re: Larry Wall: Apocalypse 6  blueArrow
3/14/2003; 2:38:04 PM (reads: 823, responses: 0)
"You may ask a subroutine to wrap itself up in another subroutine in place, so that calls to the original are intercepted and interpreted by the wrapper, even if access is only through the reference:

    $id = $subref.wrap({
        # preprocessing here
        call;
        # postprocessing here
    }

The call built-in knows how to call the inner function that this function is wrapped around."