Thursday, August 27, 2015

Using my stardock image on Amazon AWS free tier

Amazon's AWS service is great. I love the fact that it provides a free server to develop on and if I ever need more, I can pay for it.

Just one catch: many of the things I enjoy working with are small enough to fit in RAM to run, but not to build. Perl 6 is a great example. See my previous posting on building a "stardock" container for Perl 6. Anyway, that won't build on Amazon's AWS free tier, so what do I do? Well, I can spin up a local VM under a Windows box to do the build, so here's what I do:

docker build --tag=stardock .
docker save -o stardock.img stardock
scp stardock.img <awshost>:.

And then on the target system:

docker load -i stardock.img
docker run -it stardock perl6 -v

Now you have a build of Perl 6 Rakudo Star from the most recent HEAD, but without having to have enough RAM in your free dev environment on Amazon!

Thursday, July 9, 2015

Building bleeding edge Perl 6 as a Docker container

I got tired of re-building Perl 6 on every system I touch, but the public Rakudo Star build of Perl 6 that's available as a Docker image is pretty badly out of date. If you want to get and build the latest and greatest, here's how to do it in a container.

First, create your "Dockerfile" with this as its body:

FROM ubuntu:15.04

RUN apt-get update && apt-get -y upgrade && apt-get clean
RUN apt-get -y install perl && apt-get clean
RUN apt-get -y install git-core && apt-get clean
run apt-get -y install build-essential && apt-get clean

RUN git clone https://github.com/rakudo/star.git
RUN cd star && perl -i.bak -pE \
  's/git\@github.com\:/git\:\/\/github.com\//g' .gitmodules
RUN cd star && git submodule sync && git submodule init && git submodule update
RUN cd star && git clone https://github.com/rakudo/rakudo.git
RUN cd star && perl Configure.pl \
  --force --prefix=/usr --backends=moar --gen-moar --gen-nqp
RUN cd star && make && make install

CMD [ "shell" ]

Now build your image by running docker build:

$ docker build --tag=stardock .

I call my image stardock. You can call yours whatever you like. Note that the build is too large to fit in some minimal environments. It may fail, for example, on a free tier AWS EC2 instance.

Next, you want to test your build:

$ docker run -it stardock
root@5bf4853308cf:/# perl6 -v
This is perl6 version 2015.06-225-g3bdd0af built on MoarVM version 2015.06-88-g647df11
root@5bf4853308cf:/# perl6 -e 'say "Hello, world!"'
Hello, world!

And there you go, a working Perl 6 built off the latest rev of Rakudo build per the Rakudo-Star release packaging.

Because the point of this is to be up-to-date, you might want to add this line before the "RUN git clone" of Rakudo:

ADD update.txt update.txt

and just "touch update.txt" in your Dockerfile directory before you do the build to force it to pick up the latest Rakudo and rebuild from scratch.

Tuesday, January 21, 2014

Sand: Rules

Sand is a programming language that I introduced in a previous article. Sand rules are not completely fleshed out, but here are the primary design goals:

  • To be as similar to perl 6 rules as possible
  • To reduce complexity where it does not yield substantial benefit and where reduction in complexity does not come at tremendous cost to compatibility
  • Speed of parsing and execution
Specifically, these are the top-level elements:

  • A regex is a sequence of atomic assertions about patterns very similar to Perl 5 regular expressions.
  • An assertion is embedded code within a regex which returns true or false and matches on true.
  • A subexpression is a reference from one named regex to another.
  • A token is a regex which matches in a single pass (no backtracking) or fails.
  • A rule is a regex which defaults to considering whitespace significant.
  • Tokens, rules and bare regexes are all optionally named, allowing subexpressions to use those names for reference.
  • All of the above may be referred to as elements of a grammar and are technically methods. They must either be declared as part of a class that implements (does) the role, "grammar" or must be implicitly associated with the global "_regex" grammar (e.g. this code defines a method on _regex implicitly and invokes it: if "foo" ~~ regex{f} {...})
here are some examples:


class Sand :does(grammar) {
    method same_category($letter, $category by reference) {
        my $letter_cat = $letter.unicode_block_category();
        if $category {
            assert($letter_cat == $category);
        } else {
            $category = $letter_cat;
        }
    }
    method is_token_unicode() -> (!bool) {
        my $number = undef;
        my $other = undef;
        for self.match(0).str().list() -> ($letter) {
            if $letter.isdigit() {
                self.same_category($letter, $number);
            } else {
                self.same_category($letter, $other);
            }
        }
        return True;
    }
    token identifier {
        [ <alpha> | '_' ] <alphanum>* { .is_token_unicode() }
    }
    rule scalar { '$'<identifier> }
}

This code defines the "identifier" and "scalar" regexes that are part of Sand's grammar. Notice that a grammar class can define methods like any other class and those methods can be invoked from within the body of a regex.

The Sand programming language

The following is a direct cut-and-paste from my specification of the Sand programming language on my Wiki (which is now down and may never be revived, depending on how much free time I have). This copy was fetched from Google's cache.

Monday, August 19, 2013

Python line continuation

PEP 8 is Python's Bible when it comes to style, but it deliberately avoids certain kinds of assertions about how to write code while suggesting some only in examples. One area in which I feel it is too vague is line-continuation. In this article, I'll try to outline the reasons that one wants to continue lines and how one should deal with that. This is partly a matter of preference, but most of the rationales I present will come along with the practical reasons that this choices make sense.

Let's start with the simplest case. You have a line where a simple function call extends past the end of the normal boundary (79 characters per PEP 8, though I find myself trying to stay below that for historical reasons relating to specific editors, formatters and printing systems):

do_the_first_things_first(thefirstthing, thesecondthing, thelastofthethings, reasons=None)

There are many ways that would work. Here's one:

do_the_first_things_first(thefirstthing,
                          thesecondthing,
                          thelastofthethings,
                          reasons=None)

Tuesday, April 30, 2013

The frustration of Unicode in the Perl command-line

It's a small nit, but Perl is such an amazing command-line tool that I find it frustrating: you can't use Unicode brace-like tokens as delimiters for quote-like operators on the Perl command-line. Let me back up and explain...

"qq" is a Perl operator that's called a "quote-like operator" that does the same thing as double-quotes with two differences:

  • Any token can follow it (except whitespace) and it will match up to the next occurrence (or to a matching balanced token like {} or () or []).
  • If you use a balanced token after it, it will grab everything up to the next, balanced close-token, so "qq{you can put {} inside}"

Tuesday, June 19, 2012

An ORM for Perl 6

I've been using sqlalchemy in Python quite a bit of late, but as I play around more and more with Perl 6 it seems to me that the sqlalchemy model of ORM for Perl 6 would be incorrect. Certainly, the basic concept that you tie objects to database tables and rows still makes sense, but the way you gain access to those objects is probably going to want to be very different in the two languages.

Here's a bit of sqlalchemy from an online tutorial:

mary = session.query(User).selectfirst(users.c.name=='Mary')

So, we have a session object. I think that makes sense for both languages. Then there's a query to which we pass our User table spec. Perfectly sane. Then there's this "selectfirst" thing, which is really shorthand for "select" with the given arguments and then the "first" method called on that result.

In this example, we're not actually comparing "users.c.name" to "Mary". Instead, users.c.name overrides comparison and returns an object that describes to selectfirst that it should perform an equality comparison in the where clause between the "name" column and the string "Mary".

This is about as close as Python can get to a mini-language because you can't override the parser. However, Perl 6 lets you do just that...

method mary($session) is parsed(::ORM::first) {
  select($session)
  from self
  where name == "Mary"  
}

But, isn't the point of an ORM to remove all of that ugly SQL?! Well, no. The point of an ORM is to give you native language controls over databases in a portable way. Our mini-language might look like SQL, but is actually just Perl with a different parsing filter, essentially the same as the filter provided to the "selectfirst" command in the Python example.

If you were to write this out in Perl 6, it might then turn into something like:

method mary($session) {
  select($session, :source(self),
    :filter(:lhs(self!coldef<name>), :rhs("Mary"), :op("==")).first);
}


But if we're talking to an SQL database, why not use something that looks more like SQL? I'm still noodling with this and thinking about what makes sense, but when I get to sitting down and thinking about an ORM for Perl 6 (if someone else hasn't already), then this will definitely be my starting point.