Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Perl's Syntactic Legacy

Perl's Syntactic Legacy

This is a talk I gave at YAPC::NA 2015 in Salt Lake City (http://www.yapcna.org/yn2015/talk/6085). The video can be found here: https://www.youtube.com/watch?v=sJC725e8ysM

Stevan Little

June 10, 2015
Tweet

More Decks by Stevan Little

Other Decks in Programming

Transcript

  1. Legacy /ˈlɛɡəsɪ/ ! adjective ! of or relating to old

    or outdated computer hardware, software, or data that, while still functional, does not work well with up-to-date systems.
  2. /ˈlɛɡəsɪ/ ! noun ! something handed down or received from

    an ancestor or predecessor Legacy descendant or successor
  3. This talk is about ‣ the evolution of a design

    ‣ the slow breakdown of my own stubbornness
  4. Goals 1. class attributes (slots) 2. class/method vs. package/sub 3.

    role composition 4. introspection API 5. improve OO syntax
  5. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  6. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  7. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  8. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  9. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  10. package Point; ! sub new :method { my $class =

    shift; bless { x => 0, y => 0 }, $class; } ! sub clear :method { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  11. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  12. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  13. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  14. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  15. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  16. package Point; ! sub new { my $class = shift;

    bless { x => 0, y => 0 }, $class; } ! sub clear { my $self = shift; $self->{x} = 0; $self->{y} = 0; }
  17. class Point { ! has $x = 0; has $y

    = 0; ! method clear { ($x, $y) = (0, 0); } }
  18. moe

  19. My Moe Wishlist • A more consistent syntax and sane

    grammar • with a real AST • and better tooling support • A less insane runtime • proper MOP (everything is an object) • slimmer core • easy (non-XS) extension mechanism • On a modern VM platform • JVM / CLR / LLVM / V8 • cross language sharing
  20. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  21. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  22. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  23. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  24. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  25. package Foo; use strict; use warnings; ! use Variable::Magic qw[

    wizard cast ]; use Hash::Util::FieldHash qw[ fieldhash ]; ! fieldhash my %foo; ! my $wiz = wizard( data => sub { $_[1] }, set => sub { $_[1]->[0]->{ $_[1]->[1] } = $_[0] }, ); ! sub foo { my $self = shift; my $foo = $foo{$self}; cast $foo, $wiz, [ \%foo, $self ]; ! $foo = shift if @_; $foo; }
  26. package Foo; use strict; use warnings; ! has ‘foo’; !

    method foo { $foo = shift if @_; $foo; }
  27. Everything should be as simple as it can be, but

    not simpler. – Albert Einstein
  28. It can scarcely be denied that the supreme goal of

    all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience.
  29. • Plack • HTTP::Headers::ActionPack • Promises • Bread::Board • Reply

    • Forward::Routes • Action::Retry • Hashids • Net::IPAddress::Util
  30. $ perl -MDevel::Peek -e 'sub foo; Dump \&foo;' SV =

    IV(0x7fa3b3003428) at 0x7fa3b3003438 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x7fa3b3028978 SV = PVCV(0x7fa3b30271b8) at 0x7fa3b3028978 REFCNT = 2 FLAGS = () COMP_STASH = 0x7fa3b30032b8 "main" ROOT = 0x0 GVGV::GV = 0x7fa3b3028960 "main" :: "foo" FILE = "-e" DEPTH = 0 FLAGS = 0x0 OUTSIDE_SEQ = 0 PADLIST = 0x0 OUTSIDE = 0x0 (null)
  31. perl -MDevel::Peek -e 'sub foo :method { 1 } Dump

    \&foo;' SV = IV(0x7fec82003428) at 0x7fec82003438 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x7fec82029318 SV = PVCV(0x7fec82027bb8) at 0x7fec82029318 REFCNT = 2 FLAGS = (METHOD) COMP_STASH = 0x7fec820032b8 "main" START = 0x7fec81c0dae8 ===> 1 ROOT = 0x7fec81c0da60 GVGV::GV = 0x7fec82029348 "main" :: "foo" FILE = "-e" DEPTH = 0 FLAGS = 0x1 OUTSIDE_SEQ = 95 PADLIST = 0x7fec81c0cac0 PADNAME = 0x7fec82029378(0x7fec81c0cf90) PAD = 0x7fec820293c0(0x7fec81c051e0) OUTSIDE = 0x7fec82003648 (MAIN)
  32. + use v5.20; + use experimental ‘signatures’ + - SV*

    - parse_signature (code, …) - # A WHOLE LOAD OF CRAZY XS - # PARSING CODE THAT MADE YOUR - # EYES BLEED AND YOUR HEART - # SINK IN DEEP DESPAIR - # *sigh*
  33. sub foo; ! sub bar :method { … } !

    sub baz ($gorch) { … }
  34. package Foo; use v5.20; use warnings; ! our %HAS =

    ( bar => sub { “BAR” }, baz => sub { “BAZ” }, ); ! 1;
  35. our @DOES = (‘BarRole’); ! our %HAS = ( bar

    => sub { “BAR” }, baz => sub { “BAZ” }, );
  36. Many of the OO conventions that we take for granted

    are largely inherited from Java, ! … which barely existed when Larry designed the OO features of Perl 5.