Jos van Uden:

The Universal Turing Machine is working.

There are many different ways to solve this Task in D. You can write a very strongly typed Ada-like program, or a weakly typed Ruby-like program. Both have advantages and disadvantages (as years pass I am leaning more toward a stronger static typing, despite I like Python). Your version is more toward the weakly typed end of the spectrum (but not as much as Ruby).

I am now reading your code.

- - - - - - - - - -

This is bad:

void move(in int dir) {
    final switch(dir) {
        case UTM.left: left(); break;
        case UTM.right: right(); break;
        case UTM.stay: stay(); break;
    }
}


"final switche" was introduced in D to increase safety making the code more strongly typed, but there you are relying on a DMD bug, and that piece of code is the opposite of safe. A correct D compiler must refuse your code:
http://d.puremagic.com/issues/show_bug.cgi?id=5713


I have rewritten it like this:

void move(in int dir) {
    switch(dir) {
        case UTM.left:  left();  break;
        case UTM.right: right(); break;
        case UTM.stay:  stay();  break;
        default: assert(0);
    }
}


If you want to write a stronger typed code you can give a name to that enum, and then it's a good idea to use a final switch. But then the associative array "rules" must have Tuples (or structs) as values.

- - - - - - - - - -

I couldn't get the AA's to nest the way they do in Ruby, so
I had to do it differently.

I will take a look at this later. Maybe it's a known AA bug.

- - - - - - - - - -

This task seemed like a good candidate for using an invariant,
but the loop in the run method already checks the state on
every iteration, so I'm not sure what you could check except
to see if all the fields have been initialized perhaps.

Seems good to do, but maybe a pre-condition is enough.

- - - - - - - - - -

Instead of using toString() maybe it's better to add a printTape, and let run() return nothing. I have also converted UTM to a struct, because for this little program it doesn't need to be a class (and there is no need of new).

- - - - - - - - - -

I am not so fond of the D idiom of using general Exceptions, I'd like to use a bit more variety of Phobos-defined exceptions. But in this little program I think using two basic Exception is acceptable.

- - - - - - - - - -

The two casts in your code are bad, generally in D you don't cast to mutable or to immutable, because it's dangerous and unclean. So I will (try to) remove them:


this(ref TuringMachine tm) {
    this.tm = cast(immutable)tm;
    this.head = TapeHead(this.tm);
}

void run() {
    if (this.halted)
        throw new Exception("Machine already halted.");
    auto state = cast()this.tm.initialState;

- - - - - - - - - -

Maybe later I'll write more comments.

Bye,
bearophile

Reply via email to