Categories
Posts in this category
- A shiny perl6.org site
- Creating an entry point for newcomers
- Sprixel, a 6 compiler powered by JavaScript
- Another perl6.org iteration
- Blackjack and Perl 6
- Why I commit Crud to the Perl 6 Test Suite
- Report from the Perl 6 Hackathon in Copenhagen
- Custom operators in Rakudo
- Defined Behaviour with Undefined Values
- Dissecting the "Starry obfu"
- Perl 6: Failing Softly with Unthrown Exceptions
- The first Perl 6 module on CPAN
- Google Summer of Code Mentor Recap
- Building a Huffman Tree With Rakudo
- Immutable Sigils and Context
- Is Perl 6 really Perl?
- Perl 6: Lost in Wonderland
- Lots of momentum in the Perl 6 community
- Musing and the future of feather and the Pugs repository
- Musings on Rakudo's spectest chart
- My first executable from Perl 6
- Trying to implement new operators - failed
- Let's build an object
- Perl 6 is optimized for fun
- How to get a parse tree for a Perl 6 Program
- Perl 6 in 2009
- Perl 6 ticket life cycle
- The Perl 6 Advent Calendar
- How to Plot a Segment of a Circle with SVG
- Publicity for Perl 6
- Rakudo architectural overview
- Rakudo Rocks
- Rakudo "star" announced
- Rakudo's rough edges
- Rats and other pets
- Releasing Rakudo made easy
- Set Phasers to Stun!
- Starry Perl 6 obfu
- Recent Perl 6 Developments August 2008
- Strings and Buffers
- Subroutines vs. Methods - Differences and Commonalities
- A SVG plotting adventure
- A Syntax Highlighter for Perl 6
- Test Suite Reorganization: How to move tests
- The Happiness of Design Convergence
- Perl 6 Tidings from September and October 2008
- Perl 6 Tidings for November 2008
- Perl 6 Tidings from December 2008
- Perl 6 Tidings from January 2009
- Perl 6 Tidings from February 2009
- Perl 6 Tidings from March 2009
- Perl 6 Tidings from April 2009
- Perl 6 Tidings from May 2009
- Perl 6 Tidings from May 2009 (second iteration)
- Perl 6 Tidings from June 2009
- Perl 6 Tidings from August 2009
- Perl 6 Tidings from October 2009
- Timeline for a syntax change in Perl 6
- Visualizing match trees
- We write a Perl 6 book for you
- When we reach 100% we did something wrong
- Where Rakudo Lives Now
- Why was the Perl 6 Advent Calendar such a Success?
- What you can write in Perl 6 today
- Why you don't need the Y combinator in Perl 6
Tue, 12 May 2009
Subroutines vs. Methods - Differences and Commonalities
Permanent link
This is mostly a response to s1n's post about subs
and methods in Perl 6. He maintains that since methods are very common in
classes, a sub declaration inside a class should automatically
get the semantics of a method. The reason was a deep confusion about what the
difference is, and if they are different at all (especially since class
methods and subs look very similar at first).
I want to stress that both are quite different in some ways, and indeed deserve different keywords. I won't discuss multi subs and multi methods, because they add nothing new to the points I want to make.
Methods
A method is a piece of code that is associated with an object, which we call the invocant (at least in Perl land). It can never be called without the invocant.
The lookup behaviour of a method is independent of the calling code's scope ore namespace; in the abstractest sense an object passes deals with method calls by passing that method call to its "meta" object (ie that things that manages the object under the hood).
The default meta object looks for that method in the actual class of the object, and if it can't find the method there it'll fall back the parent classes.
Note that this mechanism might be rather different for calls to foreign languages; if you call a method on a Lisp object, then the dispatch will happen with Lisp semantics.
In Perl 6, all methods automatically get access to the invocant through the
self keyword.
Note that "class" or "static" methods are still ordinary objects, just the invocant is the class itself (or the type object), not an instance of that class.
Subroutines
Subroutines, short subs, are pieces of code that don't have an invocant, and live in a symbol table, a lexical scope or an ordinary variable holding it.
Calling a sub (that's not stored in an ordinary variable) involves looking down the lexical scopes, and falling back to the symbol table.
Subroutines in classes
Usually subroutines live in modules, but they can also exist in classes. However they don't have access to any attributes of that class, just to outer lexicals (as any piece of code in Perl 6 has).
Or to phrase it differently, it's like placing a subroutine in the namespace that the class happens to introduce anyway.
The "different things should look different" paradigm
In Perl 5, often things that do quite different things look very much the
same. One example is reverse, which
does string reversal in scalar context, and list reversal in list context.
That implied that print reverse "abc"; actually prints
abc, which is very confusing to the beginner, and still annoying
to everybody else.
It also uses the same keyword for subs and methods, because in Perl 5 there's no difference between the two, only the invocation makes the difference. That proofed rather difficult for introspection and static code analysis.
The proposal to automatically promote subs to methods inside classes brings us back to the dangerous part of having different things looking similar; it also raises the question how you declare subroutines (not methods) inside a class. We'd have to invent a new syntax for that.
Then when somebody asks how do I write a sub in Perl?, the answer
would be you simply write sub name { ... }, except in classes,
where you write really_a_sub name { ... }. I don't want that
kind of answers in our Perl 6 FAQs.
Comments / Trackbacks:
Trackback URL:
/blog-en/perl-6/subs-vs-methods.trackback
Colin Barrett wrote
I always thought that Python's explicit self for methods was quite elegant.
sub this_is_a_method($self, $a, $b)
sub this_is_just_a_sub($a, b)
The rule about postfixing : would still apply as well, a plain $self would be the only exception.
Write a comment
The comments on this blog post have been disabled; the comment form below will not work.