AUTLOAD and $_

4 views
Skip to first unread message

Sam Vilain

unread,
Jun 19, 2005, 8:54:00 PM6/19/05
to Perl6 Language List
From S10;

In any case, there is no longer any magical $AUTOLOAD variable. The
name being declared or defined can be found in $_ instead. The name
does not include the package name. You can always get your own package
name with $?PACKAGENAME.

So, what is the prototype of AUTOLOAD? It is clearly called from the
relevant (package dispatcher & type & perl5_compat(stash) ) object, but
how?

sub AUTOLOAD($_ = $CALLER::$_, *@_) {
...
}

In a way, $_ forms part of the prototype definition, but is "out of band"
to the regular arguments on @_; it can't interfere with positional
characteristics, or you have to "shift" it off before you goto the right
sub.

OK, we could play tricks with localization of variables, but in the face
of continuations and coroutines, localization falls apart. This is fine
for people writing `ordinary´ code (perhaps), but for a core language
feature it should be resolved IMHO.

Out-of-band arguments seem to have been a hot topic in the past;

http://xrl.us/ggt7 - Long (50+ posts) thread

http://xrl.us/ggua - suggestion from Damian;

$foo = sub { print $_ } is given($_);

I actually quite like that syntax, or at least the idea of using a trait
of some kind to specify non-positional arguments. It keeps them well
out of the way of `safe´ programming conventions :).

In fact, it has to do wierder things than just accept it out of band to
parameters - ideally it would not also interfere with another sub that
uses $CALLER::_.

Perhaps to avoid that mess, the AUTOLOAD function is simply expected to
call &func.goto if it wants all the effects of the presence of the
AUTOLOAD sub to go away. Assuming that the prototype is re-checked on a
goto, to ensure that type guarantees specified in the function signature
are honoured, then the necessary side effects should just happen.

Sam.

Juerd

unread,
Jun 20, 2005, 6:17:30 AM6/20/05
to Juerd, Sam Vilain, Perl6 Language List
Juerd skribis 2005-06-20 12:11 (+0200):
> sub AUTOLOAD ($w) { return our &::($w) = get_subref_for $w }
> sub AUTOLOAD { our &::($^a) = get_subref_for $^a }

That's :=, of course.


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Juerd

unread,
Jun 20, 2005, 6:11:47 AM6/20/05
to Sam Vilain, Perl6 Language List
Sam Vilain skribis 2005-06-20 12:54 (+1200):

> sub AUTOLOAD($_ = $CALLER::$_, *@_) {
> In a way, $_ forms part of the prototype definition, but is "out of band"
> to the regular arguments on @_; it can't interfere with positional
> characteristics, or you have to "shift" it off before you goto the right
> sub.
(...)

> Perhaps to avoid that mess, the AUTOLOAD function is simply expected to
> call &func.goto if it wants all the effects of the presence of the
> AUTOLOAD sub to go away. Assuming that the prototype is re-checked on a
> goto, to ensure that type guarantees specified in the function signature
> are honoured, then the necessary side effects should just happen.

I think there exists an even simpler way to avoid any mess involved.
Instead of letting AUTOLOAD receive and pass on arguments, and instead
of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
thing, and then have *perl* call the sub?

sub AUTOLOAD ($whatever) { # but no *@_
my $s = get_subref_for $whatever;
our &::($whatever) := $s;
return $s; # non-subref indicates failure
}

If you want to load it again each time, remove the := line.

The line can be shortened to

sub AUTOLOAD ($w) { return our &::($w) = get_subref_for $w }

or just

sub AUTOLOAD { our &::($^a) = get_subref_for $^a }

Re arguments: I think a single positional argument makes more sense than
requiring that its name be $_.

Sam Vilain

unread,
Jun 20, 2005, 5:42:07 PM6/20/05
to Juerd, Perl6 Language List
Juerd wrote:
> I think there exists an even simpler way to avoid any mess involved.
> Instead of letting AUTOLOAD receive and pass on arguments, and instead
> of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
> thing, and then have *perl* call the sub?
> sub AUTOLOAD ($w) { return our &::($w) := get_subref_for $w }

I like that. Makes it more consistent with the AUTOSCALAR, etc methods -
returning a reference to the result (variable ref/code ref/sub name) rather
than the actual result (variable value/calling the sub).

After all, presumably the compiler might sometimes call the AUTOLOAD at
compile time; to get its signature. So, for instance, you could AUTOLOAD
all the methods you optionally export, which are all pulled in at once when
a module imports a function and tries to use it in some code (as the
signature will need to be checked then). I was going to bring that up
next, but I think this has already answered it.

Sam.

Chromatic

unread,
Jun 20, 2005, 5:56:31 PM6/20/05
to Juerd, Perl6 Language List
On Mon, 2005-06-20 at 12:11 +0200, Juerd wrote:

> I think there exists an even simpler way to avoid any mess involved.
> Instead of letting AUTOLOAD receive and pass on arguments, and instead
> of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
> thing, and then have *perl* call the sub?

Who says AUTOLOAD will always either call a loaded sub or fail?

-- c

Luke Palmer

unread,
Jun 20, 2005, 6:37:31 PM6/20/05
to chromatic, Juerd, Perl6 Language List

Uh, what else can it do? It doesn't have to load a sub to return a
code reference.

Luke

Sam Vilain

unread,
Jun 20, 2005, 6:04:18 PM6/20/05
to chromatic, Juerd, Perl6 Language List
chromatic wrote:
> Who says AUTOLOAD will always either call a loaded sub or fail?

Maybe it should be passed a continuation too, then? Then it could
choose exactly what to do with it.

Sam.

Juerd

unread,
Jun 20, 2005, 6:50:22 PM6/20/05
to chromatic, Perl6 Language List
chromatic skribis 2005-06-20 14:56 (-0700):

> Who says AUTOLOAD will always either call a loaded sub or fail?

I don't recall any clearl spec of Perl 6's AUTOLOAD. If there is
something I missed, say so and please do provide example code. Questions
like the one quoted tend to irritate me.

There is almost always either success or failure. Programming would get
very hard if it weren't as black and white as that, at this level. If
there is anything in between success and failure, indicating success is
probably still the better idea in such cases.

Returning a closure avoids having to lookup the sub again before it is
executed, and it allows for not installing the sub, so that AUTOLOAD is
called again, the next time the same name is used. It also allows doing
nothing: just return sub { }.

I don't think there is anything that this setup cannot do, but I do
think this way is necessary. Because context is dictated by signature,
and signature may not be known for a not-yet loaded sub, AUTOLOAD has to
be called before the arguments are evaluated. Because they're not
evaluated, they cannot be passed, and they cannot be used by AUTOLOAD to
be fed to the (supposedly) newly loaded sub.

Chromatic

unread,
Jun 20, 2005, 6:58:46 PM6/20/05
to Luke Palmer, Juerd, Perl6 Language List

I think:

class NullObject
{
sub AUTOLOAD {}
}

is better than:

class NullObject
{
sub AUTOLOAD { return sub {} }
}

Or have I misunderstood the proposal and the purpose of AUTOLOAD?

-- c

Juerd

unread,
Jun 20, 2005, 7:22:58 PM6/20/05
to chromatic, Perl6 Language List
chromatic skribis 2005-06-20 15:58 (-0700):
> I think:

> sub AUTOLOAD {}
> is better than:
> sub AUTOLOAD { return sub {} }

It's nicer to type, but I think that your preferred syntax means that
the AUTOLOAD sub itself has to call any loaded code, which can mean that it
has to fit arbitrary given arguments to an arbitrary signature, which I
think is way too hard.

One alternative, that I don't like, is to ignore non-subref returns, but
call a returned subref. Then something else has to indicate failure, and
that thing is probably fail. The problem that I have with that is that
you lose the free verbose, clear and standard error message you could
otherwise have. Unless fail here uses a default that isn't $_ or $!, and
I do not like special cases like that.

Note that as long as empty closures can be typed without the sub
keyword, and the return keyword is optional for the last statement, the
following is perhaps a syntactically more satisfying solution for you:

sub AUTOLOAD {{}}

If I understand things correctly, a null closure will have such small
overhead that you can pass it around just as freely as integers. Of
course, calling the empty closure can be optimized away, although I hope
I also understand correctly that the overhead of calling something is
also so drastically reduced since Perl 5, that {}() is not much heavier
than do {} or the null statement between two semicolons: ;;.

> Or have I misunderstood the proposal and the purpose of AUTOLOAD?

Well, the purpose I think you have misunderstood, as your example
doesn't LOAD anything. But then, I have always thought AUTOLOAD was a
bad name, because it is so much more powerful than that. Perhaps
DEFAULT, FALLBACK or MISSINGSUB would be more appropriate.

I also don't see the symmetry between AUTOLOAD and AUTOMETH. Two things
bother be about that: LOAD versus METH, while it should be SUB versus
METH, and that METHOD is abbreviated while in the method keyword it is
not. Either it should be abbreviated everywhere: meth foo { ... }, or
nowhere: AUTOMETHOD. I personally like the "meth foo { ... }".

Rod Adams

unread,
Jun 20, 2005, 8:09:42 PM6/20/05
to Juerd, Perl6 Language List
Juerd wrote:

>I also don't see the symmetry between AUTOLOAD and AUTOMETH. Two things
>bother be about that: LOAD versus METH, while it should be SUB versus
>METH, and that METHOD is abbreviated while in the method keyword it is
>not. Either it should be abbreviated everywhere: meth foo { ... }, or
>nowhere: AUTOMETHOD. I personally like the "meth foo { ... }".
>
>
>
>

S10 talks about how it is AUTOSUB vs AUTOMETH (and others), but AUTOLOAD
is still around. S10 doesn't mention it, but I think it's been said that
AUTOLOAD only gets called as a last resort.

S10 also mentions that the 'goto' is implicit. I think I like the return
of a ref better, since you're not always going to want to build the
function out and store it. But the call can be hijacked, so I guess
that's okay.

-- Rod Adams

John Macdonald

unread,
Jun 20, 2005, 8:19:42 PM6/20/05
to Luke Palmer, chromatic, Juerd, Perl6 Language List

I recall Damian using AUTOLOAD (in perl5) to evaluate the
result of the function call without loading a function with the
given name. This was to allow arbitrary names to be invoked,
when the same name is unlikely to be used again. This was
basically a method that took a string contant argument, but
it used the method name as the constant and didn't need to
specify a name for the actual ccmmon method.

I'm not certain that this is actually a worth supporting, it's
more of a golf/obfuscation technique than a significant tool,
unless there are additional clever uses of the technique that
go beyond this basic trick.

--

Adam Kennedy

unread,
Jun 20, 2005, 10:10:32 PM6/20/05
to perl6-l...@perl.org
> I think there exists an even simpler way to avoid any mess involved.
> Instead of letting AUTOLOAD receive and pass on arguments, and instead
> of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
> thing, and then have *perl* call the sub?
>
> sub AUTOLOAD ($whatever) { # but no *@_
> my $s = get_subref_for $whatever;
> our &::($whatever) := $s;
> return $s; # non-subref indicates failure
> }

You are of course assuming that every use of AUTOLOAD, for all time,
will result in

a) Calling another function
b) An error

Wouldn't this lead to hacks where people do things like this just to
prevent perl thinking it's a failure?

sub AUTOLOAD ($whatever) { # but no *@_
my $s = get_subref_for $whatever;
our &::($whatever) := $s;

return sub () { 1 };
}

The ability to get complete control over the params and context of the
function, and maybe run something else AFTER the function call is important.

So I suspect there might be some false economy in this optimisation.

Adam K

Luke Palmer

unread,
Jun 21, 2005, 9:35:27 AM6/21/05
to Adam Kennedy, perl6-l...@perl.org
On 6/21/05, Adam Kennedy <cp...@ali.as> wrote:
> You are of course assuming that every use of AUTOLOAD, for all time,
> will result in
>
> a) Calling another function
> b) An error
>
> Wouldn't this lead to hacks where people do things like this just to
> prevent perl thinking it's a failure?
>
> sub AUTOLOAD ($whatever) { # but no *@_
> my $s = get_subref_for $whatever;
> our &::($whatever) := $s;
> return sub () { 1 };
> }
>
> The ability to get complete control over the params and context of the
> function, and maybe run something else AFTER the function call is important.

I think people are being pretty closed-minded about closures. If it
comes down to it, you can always get your good old Perl 5 AUTOLOAD
like this:

sub AUTOLOAD ($whatever) { sub (*@_) {
...
} }

Luke

Juerd

unread,
Jun 21, 2005, 12:05:52 PM6/21/05
to Adam Kennedy, perl6-l...@perl.org
Adam Kennedy skribis 2005-06-21 12:10 (+1000):

> You are of course assuming that every use of AUTOLOAD, for all time,
> will result in
> a) Calling another function
> b) An error

That is more or less what it's for. Do note that this other function
that is called can be entirely statementless, thus a no-op.

> Wouldn't this lead to hacks where people do things like this just to
> prevent perl thinking it's a failure?

There is nothing we can do to prevent dumb programmers from doing dumb
things, except dropping lots of features and operators. But if we wanted
that, adding lexicals and closures to PHP would probably be easier.

> sub AUTOLOAD ($whatever) { # but no *@_
> my $s = get_subref_for $whatever;
> our &::($whatever) := $s;
> return sub () { 1 };

Then the subref will not be executed, and the bug will very quickly be
discovered. I don't see any problem with this.

There are also people who don't understand that TIE* methods should
return objects, because they are constructors. Has this ever been a
great problem?

If there is a fixed interface that makes sense and is documented, people
not following it are either really dumb or very clever.

> The ability to get complete control over the params and context of the
> function, and maybe run something else AFTER the function call is important.

I disagree. In that case you should be using a wrapper or a macro. A
wrapper you can simply return, but I find it very bad style to install
foo and then run foo plus something else. And if you don't install foo
(with &foo := ...), you can do whatever you want anyway, by putting
whatever you want in the closure.

> So I suspect there might be some false economy in this optimisation.

It's not an optimization. It's necessary, unless there is a way to
receive arguments in unknown context, which is a bit of complexity and
complication we can very easily avoid needing.

Chromatic

unread,
Jun 21, 2005, 12:23:16 PM6/21/05
to Luke Palmer, p6l
On Tue, 2005-06-21 at 13:35 +0000, Luke Palmer wrote:

> I think people are being pretty closed-minded about closures.

I'm pretty closed-minded about writing code that does nothing to prevent
the language from doing the wrong thing by default. I already have a
fantastic way to write code that does nothing: I don't write it.

Maybe I don't really want AUTOLOAD, though. Juerd's MISSINGSUB (or
whatever the name is) has some merit, especially from a "better name for
what I want to do" perspective.

-- c

Juerd

unread,
Jun 21, 2005, 12:52:49 PM6/21/05
to chromatic, Luke Palmer, p6l
chromatic skribis 2005-06-21 9:23 (-0700):

> I already have a fantastic way to write code that does nothing: I
> don't write it.

Just add braces around the thing you don't write.

Larry Wall

unread,
Jun 21, 2005, 8:55:15 PM6/21/05
to Perl6 Language List
On Mon, Jun 20, 2005 at 07:09:42PM -0500, Rod Adams wrote:
: S10 talks about how it is AUTOSUB vs AUTOMETH (and others), but AUTOLOAD
: is still around. S10 doesn't mention it, but I think it's been said that
: AUTOLOAD only gets called as a last resort.

Really, the only point of keeping AUTOLOAD around is to make it easier
to translate Perl 5 to Perl 6. AUTOSUB and friends have the spiffy
reference-returning semantics everyone wants. I'd like the translator
to be able to turn "goto &foo" into "&foo.tailcall" or some such,
and otherwise leave AUTOLOAD alone.

Larry

Rod Adams

unread,
Jun 21, 2005, 9:08:25 PM6/21/05
to Perl6 Language List
Larry Wall wrote:

Should we then perhaps rename it to: DEPRECATED_PERL5_AUTOLOAD ?

-- Rod Adams

Juerd

unread,
Jun 22, 2005, 6:47:27 AM6/22/05
to Maxim Sloyko, perl6-l...@perl.org
Maxim Sloyko skribis 2005-06-22 14:27 (+0400):
> Can we do "return undef" in this case? I mean. can undef mean a no-op
> in subref context?

That's a rather false value. I hope undef is not executable. It's a much
better idea to special case empty closures, IMO.

Maxim Sloyko

unread,
Jun 22, 2005, 6:27:11 AM6/22/05
to perl6-l...@perl.org
Juerd wrote:

>> sub AUTOLOAD ($whatever) { # but no *[at]_


>> my $s = get_subref_for $whatever;
>> our &::($whatever) := $s;
>> return sub () { 1 };
>
> Then the subref will not be executed, and the bug will very quickly be
> discovered. I don't see any problem with this.
>

Can we do "return undef" in this case? I mean. can undef mean a no-op
in subref context?

--
Maxim Sloyko

Chromatic

unread,
Jun 22, 2005, 12:29:05 PM6/22/05
to Rod Adams, Perl6 Language List
On Tue, 2005-06-21 at 20:08 -0500, Rod Adams wrote:

> Should we then perhaps rename it to: DEPRECATED_PERL5_AUTOLOAD ?

Poster 1: I hate it!

Poster 2: I love it!

Poster 3: How about PERL_5_AUTOLOAD_DO_NOT_USE?

Poster 4: That's a stupid feature to add!

Poster 5: That's too much to type! Isn't there a two character
combination somewhere?

Poster 6: Shouldn't that be a module somewhere?

Poster 7: Shouldn't that be a macro?

chromatic: It's ugly. I'll never use it.

Damian: Good. That's the point.

chromatic: That was a straight line.

-- c

Juerd

unread,
Jun 22, 2005, 6:46:25 AM6/22/05
to Rod Adams, Perl6 Language List
Rod Adams skribis 2005-06-21 20:08 (-0500):

> Should we then perhaps rename it to: DEPRECATED_PERL5_AUTOLOAD ?

That sounds like a good idea. In fact, a pragma to enable it would not
be a bad idea either, IMO.

Piers Cawley

unread,
Jun 23, 2005, 11:28:38 AM6/23/05
to Luke Palmer, chromatic, Juerd, Perl6 Language List
Luke Palmer <lrpa...@gmail.com> writes:

For myself, I'd like to see AUTOLOAD with a signature along the lines of:

sub AUTOLOAD (Symbol $sym, ArgumentCollection $args, Continuation $cc)
returns (Code | Pair)
{
...
}

This presupposes a deal of support infrastructure, but also provides
flexibility. For the 'NullObject' case, you'd simply do C<$cc()> to return
directly to the caller, skipping over whatever Perl is up to.

'ArgumentCollection'? Well, that's the activation record and I'd like to see it
allowing methods like:

my ($foo, $bar, $baz) =
$args.parse_signature('Int $foo, String $bar, Code $baz')

That way code could probe the argument structure in order to do its own
dispatch.

As for returning a coderef or a pair. If you return a coderef, Perl simply
calls it and throws it away. Returning a pair, with a name (long or short) as
the key and the code as the value would make perl bind the code to the given
name (which should be compatible with the name passed in in the first place).

Details left as an exercise for the interested reader.

Sam Vilain

unread,
Jun 26, 2005, 7:51:50 PM6/26/05
to Piers Cawley, Luke Palmer, chromatic, Juerd, Perl6 Language List
Piers Cawley wrote:
> For myself, I'd like to see AUTOLOAD with a signature along the lines of:
> sub AUTOLOAD (Symbol $sym, ArgumentCollection $args, Continuation $cc)
> returns (Code | Pair)
> {
> ...
> }
> This presupposes a deal of support infrastructure, but also provides
> flexibility. For the 'NullObject' case, you'd simply do C<$cc()> to return
> directly to the caller, skipping over whatever Perl is up to.

That's an excellent suggestion. After your very enlightening discussion
about continuations in IRC, this popped to mind as an interesting application
for them, along with exception handlers.

This would be great for at least AUTOSUB and AUTOMETH.

However, for AUTOLOAD we're looking for simple Perl 5 alikeness. And in
Perl 5, the sub name was passed out of band.

So, we need a compromise somewhere, please @cabal.pick:

- just go for old AUTOLOAD + $AUTOLOAD interface and spit warnings
profusely
-OR-
{
- allow topic to refer to variables in lexical scope, but not in @_
(and pick a good name for $?SUB.called_as)
-OR-
- allow generic out-of-band parameters to be passed in
}
implies {
- there needs to be a special subroutine calling method, similar to
.assuming that lets you do this
-OR-
- the method prototype, and specify some way that methods
defined without a signature can inherit it from somewhere else.
}
-OR-
- declare the topic to be the only out-of-band parameter that does this.
To avoid it being an accidental global, it would need to be declared with
"my $_" when used in this manner (of course, other methods like for, given,
etc that set it have the declaration implicit).
-OR-
- scrap complete AUTOLOAD interface compatibility
-OR-
- insert solution here ;)

Sam.

Reply all
Reply to author
Forward
0 new messages