http://qs1969.pair.com?node_id=687060

If the yoke of backwards compatibility was thrown off from Perl 5.x, what would you change? And why?

(Short technical overviews rather than detailed rants preferred.)

  1. Please do not front page this post. Preferably do not upvote it. (Downvote at your choice.)
  2. This is not a anti-Perl 6 post. Nor an attempt to revisit the Perl 6 design process.

    And anti-Perl 6 rants are explicitly not solicited.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: What would you change?
by dragonchild (Archbishop) on May 17, 2008 at 03:39 UTC
    • Move most of the built-in functions to libraries that are in the core. So, instead of log(), it would be Math::log() and use Math; would bring those functions in. This goes for about 70% of the functions. This makes the whole CORE:: and CORE::GLOBAL:: thing a bit easier to manage.
    • Get rid of prototypes and find a real way to pass an array as an array to a function. The only suggestion I have is calling signatures.
    • @ISA is a hack, as is UNIVERSAL::. All OO should be left for a module. The only good thing is bless().
    And, the biggest thing is the variable tying system. I love variable tying. But, it should be really be implemented through some form of autoboxing vs. the rather ad-hoc-ish mechanism that is TIE. Having dealt with nearly every intricacy you can with DBM::Deep, there are certain parts I just go "Uhh ... it passes all the tests!" and leave it at that. At the very least, there needs to be a massive amount more documentation of exactly what gets called in what scenarios. But, autoboxing would solve the issue nicely.

    Of course, we can't autobox without a solid OO system. I'd just like to autobox with Moose. But, I can't without a performance penalty that's ridiculous above what tie imposes. So, I don't.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      I am a fan of prototypes. I know it is not recommended in Perl Best Practices because of the danger of someone pushing argments into an array and then passing the array.. e.g.

      sub prototyped( $ $ ) { print( "Arg 1: " . $_[0] . "\n" ); print( "Arg 2: " . $_[1] . "\n" ); } my @args = ( "first", "second" ); prototyped( @args );
      returns the following error:
      Not enough arguments for main::prototyped

      However, as much as the prototype solution is broken for this situation, I'm still a fan of prototypes.

      Having prototypes has helped track down a bug in code used in production in a company whereby someone went in and modified the code adding a new parameter to each function. And then a minor bug slipped through whereby a call to one of the functions didn't provide enough arguments.

      Prototypes would have caught this in the compilation phase. In fact, by adding prototypes to all the functions we caught another instance whereby a function was being called with the wrong number of parameters..

        When adding a new parameter to each call of a function, have the code behave one way with N args, and a different way with N+1. Ideally, by synthesising a default value for the missing parameter, and then going ahead and doing the same thing.

        There are many ways of working around this sort of codebase evolution. Having the code fail badly because one call was missed is just wrong. Perl is not C.

        As to the other point, yes it's true that prototypes catch things at the compilation phase, but it doesn't deal with passing a text string when a numeric was expected. For that, Params::Validate is a much more robust approach to ensure parameters are sane, especially in a large code base.

        • another intruder with the mooring in the heart of the Perl

        Although I normally neither use nor need prototypes in Perl, I'd still love to see them being extended in such a way that you could make regular Perl functions behave like Perl builtins in every respect (think of overriding print, system, etc.).  I've come across some discussion along these lines on p5p (e.g. here), but I think things never went beyond just being discussed.

        (This is not my entire Perl 5 wishlist, btw, but the other items are still too vague / not thought-out enough yet, that I would dare to present them to this audience :)

        vec() is prototyped. This pisses me off.

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: What would you change?
by friedo (Prior) on May 17, 2008 at 03:34 UTC

    I never liked the print syntax. That whole optional-parameter-but-with-no-comma thing really gets my goat. I'd rather just always use select instead of sticking the filehandle in the print statement, but I don't. It eats me up inside, I tell you.

    I can never remember what the syntax is for taking a slice on a hashref. I have to fiddle with it every time, no matter how many times it comes up. Rather than dealing with an appalling mess of curlies and sigils, I would really liked to have had a slice operator that could be used like my @stuff = slice $href, qw/key1 key2 key3/; Yeah, I could probably write it myself, but I'm lazy.

      I never liked the print syntax. That whole optional-parameter-but-with-no-comma thing really gets my goat

      There been an alternative for quite some time.

      use IO::Handle qw( ); STDOUT->print("Hello World!\n");

      Works on any handle.

      I would really liked to have had a slice operator

      How does adding slice break perl's backwards compatibility?

      Rather than dealing with an appalling mess of curlies and sigils...

      I can't recall ever wanting to take a slice of a hashref myself, but this line aroused my curiosity, so I investigated to see just how bad it could be.

      First I went for the naive approach:

      my @stuff = @$href{ qw/key1 key2 key3/ };

      And was rather surprised to discover that I'd got it right first try!

      Perhaps the reason this seems intuitive to me and not to you because I already habitually write $$href{key1} rather than $href->{key1}, so I'm used to using double sigils to dereference things? (Henceforth I shall use this consistency as an argument in favour of my preferred syntax!)

        For extra clarity (to me, anyway), I prefer to write it as:

        my @stuff = @{$hashref}{ qw(key1 key2 key3) }; # or my @keys = qw(key1 key2 key3); my @stuff2 = @{$hashref}{ @keys };

        (with the extra curlies). For some reason I never was crazy about the arrow shortcut here. In fact... umm... how do I correctly write the above using the arrow? I can't get it to work.

Re: What would you change?
by Limbic~Region (Chancellor) on May 17, 2008 at 23:29 UTC
    BrowserUk,
    I would change a lot of things.
    • I would get rid of all the overloading of functions (dual purpose select, dual purpose angle brackets, etc)
    • I am still not sure I like the extreme DWIM of shift with two different default variables depending on where it is used
    • I would throw out all the junk (study, reset, formats, etc)
    • I would get rid of the things today that have been usurped such as 2 arg open and bare word file handles
    • If I were way smart - I would fix the whole threads problem and add syntax to allow certain auto-parallelization of things
    • If I were way smart - I would add an optional type system removing the dynamic nature (magic, number/string, etc) away from certain variables allowing the speed up at runtime
    • If I were way smart - I would take experimental features like sub attributes and prototypes and make them work and be useful
    • If I were way smart - I would completely overhaul the OO system
    • If I were way smart - I would find a way of reducing the sub calling overhead (perhaps by providing an optional syntax allowing the author to give the compiler optimization hints)
    • I would enable strictures, warnings, and tainting by default
    • I would make it such that dereferencing in all situations were pretty

    The list goes on and on. On the other hand, I am quite certain that the changes I would make would result in a language that would suit me and likely not many others. I think this is more than just a matter of "take the bad with the good". I think that there is very little that almost everyone can agree should be changed (removed, added, augmented, modified, etc). I can also say with absolute certainty that the things that I would want to change today are not the same things I would have said 3 years ago which wouldn't have been the same things I would have said 6 years ago.

    Cheers - L~R

      funny list :)

      I would want to keep format, but make it work, and make it actually work, also on lexical file handles, nestable, extendable, versatile etc etc. There are a few useful modules on CPAN already, but none of them actually makes it easy to convert from the good ol' format to what the modules offer. They all have their merrits. Let's bundle and make it useful!

      I'd throw out threads. Completely.

      I'd make auto-conversion from 32bit ints to 64bit ints to bignum and vv more native, so you never loose significance on integers

      I would remove modules from CORE that do not belong in CORE, such as CGI and Text::SoundEx

      I'd like the TIE system to be more transparant, and work on all data types (currently Tie::Handle is broke, and there is no Tie::Format. Imagine the fun you could have with the latter


      Enjoy, Have FUN! H.Merijn
Re: What would you change?
by jplindstrom (Monsignor) on May 17, 2008 at 19:38 UTC
    Language support for:
    • A non-destructive s/// operator which returns the new string.
    • subs/methods with proper parameter lists (the usual stuff: names, Perl types, default values, basic type annotations)
    • Calling subs/methods with either positional or named arguments.
    • Declared methods, like "sub" but with implicitly declared $self.
    • Declared class methods, like "sub" but with implicitly declared $class.
    • Autoboxing which treats e.g. hashes and hashrefs in a similar way. This may remove the need to fix the ugly dereferencing syntax mess.
    Many of these things seem fairly compatible with Perl 5. Some may just need a bit more support in core perl to be solid and/or fast enough to be usable.

    /J

Re: What would you change?
by TimToady (Parson) on May 20, 2008 at 00:32 UTC
    I have a few ideas on this subject, but I am currently Too Busy to tell you about them. :-)

      Indeed :) I hope that the recent benevolence to the TPF is allowed to assist you personally in the goal.

      The thought train that lead to my asking the question was my starting to wonder if there weren't some minimal subset of changes to Perl 5 syntax and semantics that might act as a halfway house between Perl 5 and Perl 6.

      A clean break from the backward compatibility yoke, but that required minimal changes to existing sources,in order to accomodate the clean up and removal of long (technically or emotionally) "deprecated" parts of Perl 5 whilst retaining broad compatibility. And whether this cleaned up and enhanced (without extreme additions) language might be sufficiently simpler than the full-blown Perl 6 spec to allow it to a) be avialable more quickly; b) acts as a migration path to the full deal.

      I realise that there have been several similar proposals (and even starts:Ponie?) in the past, but my thought was that maybe the combination of a) not slavish adherance to Perl 5 compatibilty; b) not the full gusto of Perl 6 enhancements; c) just enough changes to fix a few pertinent, long-standing beefs and wish-list items; might give the idea impetous.

      However, given the proposals ideas put forward in this thread so far, there does not seem to be a common subset of desires, nor even a common direction. Everyone seems to want different things from "the next Perl" and each would pull it in a different, and usually conflicting direction.

      Which only goes to show what a complex and thankless task you set yourself with the open design process you started those years ago, and what a remarkable balancing act you've had to pull to achieve the level of consensus you achieved. I read somewhere earlier today a statement that went something like: "individuals think better than commitees". But at least commitees have finite numbers of minds, and each member represents and filters the desires (aims; goals; prejudices;) of the many minds that sit behinds them.

      I once flirted with the notion that in the modern, internet-connected world, democracy should replace MPs (political representatives in governmental forums) with one-man, one-electronic-vote, directly upon the issues themselves. The idea is attractive for many reasons, not least because it would render party politics impotent.

      I've seen it dismissed on various grounds, most commonly the scare-mongering and emminently technologically fixable problem of ensuring security, privacy and freedom from electronic ballot stuffing. I've recently come to realise that the single biggest barrier to the removal of the "representative" from the mix, is the inherent and very valuable filtering role they perform.

      I do not envy you your task. And if I could see a way of helping, without adding to the drag of controversy, I would. Another quote I read recently comes to mind: "Deliberate with caution, but act with decision; and yield with graciousness, or oppose with firmness." I'm pretty good at two of those, and a third is within my grasp (with some effort). But the fourth is something I've always struggled with and it seems to be getting harder as I get older.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: What would you change?
by moritz (Cardinal) on May 18, 2008 at 14:22 UTC
    We can dream, can't we?
    • Strictures on by default
    • I don't like the dot . for string concatenation, it's too easy to overlook. Use ~ instead. Method calls can then be written as $obj.meth
    • Variable binding with :=. Disallow empty attributes instead. (my $x := is now parsed as my $x with empty attribute at the LHS)
    • Optional signatures for subs and methods.
    • Remove the comma operator for separating statements (like in do_a(), do_b() for @list). That way we could parse many lists unambiguously without parenthesis.
    • Strictly separate byte strings and text strings. Regexes that contain codepoints larger than 255 should not be applicable to byte strings (and should croak), likewise doing IO with text strings. The current approach is hard to understand and hard to debug.
    • Make string functions (like length, substr etc.) act on graphemes instead of codepoints by default.

    I admit that most of that (if not all) is bluntly stolen from the Perl 6 synopsis. It's the subset of features I really like, and that could be integrated into perl 5 without making it a different language altogether.

Re: What would you change?
by shmem (Chancellor) on May 17, 2008 at 15:10 UTC
    Preferably do not upvote it. (Downvote at your choice.)

    Couldn't resist to upvote your post. Downvote mine if you like ;-)

    I would change bless() to construct an inside-out object incorporating Alter into the core, so that bless { @_ }, $class provides a real inside-out object with a hidden alter ego for free, which is thread-safe, garbage-collected and accessible only inside this object's package:

    package Foo; sub new { my $class = shift; bless { @_ }, $class; # @_ goes into this ref's alter ego } sub bar { my $self = shift; $self->{bar} = shift if @_; # access $self's alter ego $self->{bar}; } package main; my $ref = Foo->new( bar => 'quux'); # empty blessed hashref returned $ref->{bar} = 'blorf'; # used as a normal hashref print $ref->bar, "\n"; # yields 'quux' print $ref->{bar}, "\n"; # yields 'blorf'

    That way, an object would behave as a normal perl data type if so treated, but as an object calling one of its methods. Private and public attributes for free.

    No, I haven't thought about all the consequences...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: What would you change?
by rhesa (Vicar) on May 18, 2008 at 00:46 UTC
    I've just read the other suggestions. That kinda taints my answer, as I'd have said: "I'd want to remove (as far as possible), the inconsistencies and arcana that I'm no longer aware of because I've memorized them by now, but which took quite some time to learn".

    Actually, I think the changes I'd most like to see revolve around making perl a bit friendlier towards functional and OO programming. Function/method definition and invocation could be less verbose. See for example Method::Signatures for a step in the right direction (Moose is lovely too, of course).

    update: Oh, I forgot! I would absolutely love to have lvalue methods that work. I'm getting really tired of having to write $foo->bar( $foo->bar() + $wibble ). I'd like to be able to use more syntax than just ->() once in a while.

Re: What would you change?
by Porculus (Hermit) on May 18, 2008 at 14:19 UTC

    I would fix the expression/block ambiguity in map and similar functions: they do usually DWIM, but there's always that nasty niggling uncertainty...

    It would be such a simple fix, too! map { ... } could simply always indicate a block, not a hashref expression, which would thus always be written map +{ ... }. Problem solved.

Re: What would you change?
by Joost (Canon) on May 20, 2008 at 00:17 UTC
    I'd like something that has everything that Common Lisp has but with the ease of Perl. Ruby's somewhere in that spectrum, but I'm pretty sure we could do better by ditching more syntax. IOW something that has reliable, predictable macros and syntax, but with just a little more visual cues and a lot more readable and standardized built in function names than Lisp (possibly stealing and extending scheme's punctuated names).

    And really we should lose all or all but one sigil the whole $/@/% thing is just messing up generic calls.