Sign In/My Account | View Cart  
advertisement


Listen Print

Apocalypse 4
by Larry Wall | Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Editor's Note: this Apocalypse is out of date and remains here for historic reasons. See Synopsis 04 for the latest information.

Rejected RFCs

Just because I've rejected these RFCs doesn't mean that they weren't addressing at a valid need. Usually an RFC gets rejected simply because I think there's a better way to do it. Often there's little difference between a rejected RFC that I've borrowed ideas from and an RFC accepted with major caveats.

We're already running long, so these descriptions will be terse. Please read the RFC if you don't understand the commentary.

RFC 089: Controllable Data Typing

This is pretty close to what we've been planning for Perl for a long time. However, a number of the specifics are suboptimal.

If you declare a constant, it's a constant. There's no point in allowing warnings on that by default. It should be fatal to modify a constant. Otherwise you lose all your optimization possibilities.

For historical reasons, the assignment in

     my ($a, $b) = new Foo;

will not distribute automatically over $a and $b. If you want that, use the ^= hyperassignment instead, maybe.

Constraint lists are vaguely interesting, but seem to be too much mechanism for the possible benefits. If you really want a data type that can be polymorphic, why not just define a polymorphic type?

In general, there seems to be a lot of confusion in this RFC between constraints on variables and constraints on values. For constraints to be useful to the compiler, they have to be on the variable, and you can't be "pushing" constraints at runtime.

On aliasing via subroutine calls, note that declared parameters will be constant by default.

So anyway, although I'm rejecting this RFC, we'll certainly have a declaration syntax resembling some of the tables in the RFC.

RFC 106: Yet another lexical variable proposal: lexical variables made default

Yes, it's true that other widely-admired languages like Ruby do implicit declaration of lexicals, but I think it's a mistake, the results of which don't show up until things start getting complicated. (It's a sign of this weakness that in Ruby you see the workaround of faking up an assignment to force declaration of a variable.)

I dislike the implicit declaration of lexicals because it tends to defeat the primary use of them, namely, catching typos. It's just too easy to declare additional variable names by accident. It's also too easy to broaden the scope of a variable by accident. You might have a bunch of separate subroutines each with their own lexical, and suddenly find that they're all the same variable because you accidentally used the same variable name in the module initialization code.

When you think about it, requiring my on declaration is a form of orthogonality. Otherwise you find your default scoping rules arbitrarily tied to an inner scope, or an outer scope, or a subroutine scope. All of these are suboptimal choices. And I don't buy the notion of using my optionally to disambiguate when you feel like it. Perl gives you a lot of rope to hang yourself with, but this is the wrong kind of rope, because it obscures a needful visual distinction. Declarations should look like declarations, not just to the programmer, but also to whoever has to read the program after them, whether carbon-based or silicon-based.

And when it comes down to it, I believe that declarations with my are properly Huffman encoded. Declaring a lexical ought to be harder than assigning to one. And declaring a global ought to be harder than declaring a lexical (at least within classes and modules).

RFC 119: Object neutral error handling via exceptions

Good goals, but I don't want yet another independent system of exception handling. Simplicity comes through unification. Also, the proposed syntax is all just a little too intertwingled for my tastes. Let's see, how can I explain what I mean?

The out-of-band stuff doesn't stand out visually enough to me, and I don't like thinking about it as control flow. Nevertheless, I think that what we've ended up with solves a number of the problems pointed out in this RFC. The RFC essentially asks for the functionality of POST, KEEP and UNDO at a statement level. Although POST, KEEP, and UNDO blocks cannot be attached to any statement, I believe that allowing post, keep, and undo properties in scoped declarations is powerful enough, and gives the compiler something tangible to attach the actions to. There is a kind of precision in attaching these actions to a specific variable--the state is bound to the variable in a transactionally instantaneous way. I'm afraid if we attach transactional actions to statements as the RFC proposes, it won't be clear exactly when the statement's state change is to be considered successful, since the transaction can't "know" which operation is the crucial one.

Nonetheless, some ideas from this RFC will live on in the post, keep, and undo property blocks.

RFC 120: Implicit counter in for statements, possibly $#.

I am prejudiced against this one, simply because I've been burned too many times by implicit variables that mandate implicit overhead. I think if you need an index, you should declare one, so that if you don't declare one, the compiler knows not to bother setting up for it.

Another problem is that people will keep asking what

    for (@foo,@bar) { print $# }

is supposed to mean.

I expect that we'll end up with something more like what we discussed earlier:

    for @array.kv -> $i, $elem { ... }

RFC 262: Index Attribute

Everyone has a use for : these days...

This one seems not to be of very high utility, suffering from similar problems as the RFC 120 proposal. I don't think it's possible to efficiently track the container of a value within each contained object unless we know at compile time what a looping construct is, which is problematic with user-defined control structures.

And what if an item is a member of more than one list?

Again, I'd rather have something declared so we know whether to take the overhead. Then we don't have to pessimize whenever we can't do a complete static analysis.

RFC 167: Simplify do BLOCK Syntax

I think the "do" on a do block is useful to emphasize that the closure in the braces is to be executed immediately. Otherwise Perl (or the user (or both)) might be confused as to whether someone was trying to write a closure that is to be executed later, particularly if the block is the last item in a subroutine that might be wanting to return a closure. In fact, we'll probably outlaw bare blocks at the statement level as too ambiguous. Use for 1 {} or some such when you want a one-time loop, and use return or sub when you want to return a closure.

We'll solve the ; problem by jiggering the definition of {...}, not by fiddling with do.

RFC 209: Fuller integer support in Perl.

The old use integer pragma was a hack. I think I'd rather use types and representation specs on individual declarations for compile-time selection, or alternate object constructors for run-time selection, particularly when infinite precision is desired. I'm not against using pragmas to alter the defaults, but I think it's generally better to be more specific when you have the capability. You can force your programs to be lexically scoped with pragmas, but data wants to flow wherever it likes to go, so your lexically scoped module had better be able to deal rationally with any data thrown at it, even if it isn't in the exact form that you prefer.

By the way, the RFC is misleading when it asserts that 32-bit integer precision is lost when represented in floating point. That's only true if you use 32-bit floats. Perl has always used 64-bit doubles, which give approximately 15 digits of integer precision. (The issue does arise with 64-bit integers, of course.)

All that being said, Perl 6 will certainly have better support for integer types of various sorts. I just don't think that a pragma redefining what an "integer" is will provide good documentation to whoever is trying to understand the program. Better to declare things of type MagicNum, or whatever.

I could be wrong, of course. If so, write your pragma, and have the appropriate amount of fun.

RFC 279: my() syntax extensions and attribute declarations

We already treated this in Apocalypse 2.

The RFC assumes that the type always distributes over a my list. This is not what is necessary for function signatures, which need individual types for each formal argument.

And again, it doesn't make much sense to me to put properties on a variable at run-time.

It makes even less sense to me to be able to declare the type of an array element lexically. This is the province of objects, not arrays pretending to be structs.

RFC 297: Attributes for compiler hints

Sorry, we can't have the semantics suddenly varying drastically merely because the user decided to run the program through a different translator. I think there's a happy medium in there somewhere where we can have the same semantics for both interpreter and compiler.

RFC 309: Allow keywords in sub prototypes

This RFC is rejected only because it doesn't go far enough. What we'll eventually need is to allow a regex-ish syntax notation for parsing that may be separate from the argument declarations. (Then again, maybe not.) In any event, I think some kind of explicit regex notation is called for, not the promotion of identifiers to token matchers. We may want identifiers in signatures for something else later, so we'll hold them in reserve.

RFC 340: with takes a context

This seems like a solution in search of a problem. Even if we end up with a context stack as explicit as Perl 5's, I don't think the amount we'll deal with it warrants a keyword. (And I dislike "return with;" as a needlessly opaque linguistic construct.)

That being said, if someone implements (as user-defined code) the Pascalish with as proposed in RFC 342 (and rejected), and if the caller function (or something similar) returns sufficient information to build references to the lexical scope associated with the call frame in question, then something like this could also be implemented as user code. I can't decide whether it's not clear that this is a good idea, or it's clear that this is not a good idea. In any event, I would warn anyone doing this that it's likely to be extremely confusing, akin to goto-considered-harmful, and for similar reasons, though in this case by displacing scopes rather than control flow.

Note that some mechanism resembling this will be necessary for modules to do exportation to a lexical scope (see %MY in Apocalypse 2). However, lexical scope modification will be allowed only during the compile time of the lexical scope in question, since we need to be careful to preserve the encapsulation that lexical scoping provides. Turning lexical variables back into dynamic variables will tend to destroy that security.

So I think we'll stick with closures and continuations that don't transport lexical scopes at runtime.

RFC 342: Pascal-like "with"

I expect Perl's parsing to be powerful enough that you could write a "with" if you wanted one.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow