Perl 6 Wish List (long) 
Author Message
 Perl 6 Wish List (long)

This is a list of the things that I wish Perl had. Some of them have
already been mentioned in the Perl 6 RFCs; I include those items to
state that I would find them useful.

I would send this to one of the perl6 mailing lists, but I'm not sure if
it would be welcome.

Any items that begin with a 'require' statement are only relevant if the
specified RFC is implemented.

                            ----------------

Item: Separate namespaces for functions and methods.

Reason: Unwanted methods.

  package SomeClass;
  use LWP::Simple;
  ...
  package main;
  my $obj = SomeClass->new;
  $obj->get("whatever"); # oops: calling LWP::Simple::get

Reason: Name conflicts.

  package SomeClass;
  use LWP::Simple;
  sub get {} # oops: we can't import LWP::Simple::get and call it
             # because it conflicts with our own method namer

                            ----------------

Item: Separate namespaces for class methods and instance methods.

Reason: Dual methods are rare, and when you do have them, having to test
for whether the method was called with a class or object name is
awkward.

Reason: Currently, instance methods can be (accidentally) called as
class methods, leading to errors (that might have far-reaching
consequences).

  sub instance_method {
    some_operation_that_affects_global_state();
    $self->{foo} = some_function_that_uses_that_state();
    reset_that_state();
  }
  ...
  SomeClass->instance_method;
  # oops: instance_method dies halfway through

                            ----------------

Item: Standard, cross-platform, cross-version, flexible serialization
method.

Reason: Current modules for this have disadvantages:

  Data::Dumper: Requires eval() to restore structure, therefore not
usable for unsafe input.

  Storable: Different versions have incompatible formats.

  FreezeThaw: I actually haven't looked into this one, but I expect it
would be slower than the others, since it is written entirely in Perl.

                            ----------------

Item: Lexical symbol tables

Reason: It is often useful to pass a group of variables into one of
several 'handler' subroutines; it would be nice to avoid having to
specify an argument list for each one. Global variables could be used,
but that's a) ugly and b) raises possible problems with threading.

  %handlers = (
    num => sub { with (%{$_[0]}) { $a + $b + $c + $d; } },
    str => sub { with (%{$_[0]}) { $a . $b . $c . $d; } },
    baz => sub { with (%{$_[0]}) { ' ' x $a . "$b$c$d"; } },
  );


      '$a' => $rec->[3], '$b' => $rec->[4],
      '$c' => $rec->[5], '$d' => $rec->[6],
    });
  }

  # another example:

  sub recursive_processor {

    with (my $newcontext = {%$context}) { # copying the hash so changes
                                         # don't propagate to the caller

      ... doing something with the node ...
      if ($some_info eq 'foo') {
        ...
      }
      ... doing something with the node ...
      $some_info = $whatever;

    }
  }  

                            ----------------

Item: Fewer built-in functions

Reason: Less complexity in the core.

Reason: Shorter perlfunc.pod.

Reason: Name conflicts with methods using indirect object syntax:

  package SomeClass;
  sub send {...}
  ...
  package main;
  $obj->send(...); # okay
  send $obj ...; # oops

Reason: When was the last time you used syscall(), dump(), chroot(),
msg*(), shm*(), get*(), etc.?

                            ----------------

Item: Faster method calls

Reason: Need I explain?

Reason: Quoted from RFC 126:

Quote:
> This wouldn't bother me so much if it wasn't also incredibly inefficient
> relative to procedural Perl. Of course object-oriented design will always
> have more overhead, but it shouldn't have that much more.

> To put it another way, no one should ever be tempted to do this:

>     $obj->{'attribute'}

> for efficiency reasons inside a tight loop or what have you. (And no, the
> solution is not to ``use C when you need efficiency.'' I shouldn't need to
> use portable assembler to access an object attribute efficiently.)
> Whatever the syntax turns out to be, simple things like object attribute
> accessors should not only be faster than doing this in Perl 5:

>     $obj->attribute

> they should even be faster than the {*filter*}, encapsulation-destroying,
> implementation-revealing hash-lookup above.

                            ----------------


Reason:

  eval $code;

    do_something_which_just_happens_to_call_eval();

  }

                            ----------------

Item: Backslash operator should be assignable for symbol table
manipulation, provided its operand is a simple variable.

Reason: Typeglobs are evil.

  \$foo = \$bar; # equivalent to *foo = \$bar

Reason: I'd like to be able to alias lexical symbols:

  \(my $foo) = $big_structure->[0]{'bar'}{'whatever'};

                            ----------------

Item: Non-fatal exceptions - i.e. catchable warnings; essentially an
extension of $SIG{__WARN__} that makes this easier:

  my $oldwarn = $SIG{__WARN__};
  local $SIG{__WARN__} = sub {
    if ($_[0] =~ /whatever we're catching/) {
      ...
    } elsif ($oldwarn) {

    } else {
      warn $_[0];
    }
  };
  do_whatever_that_might_cause_a_warning;

                            ----------------

require ' http://www.*-*-*.com/ ';

Item: Most builtin functions should become object methods:

  substr($string, 0, 3); # old
  $string->substr(0, 3); # new
  substr $string 0, 3;   # or this

                            ----------------

Item: Optional autoloading of modules. Any time a class method is not
found, Perl attempts to load the corresponding module. This may be
implemented for one method with the following Perl 5 code:

  sub UNIVERSAL::new {
    my ($meth) = +(caller(0))[3] =~ /::([^:]*)$/;
    my $class = shift;
    (my $file = $class . ".pm") =~ s#::#/#g;
    !$INC{$file}
      or require Carp, Carp::croak(qq{Can't locate object method}
      .qq{ "$meth" via package "$class"});
    eval "require $class"
      or require Carp, Carp::croak(qq{Can't locate object method}
      .qq{ "$meth" via package "$class" (no module with that name)});

  }

                            ----------------

require ' http://www.*-*-*.com/ ';

Item: Prototypes allow requiring defined values.

  sub some_func (defined $foo) { ... }
  some_func(3); # okay
  some_func(undef); # dies

Reason: Many subroutines don't do anything useful with an undefined
value, and if you pass undef, you get warnings coming from inside the
subroutine, _which are not useful in finding where you called the
subroutine with an undefined value_. This allows a simple way for
subroutines to require that their arguments be defined.

                            ----------------

require ' http://www.*-*-*.com/ ';

Item: sub (%items) {...}, if called with an odd number of arguments,
should cause a warning at the calling location.

                            ----------------

Item: Symbolic references are evil. They should be completely eliminated
- if you want to mess with symbol tables, use %:: -equivalent.

Reason: Having them so easily accessible encourages new users to use
them (and we all know why they shouldn't, right?)

                            ----------------

Item: split() and map() should die if called in scalar or void context.

Reason: For split(), there's absolutely no reason to use scalar context,
and for map(), using it in scalar / void context is an abuse of the
concept. foreach exists for a reason.

                            ----------------

Item: Provide a way of de-anonymizing subroutines (WITHOUT putting them
in any symbol table) so that useful information can be provided in a
stack trace.

  set_handlers(
    Handler1 => sub { ... },
    Handler2 => sub { ... },
  );
  sub set_handlers {

    for (keys %newh) {
      name_sub($newh{$_}, "handler $_");
    }

  }

                            ----------------

require ' http://www.*-*-*.com/ ';

Item: Nothing to add here, I just think this RFC is a good idea and

traces. Also, don't forget to provide croak() or equivalent, assuming
complete stack traces are not the default output.

--
 Kevin Reid: |    Macintosh:      
  "I'm me."  | Think different.



Thu, 18 Dec 2003 04:31:38 GMT  
 Perl 6 Wish List (long)
[snip]

Quote:
> Item: Lexical symbol tables

> Reason: It is often useful to pass a group of variables into one of
> several 'handler' subroutines; it would be nice to avoid having to
> specify an argument list for each one. Global variables could be used,
> but that's a) ugly and b) raises possible problems with threading.

>   %handlers = (
>     num => sub { with (%{$_[0]}) { $a + $b + $c + $d; } },
>     str => sub { with (%{$_[0]}) { $a . $b . $c . $d; } },
>     baz => sub { with (%{$_[0]}) { ' ' x $a . "$b$c$d"; } },
>   );


>       '$a' => $rec->[3], '$b' => $rec->[4],
>       '$c' => $rec->[5], '$d' => $rec->[6],
>     });
>   }

How does the compiler tell if a given $a is a lexical from a special
symbol table, or a lexical from the enclosing scope, or if it's a
global?

our $a = 1; my $a = 2;
my $n = +(rand < 0.5) ? '$a' : '$b';
my $h = {$n=>3};
with($h) { print ++$a, "\n"; }
print "$h->{$n} $a $::a\n";

There's no way perl could possibly get this right and still be
reasonably efficient.

[snip]

Quote:

> Reason:

>   eval $code;

>     do_something_which_just_happens_to_call_eval();

>   }

I disagree.  Consider an analagous case with $_
while( <> ) {
        next unless /$re/;
        do_something_which_changes_dollar_underscore();
        print;

Quote:
}


people localise it before calling eval.  Yes, this seems a bit
cumbersome, but if we were to change to using exceptions, rather than
eval, this wouldn't be too great a concern... you could have the try

following it, or something like that.

[snip]

- Show quoted text -

Quote:
> Item: Optional autoloading of modules. Any time a class method is not
> found, Perl attempts to load the corresponding module. This may be
> implemented for one method with the following Perl 5 code:

>   sub UNIVERSAL::new {
>     my ($meth) = +(caller(0))[3] =~ /::([^:]*)$/;
>     my $class = shift;
>     (my $file = $class . ".pm") =~ s#::#/#g;
>     !$INC{$file}
>       or require Carp, Carp::croak(qq{Can't locate object method}
>       .qq{ "$meth" via package "$class"});
>     eval "require $class"
>       or require Carp, Carp::croak(qq{Can't locate object method}
>       .qq{ "$meth" via package "$class" (no module with that name)});

>   }

It seems to me that this is something which could be added to the
autouse pragma, somehow.

[snip]

Quote:
> Item: split() and map() should die if called in scalar or void
> context.

> Reason: For split(), there's absolutely no reason to use scalar
> context, and for map(), using it in scalar / void context is an abuse
> of the concept. foreach exists for a reason.


have a purpose.

As for map (and grep), I agree, to a point.

Instead of having the function itself die if called in void context,
this should be handled by a subroutine attribute :novoid, which causes
the compiler to abort if the function is called in a void context.

This is useful for things which have no side effects other than
generating a return value.... like many of the markup generators in
CGI.pm (table, Tr, td, etc); there's no point in adding to each and
every sub an extra check for void context, but you still don't want it
to be called that way.  Making it the compiler's responsibility seems
the best way to do it.

Quote:
> Item: Provide a way of de-anonymizing subroutines (WITHOUT putting
> them in any symbol table) so that useful information can be provided
> in a stack trace.

>   set_handlers(
>     Handler1 => sub { ... },
>     Handler2 => sub { ... },
>   );
>   sub set_handlers {

>     for (keys %newh) {
>       name_sub($newh{$_}, "handler $_");
>     }

>   }

Nitpick: I'm not so sure that name_sub is the best thing to call your
function for naming a sub.  I would suggest:

        attrs::get_name( $coderef );
        attrs::set_name( $coderef, $name );

--
The longer a man is wrong, the surer he is that he's right.



Thu, 18 Dec 2003 22:30:56 GMT  
 Perl 6 Wish List (long)
Well, my wish list is not soo long:

- fixes for variable loss, memory eating and other performance problems
of long-runnung scripts,
- please, please do not force the OOP and the stricter typing in a
really handy, structured script language,
- a compiler (not for better performance, but for eliminating the need
of the same perl version in all target machines).

And a few words on Kevin Reid's list.

I mostly agree on his wishes, but:

Quote:
> Item: Most builtin functions should become object methods:

>   substr($string, 0, 3); # old
>   $string->substr(0, 3); # new
>   substr $string 0, 3;   # or this

No please, if I can ask...
Why to use OO syntax for these calls?
Why loosing performance?

Quote:
> Item: sub (%items) {...}, if called with an odd number of arguments,
> should cause a warning at the calling location.

It's not so easy, I'm afraid...
The sub declaration doesn't give chance to do this at the moment.

Quote:
> Item: Symbolic references are evil. They should be completely eliminated
> - if you want to mess with symbol tables, use %:: -equivalent.

> Reason: Having them so easily accessible encourages new users to use
> them (and we all know why they shouldn't, right?)

Well, I don't know what about newbies, but this would not be so useful
IMHO.
What about flexibility?

Quote:
> Item: split() and map() should die if called in scalar or void context.

Well, personally I don't like functions dying but prefer checking return
values...

Quote:
> Reason: For split(), there's absolutely no reason to use scalar context,
> and for map(), using it in scalar / void context is an abuse of the
> concept. foreach exists for a reason.

Flexibility again.
Who knows what gives a reason to a perl hacker...

--
Laszlo Gerencser
PortoLogic Ltd.



Thu, 18 Dec 2003 22:43:27 GMT  
 Perl 6 Wish List (long)

Quote:

> Well, my wish list is not soo long:

> - fixes for variable loss, memory eating and other performance problems
> of long-runnung scripts,
> - please, please do not force the OOP and the stricter typing in a
> really handy, structured script language,
> - a compiler (not for better performance, but for eliminating the need
> of the same perl version in all target machines).

That's good, because Perl 6 looks like it'll fulfill all of the above.

--
The angels want to wear my red shoes.



Fri, 19 Dec 2003 02:53:18 GMT  
 Perl 6 Wish List (long)
[ Posted and cc'd to cited author ]

Quote:

> This is a list of the things that I wish Perl had. Some of them have
> already been mentioned in the Perl 6 RFCs; I include those items to
> state that I would find them useful.

I'm replying to one point that I would also find useful, but does have
a workable solution in Perl 5.

Quote:
> Item: Backslash operator should be assignable for symbol table
> manipulation, provided its operand is a simple variable.

> Reason: Typeglobs are evil.

>  \$foo = \$bar; # equivalent to *foo = \$bar

> Reason: I'd like to be able to alias lexical symbols:

>  \(my $foo) = $big_structure->[0]{'bar'}{'whatever'};

You can already do this with C<for>.  As in:

        for my $foo ($big_structure->[0]{'bar'}{'whatever'}) {
                # $foo is an alias to that mess
        }

Occasionally I use this idiom in a function that uses pass by reference
to create local aliases to the parameters.  However, I would prefer to
see a means of doing that does not introduce another level of scope,
so I support your proposal.

I am uncertain what the correct syntax would be:

        \(my $foo)      = $big_structure->[0]{'bar'}{'whatever'};

or

        my \$foo        = $big_structure->[0]{'bar'}{'whatever'};

which is analogous to the 'my ($foo,$bar) = ...' syntax.

Tramm
--

 /|\  http://www.swcp.com/~hudson/          H 505.323.38.81   /\  \_  

  0                                                            U \_  |



Fri, 19 Dec 2003 08:12:31 GMT  
 Perl 6 Wish List (long)

[wish list]

Quote:
>> Item: Most builtin functions should become object methods:
>>  $string->substr(0, 3); # new
>Why to use OO syntax for these calls?
>Why loosing performance?

It wouldn't lose performance if perl could notice these at compile
time.  That would be easy to do if certain method names like 'substr'
were reserved; not so easy otherwise but I'm sure the implementers
could think of a way to do it.

--

Finger for PGP key



Fri, 19 Dec 2003 16:46:14 GMT  
 Perl 6 Wish List (long)

Quote:


> [snip]
> > Item: Lexical symbol tables

> > Reason: It is often useful to pass a group of variables into one of
> > several 'handler' subroutines; it would be nice to avoid having to
> > specify an argument list for each one. Global variables could be used,
> > but that's a) ugly and b) raises possible problems with threading.
<snip>
> How does the compiler tell if a given $a is a lexical from a special
> symbol table, or a lexical from the enclosing scope, or if it's a
> global?
<snip>
> There's no way perl could possibly get this right and still be
> reasonably efficient.

Ouch. You're right.

Quote:
> > Item: Optional autoloading of modules.
<snip>
> It seems to me that this is something which could be added to the
> autouse pragma, somehow.

I was thinking of this for one-liners where you create and use an
object, so you don't have to use -M.

Alternative: 'use' has the run-time value of the package name, e.g.

  (use SomeClass)->new->...

- Show quoted text -

Quote:
> [snip]
> > Item: split() and map() should die if called in scalar or void
> > context.
<snip>
> As for map (and grep), I agree, to a point.

> Instead of having the function itself die if called in void context,
> this should be handled by a subroutine attribute :novoid, which causes
> the compiler to abort if the function is called in a void context.

> This is useful for things which have no side effects other than
> generating a return value.... like many of the markup generators in
> CGI.pm (table, Tr, td, etc); there's no point in adding to each and
> every sub an extra check for void context, but you still don't want it
> to be called that way.  Making it the compiler's responsibility seems
> the best way to do it.

This seems like a good idea, but I don't see what it has to do with map.

Quote:
> Nitpick: I'm not so sure that name_sub is the best thing to call your
> function for naming a sub.  I would suggest:

I agree that it's not a very good name. name_sub was just so I had
_something_ to put in the example.

--
 Kevin Reid: |    Macintosh:      
  "I'm me."  | Think different.



Fri, 19 Dec 2003 20:56:49 GMT  
 Perl 6 Wish List (long)

Quote:

> > Item: Most builtin functions should become object methods:

> >   substr($string, 0, 3); # old
> >   $string->substr(0, 3); # new
> >   substr $string 0, 3;   # or this
> No please, if I can ask...
> Why to use OO syntax for these calls?
> Why loosing performance?
>>From what I understand of the plans for Perl 6, it is likely that a) OO

will be much faster and b) possibly, the string really IS an object,
thus it makes sense to use OO syntax.

Quote:
> > Item: sub (%items) {...}, if called with an odd number of arguments,
> > should cause a warning at the calling location.
> It's not so easy, I'm afraid...
> The sub declaration doesn't give chance to do this at the moment.

As I stated, this item was written on the assumption that RFC 57 will be
implemented. Read <http://dev.perl.org/rfc/57.html>.

--
 Kevin Reid: |    Macintosh:      
  "I'm me."  | Think different.



Fri, 19 Dec 2003 20:56:51 GMT  
 Perl 6 Wish List (long)
Quote:



[snip]
> > > Item: split() and map() should die if called in scalar or void
> > > context.
> <snip>
> > As for map (and grep), I agree, to a point.

> > Instead of having the function itself die if called in void context,
> > this should be handled by a subroutine attribute :novoid, which
> > causes the compiler to abort if the function is called in a void
> > context.

[snip] Making it the compiler's responsibility seems

Quote:
> > the best way to do it.

> This seems like a good idea, but I don't see what it has to do with
> map.

map is a function you don't want called in void context.  Therefor, add
the :novoid attribute to map.  As a result, the compiler would die when
someone uses map in a void context, in a similar manner to how it dies
if you [try to] use the wrong type of arguments with a prototyped
subroutine.

Just as subroutine prototypes move the burden of argument checking from
runtime to compile time, adding my proposed :novoid would produce the
"map should die in a void context" behavior which you want, and at
compile time, which mostly eliminates the cost which an explicit test
for void context in map would result in.

--
The longer a man is wrong, the surer he is that he's right.



Sat, 20 Dec 2003 01:11:49 GMT  
 Perl 6 Wish List (long)
[snip]

Quote:
> I am uncertain what the correct syntax would be:

>         \(my $foo)      = $big_structure->[0]{'bar'}{'whatever'};

> or

>         my \$foo        = $big_structure->[0]{'bar'}{'whatever'};

> which is analogous to the 'my ($foo,$bar) = ...' syntax.

You forget... \( a, b, c ) is the same as ( \a, \b, \c ).  Therefor,
your two examples equivilant.  Here's a more interesting question...
I assume that
        my \$foo = \$whatever;
should make it so changing $foo changes $whatever (just as if we'd done
*foo = \$whatever... except that it's lexical, not dynamic).  What does
        my \$foo = $whatever;
do, if $whatever does not contain a reference to a scalar?  Die?

Also, since this would probably mean we could now do this:
        my \&foo = $coderef;
        foo( "bar" );
How should we handle prototypes for lexical subs?

--
The longer a man is wrong, the surer he is that he's right.



Sat, 20 Dec 2003 01:55:48 GMT  
 Perl 6 Wish List (long)
numerous people wrote lots of good stuff, I will add my 2c's worth

Here's my wish - inheritable data

e.g.





# (nothing defined, everything from base)



package main;
print base->my_important_stuff();    # output: one two three
print derived1->my_important_stuff();        # output: one two three
print derived2->my_important_stuff();        # output: six seven eight

The point being that the variable seen by the base function would not
necessarily be the one from the base package.

'bless' would seem the obvious way to do this from the end-programmer's
point of view.

Blessing a non-reference would not create an object.  Instead any access
to the variable within the scope of the bless would cause a lookup to find
the package of the variable.

I assume that the hooks used for tie'ing would provide some of the basis
for an implementation.



Sat, 20 Dec 2003 02:28:02 GMT  
 Perl 6 Wish List (long)

Quote:

> >>From what I understand of the plans for Perl 6, it is likely that a) OO
> will be much faster

Yes.

Quote:
> b) possibly, the string really IS an object,
> thus it makes sense to use OO syntax.

Snort. Not really. It will be *able* to look like one, but we ain't
going Ruby.

--
What would happen if you ran up to Hitler and mentioned Usenet?
        - Kibo



Sat, 20 Dec 2003 01:22:19 GMT  
 Perl 6 Wish List (long)

Quote:

> > b) possibly, the string really IS an object,
> > thus it makes sense to use OO syntax.

> Snort. Not really. It will be *able* to look like one, but we ain't
> going Ruby.

Or maybe the other way around: a string really *is* an object, but
it won't look like one unless you put on your OO-colored glasses.
AFAICT, that ain't going Ruby.

--
John Porter



Sat, 20 Dec 2003 02:30:53 GMT  
 Perl 6 Wish List (long)

Quote:

> Or maybe the other way around: a string really *is* an object

Oh, if you like. A string really is an object right now, though, if
you look squinty enough at it. It even has an inheritance tree,
polymorphism and all sorts...

--
It's a testament to the versatility of the human mind that we're so able
to compensate for our own incompetence.
    - Darrell Furhiman



Sat, 20 Dec 2003 03:33:55 GMT  
 Perl 6 Wish List (long)

Quote:

>I assume that
>    my \$foo = \$whatever;
>should make it so changing $foo changes $whatever (just as if we'd done
>*foo = \$whatever... except that it's lexical, not dynamic).  What does
>    my \$foo = $whatever;
>do, if $whatever does not contain a reference to a scalar?  Die?

Presumably it would try to use $whatever as a symref (and die if in
strict mode).

Quote:
>Also, since this would probably mean we could now do this:
>    my \&foo = $coderef;
>    foo( "bar" );
>How should we handle prototypes for lexical subs?

We could decide not to -- the only things you can make lexical in Perl 5
are scalars, arrays, and hashes, and nothing _requires_ changing that.
If we do decide to allow lexical subs, presumably something will have to
be done about prototypes.  But it's not really related to aliasing.

--
Ilmari Karonen -- http://www.sci.fi/~iltzu/
"Get real!  This is a discussion group, not a helpdesk.  You post something,
we discuss its implications.  If the discussion happens to answer a question
you've asked, that's incidental."           -- nobull in comp.lang.perl.misc



Sat, 20 Dec 2003 06:03:19 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. image scaling

2. Database Encrytion

3. Dynamic memory allocation in interrupt code

4. Perl 5 wish list - is it too late?

5. Perl wish list

6. Announce: The Perl Wish List

7. Wish List

8. Configure wish list

9. wish list

10. comments in regular expressions (wish list)

11. wish list

12. BDE in console apps

 

 
Powered by phpBB® Forum Software