The time between posts should be smaler than this.
Ack, part one wrote itself
The source for my solution to part one of this week’s challenge looks pretty similar to the question.
This is because of Perl 6’s built in support for multi dispatch. 3 function definitions; one symbol; branching recursions; no ifs or switches.
So I thought, what can I do to make this more interesting?
Coincidentally, for large values of m and n (mostly m), A(m,n) can be quite slow. Also, it could be called many times for the same values of m and n.
So why not cache it?
What this does:
- Creates a new Array and sets it as the topic
- Wraps every symbol called A (there’s three of them)
Every time the wrapper is called, it retrieves the cached result for a given m and n, first setting them by calling the wrapped function only if no such value is defined.
Alternatively there’s built in behaviour for this if you mark the prototype as
is cached, but then you (a) have to declare
use experimental :cached and (b)
get a caching mechanism that’s not quite so optimised for this use case.
Part two sort of wrote itself, too.
Okay, so not quite. However, there’s a BNF available
for URI format (the example given isn’t a URL, or in fact a URI as
is not a valid scheme owed to the colon, but it’s close to a URI than a URL).
Converting BNF to Perl 6 Grammar syntax is pretty straightforward. Mostly. Up to a point. I put dots in front of a lot of parts we don’t actually care about.
Anyway, I wanted to actually talk about action classes again, since last time I sort of glossed over time, but my blog post was referred to as though it was some kind of useful reference.
The Action class - actually an instance of it is generally more useful – is
passed into the
.parse method of a Grammar. Each method in the class is named
corresponding to a rule, token, or regex in the Grammar you’re parsing that you
want to perform an action with.
Each method is called immediately after its corresponding element is matched,
and is passed the resulting
Match when this happens. It’s convenient to use
$/ as the name of the passed in Match parameter, as you can refer to
$<sub-match> in your method.
This time our action class,
A::URLish, has two methods, because on the whole
we just want to stringify our matches directly.
TOP is run when the whole thing matches. This creates an object of type URL
from (mostly) the strings that were matched by submatches of the Grammar as a
whole. The exceptions are the
.query property, which is built up into a hash
<param> elements of the
<query> submatch, and the
property, which is “made” by another method specially for it.
This is where things get cooler.
Grammars allow you to specify a prototype for a kind of multi-dispatch
subexpression. In our case, the
<userinfo> expression has been defined this
way, so that we have a regex
userinfo:sym<user-pass> that parses specifically
<user>:<password> style authentication string, but when we’re referring to
it later, either in the Grammar or the Actions class, we only have to say
<userinfo>. In this way, we could extend it later to accept a different style
of authentication string.
In the action class, we just write a
method userinfo:sym<user-pass> which
URL::UserInfo object (it would be better if this were a role our
does), and when we call
$<userinfo>.made in the
this is what we get back. Note how the calling function doesn’t need to know
which particular userinfo symbol we’re calling, just that it was matched and
made by some userinfo. Polymorphism in regular expression parsers.
Apologies for the poor quality explanation.
‘til next time…