Skip to content

Instantly share code, notes, and snippets.

View wimvanderbauwhede's full-sized avatar

Wim Vanderbauwhede wimvanderbauwhede

View GitHub Profile
# 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 {
@wimvanderbauwhede
wimvanderbauwhede / writing-faster-raku-part-2.md
Created December 2, 2020 17:52
Writing faster Raku code, Part 2

Writing faster Raku code, Part 2

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.

String processing: regular expressions, string comparisons or list operations?

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

@wimvanderbauwhede
wimvanderbauwhede / writing-faster-raku-part-1.md
Last active December 2, 2020 17:53
Writing faster Raku code, Part 1

Writing faster Raku code, Part 1

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.

Expression parsing

What I loosely call an expression parser is actually a combination of a lexer and a parser:

@wimvanderbauwhede
wimvanderbauwhede / writing-faster-raku.md
Created November 24, 2020 16:21
Writing faster Raku code

Writing faster Raku code

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.

Raku performance as we know it

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

@wimvanderbauwhede
wimvanderbauwhede / raku-junctions-reconstructed.md
Last active October 15, 2020 09:14
Reconstructing Raku's Junctions

Reconstructing Raku's Junctions

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.

Junctions in Raku

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,

@wimvanderbauwhede
wimvanderbauwhede / raku-greedy-junctions.md
Last active October 8, 2020 19:57
The strange case of the greedy junction

The strange case of the greedy junction

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>;

Keybase proof

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: