BF

When you know deep-down that a Brainfuck interpreter should only ever be written in C, but you’re not quite ready to leave the comfort of C#. So in a spirit of minimalism you find yourself writing C# in a C style just for the hell of it.

public static void Execute(string program, Stream? input, Stream? output)
{
    int ip = 0;
    int dp = 0;
    var data = new byte[30000];

    while(true)
    {
        if (ip >= program.Length)
            break;
        switch(program[ip])
        {
            case '>':
                dp++;
                break;
            case '<':
                dp--;
                break;
            case '+':
                data[dp]++;
                break;
            case '-':
                data[dp]--;
                break;
            case '.':
                output?.Write(data, dp, 1);
                break;
            case ',':
                input?.Read(data, dp, 1);
                break;
            case '[':
                if (data[dp] == 0)
                    ip = JumpTo(']', +1, program, ip);
                    break;
            case ']':
                if (data[dp] != 0)
                    ip = JumpTo('[', -1, program, ip);
                break;
        }
        ip++;
    }
}


private static int JumpTo(char match, int incr, string program, int ip)
{
    while (true)
    {
        ip += incr;
        if ( (match == ']' && program[ip] == '[') || 
             (match == '[' && program[ip] == ']') )
            ip = JumpTo(match, incr, ip, program);
        else if (program[ip] == match)
            return ip;
    }
}

This made me wonder if the style of a language affects the style of its implementation. Not sure.

(For any impressionable children reading this: don’t do it this way. Use descriptive variable names and comments and put braces around your if/else clauses.)

(And for any hiring managers reading this: its deliberate, I promise.)

SLotD: Pushing the model

Software Lesson of the Day for 16/10/2024:

Sometimes you will try something and it works. And then you extend it a bit. And then a bit more. And it stops working and/or doing what you want.

Consider the possibility that the fact it initially worked was just a false signal, and that actually you should never have done it that way at all. Because the model or pattern for doing $thing$ is actually somewhat different — and whether you approve of that pattern or not, and whether you like deleting superficially working code or not, that’s the way you have to do it. Because we rarely write software nowadays without what we write having to fit into a more or less opinionated container. So make sure you actually understand the pattern, not simply what you want it to be.

(This post is brought to you by trying to implement an Android ViewPager with hard-coded child elements in the layout xml. No matter how hard you try, you can never defeat the PagerAdapter‘s beliefs about page instantiation and caching.)

SLotD: Serialise/Deserialise is Copy

Software Lesson of the Day for 2/12/2022. Rather than waste all that time writing a perfect universal .net object copy library that copes with every possible variation of nested reference types, value types, fields, properties, statics, and twenty-plus years of special cases and regret and technical debt baked into the framework… just serialise your damn source object to json and de-serialise it back out again. And then be on your way.

SLotD: Premature Abstraction

Software Lesson of the Day for 2022-10-04: Note to self. If you’re struggling to create a generic, reusable, well factored, abstraction to implement a simple, application-specific piece of functionality – then it may just be that instead you can get away with a couple of simple data fields and a static function or two. Remember this for the next time.


(Lets see if I can remember to do this more often…)