lexical subs

3 views
Skip to first unread message

H.Merijn Brand

unread,
Mar 9, 2007, 2:45:15 AM3/9/07
to Perl5 Porters
Now that we have lexical $_, why not lexical subs

if ($some_expression) {
sub complex_calc {
# Some very complex calculus for this lexical scope only
}
my $foo = complex_calc (.....) + complex_calc (.....);
my $bar = $foo * complex_calc (.....);
# etc
}
if ($some_similar_expr) {
sub complex_calc {
# Some very complex calculus for this lexical scope only
}
my $foo = complex_calc (.....) + complex_calc (.....);
my $bar = $foo * complex_calc (.....);
# etc
}

And guess what happens without a warning
Same if complex_calc would also have been defined outside of
the scope(s). It would be so handy and useful to be able to

if (...) {
my sub handy {
# ...
}
# ...
}
if (...) {
my sub handy {
# ...
}
# ...
}

and now have *two* functions handy () that are invisible
outside of the lexical scope.

This would also be an ideal solution to hide private
functions and methods inside modules.

feasible? useful? doable?

--
H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using & porting perl 5.6.2, 5.8.x, 5.9.x on HP-UX 10.20, 11.00, 11.11,
& 11.23, SuSE 10.0 & 10.2, AIX 4.3 & 5.2, and Cygwin. http://qa.perl.org
http://mirrors.develooper.com/hpux/ http://www.test-smoke.org
http://www.goldmark.org/jeff/stupid-disclaimers/

Dr.Ruud

unread,
Mar 9, 2007, 4:10:54 AM3/9/07
to perl5-...@perl.org
"H.Merijn Brand" schreef:

> Now that we have lexical $_, why not lexical subs
>
> if ($some_expression) {
> sub complex_calc {
> # Some very complex calculus for this lexical scope only
> }
> my $foo = complex_calc (.....) + complex_calc (.....);
> my $bar = $foo * complex_calc (.....);
> # etc
> }
> if ($some_similar_expr) {
> sub complex_calc {
> # Some very complex calculus for this lexical scope only
> }
> my $foo = complex_calc (.....) + complex_calc (.....);
> my $bar = $foo * complex_calc (.....);
> # etc
> }

There already is $complex_calc->(), which can be used well for above
example. But that just makes the example bad; lexical subs would be
great to have.

--
Affijn, Ruud

"Gewoon is een tijger."

H.Merijn Brand

unread,
Mar 9, 2007, 4:39:41 AM3/9/07
to perl5-...@perl.org
On Fri, 9 Mar 2007 10:10:54 +0100, "Dr.Ruud" <rvtol...@isolution.nl> wrote:

> "H.Merijn Brand" schreef:
>
> > Now that we have lexical $_, why not lexical subs
> >
> > if ($some_expression) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> > if ($some_similar_expr) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
>
> There already is $complex_calc->(), which can be used well for above

Which is what I used

> example. But that just makes the example bad; lexical subs would be
> great to have.

Rafael said that the parser already knows how to do it, but added:
"but nobody figured out what to make with that" :)
Now I hope my example just makes enough sense to someone to just
make it happen.

Tels

unread,
Mar 9, 2007, 5:47:28 AM3/9/07
to perl5-...@perl.org, H.Merijn Brand
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 09 March 2007 07:45:15 H.Merijn Brand wrote:
> Now that we have lexical $_, why not lexical subs
>
> if ($some_expression) {
> sub complex_calc {
> # Some very complex calculus for this lexical scope only
> }
> my $foo = complex_calc (.....) + complex_calc (.....);
> my $bar = $foo * complex_calc (.....);
> # etc
> }
> if ($some_similar_expr) {
> sub complex_calc {
> # Some very complex calculus for this lexical scope only
> }
> my $foo = complex_calc (.....) + complex_calc (.....);
> my $bar = $foo * complex_calc (.....);
> # etc
> }
>
> And guess what happens without a warning
> Same if complex_calc would also have been defined outside of
> the scope(s). It would be so handy and useful to be able to

I really don't like the idea of having two subroutines with the same name,
this makes code only more confusing.

You can always do the equivalent of:

$complex_calc = sub { ... };

$foo = $complex_calc->(123) + $complex_calc->(124);

so would this scheme only save you writing the "$" and the "->"?

All the best,

Tels

- --
Signed on Fri Mar 9 10:10:11 2007 with key 0x93B84C15.
View my photo gallery: http://bloodgate.com/photos
PGP key on http://bloodgate.com/tels.asc or per email.

"Don't worry about people stealing your ideas. If your ideas are any
good, you'll have to ram them down people's throats."

-- Howard Aiken
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRfE7QHcLPEOTuEwVAQJb5wf5AQ2juENVmfqORKPePmm2QPeuk0BWadun
WWNHCjpuLznb2bZB0BcoAYheLM5vya6O2BclC7K21mVdO0phG9zRUsqR0bDjFdcM
njxb+fih0Af7e1c1L8aY0dLJglMYB3IOa6fjQn2nbHyoqGwdUTRCh3dzyWzvs4OW
XOIekrRAXkBjmTDN0hqX9SjtxS2Hdy8WupS+pwNU+pajB6ffmTfJPhL7V+UlQIJa
3tJTR8+XwZO6Tk47TofeYM/oP7G2WWJp4zHNUkTtJcqk7M10YvgmWo+Ny44FCV3R
RA36FlXcK3TOp4ua+D69Izplv6bkIfXKqiCFQ/uyENelExuWYt7p/w==
=6Rdx
-----END PGP SIGNATURE-----

Johan Vromans

unread,
Mar 9, 2007, 5:03:54 AM3/9/07
to Tels, perl5-...@perl.org, H.Merijn Brand
Tels <nospam...@bloodgate.com> writes:

> I really don't like the idea of having two subroutines with the same
> name, this makes code only more confusing.

... unless they're lexical.

I assume you're not bothered by multiple occurrances of a lexical $i
or so?

-- Johan

H.Merijn Brand

unread,
Mar 9, 2007, 5:02:46 AM3/9/07
to perl5-...@perl.org
On Fri, 9 Mar 2007 10:47:28 +0000, Tels <nospam...@bloodgate.com> wrote:
> On Friday 09 March 2007 07:45:15 H.Merijn Brand wrote:
> > Now that we have lexical $_, why not lexical subs
> >
> > if ($some_expression) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> > if ($some_similar_expr) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> >
> > And guess what happens without a warning
> > Same if complex_calc would also have been defined outside of
> > the scope(s). It would be so handy and useful to be able to
>
> I really don't like the idea of having two subroutines with the
> same name, this makes code only more confusing.

You're free to use it, or not. Just like with most features

> You can always do the equivalent of:
>
> $complex_calc = sub { ... };
>
> $foo = $complex_calc->(123) + $complex_calc->(124);

Of course, and - as said, that is what I had to use right now,
but not only is it ugly (it looks like OO where it isn't), but
also stupid if you think about what you wanted.

> so would this scheme only save you writing the "$" and the "->"?

Though the gain in less keystrokes is a plus, this is not the
motivation to ask for it.

Abigail

unread,
Mar 9, 2007, 5:22:21 AM3/9/07
to Tels, perl5-...@perl.org, H.Merijn Brand
On Fri, Mar 09, 2007 at 10:47:28AM +0000, Tels wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Moin,
>
> On Friday 09 March 2007 07:45:15 H.Merijn Brand wrote:
> > Now that we have lexical $_, why not lexical subs
> >
> > if ($some_expression) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> > if ($some_similar_expr) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> >
> > And guess what happens without a warning
> > Same if complex_calc would also have been defined outside of
> > the scope(s). It would be so handy and useful to be able to
>
> I really don't like the idea of having two subroutines with the same name,
> this makes code only more confusing.

How's that different from having two variables with the same name?

> You can always do the equivalent of:
>
> $complex_calc = sub { ... };
>
> $foo = $complex_calc->(123) + $complex_calc->(124);
>
> so would this scheme only save you writing the "$" and the "->"?

Yes, and? If that would be the enough reason not to add something to
Perl, Perl wouldn't be as rich as it is.

Abigail

Tels

unread,
Mar 9, 2007, 6:25:34 AM3/9/07
to perl5-...@perl.org, Johan Vromans, H.Merijn Brand
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 09 March 2007 10:03:54 Johan Vromans wrote:
> Tels <nospam...@bloodgate.com> writes:
> > I really don't like the idea of having two subroutines with the same
> > name, this makes code only more confusing.
>
> ... unless they're lexical.

? if you have lexical and global subroutines, then the line:

$foo = complex_calc() + complex_calc();

cannot examined without checking the lexical scope to see what sort of
complex_calc() is actually called. Computers are very good at this, but
humans are not.

(I disregard the (ab)use of toying around with *complex_calc here for a
moment)

> I assume you're not bothered by multiple occurrances of a lexical $i
> or so?

Usually, $i is lexical. Globals are rare, and generally regarded as bad.

So in:

$foo = complex_calc() + complex_calc();

is very likely that $foo is a lexical. (Yes, I wish you wouldn't have people
adding global $foos - but that is another matter :)

At least now you know that a variable can be lexical or global (although
globals are usually regared as a bad idea), but subroutines are
always "global" so to speak.

So in praxis you end up with a lot of lexical variables, and some globals
(or lots, in bad code) and file-scoped sub routines.

If you can have lexical subroutines, well, it's one more way to write the
same code, slightly different. I am not sure it is really nec. to invent
YetAnotherWayToDoIt.

As for the "you dont have to use it" - no, but I will eventually have to
maintain code that (ab)uses it. :-)

So far, this new feature looks like a solution in search of a problem.

Of course, that never has stopped anyone :) So Don't let my opinion get in
the way of adding Cool New Features[tm] :-)

All the best,

Tels

- --
Signed on Fri Mar 9 11:16:52 2007 with key 0x93B84C15.


View my photo gallery: http://bloodgate.com/photos
PGP key on http://bloodgate.com/tels.asc or per email.

"A bus station is where a bus stops. A train station is where a train
stops. On my desk I have a work station."

-- Unknown


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRfFELncLPEOTuEwVAQLdSAf9Ha17BwX9oCTq0NOA8gmHnWsPUjgxn9aZ
y0zUwAVQ416I2mkyN7KmESSX4FXJMcgn0Q8d2LG7w4aXKf03nljnr16qHR4yFQ0o
b9yeLZrl26SsWXWYVhMAhOm1h8mog42wtqftNS4iuK3GuJfldJoE9AL+gMMqO3KT
0orR16wtPKdFkEI22uXf3RRA3jVwzIbsBxY6XLmSLbdZ/3V2fQDDg7q76GlQTUAa
2L5zRtJ426AiZhNDKy7xUGkl/ZPVD8oauMPRM450MXYfkUdDq8HvLXLx4tA6nJTu
uxsrp76Lwoc+jqEZvDSkQOsL2BHz4G+W/kMXnEYhdornJNi5aLQemQ==
=9hfG
-----END PGP SIGNATURE-----

Demerphq

unread,
Mar 9, 2007, 5:39:30 AM3/9/07
to Tels, H.Merijn Brand, perl5-...@perl.org
On 3/9/07, Tels <nospam...@bloodgate.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Moin,
>
> On Friday 09 March 2007 07:45:15 H.Merijn Brand wrote:
> > Now that we have lexical $_, why not lexical subs
> >
> > if ($some_expression) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> > if ($some_similar_expr) {
> > sub complex_calc {
> > # Some very complex calculus for this lexical scope only
> > }
> > my $foo = complex_calc (.....) + complex_calc (.....);
> > my $bar = $foo * complex_calc (.....);
> > # etc
> > }
> >
> > And guess what happens without a warning
> > Same if complex_calc would also have been defined outside of
> > the scope(s). It would be so handy and useful to be able to

Unless you can differentiate between a sub declared in a bare block
and a sub declared in a condition I think this is a non starter as it
would break anything that used a block to make a named subroutine into
a closure so as to simulate a static var.

{
my $counter;
sub next_id { return ++$counter }
}


> I really don't like the idea of having two subroutines with the same name,
> this makes code only more confusing.
>
> You can always do the equivalent of:
>
> $complex_calc = sub { ... };
>
> $foo = $complex_calc->(123) + $complex_calc->(124);
>
> so would this scheme only save you writing the "$" and the "->"?

If i understand it correctly this isnt quite right. When you want to
do a recursive subroutine with lexically scoped references to
anonymous subroutines you have to be extremely careful not to end up
with a memory leak. Using named subroutines doesn't have this problem,
so from that point of view IMO this would be an improvement.

Cheers,
yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

Tels

unread,
Mar 9, 2007, 6:34:05 AM3/9/07
to perl5-...@perl.org, Abigail, H.Merijn Brand
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Moin,

On Friday 09 March 2007 10:22:21 Abigail wrote:
> On Fri, Mar 09, 2007 at 10:47:28AM +0000, Tels wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > Moin,

[snip]


> > I really don't like the idea of having two subroutines with the same
> > name, this makes code only more confusing.
>
> How's that different from having two variables with the same name?

At least with a naked call to a subroutine, you know now it is the *one*.

$deity knows there is already twisted enough Perl code out there that we
really don't need to add more complexity. IMHO of course.

> > You can always do the equivalent of:
> >
> > $complex_calc = sub { ... };
> >
> > $foo = $complex_calc->(123) + $complex_calc->(124);
> >
> > so would this scheme only save you writing the "$" and the "->"?
>
> Yes, and? If that would be the enough reason not to add something to
> Perl, Perl wouldn't be as rich as it is.

If you have to maintain code, million little ways to write the same code are
actually not a good idea.

Global variables, (ab)usive use of $_, side effects, actions-at-a distance,
very short variable names for long stretches of code, this are all things
that make it much harder to understand the code for humans.

And I don't think piling on yet-another-way to acomplish the same is a good
idea, especially if it doesn't actually look to savemore than a few
keystrokes, but creates confusion on the wake.

However, don't let me discourage you. At least the golfers will love
it... :)

All the best,

Tels

- --
Signed on Fri Mar 9 11:25:55 2007 with key 0x93B84C15.
Get one of my photo posters: http://bloodgate.com/posters


PGP key on http://bloodgate.com/tels.asc or per email.

"...pornographic images stay in the brain forever." - Mary Anne Layden

"That's a feature, not a bug." - God

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iQEVAwUBRfFGLXcLPEOTuEwVAQLhCAf+OttQX5JVdYQim7qvWeuwoOpE1l/1OLfx
2d0r34JgUadVQKWuX1ZfwU/lMtmMhtyd2LOWOmtnWNRNJBmasm7Q62TCVF841wnN
2r+3oNbn+BneIH0HAOqlXaZ0NN9THQTxB47T1e3t7l2C/IjKeS/qTmljrPBFnP6j
pMgtkHpoBcWY0+mZHd2VLv/MYpMIlfuAyvUBKG/o/xPh3u7exgfH0IRCpjyivA0N
oa2i9sHmaCaCDptpkuFvyWdXazs5s2W7+ioBLqtFruKLwWJ1RxH9MXtSJB2bnqn6
e+ctGXZ7LdrXrx7dgOE02OC1Qdm4tjeo+qtd1CWes5u06sZDkdth5A==
=j8aI
-----END PGP SIGNATURE-----

Abigail

unread,
Mar 9, 2007, 5:41:08 AM3/9/07
to Tels, perl5-...@perl.org, Johan Vromans, H.Merijn Brand
On Fri, Mar 09, 2007 at 11:25:34AM +0000, Tels wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Moin,
>
> On Friday 09 March 2007 10:03:54 Johan Vromans wrote:
> > Tels <nospam...@bloodgate.com> writes:
> > > I really don't like the idea of having two subroutines with the same
> > > name, this makes code only more confusing.
> >
> > ... unless they're lexical.
>
> ? if you have lexical and global subroutines, then the line:
>
> $foo = complex_calc() + complex_calc();
>
> cannot examined without checking the lexical scope to see what sort of
> complex_calc() is actually called. Computers are very good at this, but
> humans are not.

And that is worse than checking the entire %INC tree for complex_calc()?

>
> (I disregard the (ab)use of toying around with *complex_calc here for a
> moment)
>
> > I assume you're not bothered by multiple occurrances of a lexical $i
> > or so?
>
> Usually, $i is lexical. Globals are rare, and generally regarded as bad.

Yes, and? I fail to see why that fact that a sub can be lexical is
confusing, while at the mean time, it's not confusing for variables.

Noone really cares whether a particular variable is lexical or global.
What matters is if I have a variable $foo and it's used in lines X and Y,
whether that's the same $foo or not. Even it's given that $foo is lexical
doesn't answer the question. Yet programmers aren't confused by that, in
fact, it's consider a *good* thing to have lexical variables.

Since it isn't confusing for variables, why would it be for subs?

Abigail

Abigail

unread,
Mar 9, 2007, 5:55:51 AM3/9/07
to Rafael Garcia-Suarez, H.Merijn Brand, Perl5 Porters
On Fri, Mar 09, 2007 at 11:46:25AM +0100, Rafael Garcia-Suarez wrote:
> On 09/03/07, H.Merijn Brand <h.m....@xs4all.nl> wrote:
> >Now that we have lexical $_, why not lexical subs
>
> From what I see in Synopsis 6, Perl 6 has lexical subs.
> The perl 5 parser has them, too :
>
> $ bleadperl -e 'my sub foo'
> "my sub" not yet implemented at -e line 1.
>
> What's missing is actually implementing them, that is, storing them in
> the pad and looking them up there. (And adding warnings when a lexical
> hides a global, etc)
> Also, if we want "my sub", we probably want "our sub" too.
> But I see no pressing need for that. Especially because I consider
> 5.10 to be almost finished :)


$ echo "lexical subs" >> perl5.14todo


;-)

Abigail

Demerphq

unread,
Mar 9, 2007, 5:53:25 AM3/9/07
to Rafael Garcia-Suarez, H.Merijn Brand, Perl5 Porters
On 3/9/07, Rafael Garcia-Suarez <rgarci...@gmail.com> wrote:
> On 09/03/07, H.Merijn Brand <h.m....@xs4all.nl> wrote:
> > Now that we have lexical $_, why not lexical subs
>
> From what I see in Synopsis 6, Perl 6 has lexical subs.
> The perl 5 parser has them, too :
>
> $ bleadperl -e 'my sub foo'
> "my sub" not yet implemented at -e line 1.
>
> What's missing is actually implementing them, that is, storing them in
> the pad and looking them up there. (And adding warnings when a lexical
> hides a global, etc)
> Also, if we want "my sub", we probably want "our sub" too.
> But I see no pressing need for that. Especially because I consider
> 5.10 to be almost finished :)

I dont think we do need an our sub. our isnt a declaration like my is,
its just a pragma for strict.

my sub foo { ... };

is apparently the same thing as

local *foo=sub { ... };

I think it might be a nice as a syntax enhancement, but i think its
potentially confusing, as it crosses the divide between dynamic and
lexical values. Maybe this could be resolved by making the syntax:

local sub foo { ... };

so the meaning is clear. Anyway, if this meme becomes common then we
will need to look into changine the method-cache as it will be spoiled
every time this code is executed.

cheers,

Rafael Garcia-Suarez

unread,
Mar 9, 2007, 5:46:25 AM3/9/07
to H.Merijn Brand, Perl5 Porters
On 09/03/07, H.Merijn Brand <h.m....@xs4all.nl> wrote:
> Now that we have lexical $_, why not lexical subs

From what I see in Synopsis 6, Perl 6 has lexical subs.

Abigail

unread,
Mar 9, 2007, 5:52:41 AM3/9/07
to Tels, perl5-...@perl.org, H.Merijn Brand
On Fri, Mar 09, 2007 at 11:34:05AM +0000, Tels wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Moin,
>
> On Friday 09 March 2007 10:22:21 Abigail wrote:
> > On Fri, Mar 09, 2007 at 10:47:28AM +0000, Tels wrote:
> > > -----BEGIN PGP SIGNED MESSAGE-----
> > > Hash: SHA1
> > >
> > > Moin,
> [snip]
> > > I really don't like the idea of having two subroutines with the same
> > > name, this makes code only more confusing.
> >
> > How's that different from having two variables with the same name?
>
> At least with a naked call to a subroutine, you know now it is the *one*.

At least with lexical subroutines, its definition is 'close', and not
somewhere burried in a twingled maze of "use"d modules.

> $deity knows there is already twisted enough Perl code out there that we
> really don't need to add more complexity. IMHO of course.
>
> > > You can always do the equivalent of:
> > >
> > > $complex_calc = sub { ... };
> > >
> > > $foo = $complex_calc->(123) + $complex_calc->(124);
> > >
> > > so would this scheme only save you writing the "$" and the "->"?
> >
> > Yes, and? If that would be the enough reason not to add something to
> > Perl, Perl wouldn't be as rich as it is.
>
> If you have to maintain code, million little ways to write the same code are
> actually not a good idea.

No, but Perl doesn't have a history of having that as one of its main
points. OTOH, having more than one way of doing things is considered
to be a Perlish thing.

> Global variables, (ab)usive use of $_, side effects, actions-at-a distance,
> very short variable names for long stretches of code, this are all things
> that make it much harder to understand the code for humans.

Ah, yes. If only Perl was designed to not have global variables, $_,
side-effects, short variables, then we wouldn't have any of the problems
you just mention. We wouldn't have the language we have now though.

Now, there could be all kinds of reasons not to add lexical subroutines
(or any other feature) to Perl, but "it can be used in such a way that
code becomes harder to understand", is IMO, a bad reason to dismiss a
feature.

> And I don't think piling on yet-another-way to acomplish the same is a good
> idea, especially if it doesn't actually look to savemore than a few
> keystrokes, but creates confusion on the wake.
>
> However, don't let me discourage you. At least the golfers will love
> it... :)


Real golfers don't use subroutines.

Abigail

H.Merijn Brand

unread,
Mar 9, 2007, 5:48:40 AM3/9/07
to perl5-...@perl.org

No, as there is no "my" there. It would be different with

{ my $counter;
my sub next_id { return ++$counter }
}

but that is kinda useless anyway

> > I really don't like the idea of having two subroutines with the same name,
> > this makes code only more confusing.
> >
> > You can always do the equivalent of:
> >
> > $complex_calc = sub { ... };
> >
> > $foo = $complex_calc->(123) + $complex_calc->(124);
> >
> > so would this scheme only save you writing the "$" and the "->"?
>
> If i understand it correctly this isnt quite right. When you want to
> do a recursive subroutine with lexically scoped references to
> anonymous subroutines you have to be extremely careful not to end up
> with a memory leak. Using named subroutines doesn't have this problem,
> so from that point of view IMO this would be an improvement.

--

Demerphq

unread,
Mar 9, 2007, 6:11:27 AM3/9/07
to Rafael Garcia-Suarez, H.Merijn Brand, Perl5 Porters
On 3/9/07, Rafael Garcia-Suarez <rgarci...@gmail.com> wrote:
> On 09/03/07, demerphq <deme...@gmail.com> wrote:
> > I dont think we do need an our sub. our isnt a declaration like my is,
> > its just a pragma for strict.
>
> That was just for symmetry. (I don't want to think about "state sub foo{}".)

>
> > my sub foo { ... };
> >
> > is apparently the same thing as
> >
> > local *foo=sub { ... };
>
> (You meant local &foo, if perl supported that syntax)

Well to be totally picky i think i meant:

local *foo=*foo;
*foo=sub { ... };

> I don't think so. my only restricts visibility at compilation time,
> while local has a runtime effect.

Ok,clearly i was having a mental block on this stuff. I get it now.

Cheers,
Yves

Rafael Garcia-Suarez

unread,
Mar 9, 2007, 6:00:34 AM3/9/07
to demerphq, H.Merijn Brand, Perl5 Porters
On 09/03/07, demerphq <deme...@gmail.com> wrote:
> I dont think we do need an our sub. our isnt a declaration like my is,
> its just a pragma for strict.

That was just for symmetry. (I don't want to think about "state sub foo{}".)

> my sub foo { ... };


>
> is apparently the same thing as
>
> local *foo=sub { ... };

(You meant local &foo, if perl supported that syntax)

Aaron Crane

unread,
Mar 9, 2007, 6:39:02 AM3/9/07
to perl5-...@perl.org
Tels writes:
> You can always do the equivalent of:
>
> $complex_calc = sub { ... };
> $foo = $complex_calc->(123) + $complex_calc->(124);
>
> so would this scheme only save you writing the "$" and the "->"?

You'd also get the benefit that a sub with a fully-lexical name
couldn't be mistaken for a method by something attempting to
perform introspection on your class.

--
Aaron Crane

Wolfgang Laun

unread,
Mar 9, 2007, 8:21:58 AM3/9/07
to h.m....@xs4all.nl, perl5-...@perl.org
On Fri, 9 Mar 2007 11:48:40 +0100 H.Merijn Brand wrote:

> No, as there is no "my" there. It would be different with
>

> my sub next_id { return ++$counter }
>

If this is meant to restrict visibility to the scope
where it is written, also outside any {...}:
Will we see information hiding in Perl yet? ;-)

sub new { ... }
my sub localMethod {...}
sub publicMethod { shift->localMethod(); }

This, too?

kr
Wolfgang


Rafael Garcia-Suarez

unread,
Mar 9, 2007, 9:16:44 AM3/9/07
to Wolfgang Laun, h.m....@xs4all.nl, perl5-...@perl.org
On 09/03/07, Wolfgang Laun <Wolfga...@thalesgroup.com> wrote:
> sub new { ... }
> my sub localMethod {...}
> sub publicMethod { shift->localMethod(); }
>
> This, too?

That's a whole can of worms. See, what to do with $obj->$method()
where $method="localMethod" ? What to do with $obj->can("localMethod")
? Will we forced to blow up the method cache every time the scope is
entered or exited ? etc etc.

Paul Johnson

unread,
Mar 9, 2007, 9:32:47 AM3/9/07
to Abigail, Tels, perl5-...@perl.org, H.Merijn Brand
On Fri, Mar 09, 2007 at 11:52:41AM +0100, Abigail wrote:
> On Fri, Mar 09, 2007 at 11:34:05AM +0000, Tels wrote:
> > On Friday 09 March 2007 10:22:21 Abigail wrote:
> > > On Fri, Mar 09, 2007 at 10:47:28AM +0000, Tels wrote:
> > > > I really don't like the idea of having two subroutines with the same
> > > > name, this makes code only more confusing.
> > >
> > > How's that different from having two variables with the same name?
> >
> > At least with a naked call to a subroutine, you know now it is the *one*.
>
> At least with lexical subroutines, its definition is 'close', and not
> somewhere burried in a twingled maze of "use"d modules.

IMHO, lexical subroutines are to global subroutines as lexical variables are
to global variables. If you have used a language that allows them, you may
well miss them in Perl. If not, you probably don't know what you are missing.

I would be very happy to see them in Perl, but I would prefer to see 5.10 out
first.

--
Paul Johnson - pa...@pjcj.net
http://www.pjcj.net

Jan Dubois

unread,
Mar 9, 2007, 10:34:57 AM3/9/07
to Abigail, Rafael Garcia-Suarez, H.Merijn Brand, Perl5 Porters
On Fri, 09 Mar 2007, Abigail wrote:
>
> $ echo "lexical subs" >> perl5.14todo

I was about to say "it's already in there", but when I checked
it was gone. In Perl 5.6.1 perltodo.pod contains:

| =item Scoped subs
|
| lexically-scoped subs, e.g. my sub

I guess this has been removed somewhat prematurely when the
syntax was added to the parser.

Cheers,
-Jan

Mark Jason Dominus

unread,
Mar 9, 2007, 2:13:41 PM3/9/07
to Perl5 Porters

I don't care much whether this goes in or not, but if someone does
come up with an implementation, I humbly request that they notify me
before releasing it, since I can supply a whole bookful of test cases
for this feature. Some of these test cases will exercise behaviors
that the implementor may not have considered.

For example, what does this do?

sub fib { die; }

{
my sub fib {
my $n = shift;
return $n < 2 ? $n : fib($n-1) + fib($n-2);
};
}

David Nicol

unread,
Mar 9, 2007, 3:02:32 PM3/9/07
to Mark Jason Dominus, Perl5 Porters
On 3/9/07, Mark Jason Dominus <m...@plover.com> wrote:

> For example, what does this do?
>
> sub fib { die; }
>
> {
> my sub fib {
> my $n = shift;
> return $n < 2 ? $n : fib($n-1) + fib($n-2);
> };
> }

absolutely nothing, since there is no way to call the inner one :)
The discussion
below assumes that the ellipsis after the lexical sub def was left
out by mistake.

Following the model of my $var = EXPR, where $var is not visible within EXPR,
that would die on any $n GE 2. To get a recursive lexical sub you'd have
to declare the sub (and its prototype) within the scope before defining it:
{
- my sub fib {
+ my sub fib;
+ sub fib {


my $n = shift;
return $n < 2 ? $n : fib($n-1) + fib($n-2);
};

+ ... # stuff that can see my sub fib
}


Without further exercise of restraint, here's my opinion of the
feature in question:
We don't need it as it would further confuse things. The test for
inclusion seems
to be if the proponent of the feature feels strongly enough about the
need for it
to make it work and there aren't serious objections, in it goes. I
think that the
current ability to assign a coderef to a scalar is sufficient for all
possible use
cases, and the additional decoration on the resulting calls is a good thing as
it makes lexically scoped routines look different. And $name->(ARGLIST)
does not look like a method call to my eyes. A method call looks like
$name->method(ARGLIST) -- notice the token between the arrow and the (.

bash-3.00# perl -l
{ my $subfib;
$subfib = sub {
my $n = shift;
return $n < 2 ? $n : $subfib->($n-1) + $subfib->($n-2);
};
print $subfib->($_) for 1..10;
}

__END__
1
1
2
3
5
8
13
21
34
55
bash-3.00#

--
"Big discoveries are protected by public incredulity." -- Marshall McLuhan

Jan Dubois

unread,
Mar 9, 2007, 3:19:51 PM3/9/07
to Michael G Schwern, Mark Jason Dominus, Perl5 Porters
On Fri, 09 Mar 2007, Michael G Schwern wrote:
> This will recurse into the lexical fib() routine.

>
> sub fib { die }
>
> {
> my sub fib {
> my $n = shift;
> return $n < 2 ? $n : fib($n-1) + fib($n-2);
> };
>
> fib(5);
> }

Nope, this should die too (in the first recursive call). Any calls to
fib() from inside the lexical function will not result in recursion but
call the function visible in the outer scope. This has to be consistent
with usage like this:

$x = 10;
{
my $x = $x + 1;
print $x;
}

This has to print 11 and not 1 because the right hand side of the
assignment to the lexical still references the variable from the
outer scope.

This make the lexical sub form unsuitable for recursive function.

You could work around it by allowing:

my sub fib;
my sub fib { ... fib() } ;

This is still inconsistent with the way multiple "my" declarations
work for other variables.

Cheers,
-Jan


Michael G Schwern

unread,
Mar 9, 2007, 3:01:00 PM3/9/07
to Mark Jason Dominus, Perl5 Porters

Well, nothing since you only declared functions and didn't call then. :)
Anyhow, good question.

The following will die.

sub fib { die }

{
my sub fib {
my $n = shift;
return $n < 2 ? $n : fib($n-1) + fib($n-2);
};
}

fib(5);


This will recurse into the lexical fib() routine.

sub fib { die }

{
my sub fib {
my $n = shift;
return $n < 2 ? $n : fib($n-1) + fib($n-2);
};

fib(5);
}


And this will die.

sub fib { die }

{
fib(5);

Juerd Waalboer

unread,
Mar 9, 2007, 3:32:20 PM3/9/07
to perl6-l...@perl.org, perl5-...@perl.org
Juerd Waalboer skribis 2007-03-09 21:27 (+0100):
> Just a short note: please, if this is implemented, make sure that either
> Perl 6 conforms to Perl 5 behaviour, or the other way around.

Wanted to CC this list, but by accident replaced the To instead. Now
CC'ing p5p.
--
korajn salutojn,

juerd waalboer: perl hacker <ju...@juerd.nl> <http://juerd.nl/sig>
convolution: ict solutions and consultancy <sa...@convolution.nl>

Ik vertrouw stemcomputers niet.
Zie <http://www.wijvertrouwenstemcomputersniet.nl/>.

Michael G Schwern

unread,
Mar 9, 2007, 3:23:09 PM3/9/07
to David Nicol, Mark Jason Dominus, Perl5 Porters
David Nicol wrote:
> On 3/9/07, Mark Jason Dominus <m...@plover.com> wrote:
>
>> For example, what does this do?
>>
>> sub fib { die; }
>>
>> {
>> my sub fib {
>> my $n = shift;
>> return $n < 2 ? $n : fib($n-1) + fib($n-2);
>> };
>> }
>
> absolutely nothing, since there is no way to call the inner one :)

Zounds! I fell into his infernal trap!

Of course, "my $code = sub" acts exactly the same way.


> Without further exercise of restraint, here's my opinion of the
> feature in question:
> We don't need it as it would further confuse things. The test for
> inclusion seems
> to be if the proponent of the feature feels strongly enough about the
> need for it
> to make it work and there aren't serious objections, in it goes. I
> think that the
> current ability to assign a coderef to a scalar is sufficient for all
> possible use
> cases,

Someone who does Perl training for a living can probably answer this more
definitively but a common newbie question is "how do I declare a lexical
subroutine?" (or local or private or whatever) and they're often quite
surprised when "my sub foo" doesn't work and weirded out by "my $foo = sub".

"my sub foo" makes sense. If you already understand lexical scope you don't
have to explain it. You don't have to wonder about it. Rather than
confusing things it will make them simpler. Rather than add a special case
it eliminates one. How do you declare a lexical variable? You put "my" in
front of the declaration. How do you declare a lexical subroutine? Same
answer.

On the contrary, "my $private = sub" and "$private->($obj, @args)" and
"$obj->$private(@args)" are different and confusing. It took us HOW many
years to think of that? 5? 10? You show someone "my $code = sub" and all
the special attendant syntax and they wonder what in the hell is going on.
Every time I've introduced that idea to a new shop I've gotten questions,
confusion and push back.

Real lexical subs line up beautifully with the rest of the lexical system.
Its a missing piece.


> and the additional decoration on the resulting calls is a good
> thing as
> it makes lexically scoped routines look different.

By this argument, and I believe Abigail pointed this out several times,
there should be a different syntax for using lexical variables than global
variables.

And who knows, maybe there should be. Ruby does it, I think. But that's
Ruby, this is Perl, and we don't make lexicals look different and its a
little late in the game to start.


> And $name->(ARGLIST)
> does not look like a method call to my eyes. A method call looks like
> $name->method(ARGLIST) -- notice the token between the arrow and the (.

You know that $object->$coderef(@args) works?

$ perl -wle 'my $private = sub { join "\n", @_ }; $o = bless {}; print
$o->$private(42)'
main=HASH(0x1801180)
42

Demerphq

unread,
Mar 9, 2007, 3:20:28 PM3/9/07
to Michael G Schwern, Mark Jason Dominus, Perl5 Porters

I think the issue that MJD was alluding to was that it is reasonable
to assume that the fib() calls in the lexically scoped fib() will
actually reference the dynamically scoped fib() because the lexically
scoped fib() wont be defined at the time the content of the sub is
compiled. And that changing this behaviour probably has deeper
ramifications than appear at first glance.


>
> And this will die.
>
> sub fib { die }
>
> {
> fib(5);
>
> my sub fib {
> my $n = shift;
> return $n < 2 ? $n : fib($n-1) + fib($n-2);
> };
> }

If you assume that

my sub foo {..};

is the same as

local *foo=*foo;
*foo=sub{...};

then the interpretation given here is reasonable. But then you have
problems elsewhere such as with

sub foo { print 1 }
sub bar { foo() }

{
my sub foo { print 2 };
bar();
}

which would print 2. But most people seem to expect that the above
should print 1.

So you then have a problem in that you either have to change the rule
about when the sub declaration comes into effect so that the lexical
sub declaration is valid before the sub body is parsed, or you have a
problem that it just simulates localization.

Abigail

unread,
Mar 9, 2007, 3:48:35 PM3/9/07
to Jan Dubois, Michael G Schwern, Mark Jason Dominus, Perl5 Porters
On Fri, Mar 09, 2007 at 12:19:51PM -0800, Jan Dubois wrote:
> On Fri, 09 Mar 2007, Michael G Schwern wrote:
> > This will recurse into the lexical fib() routine.
> >
> > sub fib { die }
> >
> > {
> > my sub fib {
> > my $n = shift;
> > return $n < 2 ? $n : fib($n-1) + fib($n-2);
> > };
> >
> > fib(5);
> > }
>
> Nope, this should die too (in the first recursive call). Any calls to
> fib() from inside the lexical function will not result in recursion but
> call the function visible in the outer scope. This has to be consistent
> with usage like this:
>
> $x = 10;
> {
> my $x = $x + 1;
> print $x;
> }
>
> This has to print 11 and not 1 because the right hand side of the
> assignment to the lexical still references the variable from the
> outer scope.
>
> This make the lexical sub form unsuitable for recursive function.

Is that true?

sub fib {
my $n = shift;
return $n < 2 ? $n : fib($n-1) + fib($n-2);
}

works without a problem. It's only problematic if you leave the parens
off when calling fib() - then you need the forward declaration.

So why would it be different with a lexical sub?

>
> You could work around it by allowing:
>
> my sub fib;
> my sub fib { ... fib() } ;
>
> This is still inconsistent with the way multiple "my" declarations
> work for other variables.


Yes, to make it consistent, you would write it as:

my sub fib;
sub fib { ... fib() };

Abigail

Mark Jason Dominus

unread,
Mar 9, 2007, 3:47:22 PM3/9/07
to perl5-...@perl.org
demerphq <deme...@gmail.com>:

> I think the issue that MJD was alluding to was that it is reasonable
> to assume that the fib() calls in the lexically scoped fib() will

No, not really.

The issue that I was alluding to is that the semantics are not totally
clear and that there are a bunch of edge cases that would need to be
considered IF someone were to do an implementation.

And that I have a large supply of code here that could be used to test
such edge cases.

The rest of you guys are all just showing off your l33t sk1llz at
writing "fizz buzz" programs.

David Nicol

unread,
Mar 9, 2007, 4:01:19 PM3/9/07
to Michael G Schwern, Perl5 Porters
On 3/9/07, Michael G Schwern <sch...@pobox.com> wrote:

> Someone who does Perl training for a living can probably answer this more
> definitively but a common newbie question is "how do I declare a lexical
> subroutine?" (or local or private or whatever) and they're often quite
> surprised when "my sub foo" doesn't work and weirded out by "my $foo = sub".

And a good answer to that might be "You can do them but it's complex
and ugly. Do you really need them?" That's the way things are with
aliaing through l-value reference syntax -- it too is a missing piece
with absence strange to C++ programmers, as lexical subs is a missing
piece with absence strange to Pascal programmers (and whoever else
expects them to be there.)

> Real lexical subs line up beautifully with the rest of the lexical system.
> Its a missing piece.

Sure it's a missing piece, but we've gotten by without it for this long, and
there are available workarounds for when you Really Need It. Just like
proposed l-value reference syntax shorthand for Devel::Lexalias. I doubt
that the OP will create enough buzz to cause some Other Person to
do the implementation.

> > And $name->(ARGLIST)
> > does not look like a method call to my eyes. A method call looks like
> > $name->method(ARGLIST) -- notice the token between the arrow and the (.
>
> You know that $object->$coderef(@args) works?

Why anyone would write that instead of $coderef->($object, @args) is a mystery
to me. the scalar in the $coderef spot can also hold a method name, right?

Larry Wall

unread,
Mar 9, 2007, 4:39:17 PM3/9/07
to perl5-...@perl.org
On Fri, Mar 09, 2007 at 03:47:22PM -0500, Mark Jason Dominus wrote:
: The issue that I was alluding to is that the semantics are not totally

: clear and that there are a bunch of edge cases that would need to be
: considered IF someone were to do an implementation.
:
: And that I have a large supply of code here that could be used to test
: such edge cases.
:
: The rest of you guys are all just showing off your l33t sk1llz at
: writing "fizz buzz" programs.

[This is addressed to everyone, not specifically to MJD.]

If someone wants to show off their 1334 cross-language 6ki1z they could
translate those test cases to Perl 6 and install them into the pugs
test repository, since pugs already purports to handle lexically scoped
subs. We've already dealt wit