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