A little of coordination for Rosettacode

bearophile bearophileHUGS at lycos.com
Fri Feb 15 18:16:45 PST 2013


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


More information about the Digitalmars-d-learn mailing list