Note: these documents may be out of date. Do not use as reference! |
To see what is currently happening visit http://www.perl6.org/
It's the last Perl 6 Summary of 2003 already. Where did the year go?
A large part of my year went down the plughole in the great double disk disaster which saw about 3 years of mail, a few gigabytes of photos and my entire summary archive disappear into the ether. I have backups now. This means I won't be going back through the archive to give you a potted history of Perl 6 and Parrot 2003. Instead, I'll plough on with what happened last week, starting with perl6-internals.
A few weeks ago, Dan asked for volunteers to implement a nice Parrot OO interface to the Postgres RDBMS to replace the purely procedural version that he wrote before Parrot had objects. Harry Jackson has stepped up to the plate. Go Harry.
Threads are evil. But they're also handy tools for a lot of work. This dichotomy means that people have opinions about them. And they express them. The rolling threads thread made it to p6i this week. Well, it made it to p6i last week too, but (in the nature of the roving threads thread) it continued this week too.
Later in the week Dan laid down the ground rules and the beginnings of the design of Parrot's thread capabilities. Essentially, Parrot will guarantee that 'nothing that bytecode does should be able to corrupt the internals of Parrot'. C extensions are free to muck up everything, but they should try not to. That's about the only guarantee Parrot will make; keeping user level code thread safe is the job of the author of said code. Dan went onto list the various rules about how data is shared between threads.
This being a threads thread a few people dragged it off into a discussion of how to design programs with/without threads. Ho hum.
Leo Tötsch got stuck into the technical meat of Dan's post, and kicked off a discussion of the impact of threads on the memory management system (in the presence of threads, a copying garbage collector becomes impractical for instance, and things can get ugly when, say, thread 2 needs to grow a shared string that originated with thread 1).
groups.google.com[10.0.1.2]
groups.google.com[10.0.1.2]
Cory Spencer wanted to know if it would be possible to push a
character/byte back onto a ParrotIO stream. Melvin Smith promised that
parrot would get both unget
and peek
but not necessarily until
he'd recovered from a bout of flu.
Why does it have to be so hard to give stuff away if you want to stop other people claiming it as their own? Not content with having the thread thread, this week also saw the return of the licensing thread. Dan wants to have any library wrappers like ncurses.pasm that get included with Parrot be as nearly in the public domain as their authors can make them. The few people that commented agreed with him.
groups.google.com[10.0.1.2]
Not content with having a threads thread and a licensing thread, this week also saw a "Python's really quick on .NET" thread. It seems that Miguel de Icaza has been showing off some benchmarks from 'IronPython', a Python compiler that targets .NET. Dan was dismissive, pointing out that the bits of Python that will 'give .NET serious fits' hadn't been implemented. Joe Wilson wasn't so sure and, later in the thread, implemented a couple of benchmarks that gave some worrying performance numbers (with Perl 5 going substantially faster than Parrot). This led to a certain amount of rewriting of the benchmarks to make them really equivalent and Dan realizing that there's a need for a faster, less flexible base array type.
Joe also came up with a recursive Fibonacci sequence function that ran horribly slowly in its IMCC incarnation when using the full Parrot Calling Convention. Again the code generated needed optimizing, but it did point up some issues that will be looked at. Leo Tötsch in particular redid the original benchmark with continuation creation hoisted out of the loop and ended up with an IMCC version that, unoptimized, ran about 33% faster than the Perl code. Work continues on identifying and fixing the bottlenecks these benchmarks threw up.
Jonathan Worthington pointed to some documentation from Microsoft which states that, in the future, Win32 will turn on execution protection of data pages by default, which has implications for any JIT system. The fix is to use the appropriate Win32 API call to allocate memory that's marked as okay for execution. Jonathan wondered if this would have any effect on the current Parrot Win32 JIT. In short, yes it does (and it's apparently already causing problems with Parrot's JIT when running on Redhat's Fedora). Leo proposed a parrot internal API for allocating executable memory and wondered how to probe for the appropriate system calls at Configuration time.
Dan is pondering adding a new type which automagically converts a Parrot level Array into a C array but wondered if that might just be making the NCI interface too big. Various people said that they'd find such a type very useful and told Dan to go for it.
groups.google.com[10.0.1.2]
foldup
opDan added a new foldup
operator to parrot's assembly
language. foldup Px
sticks a new Array PMC into Px containing all
the PMC arguments, both from the registers and from the overflow
array. This should make working with variable argument lists and
unprototyped calls somewhat easier.
groups.google.com[10.0.1.2]
Dan's added an External PMC Registry to the design. The idea is to register PMCs that get passed into external libraries and may cease to be reachable from the current root set (those things in memory that the Garbage Collector uses as its initial set of live objects when doing a DOD run) for a short while. The registry of PMCs will, of course, be considered part of the root set. It's not been implemented quite yet, but it's only a matter of time before Leo posts a patch. Why not see if you can beat him to it?
groups.google.com[10.0.1.2]
It was quiet. Too quiet. A single message blew through the list like tumbleweed, discussing how Perl 5 style objects will work in Perl 6 (according to Dan, the poster, they'll work like they always did).
So, without further ado
As perl6-language was so quiet this week, I've taken the opportunity to finally get 'round to providing an overview of Roles/Traits/Properties. Note that I've almost certainly got the syntax wrong, but hopefully it's close enough in flavour to what Larry's been thinking about that you'll have some idea. And it does at least give a baseline so you'll be able to understand what people are talking about in future.
In the original paper, Traits are introduced to provide small units of reusability that can be neatly composed with small amounts of glue code within classes. The example they use is of a drawable circle class that is implemented by composing the traits TCircle and TDrawing.
A Trait is a little like a partially abstract class, but instead of virtual methods it has required methods. Here's a Perlish version of the paper's 'TDrawing' Trait which deals with drawing in a generic fashion (We assume a Smalltalkish environment)
trait TDrawing; requires &.bounds, &.drawOn; method draw { .drawOn: World.canvas } method refresh { .refreshOn: World.canvas } method refreshOn($aCanvas) { ... }
Meanwhile the TCircle Trait represents the geometry of the circle,
with methods like area
, bounds
and circumference
. As described
by the original paper, Traits don't have any state of their own, so
TCircle requires accessors for the centre
and radius
attributes. Here's my rough take on what TCircle might look like:
trait TCircle; requires(Point $.centre, $.radius); method area { PI * .radius ** 2 } method circumference { PI * 2 * .radius } method bounds { given Vector(.radius, .radius) { return [ .centre - $_, .centre + $_ ] } } ...
These Traits can then get composed to make a real class:
class Circle; has Point $.centre, $.radius; does TCircle & TDrawing; method drawOn($self: Canvas $aCanvas) { $aCanvas.fill_oval($self.bounds, colour => Colour.black) }
The paper goes on to discuss conflict resolution. Suppose we have our
TCircle trait, which (amongst other things) handles testing for the
equality of circles, and we decide we need a ColouredCircle class that
makes use of a TColour Trait, which handles testing for the equality
of colours. This means that both Traits implement an equals
method. We need to resolve this in some fashion. Here's how the
original Traits proposal handles things (I'm making guesses as to the
Perlish versions of the syntax...)
class ColouredCircle; has $.centre, $.radius, $.rgb; does TCircle but rename( &.equals => &.circle_equals ) & TColour but rename( &.equals => &.colour_equals ); method equals($other) { .circle_equals($other) && .colour_equals($other) }
Or, if you decide colour is unimportant when comparing the equality of circles:
class ColouredCircle; has $.centre is protected, $.radius is protected, $.rgb is protected; does TCircle & TColour but without( &.equals );
Of course, this being Perl, the original Traits formulation doesn't go
far enough because Traits don't have state of their own, so let's
start speculating. Consider the TCircle Trait. it would be great if
you could specify that the Traits should provide the centre
and
radius
attributes if they didn't already exist (At this point I
think we're really talking about a Perl 6 Role, so lets introduce the
'role' keyword instead)
role RCircle; requires $.centre is optional, $.radius is optional; ...
In other words we state that, if the class/other roles don't provide
those attributes, then RCircle should provide its own. There probably
needs to be a way of specifying whether such attributes are private to
the role or shared with other roles etc, but that can be worried about
later. Or say you're working on a Comparable role (a la Ruby) and
you'd like a default implementation for a &.cmp
method, you might
be able to do (but there will probably be substantially better syntax
for doing it):
role Comparable; requires &.cmp is implemented(method ($other) requires(&.magnitude) { .magnitude <> $other.magnitude });
so classes that don't provide a working &.cmp
get a default
implementation (assuming they provide a working &.magnitude
instead).
Larry has been talking about using Roles to implement runtime
properties too (The canonical example being return $value but
true
). The idea seems to be that applying a property to a value turns
that value into an instance of a singleton class with an added
role. However, this is proving to be a little thorny. The problem is
that, in applying a property you sometimes want to override the
underlying object's implementation of some things (for instance, but
true
needs to override the usual boolean methods of the underlying
object) and at others you want the property to respect any preexisting
things (<$circle but blue> should probably set any underlying $.rgb
attributes correctly). I'm sure the problem is soluble, but that
doesn't make it easy.
I think Larry has implied that a Role can be used in a method signature as if it were a type, so one could write:
method some_method(DrawableRole $glyph) {...}
and any class which used the DrawableRole role would satisfy the type
requirement. If you think about it, this means that you could use a
role like a Java interface. In the 'pure' interface variant you would
only have a requires
section:
role NSDraggingDestination; requires { method draggingEntered(NSDraggingInfo sender) {...} method draggingUpdated(NSDraggingInfo sender) {...} method draggingEnded(NSDraggingInfo sender) {...} method draggingExited(NSDraggingInfo sender) {...} method prepareForDragOperation(NSDragginInfo sender) {...} method performDragOperation(NSDragginInfo sender) {...} method concludeDragOperation(NSDragginInfo sender) {...} }
I want Camel6Bones, and I want it now (actually, I'd be happy with a CamelBones that worked with Perl 5 and OS X 10.3, but I like to think big).
The toolmaker in me notes that Roles really come into their own when you have tool support for them. The authors of the original Traits paper modified the Squeak class browser in such a way that a Class could be looked at as a collection of Traits or you could flatten the traits out and view it as a collection of methods. Hopefully it will be a good deal easier to write similar tools for Perl 6 than it is to write them for Perl 5.
Thanks to everyone for reading these summaries, and special thanks to those of you who've sent me feedback over the course of the year. My postbag has been small, but positive. No thanks at all to the scum-sucking lowlifes who continue to pepper my mailbox with spam; I've stuck with one main email address for nearly 10 years now, and I'm not about to change it just because of the utter arsewits who keep trying to sell me Viagra or Lolitas or a fortune in Nigerian bullion. It doesn't mean I'm not tired of it though.
Thanks to Leon Brocard for being so good humoured over the months that a certain running joke has dragged on. Leon, I promise that you will only be mentioned in the 2004 summaries if you've actually done something Parrot or Perl 6 related to warrant your inclusion.
Thanks and best wishes to Larry, Damian, Dan, Allison, Leo, Luke, Melvin, Garret, Steve, Daniel, Brent, Jürgen, Clint, Gregor, chromatic, the various and several Michaels, Austin, Smylers, David, Joseph, Stéphane, Gordon, Jonathan, Paul, Ziggy, Andy, Chip, Simon and all the others that I've missed for giving me so much to write about (even if I haven't quite understood what I'm supposed to be summarizing on occasion).
If you find these summaries useful or enjoyable, show your appreciation by contributing to the Perl Foundation to help support the ongoing development of Perl. Money and time are both good. Also, I'm always pleased to get feedback at [email protected]'>p[email protected] and traffic at my website.
donate.perl-foundation.org -- The Perl Foundation
www.bofh.org.uk -- My website, Just a Summary