# Any expression in the language
role Expr {}
# map f v
role MapV[Expr \f_,Expr \v_] does Expr {
has Expr $.f = f_;
has Expr $.v = v_;
}
# function composition f . g
role Comp[Expr \f_, Expr \g_] does Expr {
This is the follow-on article about writing an expression parser in Raku. In the previous article, I explained the background looked at some basic performance comparisons relating to data structures for parsing and ways to process them: lists, parse trees, recursive descent and iteration.
In this article, we'll have a look at the performance of various ways of processing strings, and then see how it all fits together in the expression parser.
How should we parse the expression string in Raku? The traditional way to build an expression parser is using a Finite State Machine, consuming one character at a time (if needed with one or more characters look-ahead) and keeping track of the identified portion of the string. This is very fast in a language such as C but in Raku I was not too sure, because in Raku a character is actually a string of length one, so every test against a character is
Last year, in Perl land, I discussed the result of my attempts to optimize the performance of an expression parser which is part of my Perl-based Fortran source-to-source compiler. An expression parser takes strings representing expressions in a programming language (in my case Fortran) and turns it into a data structure called a parse tree, which the compiler uses for further analysis and code generation.
I have recently been writing quite a bit of Raku code but so far I had not looked at its performance. Out of curiosity I decided to rewrite and optimise this Fortran expression parser in Raku.
What I loosely call an expression parser is actually a combination of a lexer and a parser:
In an earlier article, I discussed the result of my attempts to optimize the performance of an expression parser written in Perl. I have recently been writing quite a bit of Raku code but so far I had not looked at its performance. Out of curiosity I decided to write and optimise my Fortran expression parser in Raku.
In the current stage of its development, Raku prioritises functionality over performance. So an easily-made argument is that if you want performance, you should not write your code in Raku. And it is of course true that compiled code will almost always be faster. However, often, rewriting in a compiled language is not an option, so it is important to know how to get the best possible performance in Raku.
The Raku documentation has a page on performance which offers good adv
Junctions in Raku are cool but at first glance they do not follow the rules for static typing. I was curious about their formal typing semantics, so I deconstructed and then reconstructed junctions from a functional, static typing perspective.
Raku has this neat feature called Junctions. A junction is an unordered composite value. When a junction is used instead of a value, the operation is carried out for each junction element, and the result is the junction of the return values of all those operators. Junctions collapse into a single value when used in a Boolean context. Junctions can be of type all (&
), any (|
), one (^
) or none (empty junction).
For example,
An illustration of how Raku's junctions are greedy by design, and a proposal.
Raku has a neat feature called Junctions. In this short article I want to highlight a peculiar consequence of the interaction of junctions with functions: they are greedy, by which I mean that they inadvertently turn other arguments of functions into junctions. To illustrate this behaviour, I will create a pair data structure that can take two values of different types, using a closure.
enum RGB <R G B>;
I hereby claim:
- I am wimvanderbauwhede on github.
- I am wim (https://keybase.io/wim) on keybase.
- I have a public key whose fingerprint is ADF4 3E1B 5261 A3CC 6F5F 43E9 53E9 EA35 501B 8491
To claim this, I am signing this object: