Tuesday, December 31, 2013

First Sunrise 2013

Last year, I managed to wake myself up early enough to see the first sunrise of the year , because I managed to convince myself that it was "research" for writing my fanfic.  This is a Japanese custom known as Hatsuhi (初日 - literally "first day"), where people will go outside, often together, to catch the first rays of light of the new year.  I didn't have a blog last year to share this on, but I did write an account in an email to a friend.

If you did watch the Rose Parade [in 2013], you may have noticed that it was not particularly sunny, but the weather wasn't bad -- just a broken altostratus deck.  So there was a good chance that I would see new sun as it shed the first light on the new year.

I woke up at around 6:50, and threw on a flannel shirt over my flannel pajamas. When I first woke up, the sky was still dark enough that I could see a couple of planets, but dark clouds obscured most everything but the bright gibbous moon.  I got out a ladder and set it up against the house -- the lightest part of the sky was behind the orange tree, so I had to climb up to get a better view.

The black shingle of the roof was cold to the touch, but the wind was calm, and I still warm from bed.  I ambled up the the apex of the garage, so as not to wake anyone up, and turned towards the eastern sky.  There were still a lot of trees -- more than I had thought there were in my neighborhood -- but it was obvious from the clouds that I wasn't going to see sunrise directly.  The appointed time, 7:03, came and went, with only a slight brightening of the eastern sky.  Of course, I thought -- the sun's gotta rise above the Santa Monica Mountains.  I did a quick calculation: 3° above the horizon is about 10 minutes -- and settled down to wait.

A pair of crows joined me on a nearby power line, staring eastward too.  The sky started to brighten as the sunlight filtered to the bottom of the clouds, and suddenly the gloomy sky was replaced with a warm glow.  Everything started to come alive, and the finches started singing their calls, telling all of the other birds, "Hark, awaken, for a new day has come, everyone be excited.  I'm going to tweet to everyone I know, Happy New Year!  Hey everyone, wake up!"  And then of course, they stopped, because everyone knows only 140 characters can fit into a tweet.

The crows, whom by this point I had nicknamed Phobos and Deimos, awaited the sunrise.  And then, finally, the bottom of the clouds at the horizon was lined with a golden glow.  And, that was it.  Phobos cawed to Deimos, "Huh, is that it?"  They looked on for a moment more, before the reply came from Deimos, "Yeah, I guess that's all it's gonna be."  Some crows in the large ficus behind us called out, and my crow friends departed to join their friends for the day.

But, I had gotten up especially for this, so I was undeterred.  It looked like a break in the clouds was up a little bit further, and I was definitely going to catch the first rays of sun.  A man passed by, walking a dog, disturbing the canine living next door.  I took the chance to look at the hills, and the sky, and the strip of ocean to the south.  Things really do look different from up high, so I took in the view of the house's roofs as a pair of house finches zoomed by me.

And then, ten minutes later, the sun finally broke through the clouds -- well -- partially.  It was still obscured by the clouds, so I couldn't see the golden disk.  But I saw a bright enough glow to etch the afterimage into my eyes.  I blinked, and the image of the sun's light through the clouds formed a shape that looked exactly like this: ^_^   The sun had smiled upon my weeaboo endeavor, and blessed me with an Asian smiley for the new year.  And with that, I accepted the blessing and headed back down to a warm bed.

Wednesday, December 18, 2013

The Edge of the Creative Commons

As you may or may not be aware, last year I left TV Tropes (TVT) on unfriendly terms.  I may have been banned, but the feeling was certainly mutual.  I felt that the TV Tropes policy on keeping things "family friendly" had gone to a ludicrous extreme, eliminating academic discussion of things that made administrators and advertisers uncomfortable.  I was not alone in leaving TVT.  I was banned for noting that their "panel of people who determine what content is appropriate" is in fact a "Censorship Panel" -- but others just saw the way that the wind was blowing and left.

When I left, I wanted to leave open the possibility of forking the project, so I did a low-speed crawl of the website, that gathered up source pages, and did under 200,000 requests over the course of seven days.  I hadn't really planned on running a wiki, but I wanted to gather content before it was all censored and/or deleted.

At that time, the wiki had a message in the footer:

This wiki is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
That was before I told a forum that I had done a siterip.  Fearing that I might use this data to fork the wiki, the TV Tropes website unilaterally changed it's license to the CC-BY-NC-SA 3.0, adding the NonCommercial clause to the license.  Note that these are not compatible licenses -- CC-BY-SA derivatives must be CC-BY-SA licensed; CC-BY-NC-SA derivatives must be CC-BY-NC-SA licensed.  They never asked the wiki editor's consent to make the change.  This happened in July of 2012. 

I don't believe that this move was, in fact, legal.  The barrier to editing, the "Getting Known" page, was, in its entirety:
Being known on the wiki means that the software is aware of your wiki handle (user name). It reserves the use of your handle for you, and provides some services to known people that are not available to completely anonymous folks. Posting and editing are reserved for people 13 years of age or older. By posting or editing here, you are stating that you are at least 13 years old.
Handle:   
(spaces will be removed)
Password:   
(passwords are case sensitive)
Create Know-age!
You can also use this form to just set/reset your cookie on this machine, if you are already known. Put your handle and password in the boxes above and press:

Already Known. Just bake a new cookie.
Quick link to You know, that thing where ...

"Well, duh," you are thinking. "It's a user account." Not exactly. We don't bug you for an email address. Using this form is the entire process. We do need to put a cookie on your system, so you'll have to allow that. You will be logged in on the machine you are using now automatically, unless something happens to the cookie.
Looking over that, I never granted TV Tropes any rights to relicense content that I wrote.    I never granted them any explicit license, in fact.

I simply assumed, that as an editor of a wiki that displays a CC-BY-SA license, that my content would be distributed under those terms.  As the EFF notes, posting something online can come with an implied license to distribute the content under the terms stated on the website.  I don't dispute that.   I granted an implied license (and hereby explicit) to distribute all content I wrote on tvtropes.org under a CC-BY-SA 3.0 license.

But I did not grant them any ability to change that license.  And when you distribute CC licensed content outside the terms of the license, their license to use your work -- and all derivative works -- is terminated.

As I got around to launching a new wiki to compete with TV Tropes, these issues came back into the foreground.  People started asking if we could copy over content from TV Tropes.  And the answer was not "no, they're using a different license from us"; instead we told people "no, because we cannot be sure that the content is not copyright infringement".

This sparked a reaction over at TV Tropes.  Someone asked about the license in this thread.   Then, on On November 11, 2013, one of their administrators posted this on the Administrivia/Welcome To TV Tropes page: 
By contributing content to this site, whether text or images, you grant TV Tropes irrevocable ownership of said content, with all rights surrendered ...

We are not required to attribute content you contribute to you, nor do you retain ownership of anything you contribute. Anything you contribute may be deleted, modified, or used commercially by us without notification or consent, to the extent permitted by applicable laws. For that reason, we strongly recommend that you do not post material on our site, whether in text or image form, that you wish to receive commercial benefit from in the future.
Well...!  I definitely did not expect that.  The TV Tropes administration has the cojones to not only assert ownership over my writing and relicense it, they also claim the authority to delete the evidence of the deed.  I guess they already violated the ShareAlike clause, so they might as well violate the Attribution one as well.  All while claiming to be a site honoring writers.  This is beyond the pale.

I could just send a DMCA request, requesting that they take down all of the pages that I edited -- and all revisions thereafter, because they're derivatives of my work.  This is how CC-BY-SA works.  And, as I said earlier, the CC license infringement terminates the CC license.  Legal action by myself and my allies could take out a huge swath of the TVT wiki.  But I didn't start a wiki to get into the content deletion business, so this idea makes me very uncomfortable.

At the same time, they are violating the rights of hundreds of writers on the site, by claiming ownership without even telling them.  There is still nothing in user registration that announces their "we own your work, so don't expect to ever profit from it" policy.  The page editor says that the site has a CC-BY-SA-NC license, but do not actually ask users to place their edits under this license.  Users are never directed to any kind of Terms of Service.  They do The Wrong Thing at every step of the way.

So if I don't stand up for these people, who will?  If a website is allowed to transition from Creative Commons to private ownership, that undermines the entire structure of the information commons.

In fact, their actions undermine the stability of both of our wikis.  Because only got an implicit license to distribute content -- and make multiple claims about what said implicit license means -- it undermines faith in the older CC-BY-SA license that we use to distribute data.  All The Tropes' license could be held invalid because of the outrageous claims coming from TV Tropes.

The legal situation for TV Tropes, however, is far worse.  Unlabled mixes of CC-BY-SA and CC-BY-NC-SA content are copyright infringement.  Period.  If an editor agrees to relicense his content under the new license, that's legal.  If we transfer ownership to TVT, that would be legal.  But I certainly haven't done either, and neither have my colleagues at All The Tropes.  So all pages that I edited which are still distributed at TVT are infringing.  All editors of those pages may also be copyright infringers, because they release a revision under CC-BY-NC-SA.  The weird mixed licensing situation at TVT is simply not tenable.

All The Tropes and TV Tropes are in a Mutually Assured Destruction situation, and I don't see a way out of it.  I am not a lawyer; maybe it's about time I hired one.

Sunday, July 21, 2013

Interpol Manzai, my new fanfic

I know anyone who's been following me so far thought that this might be a programming-centric blog, but that's not always gonna be the case -- my interests are pretty diverse.  You can always just search for the perl tag.

Anyway, I'm pleased to announce that I've finally gotten around to putting my fanfic online: Interpol Manzai, an Azumanga Daioh-centric megacrossover, following the lives of the cast of girls as they move into adulthood.  In particular, the Interpol part of the title refers to Tomo finally getting her dream job at the ICPO, which is something that you can get a lot of stories out of.  She can fly anywhere in the world looking for trouble -- and that's not to mention the trouble she causes herself, a la Dirty Pair.

The original idea came from a news report I saw back in December 2010, where I saw that Interpol issued an internation arrest warrant (actually a red notice) for Julian Assange.  I started wondering who Interpol would send to arrest him, and Tomo drifted to the top of my mind as the natural choice, lol.   So wrote that, and stayed true to original idea.

But as I got further into the story concept, I realized that I'd want to talk about all of the Azumanga characters as they move into adult life.  After all, I had gone through similar changes in my own life recently, and writing about is a good way of understanding myself.

I figured that since the anime ended in 2003, and the Assange story took place in 2010, I could age the whole cast seven years and see where they are now.  And they all went out and took on different paths in life, but I believe that they'd all still be happy people.  It certainly adds more of a sense of mono no aware, but the overall tone stays light and cheerful.  Plus, if they're taking on the wider world, it's a good excuse to throw in some crossovers.

Lots of crossovers.  Crossovers to You're Under Arrest, Yotsuba&, Ghost in the Shell: Stand Alone Complex, K-On!, Bubblegum Crisis, Kimi wa Petto, Lupin III, and whatever else I can think of.  So long as it it's a modern-day story without huge supernatural element, it's fair game.  It's a pretty diverse group, and therefore hard to keep on a light comedic note all the time.  But the Azugirls have good strong characters, and can deal with a bit of adversity.

In fact, they helped me with a bit of my own adversity.  I recently attended the YAPC:NA conference, as my blog readers know, and one of my main reasons for going there was to look for work.  And it's pretty intimidating, going in and trying to sell yourself with no experience, and very little resume to speak of.  But I was pondering Tomo, and about how she would never be insecure in a situation like that.  Like Jack Rakan told Negi Springfield in Negima, sometimes you just have to be a little bit stupider to be successful.  Sometimes, being happy and believing in yourself is enough.

So I went in there, and decided to act a bit more like Tomo.  More brash, more self-confident, and less concerned about making mistakes.  After all, hubris is one of the virtues of a programmer.  And #perl6 itself had talked about how "adults are imperfect children", because they're too afraid of failure when failure is one of the best ways to learn.  Like a child, Tomo Takino knows she's perfect.  Not factually perfect or free of mistakes, but in always trying to be the best, funniest, most exciting person she can be.

At YAPC I talked to everyone I could, networked like crazy, and summoned the best of my self-confidence.  I did keep a lower "annoyance" level than Tomo though.  Somehow, this actually worked for me, and I got a good $dayjob.   There's something to be said for a philosophy where you always reach for the heavens, but are happy when your hands come back with only a few raindrops.

Anyway, I'll be writing more fanfic when I have time, though my schedule is currently busy with $dayjob and writing Perl 6 stuff as well.  So go read the fic -- although it will help to have seen Azumanga Daioh before hand, hopefully you shouldn't have to -- and the first story is entirely done.  Feedback is very much appreciated; praise for my perfection and cursing my stupidity is equally desired.

Saturday, June 22, 2013

Camelia at Age 13: Perl 6 on the JVM Debuts

Perl 6 is now thirteen years old.  And she's very much a teenager in attitude, self-confident yet still growing up.  This contrasts with Javascript, which emerged from Brendan Eich's head, fully-formed like Athena -- but that only shared the Zeus-sized headaches with everyone until JQuery came along.

But Camelia, as she is fondly referred to by fans of Perl 6, is growing up fast.  Both too fast, and not fast enough.  To some of the community, the prospect of major changes to the language is scary.  Perl 6 is trying all of these crazy new things -- invariant sigils, metaoperators, grammars. She's even doing subroutine signatures, because "all of her friends are doing it".

They can't stay little children forever, you know.

And teenagers are liable to do surprising things.  So it was, that this week we announced Rakudo Perl 6 now runs on the Java Virtual Machine (JVM).  It's not perfect yet, but 62% of the files in the spectest pass as of yesterday.  Given the rate things are progressing, I'm sure it's already at a higher pass percent.

And yet, I'm sure there is no small number of you whose first thought about Perl on the JVM was "Heresy!".

There are certainly good reasons to support this point of view.  Startup times are horrible at this early stage, still O(seconds), and much of that is JVM's overhead.  It has well known security issues.  And of course the major implementation is controlled by $corporation, who just wants to make money off it.  And why would we want to abandon open-source VMs?

Still, there are plenty of good reasons for the port.  One is that the JVM is ubiquitous, and many devices have a copy pre-installed.  Most of Java's stability issues have been dealt with, and it serves Perl's competitors well enough through Jython and JRuby.  And it is well-documented, with bazillions of libraries (more than fooilions, anyway).  So we can finally address the longstanding desires of the community in things like sockets and threading, because we can tell the difference between our mistakes and those of the VM.

Instead of thinking of Perl 5 as a "sister language", I like to think of it as Camelia's father instead.  A father that might be kind of upset that she brought "that kind of language" into our house.  But she has a mind of her own, and I'm afraid that this won't be the only boyfriend she'll be bringing home.  There is a GSoC grant to build a Javascript backend to Rakudo.  And Niecza Perl 6 already uses the .NET Runtime.

However, Perl 6 is not abandoning open-source and C language implementations, either.  The announcement of MoarVM shows that Perl 6 developers plan to develop a lightweight VM specifically for NQP and Rakudo.  C functions will be directly callable within Perl itself, with the NativeCall interface.

Now, if Parrot fly off on its own course, that's Parrot's call.  You know how these teenage relationships go -- this could end up in a blow-up on the quad, or just as easily turn into hot makeup coding.  What, you didn't think I was going to say something that would violate the CoC, did you?

But Perl 6 is not done growing yet.  Camelia, like other teenagers, cares about fashion and wishes she had better threads.  And, once we get tuits, this is pretty high priority.  Because any modern language needs to live in the multi-core reality.  This is something that we can still design around,  that may not have recieved the same care ten years ago.  Many threading features are already baked into the language, like hyper operators and async blocks.

So I view the debut of the JVM port as Rakudo's real début, as with a debutante.  A treceañera, if you will.  I guess, given that she's 13, maybe it's a Bar Mitzvah -- except that she's not a boy, she's a butterfly.  But this is a chance acknowledge Perl 6's presence in the language scene.  Of course, these coming-of-age ceremonies don't mean the teenager is truly grown up yet. 

But grow up she will, and faster than some of you might like.  Perl 6 is rebellious, and changes things that those in her father's Perl 5 community don't understand.  But if you talk to the pumpkings, they sincerly hope that Camelia doesn't turn out exactly like her father.

After all, do we want keep the ithreads model?  Do we want to modules that dig into the compiler internals like XS does?  Perl 5 isn't perfect, we are just accustomed to its particular idiosyncrasies.

But for all that Perl 6 is different, she still loves her father.  We still have sigils, classes, @_ in subs (if you still want it), P5-style regexes, modules, and TIMTOWTDI.  It's still Perl.  Moreover, there are at least two efforts to run Perl 5 code in Perl 6 -- the v5 grammar/compiler in Perl 6, and access to libperl from MoarVM.  So the sky isn't falling on compatibility.

Nor is the other extreme true: Perl 6 development is in fact moving forward at a fast pace.  We know that Perl 6 is late.  Very late.  So late, in fact, that it's her father that's going to turn into a Pumpkin.  But when Perl 6 finally comes of age -- sooner than you think -- it will be something that the Perl community will be proud of.

And I apologize in advance for anything Camelia does in her bratty teenage years.

Thursday, June 6, 2013

Thanking the Perl Community for an Awesome YAPC

My first time at YAPC::NA was too incredible for words. That said, because this is a blog, I'm going to have to put it in words anyway.

So, about a month ago, I didn't even know that I was even going to YAPC.  I was just talking to raiph++ in an IRC back channel, when he asked me if I was going to the conference.  I said that it would be fun, but I didn't really have money to go.  Being unemployed means lots of free time for hacking, but not so much free money for going places.

Well, raiph told diakopter++, who asked if I could be willing to go, if he found funds.  I responded, "Of course, if you think it's possible."  I soon went to sleep, and twelve hours later, I had a plane ticket to Austin in my inbox courtesy of The Perl Foundation.   So just like Peter Rabbitson's case, the Perl community eagerly gave me a chance to attend.  So thank you to all 440 attendees, and all of the sponsors for your own personal contribution to my attendance.  Even though I'm new, you all gave a me a chance to participate in the community, and for that I am grateful.

And what a community it is.  I've long known that Perl programmers were a little strange.  Naturally, I fit right in.

The conference itself had quite a fun and informative series of talks.  More often than not, I had two or more that I wanted to attend at the same time.  For the most part, I stuck to the Perl 6 "track", where most of my work has been so far.  After all, it's not often that so many of the European contingent make a trip to our humble continent, so I was eager to spend time with them.

No one warned me that jnthn++ has a tendency to spring wild new features on us at YAPCs.  Reversible grammars, seriously?!  I'm still trying to wrap my head around that one.  The announcement of MoarVM was equally exciting, as it offers us a chance to start fresh with everything we learned about Perl 6 and virtual machines in the last five years.

So I have to say diakopter++ once again.  Besides introducing Moar in his talk, Matthew Wilson was constantly busy behind the scenes, making sure that everything ran smoothly the entire conference.  I think the man must be buying tuits on the black market.

YAPC also helped immensely in my hunt for a job.  The job fair brought me several contacts, and the talks helped me learn which skills I'll really need to learn in those jobs.  Person-to-person contact offers so much more in truly understanding the state of the language, and of what projects are of the greatest use right now.

Truly, Perl's community is it's greatest strength. 

It's the community that keeps Perl vital.  After seeing YAPC for myself, the whole "Perl is Dead" meme seems entirely baseless.  Conference attendance was up 19% over last year, which was the previous record high.  Perl feels like a growing language, with lots of experiments in how to revitalize the now 25-year-old syntax with p2, moe, and Perl 6.

The community keeps Perl relevant.  While it may not be the sole alternative to bash scripts like it once was, it is used for enterprise and homebrew projects alike, from the stock exchange to the surface of Mars.  Projects like DBIx, Moose, and Dancer provide modern frameworks to acomplish more with less work.

The community keeps Perl open.  No one seemed to be afraid to say what they felt, on CGI.pm or anything else, but everyone remained civil.  Hallway++ is a great social hack to get everyone to feel comfortable talking to each other.  So when I found myself sitting across from TimToady, instead of being intimidated as a newbie, I had a great conversation with him about supervolcanoes and nonverbal Japanese language.

And the community really wants all of the projects to succeed.  I spent a lot of time at non-profit and political events in the past, where we were all theoretically working for a common cause.  And yet scheming, conflict, and political maneuvering were inevitable.  But in Perl, where we actually have multiple implementations and modules competing for mindshare and tuits, people cheer for everything to succeed.  No one fights each other or rages against $language_of_the_week stealing our users, for the real enemy is the lack of tuits.

I overheard this at dinner last night, from a fellow first-time attendee:
"I'm just happy that the two of you liked my work." -- vanstyn
Although he was talking about DBIx, I think that captures the spirit of conference as a whole.  All of us here -- from the n00bs to the pumpkings -- want to share our work and make something useful for others.  It's not an organization where we wait for pronouncements from on high, but one where users create endless variations and share them.  Not an organization so much as a family.

During TimToady's epistle/speech to the community, he said something like:
"We have faith, hope, and love, but the most awesome of these is love." -- Larry Wall
A line like this might seem a bit hokey out of context, but it was actually moving when I heard it.  We have faith that we can use Perl to solve our problems.  We have hope that Perl 5 and 6 will continue to get better. And we love Perl, unconditionally, despite all of her flaws.  And as Wil Wheaton says about us geeks, we just want to love our special thing the best we can, and go the extra mile to share it with others.

I just want to say that I love the Perl community right back.  You went out of your way to include me and all the other newcomers.  You all gave me all a chance to learn, play, and code with you -- and to be part of your community -- and I am so glad you did.

Wednesday, May 8, 2013

How to start hacking on Rakudo Perl 6

In the course of writing modules, I finally got the urge to start implementing features I wanted in Rakudo itself.  And since there wasn't a real guide on how to set up and patch Rakudo, I decided to share what I had learned in the process.

The nice thing about Perl 6 implementations is that as significant portion of them is written in Perl 6.  (Well, one nice thing anyway.)  This means that if you're comfortable writing Perl 6 modules and classes, you should feel pretty much at home in the source.

This guide assumes so, and that you have a basic familiarity with Github, git, and make -- enough to commit to repositories and build a software package, anyway.

Getting Started

This first thing is to get your own branch of Rakudo to work on.  So go to the Rakudo repository and click the fork button in the upper right.  Relax while Github photocopies a book.  Once that's done, find an appropriate directory to git clone it to on your own machine.

Go ahead and cd into the new rakudo directory.  There are a few setup things that you'll want to do.  First of all, go ahead and build Rakudo, using the normal steps:
    perl ./Configure.pl --gen-parrot
    make
    make install

That will pull a copy of NQP and Parrot, and make sure that everything is working okay to begin with.  Now that that's done, you'll want to add the new perl6 to your system $PATH environment variable.   Which, if you don't know how to do it -- well here's Google.  In particular, you'll need to add the full path to the rakudo/install/bin directory.

There's a couple more things you'll want to do now.  First of all:
    make spectest
You don't have to run the full tests now, but let it download the roast repository into your t/spec before hitting ^C.  You will need these tests later to make sure you didn't break anything.

Next, you'll want to set up a link back to the main Rakudo repository, so you can pull changes from there.  So do:
    git remote add upstream git://github.com/rakudo/rakudo.git

You'll also want the module installer, Panda.  Now, obviously, you shouldn't add anything to Rakudo that depends on an outside module.  But Panda is the one piece of software you really don't want to break, ever.  People will still want to be able to download modules even if functionality changes.  We will have to go through a deprecation cycle if you intentionally change something to cause Panda to start failing its tests.  So to download and install it:
    git clone git://github.com/tadzik/panda.git
    cd panda
    perl6 bootstrap.pl

This will set up Panda's dependencies, and test all of those modules.  The bootstrap script will tell you a path to add to your $PATH environment variable -- add it too, so that panda will run from anywhere.

Finally, you really should set up a new branch to work on, so you can switch back to a working Rakudo if you need to.  Move back into the rakudo directory and run:
    git checkout -b mynewbranchname

A very short overview of the source


Now that all the setup is done, let's take a quick look around.  Most of what we build into Perl 6 lives in the rakudo/src folder, so this is where you'll want to edit the contents.
  • The vm directory contains files specific to the virtual machines Rakudo runs under.  At this time of this writing, there's only one thing in there, parrot, but very soon there will also be a jvm directory.  Exciting!  Most of the purpose of this code is to map functions to lower-level operations, in either Parrot or Java.
  • The Perl6 directory contains the grammar and actions used to build the language, as well as the object metamodel.  The contents of this folder are written in NQP, or Not Quite Perl.  This section determines how the language is parsed.
  • The core directory contains the files that will be built into the core setting.  You'll find classes or subroutines in here for just about everything in Perl: strings, operators like eq, filehandles, sets, and more.  Individual files look similar to modules, but these are "modules" that are available to every Perl 6 program.
  • The gen directory contains files that are created in the compliation process.  The core setting lives here, creatively named CORE.setting.  And if you look at it, it's just a concatenation of the files in core, put together in the order specified in rakudo/tools/build/Makefile.in.  While these files can and do get overwritten in the build process, it's often a good idea to keep a copy of CORE.setting open so you can find what you're looking for faster -- and then go edit it in core.

Let's start hacking!


Now's the time to start changing Rakudo.  Have the appropriate amount of fun!  Be sure to commit functioning changes occasionally, so that you can git bisect for problems later.  And push your edits to Github as a free backup.  If you get stuck, drop by #perl6 on irc.freenode.net and ask questions.

If it's your first time, you have to fi^W^W^W^W you will probably make a lot of mistakes.  I know I did on my first project, as explained in detail in a previous post.   But I promise you, the learning curve is surprisingly easy, and your compiler-fu will increase to fuchsia-belt level in no time.  (What?  We're not just giving black belts away... and Camelia likes fuchsias.)

Testing and Specs


When you think you're finished with your code, the first thing you should do is merge in the upstream rakudo, and rebuild:
    git fetch upstream
    git merge upstream/nom
    perl Configure.pl
    make
    make spectest

The spectests will make sure that you didn't accidentally break the codebase.  You should pass, or at least not fail worse than the current roast data.

You should add your own tests into the roast repository about now.  You do have unit tests, right?   Writing tests is "optional", just like brushing your teeth -- you don't have to do it, but if you never do it you're in for a lot of pain later.  Here's a fine and elegantly crafted hyperlink to S24 (Testing) for reference.

When editing a file that already exists in roast, you may need to fudge the tests for Niecza and Pugs.  This tells us "we know the test failed or fails to parse, nothing has changed".  Just add lines like the following above broken tests:
    #?pugs 1 skip 'reason'
    #?niecza 1 skip 'reason'

The "1" is actually the number of tests you want to skip, but really, look at the README in roast for more details.

If you want to add a whole new test file, you'll need to add it into rakudo/t/spectest.data.  If your code fixes broken tests, then you'll want to *unfudge* by removing the #?rakudo skip lines above the relevant tests.

You should also test that Panda is still working.  Since you'll have to rebuild panda after recompling Rakudo anyway, just check the rebootstrap for test failures:
    perl6 panda/rebootstrap.pl

Commiting to Rakudo


The easiest way to get your code merged is to push it back to Github, and then send a pull request into Rakudo.  If you're really committed to committing, consider sending in a Contributor License Agreement to The Perl Foundation.  This makes you eligible for a commit bit to push directly to the Rakudo repo.

If there's a problem, someone will get back to you pretty fast on the Github issues page.  Hopefully, these problems will be easy to fix, and a standard git commit; git push will add it to the ticket.  If there aren't any problems, someone will just merge it in a couple days.

Huzzah! \o/  A Rakudo Hacker is you!

Implementing IO::Path in Rakudo

I started off implementing the File::Spec module for Perl 6, as explained in the last blog post, but what I really wanted to do was to get some sanity in working with paths through IO::Path objects.  And if I was going to do this, I needed to actually edit the core modules of Rakudo.

Starting with a module which does stringy operations on directory paths, I set out with the goal of making some sort of easy-to-use, path manipulation class in the core.  Something like how Path::Class works in Perl 5.  Then I looked at S32::IO, and realized that IO::Path was exactly what I was seeking.  But it was only partially implemented, and only for POSIX.

So I'm going to walk through the steps I took to integrate multiple-OS path support into Rakudo, in the hopes that it will help other people to avoid my mistakes.  Which were fairly numerous. :/

This was my first foray into hacking a compiler, and I must confess it was fairly intimidating.  I'm no script kiddie, but I hadn't worked on any large open-source projects before.  However, the setting is made of Perl 6 code, so it was more or less a matter of integrating what FROGGS and I had already written.

Baby's first steps


I had played around with using File::Spec as a backend to an IO::Path in the IO::Path::More module, so it became clear that this was the best way forward for Rakudo. 

I realized right away that IO::Path's interface would have to change to include systems with a concept of volume.  I did a small edit to IO.pm to add a $.volume attribute, changed a few lines of code in sub dir, and compiled.  Everything worked.  I sent a pull request into Rakudo, just to get the interface-changing out of the way first.  It tested okay, and was accepted.  Wow, I'm good at this!

Naturally, it all got worse from there.

Problem 1: Biting off more than I can chew


The next step was to add the File::Spec modules into the core.  So I just started by copying over the .pm files into the core directory.  Unlike in normal Perl code, the modules aren't included with use Module;.  Instead, I edited the Makefile.in to add the modules in the correct order.

Since the File::Spec object needs to inherit from the subclasses, and the other subclasses inherit from File::Spec::Unix, I went with this order:  File::Spec::Unix, File::Spec::Win32, File::Spec::Cygwin, File::Spec.  Now, some of you might already see a problem with that.  To them, I say: "Shh!  No spoilers!"

I realized that I couldn't use the file-scoped class definition (class Foo;) if it was going to end up all in one file, so I switched those out for curly braces.  Then I rebuilt the makefile and compiled rakudo.

That generated a whole mess of errors.  And not all nice errors like before -- Exception.pm hadn't even loaded yet!  This was a bunch of nqp recursion errors.  I tried scaling back a little at a time, even commenting out the entire inside of classes, but I still had issues building Rakudo.  Eventually, I had to scale back my approach, and add files to the build one at a time.

Problem 2: Inheritance


It turned out that each file in my additions had it's own unique problems.  The first was well, it seemed like File::Spec::Unix just, well, disappeared.  Unless I completely removed the File::Spec class, and then it worked.

When you declare a subclass, you're actually adding to the main class' package.  So File::Spec::Unix is really File::Spec.WHO<Unix>.  So if you initialize File::Spec after File::Spec::Unix, it nukes the previous package and its symbol table.  This problem was a lot of no fun to figure out, and I'm glad moritz++ and jnthn++ walked me through it.

The solution here was simple enough -- stub out File::Spec with class File::Spec { ... } before creating File::Spec::Unix.  This is enough to make sure File::Spec will be able to refer to its children.

Although... the last thing I need is some yahoo doing my class File and then complaining about why they can't load File::Spec.  So it was at this time I decided to change File::Spec to IO::Spec.  Making a File class I can see -- if you decide to replace class IO, then you deserve what you get.

Problem 3: The language is in the process of building


The setting may feel like normal Perl code, but it's not.  It's still in the process of being built.  It's like a house in the process of construction.  If there's only a wood frame, you can still hang a portrait on the "walls" -- but this will only get in the way when it's time to hang the drywall.  Things need to come together in the correct order.

I encountered these problems in a couple of different ways.  The first was in using rx// to precompile some patterns before Regex.pm was loaded.  Windows-style paths really need this for readablity, because they use both kinds of slashes as separators and the concept of volume is fairly complicated.  I tried a lot of different ways of formatting, each of which made the build fail in new and unique ways. Then I discovered MAKE_REGEX() had loaded a bit before the IO modules.  This particular problem seemed to be solved.

The next couple of problems were caused by $*OS not being in scope at build time, as terms.pm was way, way down at the end.  It works just fine in method calls, but if it's needed as a class attribute, it's simply not in scope when you're building the class.  I ended up replicating the same op used in terms.pm to get the kernel string, so I could have it available earlier.  Early enough to figure out which subclass of IO::Spec to use for the main object.

So remember, object building happens right away, but subs and methods can carry references to things that happen later.

Problem 4: Breaking Panda


Everything seemed like it was working pretty okay at this point.  Until I got to the day of the masakism IRC seminar.  It was at this point that tried to install a module for the class, so I couldn't help but notice that Panda seemed to die horribly.  I checked out and built the nom branch to use for the duration, but I really had no idea what was going on.

When I golfed the breakage in Panda, it came down to its "use lib" line -- and lib.pm is shockingly simple.  Running use lib 'foo' in the REPL alternated between three different errors from the NQP level.  Something was seriously wrong.

My only choice was to work backwards, and see what was causing the problem.  I would say git bisect here, but I hadn't actually been making enough commits to effectively get at the problem.  So that was the first learning experience here -- commit any time you think you have functional code.

Anyway, it took a lot of edits, and I got most of the way through a novel while waiting for Rakudo to recompile, but I eventually traced it back to the precompiled regexes that were giving me a problem earlier.  At this point I was about to give up, and make long, ugly regexes. Finally jnthn++ noted that Regex.pm hadn't loaded when this was trying to run, so I should just move all of the IO modules to later in the build.

So I swapped back in the rx// syntax, and naturally, it all worked.  The lesson here is that running some real software can pick up bugs (although the spectests would have shown it too).  And that you really do need to make sure that dependencies come earlier.  And most of all, if you're stuck, just ask in #perl6.

Spectesting


The methods I developed for IO::Path::More to IO::Path went in painlessly.  I ended up writing an additional set of methods for IO::Spec -- .split and .join, to replace .splitpath and .catpath but with basename and dirname syntax.  That allows IO::Path.basename to always have the current item in question, and all of the trailing slashes are gone.

It was at this point where I started thinking about testing.  IO::Spec had literally hundreds of tests from File::Spec in Perl 5.  But ironically, IO::Spec wasn't actually specced.  So the question became, should IO::Spec be just a backend, or a fully specified part of Perl 6?

Implementations in Perl 6 are supposed to inform the spec, as well as the other way around.  And the more I thought about it, *something* has to do the low-level string operations on paths.  And there is no reason to hide it, either.  Rakudo already provides access to all of its lower layers via nqp or pir ops, so it made sense to include it as a specced part of Perl 6.

So I went ahead and edited the Specification for S32::IO, adding IO::Spec and several methods for manipulating IO::Paths.  Lots of text.  And then even more went into writing tests for IO::Path.  Naturally, these uncovered some more minor bugs, but that's what tests are for.

Patch Approved


It didn't take all that long for my pull request to get merged, especially after I started writing tests.  This whole process took about three weeks.  I'll have a few minor cleanup I'm going to have to do in the next couple of days, as I resolve a bug in using IO::Spec::Unix.rel2abs.  Parrot just added a readlink op on my request, so IO::Path.resolve should be working soon.

And what we have to show for all this work is a Perl 6 implementation that does file path modifications on Linux, Cygwin, or Windows/DOS.
    On Linux:
    "/foo/./bar//"\   .path.cleanup.parent;  #yields "/foo"
    On Windows:
    "C:/foo\\.\\bar\\".path.cleanup.parent;  #yields "C:\foo"
    On any platform:
    IO::Path::Win32.new("C:/baz").volume;    #yields "C:"

I never finished VMS, or Mac Classic, but at this point, they can just be dropped in, by adding a new IO::Spec subclass.

So there it is, at long last: sanity in file paths in Perl.  I think, if I had known how it was going to go from the beginning, I would have been even more intimidated.  Even so, it was just the same kind of debugging I'm used to in modules.  Only without the safety rails of the parser and a much longer build time.

But if you can write a module and a class in Perl 6, you already have most of the skills to contribute to the setting.  A compiler with internals that feel like a high-level scripting language:  that, like digital watches, is a pretty neat idea.

Monday, May 6, 2013

Porting a Module to Perl 6

CPAN is a huge draw for Perl 5, with approximately umpteen zillion modules available for a wide arrangement of purposes.  It's probably the biggest draw for the Perl 5 language these days, given the newer, hipper scripting languages out there like Ruby, Python, and of course INTERCAL.

The problem is, these modules are not yet usable in Perl 6 directly.  There is an ongoing project to allow Perl 5 code to run in Rakudo, but so far only the most basic code works: like basic loops, quite a few builtins, backticks, etc.  It does inherit from the Perl 6 object system, which is pretty cool, so $foo->WHAT can tell you if you have a Str, Int, or IO::Handle.

So for right now, the only practical way to use Perl 5 modules is to rewrite them in Perl 6.  I just finished porting the File::Spec module, one of Perl 5's core modules, to help deal with file paths on different operating systems. FROGGS++ did much of the initial work on it, but he's moved on the P5 in P6 project mentioned above, so I picked up the slack. The end goal of the project is for me to integrate functionality like Perl 5's Path::Class into the core language, so that OS interoperability comes naturally when using the native functions.

As I got further into the port, I have been convinced that porting the module is a much better choice than relying on the Perl 5 code being integrated.  There are several reasons for this:

Code Cruft


There is a lot of support for operating systems that are now out of date.  This isn't a bad thing.  I'm sure that there's some hobbyist who will want to run Perl 6 on their OS/2 Warp system.  The problem comes when you look inside the code for the OS2 module:
    $path =~ s/^([a-z]:)/\l$1/s;
This little no-op snippet from canonpath (to produce the canonically correct path) converts a lowercase drive letter to lowercase.  It's not harmful, but it does illustrate the fact that no one has edited this code in 9 years.

This isn't the fault of the Perl 5 Porters -- they have plenty of better things to do than to support outdated OSes when not even bug tickets are coming in.  But translating the code sure gives a great opportunity to notice these problems.

In the end, I ended up cutting the entire OS2 module and delegating to Win32.pm, because it had support for things like UNC paths (//server/share) that OS2.pm had only half-implemented.  And so a huge block of code cruft bit the dust.

Readability and Maintainability


Part of the reason these issues happen in the first place is that it's harder to see what's going on in a given piece of code.

An example I came across was in this helper for tmpdir, a method to return the first temporary directory that's writable in a list of parameters.  In Perl 5, we get:

sub _tmpdir {
    my $self = shift;
    my @dirlist = @_;
    my $tmpdir;

    foreach (@dirlist) {
    next unless defined && -d && -w _;
    $tmpdir = $_;
    last;
    }
    return $self->canonpath($tmpdir);
}


That's actually good, idiomatic code for Perl 5, though it can look like spooky action at a distance if you're not aware of what's going on with $_, @_, and shift.

Equivalent code in Perl 6 looks like this:

method !tmpdir( *@dirlist ) {
    my $tmpdir = first { .defined && .IO.w && .IO.d }, @dirlist;
    return self.canonpath($tmpdir);
}


No messing about with parameters and keeping track of the object -- it all happens in the signature.  You no longer have to read through a loop to understand the code either -- in Perl 6 you can just say that you want the first matching candidate, and first() will lazily test the list for you.

The P6 version gets to the point much faster, and it's much closer to natural language: "set $tmpdir to the first defined writable directory in @dirlist."  Less, easier to read code is easier to maintain.

Changing Old Features


At some point, your code was working perfectly and passes all the tests.  But then the computer world changes around you, and it no longer makes any sense.  And you would like to refactor, but people rely on the old functionality.

This is exactly what happened for File::Spec's case_tolerant function.  It essentially looks at the operating system alone, and uses that to determine if the filesystem is case-sensitive.  Which in the old days made perfect sense when Macs used HFS+, Windows used FAT, and Unix used ufs or a variant.  But my computer runs Mac OS X and Windows and has several drive partitions in different formats.  Heck, the NTFS drives are case sensitive in POSIX-land, but as soon as I boot Windows they become case insensitive.

The only reasonable way to check this now is to actually check the filesystem for a specific directory, given widespread support for symlinks.  This breaks the old functionality.  But there's no time like a major language revision to break old APIs and replace them with shiny new ones.

However, there are a couple of major downsides to porting:

This is really time-consuming


Sure, you don't have to implement the algorithm from scratch, and you have plenty of tests to help your development.  It would be possible to just translate the existing code, because things aren't that different.  Change an if( $foo ) to if $foo, etc.

However, a major reason for doing the porting is to use the Perl 6 idioms instead, especially in function declarations and regular expressions where it makes a major difference in code readability.

Dependencies aren't available


Sometimes your code relies on separate modules not available, or on not yet implemented functions.  Your choice becomes to either implement the functionality yourself and embark on yet another yak-shaving expedition, or mark it as todo and wait for the appropriate functionality to arrive.

This has become a much smaller problem as of late as the core language matures.  But "done enough" is not really "done".



Now that I've written this, I've realized that my own project is a microcosm of the Perl 6 saga.  Making a better codebase takes a lot of time, but it ultimately seems worth the effort.

Of course, once I had gotten this far, I realized that File::Spec -- or something very much like it -- would be needed to implement IO::Path objects for non-unixlike OSes.  So stay tuned for the next part in this saga: How to add File::Spec to Rakudo.

Update: It ended up turning into two posts:  One was a simple guide on How to Start Hacking Rakudo Perl 6, and the other covered my follies in trying to add to the compiler for the first time.  But the short story is that IO::Path is now added to Perl 6 and implemented in Rakudo -- this means that both File::Spec and Path::Class' behavior are now available in the core language without adding modules.

Thursday, April 11, 2013

Perl 6 is my MMORPG expansion pack: Perler's Handbook II

Three years back, masak++ wrote an excellent post, comparing his participation in the Perl 6 community to playing an online role-playing game.  And participating in the community has become a similar experience in my own life:
  • It is time-consuming: I spend hours contemplating new puzzles.
  • Dangers lurk about: I have to carefully avoid bugs that aren't at my level to squash yet.
  • Addictive properties: I can't go to bed until I pass just that one more test.
  • Great glory awaits those who triumph: in the form of IRC karma.
  • And most of all, it is fun.

And just as in RPGs, balanced parties and teamwork are the key to success.  The compiler improves with testers and application developers helping the implementers find bugs.  The ecosystem grows faster with advocates helping to recruit new users. Everyone plays an important part.

But looking at masak's post, I didn't seem to see my own role in the character class descriptions he wrote.  Obviously, we need to have more base classes to describe the full range of participation in the community.  So without further ado, here are the new character classes:

Monk

Calm and collected, the Monk contemplates the meaning of Mu and recites mantras like "There Is More Than One Way To Do It".  Where a Priest might answer newbie questions and offer helpful advice, a Monk will go deeper, meditating on a question until reaching enlightenment.  Because they are similar to the warrior class, they will sometimes go so far as to implement the answer to your query.

Being a monk requires wisdom to contemplate mysterious new problems, constitution to deal with newbies, and strength to implement solutions to problems.  Given the way TimToady++ has been flooding Rosetta Code lately with new Perl 6 examples, he just might be multi-classing in Monk.

For now the life of the Monk is solitary, and they can only be found by traversing to the remote mountain temple (actually #perl6).  But one day, the gates of the monastery will be flung open, and all will be able to seek their counsel -- so saith masak's prophecy.

Druid

A master of the wild, the druid is most knowledgeable about the monsters lurking in our code: bugs.  They help to manage these wild creatures by managing bug reports and writing tests.  They may or may not participate in a bug hunt, but they will be happy to tell you where the critters live.  (Note: our spokesbug, Camelia, lives in our hearts.)

Druids are as one with the ecosystem, helping to take care of all of the little things that make the Perl 6 work together.  As such, they help take care of things like module installers and keeping our websites running.  They don't actually have a secret druidic alphabet -- it's just Unicode.

To be a druid, one needs lots of constitution to deal with the never-ending cycle of bugs, strength to wrangle with RT, and wisdom for the patience to accept the errors one cannot fix.

[Coke]++ is the leader of our druidic circle; he keeps Perl 6 implementations properly roasted.

Bard

Bards are free spirits who wander from place to place, working on whatever strikes their fancy.  The Bard dabbles in all aspects of Perl 6, but rarely into great depth.  For this, they are often described with the phrase "jack of all trades, master of none".

Bards are useful because they can jump in to assist where needed.  They can answer newbie questions like the Monk, implement a few language features like the Wizard, write small modules and applications like the Warrior, submit bug reports like a Priest, and bolster the courage of a community like a Healer.  Just don't expect a Bard to write the next killer app, resolve a heated discussion, or port NQP to a new VM without major help.

A major role of the Bard is that of story and song.  They spread tales far and wide of Perl 6 and it's heroes -- tales of Larry the Wise, Audrey the Great, Jonathan the Strong, Tobias the Bold, and Mäsak the Pretty Cool Guy.  But mostly, they should write about the language and its features in the most eloquent way possible, and share the knowledge through writing documentation and blogging.

Being a Bard requires charisma to communicate clearly and convincingly about the language, and dexterity to switch easily from one task to another.  But in general, they need balanced stats, so they can work in different areas.

I tend to consider myself a Bard, which is why I wrote this article.

All right chums, let's do this!

So I hope that you were entertained, because Perl is supposed to be -Ofun -- min/maxed for fun.  And after all of these years, it looks like we have a much greater than (97/3).Rat percent chance of succeeding. 

So if you'd like to participate, come and find a role that suits you in the Perl 6 community.  You'll earn XP (Extreme Programming skills) and piles of tuits!

Wednesday, April 3, 2013

Why I use Perl 6

I'm one of those mythical beasts that you've been hearing about for years but have never actually seen -- I am a Perl 6 user.  And much like the hidden Bigfoot of the northern forests, I'm kind of a lurker.  But I do exist, and the time has come for me, at long last, to delurk.

Why now?  The main reason for this is that there is finally an implementation that "just works", Rakudo.  Sure it's still too slow, but most of the dreaded "Not Yet Implemented" errors have faded away.  The module ecosystem is starting to pick up steam, even if it still tiny.

And, coding in P6 is fun.  While at it's heart, everything is an object, Perl doesn't force you into any one paradigm.  If you want to see if a variable is defined, you can use functional (defined $a), object-oriented ($a.defined), or even smart match against the defined property ($a ~~ :defined).  This philosophy runs throughout the language, yet everything works together seamlessly.

And when it comes down to it, Perl 6 is easy to look at.  I've even heard beginners say it was a "beautiful language".  This is not exactly Perl's reputation, but it's true.  Sure, you can still write obfuscated spaghetti code if you want -- we're not talking about Python here -- but it's easy to avoid doing so.  Regexes and grammars are actually readable now, and far more powerful than in Perl 5.  Backslash hell is gone.

Here's a quick example.  In bit of code I ported from Perl 5, I had to turn a path like "././foo/bar" to "foo/bar".  In Perl 5, we have this:
    $path =~ s|^(?:\./)+(?=[^/])||s;
Okay, a strange looking regular expression, but I've seen worse.  But now in Perl 6:
    $path ~~ s/^ './'+  <?before <![/]> >//;
The major difference is that you can tell what it does at a glance without first putting on your robe and regex wizard hat.

The end result is that when I see a piece of new Perl 6 code, it takes me very little time to figure out what it actually does.  I certainly can't even come close to that speed in grokking C++, and even Perl 5 seems like a storm of pointy arrows and curly braces when OOP is involved.

Finally, the community is amazing.  They're not a large group, but they are an active one.  Sometimes, you can report a bug, and it gets a patch 15 minutes later.  Other times it's joking about horse meat on the IRC channel.  But always, they're welcoming to newcomers, encouraging people to play around, send in bug reports, and write code.  They're the kind of people who make one want to delurk.

Perl 6 is powerful, easy to read, adapts to your style, has a friendly community, and most importantly is fun.  Even if it's not "done", I got tired of waiting for Christmas and opened my presents early.  And inside, I found a perfectly usable language.