In fact, I am beginning to see how a language could conceivably support the concept of killing a cow at runtime while ensuring at compile-time that it is not killed twice:

A language that allows deleting symbols from the current namespace could be extended to allow linking the action of killing the cow run-time object with deleting the compile-time symbol referring to the cow. Furthermore, it would have to be ensured that there is only ever a single reference to the cow and it would have to be prohibited that the cow is killed within run-time conditional blocks.

In D, definitions within a source file do not have a well-defined order. This solves the issue of forward references because a symbol is essentially defined before it appears in the source. This fact, of course, makes the deletion of symbols pointless because in the view of the D compiler, there is not "before" or "after" within a source file.

Order is only defined within routines, where local variables cannot be references before they are defined. The cow would therefore have to be a local variable in a routine. The state of the cow would also have to be tied to the routine where a time-order is defined.

More generally: the whole concept of type-states that have been discussed only makes sense within a routine. The global name-space does not evolve in any ordered way, and without time evolution, the concept of changing state does not make sense.



On 30/09/10 14:04, bearophile wrote:
Norbert Nemec:

Which confirms my original position: the final three tests in the
contest are flawed by concept.

Those tree tests may be impossible to do, but they are not flawed (and they are 
not impossible to do, see below).


If the actions of eating and slaughtering
are supposed to happen at run-time, no compiler in the world can
reliably detect them happening twice.

The Rust language (that doesn't exist yet, by Mozilla) will probably be able to do that. It 
implements the idea of "typestate". This is the old original paper about typestates, 
Typestate: A Programming Language Concept for Enhancing Software Reliability", by Robert 
E. Strom and Shaula Yemini, 1986:
http://www.cs.cmu.edu/~aldrich/papers/classic/tse12-typestate.pdf

In a language like D a type has no state, a int value is always an int. In a 
language that supports typestate you may think of a File type as a finite state 
machine, in each state of this FSM you are able to access only a subset of the 
File methods, when the state of the File type is open, you can't access the 
'open' method, and so on. The transitions between those states don't happen at 
runtime, they happen in the code space. The compiler must analyse the code, 
perform some flow analysis and change the state of the File type in different 
parts of the program. Before the File.open() the File type is in the start 
state, then in the section of the code after the call to open the type of that 
File instance is in the opened state, and so on.

So the FSM of a Cow state is just two states, alive and dead/eaten, and the 
compiler that supports typestates disallows the eat() method in the section of 
the code where the state of that Cow instance is Eaten.

I'd probably like to have typestates in D3 too.

Bye,
bearophile

Reply via email to