Hi, I'm Lukas Atkinson. My irregularly published long form blog posts cover topics such as software development, testing and quality assurance, programming language concepts, data protection, and whatever I currently find interesting.
Recent Posts
Rust doesn't actually follow its Golden Rule
(when it comes to async functions)
A couple of days ago, Steve Klabnik published an article discussing Rust's Golden Rule, arguing that Rust's function signatures provide a clear contract that doesn't depend on the function's contents, which aids reasoning about the code. In particular, function signatures are never inferred.
However, the Rust language has evolved so that it violates this Golden Rule.
While impl Trait
return types by themselves are fine,
they combine with auto-traits such as Send
in an unfortunate manner.
This is a noticeable limitation when it comes to writing async Rust code.
Brexit deal and GDPR: no adequacy yet, but transfers can continue for a while…
The last-minute Brexit deal essentially extends the transition period status for a few months with regards to data protection issues.
gcovr 4.2
Gcovr 4.2 is out, and provides a broad array of new features! With the ability to use config files, new output formats like JSON and SonarQube XML, and the ability to combine coverage data from multiple runs, this release should make it easier to create coverage report in more complex scenarios.
Gcovr is a command line tool that uses gcov to produce code coverage reports in various formats, such as text summaries, detailed HTML reports, and various machine-readable formats. It works with the GCC and Clang compilers.
You can pip install gcovr
from PyPI,
read the overview on GitHub,
or read the full documentation.
On the ECJ's ruling that the GDPR Right to Erasure doesn't apply outside the EU
Today's ruling by the ECJ on the Google v CNIL case seems to limit the territorial scope of the GDPR.
But that misses the main point of the ruling. First, the analysis is specific to the Right to Erasure. Second, it's more about the territorial scope of EU data protection authorities: they have no direct right to mandate changes to non-EU activity unless the authority first balances data subject rights against the freedom of information to show that such changes are necessary and proportional.
MongoDB no longer seeks OSI approval for SSPL
MongoDB announced that they are withdrawing the SSPL license from the OSI license-review process.
This reduces confusion about what is Open Source and what is not, but leaves a crucial question unsolved: how can we ensure sustainable development for Open Source projects?
Interface Dispatch
Virtual method calls are simple: you just look up the method slot in a vtable and call the function pointer. Easy! Well, not quite: interfaces present a kind of multiple inheritance, and things quickly become complicated.
This post discusses interface method calls in C++ (GCC), Java (OpenJDK/HotSpot), C# (CLR), Go, and Rust.
It is an expanded version of my answer on Software Engineering Stack Exchange on Implementation of pure abstract classes and interfaces.
How to check for an array reference in Perl
So you've got a Perl $variable
.
Can we use it as an array or hash reference?
If you do an online search for possible solutions,
you'll find a number of suggestions, most of them wrong.
TL;DR:
checking if ref $variable eq 'ARRAY'
is almost always a bug.
Depending on your use case, you want:
reftype $variable eq 'ARRAY'
from Scalar::Util as a check for physical array references, or_::is_array_ref $variable
from my module Util::Underscore as a check for logical array references.
Dist::Zilla on Travis CI
With Dist::Zilla (dzil), testing Perl projects on Travis CI can be a bit tricky. Here's my approach.
Should I Separate Unit Tests from Integration Tests?
When does it make sense to keep integration tests separate from your unit tests, and when is it OK to make no distinction?
Well, it's all about getting fast feedback.
Dynamic vs. Static Dispatch
This article explains the difference between dynamic dispatch (late binding) and static dispatch (early binding). We'll also touch on the differences in language support for virtual and static methods, and how virtual methods can be circumvented.
Simpler Tests thanks to “Extract Method” Refactoring
I'm currently refactoring a huge method into smaller parts. It is stock full of nested loops, maintains a complex state machine with more variables than I have fingers, and is the kind of code where I have to ask myself how I could ever think this would have been a good idea. So obviously, I'm splitting that function into smaller, independent chunks with the Extract Method refactoring technique.1 Since the control flow is now simplified, the code has also become easier to test – as long as I'm comfortable with testing private methods. Why?
The number of test cases needed for full path coverage corresponds directly to the McCabe complexity of the code under test. Since many simple functions often have lower total complexity than one convoluted function, the overall required testing effort is reduced. As this reduction can be substantial, there is a strong incentive to test the extracted methods directly, instead of testing only through the public interface.
Extract Your Dependencies
Making your code ready to be tested
Global dependencies make it difficult to properly test a piece of code. By extracting all dependencies into a single manageable object, we can easily mock the necessary services and avoid a large-scale refactor.
An Overview Of The Marpa Parser
There are many exciting parser technologies out there, and one of the most promising is Marpa. This post discusses how Marpa improves over commonly used parsers.
Emerging Objects
Building a simple object system out of closures
Object-oriented programming and functional programming imply each other. While encoding closures as objects is a well-known technique (see the command pattern, and e.g. Functors in C++), using closures to implement objects is a bit more unusual.
In this post, I will explore creating a simple object system in JavaScript, using only the functional parts.
Transforming Syntax
Or: how to write the easy part of a compiler
A Stack Overflow question asked how to translate a VB-like conditional into a C-like ternary. The other answers suggested regexes or treating it as Perl code *shudder*. But transpiling code to another language can be done correctly.
This post aims to cover:
- parsing with Marpa::R2,
- AST manipulation,
- optimization passes,
- compilation, and
- Perl OO.
In the end, we'll be able to do all that in only 200 lines of code!
Since this post is already rather long, we will not discuss parsing theory. You are expected to be familiar with EBNF grammar notation.
Archive
- 2023 (2 posts)
- 2020 (1 posts)
- 2019 (3 posts)
- 2018 (5 posts)
-
2017
(8 posts)
- What are Containers, and how are they useful? (29 mins)
- Transforming Syntax updated (0 mins)
- What is a Source Code Comprehension Tool? (2 mins)
- Perl Docstrings: Put your POD into Heredocs (7 mins)
- Unix is my IDE: script everything (5 mins)
- How to check for an array reference in Perl (6 mins)
- Dist::Zilla on Travis CI (5 mins)
- Should I Separate Unit Tests from Integration Tests? (4 mins)
- 2016 (5 posts)
- 2015 (6 posts)
- 2013 (1 posts)
See also the note dump.