Won a programming contest using D - Thank you for the tool!

Ivan Kazmenko via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 18 04:53:37 PDT 2014


On Monday, 18 August 2014 at 07:44:14 UTC, Joakim wrote:
>> A technical report draft: 
>> http://acm.math.spbu.ru/~gassa/az/alphabet-city/technical-report.html
>
> It would be good if you could expand on your thoughts on D from 
> part 11 of your technical report and post it somewhere, so that 
> others can learn from your experience.

Hmm, the program does contain a few features which are convenient 
or possible at all because of the choice of language.  For 
example, I found inner functions and internal iteration (opApply 
and foreach body converted to a delegate) very useful when 
iterating over small changes on complex objects.  Still, the 
examples are very solution-specific, so it would require a bit of 
thought to convert them to points of general interest.

I'll elaborate a bit.  Suppose we have a large and complex object 
(a Scrabble game state), and we want to iterate over small 
changes to that object (single word plays).  In pseudocode, that 
would be:

(1)
consider object o
for each change to object o:
     yield o

Here, "each change to object" actually spans a few hundred lines 
in a few inner recursive functions.

The yield must transfer control to another part of the code (also 
complex) which, for example, accounts for good states.  There are 
many states generated, but only a few valid and good states get 
actually copied, so the yield must be by reference to avoid 
excessive copying.  For example:

(2)
for each o yielded:
     if (o is valid and good):
         copy o to storage

Here, the checks for being valid and good, or maybe some other 
stuff, can also be long enough.

The catch is that the iteration on changes (which can be one of 
several possible iteration schemes) must be separated from the 
use of yielded states (which can again be one of several uses).

After a bit of attempting to simulate yield efficiently for my 
case, I realized that there is no need for the generator to 
actually hang in the heap waiting for another call.  The desired 
flow of the program is non-concurrent: for each o yielded by (1), 
we process it in the body of (2) immediately and return control 
right after that.

The concept of delegates makes this possible: (2) can be made a 
delegate and passed as an argument to (1).  Well, it can be 
emulated in other languages by passing an object containing the 
state, but the code would be harder to follow.

The mechanism for inner iteration makes it convenient: just write

foreach (o; call (1) as a function)
     put (2) as a body

and the body (2) is automatically converted into a delegate.  
This syntax coincides with my way of thinking about the problem, 
so I'm delighted to use it.

Ivan Kazmenko.


More information about the Digitalmars-d mailing list