I have previously written that, when given the option of many similar implementation strategies, you should prefer the one which is easiest to test. There is a simple corollary to this proposition: whenever possible, grow your codebase in areas covered…
Change your Constants
Like Yegor Bugayenko, whenever I see code making heavy use of utility classes, I strongly suggest alternatives that better fit the domain. I have also noticed that where Utility classes are found, their evil cousins — Constants classes — tend…
Async minutiae: EndOfStream
Consider the following method to read all text of a file asynchronously. Do you see any issues? The code is perfectly functional and produces the correct result. There are no obvious performance issues (other than perhaps some tuning of the…
Binary implosion: use the source!
As I’ve written previously, we seem to have a real problem with binary explosion and we would do well with some techniques to curtail it (such as a monolithic core design). Today I want to talk about another definitely-not-new practice…
Binary implosion via the monolithic core
Long ago, I wrote about binary explosion — the practice of building a large number of assemblies to provide comparatively little functionality. Despite my protestations, I do not see this problem lessening any time soon. If anything, with the increasing…
Async recipes: after first (matching) task, cancel rest
When it comes to the Task-based Asynchronous Pattern, there are easy patterns to run tasks sequentially (await in a loop) and all in parallel (add to list, await WhenAll). Things get slightly more complicated when the execution model doesn’t fit…
Refactoring techniques for legacy code
After successfully generating some barely readable C# code from a GW-BASIC program, I mentioned how it would make a good basis for a legacy code refactoring exercise. Today I will share the results of this exercise with a brief survey…
BASIC solutions: code generation!
It’s been a long slog, but the quest is over. I now have a functional-enough GW-BASIC to C# code translator. Using adventure.bas as a guide, I implemented enough features to produce a working version of it reimagined in C#. The…
BASIC solutions: statements
My last post showcased what I thought was a complete GW-BASIC expression parsing solution. Hence, I pushed forward with a new project to implement statement parsing. This went fine for a bit, but I quickly encountered overly complicated situations. Without…
BASIC solutions: expressions
Previously, I showed the beginnings of a GW-BASIC expression parser. As of now, the parser is essentially feature complete! I fixed the unary minus bug and went on to implement all the remaining features — mainly relational, logical, and functional…