Having hit rock bottom with an ‘I can’t understand my own code sufficiently enough to extend/maintain it’, I have been on a journey to review the perl5 Physics::Unit design and to use this to cut through my self made mess of raku Physics::Unit version 0.0.2.
Now I bring the perspective of a couple of years of regular raku coding to bear, so I am hoping that the bastard child of mature perl5 and raku version one will surpass both in the spirit of David Bowie’s “Pretty Things”.
One of the reasons I chose Physics::Units as a project was that, on the face of it, it seemed to have an aspect that could be approached by raku Grammars – helping me learn them. Here’s a sample of the perl5 version:
Yes – a recursive descent parser written from scratch in perl5 – pay dirt! There are 215 source code lines dedicated to the parse function. 5 more screens like this…
So I took out my newly sharpened raku tools and here’s my entire port:
Instead of ranging over 215 lines, raku has refined this down to a total of 58 lines (incl. the 11 blank ones I kept in for readability) – that’s a space saving of over 70%. Partly removal of parser boilerplate code, partly the raku Grammar constructs and partly an increased focus on the program logic as opposed to the mechanism.
For my coding style, this represents a greater than a two-thirds improvement – by getting the whole parser onto a single screen, I find that I can get the whole problem into my brain’s working memory and avoid burning cycles scrolling up and down to pin down butterflies bugs.
Attentive students will have noted that the Grammar / code integration provides a very natural paradigm for loading real-world data into an OO system, the UnitAction class starts with a stub object and populates ‘has’ attributes as it goes.
Oh and the raku code does a whole lot more such as support for unicode superscripts (up to +/-4), type assignment and type checking, offsets (such as 0 K = 273.15 °C), wider tolerance of user input and so on. Most importantly Real values are kept as Rats as much as possible which helps greatly for example, when round tripping 38.5 °C to °F and back it is still equals 38.5 °C!
One final remark – use Grammar::Tracer is a fantastic debugging tool for finding and fixing the subtle bugs that can come in and contributing to quickly getting to the optimum solution.
> 0 K = 273.15 °C
You dropped a minus sign in front of the 273.15 …
Ah yes, thank you for the fix – just to clarify, these code samples are illustrative, I have not yet tested/released this version (0.0.7).
That’s global warming for you!
LikeLiked by 1 person
Grammar::tracer is indeed a great visualization module; since you like shorter code you may also like shorter output: I wrote https://github.com/nkh/P6-Grammar-Tracer-Compact, based on JW’s code, which has a shorter output.
thanks for the info @nadim – I look forward to giving it a whirl
a screenshot (that should be on the repo page), Grammar:Tracer the top, Grammar:Tracer::Compact at the bottom:
in the grammar.pl example the match is dumper with Data::Dump:Tree (there’s a “if 0” in front that needs changing), that may also be interesting (to see the result) and it can be filtered ad nauseam