Part 2 of my Regular Expressions to Grammars tutorial is now up at The Perl Fisher. The previous part covered the basic metacharacters, this fills out the set and demonstrates how to use regular expressions inside Perl 6 code.
I'm going to talk about that which I know very little, but looking at the Perl6 Module Directory, I see a namespace that's already storing up pain. Why are there so many modules in the top level namespace that make no sense for a language that has designs on world domination? I can believe that in the early days of development there's an intoxicating freedom to give your module a snappy name, but didn't we learn these lessons 20 years ago? What happened to Noun::Adjective::Adjective as the guiding principle?
If you're determined to re-invent the wheel, at least try to invent a better one. - Camel Book, 2nd ed. p277. footnote on False Impatience.
I've always admired Python's way of serving local files by simply doing:
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
And I've been wondering if there's a way to achieve the same in Perl without requiring lots of dependencies from CPAN. This morning I just came out with this:
$ perl -Mojo -E 'a->static->paths(["."]);a->start' daemon
Server available at http://127.0.0.1:3000
It shows the file content, though it doesn't show the directory listing.
I think of text, grammars that parse the text, and the syntax trees (data) generated by a parser as a triangle. Most of the time in computerland, people doing something with this triangle are interested in converting a text into a tree using a parser.
Every once in a while I need to write a parser. My first serious parser was in the late 90's, for a radio station that needed each week to convert a large plain-text weekly email to tables of venues and shows. For that, I used a version of Bison (yacc) that allowed me to write actions in Perl.
These days, I'm excited to get my hands dirty in Perl6 grammars. Writing a correct parser is never easy, so a clean, well-thought-out "featureful" parser language means less effort spent on fighting the tool, more on attacking the problem.
We're happy to announce that the 9th annual Perl QA Hackathon (QAH) will be held in Rugby in the United Kingdom. The event will run from Thursday 21st April to Sunday 24th April.
The QAH is a face-to-face gathering of the lead developers who work on the Perl toolchain that all Perl programmers rely on and build upon. The first QAH was held in Norway, in 2008, and so far it's always been in Europe. The QAH provides dedicated time over 4 days to work on the critical systems and tools, with all the right people in the same place.
B::C has now better support for copy-on-write (COW) strings with about 6%
memory savings for 5.20 and 5.22.
The perl5.18 implementation for COW strings is totally broken as it
uses the COW REFCNT field within the string. You cannot ever come to a
true successful copy-on-write COW scheme. You cannot put the string
into the .rodata segment as with static const char* pv = "foo"; it
needs to be outlined as static char* pv = "foo\000\001";. The byte
behind the NUL delimiter is used as REFCNT byte, which prohibits its
use in multi-threading or embedded scenarios. In cperl I'm was working
on moving this counter to an extra field, but the 2 authors made it
impossible to write it in a maintainable way. I could easily seperate
the refcnt flag but I couldn't make it COW yet.
This is a module I wrote a while back, but I never announced. I am pretty happy with how this came out, so here's the announcement. Some JAPHs might be disappointed to learn that one feature of Perl 5 that did not make it to 6 is globbing. That is, doing something like this:
for my $file (glob "src/core/*.pm") { say $file }
With just Perl 6, you need to do something like this instead:
for "src/core".IO.dir(:test(/ .* ".pm" $/)) -> $file { say ~$file }
That's not too terrible, but I still miss the simplicity of globs. In that case, I can use IO::Glob:
use IO::Glob;
for glob("src/core/*.pm") -> $file { say ~$file }
That does the same thing as the Perl 5 code, more or less.
But, that's not all. I always wished that globs could be used for pattern matching. Sometimes, just matching a string against a glob is handy, but Perl 5's globs are narrow minded. IO::Glob is not:
use IO::Glob;
for <abc acc acdc>.grep(glob('ac*')) { .say }
On October 29th, 2015, I released Test-Stream as stable. I did this because
I felt it was ready, and because I was no longer receiving any feedback from
perl-qa asking me to change things. Since that release, the feedback picked
up substantially. It seems that declaring something done is the best way
to find out ways in which it is not actually done.
Here are the big things people wanted:
Split the dist into multiple dists, making the internals and tools separate.
Abandon the loader system (use Test::Stream -/:/etc)
Loosen the tight coupling of Test::Steam to TAP
Make context() less magic (don’t use INTERNALS::SvREFCNT)
Use less import() magic
Better namespace structuring
Changes to how SKIP and TODO are implemented
We decided that the best way forward was to forget about compatibility
with Test-Stream, which is still new enough that it is not seeing much use, and make a new name with
everyone’s changes. That’s Test2.
CPAN Weekly is a mailing list for Perl 5 programmers.
Each week there will be one short message sent to the list,
with a brief description of a CPAN module,
and example usage.
The idea is not to provide a tutorial, but just to make you aware of the module,
and show one basic use case.
By planting seeds in your mental Perl toolbox,
hopefully next time you have certain needs you will think "oh, I read about
a module for that!", rather than "I'll just write a module for that".
Occasionally I find myself writing a Perl subroutine that uses a module that no other part of the code needs. This subroutine may be called multiple times, or not at all. At some point I wondered if putting some logic around the require statement would be faster than just calling it every time. require() is idempotent, after all. You could do something like $counter++ or require Foo;, but the variable has to live somewhere outside the subroutine. Not neat.
It occurred to me that, given Perl 5.10 or greater, something like state $dummy = require Foo; might do the trick. I would be willing to bet this is a use of state that was not anticipated when it was designed. But does it actually do what I want, and is what I want worth doing?
The answer to the first question is "yes." A quick script with require overridden proved that the module was in fact loaded, and that require was called only once no matter how many times it was executed.
Happy Bit Rot Thursday! This week I'm taking care of fixing minor issues with packaging of my Perl 6 modules, and so, I'll talk about the general process of
releasing a Perl 6 module. Let's dive in!
Prelude
Perl 6 is a brand new language, so there's yet no well-established module system like what Perl 5 has, but there is a work in progress. Thus, I'll first describe the process for our temporary GitHub-based system and then I'll talk about the PAUSE-based system that's being worked on.
There are some tools and helpers available to help with the process of module development, but they are beyond the
scope of this post.
B::C and cperl has now proper support for copy-on-grow (COG) and
copy-on-write (COW) arrays.
COG means that the array of SV* pointers is allocated by the compiler
statically, not dynamically, and that the cperl runtime creates a
new array whenever the array is extended (copy-on-grow).
COW means that the array of SV* pointers is allocated by the compiler
constant and static in the .rodata segment, and that the cperl runtime
creates a new array whenever an element of the arrays is changed
(copy-on-write).
With a typical example of a medium sized module, Net::DNS::Resolver, the
memory usage is as follows:
What’s in a name? that which we call a rose
By any other name would smell as sweet;
(William Shakespeare, Romeo & Juliet, Act II Scene ii)
I went to FOSDEM in Brussels this year as a representative of the Perl Foundation. As such I spent the weekend doing my best to be a good advocate of the Perl programming languages.
FOSDEM for those of you in gentle unawareness is probably the world's largest, free, Open Source event. It is held each year in Brussels, Belgium, and attracts speakers for hundreds of talks on dozens of projects, languages and distros. The event is attended by over seven thousand people from almost everywhere in the world.
On the bus ride out to Charleroi I caught a stray brainwave about how to properly notate at least some of Haskell's Lens library, so I wrote up some notes on it. This is going to be slightly spooky, but not much more than the previously-existing ability to bind one data structure to another.
I do want to finish up the Scheme work, if only to prove the crowd on Perlmonks wrong, first though.
The 'lens' library is essentially a metaphor for focussing in on your data, in roughly the following sense:
I came across an excellent book on mazes, written for programmers (Mazes for Programmers). My only complaint is that all the examples are written in ruby. All is good though, as I work through the book, I will be converting the examples into working perl examples, detailing that experience here.
I also came across a perl module that makes some good mazes Games::Maze which also has some TODOs. Bonus! I'll take what I learn and apply it to that distribution, hopefully making Games::Maze into the goto resource for making maze-like games in perl.
I am not the author of Games::Maze. I hope that he/she is ready for some pull requests. 8)
To me It seemed a particularly good FOSDEM for both for Perl5/6 and
other talks although very crowded as usual and I didn't see the usual
*BSD or Tor stalls. I was stuck by the statistic that there were
about 500 speakers from many thousands of people so of the order of
one speaker per tens of attendees which is very high.
On Saturday I started with Poettering and systemd which was a keynote
and perhaps a little disappointing since he usually is a better
speaker and the audio was a little indistinct. systemd had won being
used by all distros except gentoo and slackware. They were now working
on a dns resolver component which supported DNSSEC although in
practice validating signed zone files would slow down browsing and
currently only 2% of websites had it activated. He didn't mention
strong criticisms of its security by crypto experts such as DJB.