tag:blogger.com,1999:blog-13687314832440515082024-03-08T21:59:58.840+11:00while(nan)What exactly does that do, anyway?Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-1368731483244051508.post-5255541222478071122010-04-15T13:07:00.003+10:002010-04-15T14:17:14.180+10:00NOCOMMIT for Mercurial<p>One problem with DVCSes (DVCSii?) is that because they encourage committing often, I sometimes accidentally end up committing temporary debugging code I didn't mean to.</p>
<p>So here's a simple little Mercurial pre-commit hook that blocks any commit which adds a line containing the string <code>!NOCOMMIT</code>.</p>
<pre><code>#!/usr/bin/env python
#
# Prevents any commits which contain the string `!NOCOMMIT'.
#
# Based on code at:
# http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html
#
import re
def scan_nocommit(difflines):
linenum = 0
header = False
for line in difflines:
if header:
# capture name of file
m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)
if m and m.group(1) != '/dev/null':
filename = m.group(1).split('/', 1)[-1]
if line.startswith('+++ '):
header = False
continue
if line.startswith('diff '):
header = True
continue
# hunk header - save the line number
m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)
if m:
linenum = int(m.group(1))
continue
# hunk body - check for !NOCOMMIT
m = re.match(r'\+.*!NOCOMMIT.*', line)
if m:
yield filename, linenum, line[1:].rstrip()
if line and line[0] in ' +':
linenum += 1
def main():
import os, sys
msg_shown = False
added = 0
for filename, linenum, line in scan_nocommit(os.popen('hg export tip')):
if not msg_shown:
print >> sys.stderr, 'refusing commit; nocommit flags present:'
msg_shown = True
print >> sys.stderr, ('%s:%d: %s' % (filename, linenum, line))
added += 1
if added:
# Save commit message so we don't need to retype it
os.system('hg tip --template "{desc}" > .hg/commit.save')
print >> sys.stderr, 'commit message saved to .hg/commit.save'
return 1
if __name__ == '__main__' and not __file__.endswith('idle.pyw'):
import sys
sys.exit(main())
</code></pre>
<p>To use this:</p>
<ul>
<li>Save the above as <code>.hg/block_nocommit.py</code> in your repository.</li>
<li>If you're on *nix, set execute permissions on the script.</li>
<li>Add <code>pretxncommit.nocommit = .hg/block_nocommit.py</code> in the <code>[hooks]</code> section of your <code>.hg/hgrc</code> file.</li>
</ul>
<div class="quip">Now all I need to do is figure out how to write a 'block commits that contain bugs' script...</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com0tag:blogger.com,1999:blog-1368731483244051508.post-9227688415942089462007-11-04T00:14:00.000+11:002007-11-04T02:56:55.320+11:00Firefox: How to Crash in Style<p>So <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> just crashed on me. Again. So why, exactly, am I grinning like an idiot?</p>
<p>Back in the <a href="http://en.wikipedia.org/wiki/Good_old_days" title="No, I can't believe there's an article on this, either...">appreciatively nostalgic days</a>, when <a href="http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox#Naming">Phoenix</a> crashed, it just vanished from your desktop with maybe a generic "This program just lost the page you spent an hour trying to find with Google: sucks to be you" dialog and that's it. Firefox 2 made things a little more bearable by keeping track of what tabs you had open. In the event of a crash, it could then restore your session pretty much most of the time.</p>
<p>The one bug-bear was the damned crash reporter. It made you fill in all sorts of stuff, and click buttons, and half the time it just sat there twiddling its thumbs complaining about how it couldn't access the internet.</p>
<p>Enter the current alpha of Firefox 3. This thing makes crashing almost a total non-issue. I was reading through some old <a href="http://www.codinghorror.com/">Coding Horror</a> posts when Firefox just up and died; vanished from the face of the desktop. A second or two later, it pops up this dialog saying "Aww jeeze; sorry about that. We screwed up, but we'll get right on it." It then gives me a little field to pop in my email address if I want to be kept in the loop, a quit button and a restart button.</p>
<p>I clicked restart, and a few seconds later it's like the crash had never happened. The best part of all is that in the background, it's sending crash data back to those tireless peeps at Mozilla so they can figure out why it crashed, and stop it from happening again.</p>
<p>Why is this so much better than anything else I've used? I think Mozilla have managed to do three things really right with this:</p>
<ol>
<li><p>There's no long speech about how sorry they are, and how my bug report will help them and that my privacy is always blah, blah, blah, where's the cancel button?</p></li>
<li><p>They don't ask me for any information at all. The crash reporter is apparently smart enough to get everything they need.</p></li>
<li><p>There are two prominent buttons: quit and restart. Clicking restart puts me straight back where I was without any fuss.</p></li>
</ol>
<p>Contrast this to the OpenOffice.org crash experience<a class="fna" name="fna-1" href="#fn-1"><sup>1</sup></a>. When that crashes, it throws up a full-blown wizard, asking for details on what you were doing. When it restarts (eventually, since OOo is so damnably lethargic) it then throws <em>another</em> wizard at you asking you if you want to recover your work. Well, of <em>course</em> I want to recover my work. What a stupid question. And then when it's done that, it stops you again to let you know that it's finished. That's great; get out of my way, already!</p>
<p>Now, all this is not to say that I'm happy with how often Firefox 3 appears to be crashing; I sincerely hope it gets more stable before it gets released proper. But when Firefox <em>does</em> crash, it does what it can to minimise the impact and let you get on with what you were doing.</p>
<p>Really, in an ideal world, this is how all software would work.</p>
<div class="quip">To get back to the old car analogies, Firefox 3 is the car that inexplicably explodes every few hours followed by immediately re-assembling itself, all while leaving the driver unscathed.</div>
<div class="footnotes">
<p class="fn"><a name="fn-1" href="#fna-1">[1]</a>: Note that I haven't actually had OpenOffice.org crash on me in a while. The following description could, in fact, be an amalgamation of various crash reporters I've experienced.</p>
</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com1tag:blogger.com,1999:blog-1368731483244051508.post-40627155098955611872007-08-29T00:49:00.000+10:002007-08-29T00:52:01.135+10:00Fakin' closures<p>Closures are awesome. There are so many algorithms that can be
implemented in a very straightforward manner once you have the ability to make
little customised functions and pass them around.</p>
<p>For example, it makes functional programming in D a snap. Here's a simple
example of what I mean:</p>
<pre><code class="d"><span class="Type">string</span> format_list(<span class="Type">real</span>[] parts, <span class="Type">string</span> sep)
{
<span class="Type">string</span> reduce_closure(<span class="Type">string</span> left, <span class="Type">string</span> right)
{
<span class="Statement">return</span> left ~ sep ~ right;
}
<span class="Type">string</span> map_closure(<span class="Type">real</span> n)
{
<span class="Statement">return</span> toString(n);
}
<span class="Statement">return</span> reduce(&reduce_closure, map(&map_closure, parts));
}</code></pre>
<p>The one failing of D's closures are that... they aren't really closures.
See, D's closures are made up of a function pointer, and a pointer to the
enclosing function's stack pointer. The stack pointer is what allows you to
actually <em>create</em> closures, but it's also why you <em>must not</em> use
them outside the enclosing scope's lifetime. As soon as your closure goes out
of scope, it's bye-bye stack frame, and hello Mr. Segmentation Fault if you
should try to call it. Oh dear.</p>
<p>In practice, this can be worked around by putting your closure inside a
class and heap allocating it, but that's annoying. Wouldn't it be nice to be
able to just return the damn things out of your functions, or store them
somewhere for later use?</p>
<p>If you're easily put off my horrible, hackish code: you'd best leave
now. It's going to get nasty.</p>
<p>Remember how I said that closures are made up of a pointer to some code and
the enclosing function's stack pointer? Well, on x86 the stack grows
downwards, and a function's arguments are stored just above the
stack pointer with its local variables below the stack pointer.</p>
<p>Say we have a function <code class="d">foo</code>, with a closure <code class="d">bar</code>,
and another function <code class="d">baz</code>.</p>
<p>If we call <code class="d">baz</code> from <code class="d">foo</code>, passing our closure
<code class="d">bar</code>, then <code class="d">baz</code> would know two important things:</p>
<ol>
<li><p>It would have an upper-bound on <code class="d">foo</code>'s local variables
by virtue of knowing its stack pointer (which is contained in the delegate
to <code class="d">bar</code>) and</p></li>
<li><p>it would have a lower-bound based on the address of its own first
argument on the stack.</p></li>
</ol>
<p>So if we have both a lower and upper bound, we can create a heap copy of
<code class="d">foo</code>'s local variables, and store <em>that</em> in our delegate
instead of the pointer to the stack.</p>
<p>Just to prove the concept, here's a working implementation:</p>
<pre><code class="d"><span class="PreProc">module</span> closures;
<span class="PreProc">import</span> std.stdio;
<span class="Comment">/**</span>
<span class="Comment"> * Takes a closure defined in the caller, copies the local variables onto the</span>
<span class="Comment"> * heap, and returns a modified delegate.</span>
<span class="Comment"> */</span>
dgT closure(dgT)(dgT dg)
{
<span class="Type">void</span>* end_ptr = dg.ptr;
<span class="Type">void</span>* start_ptr = &dg;
<span class="Type">auto</span> context = <span class="Statement">new</span> <span class="Type">ubyte</span>[end_ptr-start_ptr+<span class="Constant">1</span>];
context[] = <span class="Statement">cast</span>(<span class="Type">ubyte</span>[]) start_ptr[<span class="Constant">0.</span>.context.length];
dg.ptr = &context[$-1];
<span class="Statement">return</span> dg;
}
<span class="Comment">/**</span>
<span class="Comment"> * Creates a closure that sets *ptr to value when called.</span>
<span class="Comment"> */</span>
<span class="Type">void</span> <span class="Statement">delegate</span>() make_dg(<span class="Type">uint</span>* ptr_, <span class="Type">uint</span> value_)
{
<span class="Type">auto</span> ptr = ptr_;
<span class="Type">auto</span> value = value_;
<span class="Type">void</span> dg()
{
*ptr = value;
}
<span class="Statement">return</span> closure(&dg);
}
<span class="Type">void</span> main()
{
<span class="Type">uint</span> f;
<span class="Type">auto</span> fn1 = make_dg(&f, <span class="Constant">42</span>);
<span class="Type">auto</span> fn2 = make_dg(&f, <span class="Constant">1701</span>);
f = <span class="Constant">15</span>;
writefln(<span class="Constant">"f: %s"</span>, f);
fn1();
writefln(<span class="Constant">"f: %s"</span>, f);
fn2();
writefln(<span class="Constant">"f: %s"</span>, f);
}</code></pre>
<p>When run, it prints:</p>
<pre>f: 15
f: 42
f: 1701</pre>
<p>Just like one would expect. As I mentioned before, this <em>only</em>
works if your closure doesn't access the enclosing function's arguments. But
apart from that, it's a pretty neat trick, don'tcha think?</p>
<div class="quip">Well, hey, let's just make everything into a closure, and
then we'll have our general garbage collector, installed by 'use less memory'.
—<cite>Larry Wall</cite></div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com4tag:blogger.com,1999:blog-1368731483244051508.post-19497525855423278592007-08-26T17:40:00.000+10:002007-08-26T17:48:07.572+10:00The Future of D Is Aaargh, My Eyes!<p>So the first ever <a href="http://d.puremagic.com/conference2007/">D Conference</a> has come and gone. Sadly, being a poor <a href="http://uow.edu.au/">uni
student</a>, <a href="http://en.wikipedia.org/wiki/Australia">Australian</a> and busy like an anime nerd in <a href="http://en.wikipedia.org/wiki/Akihabara">Akihabara</a> with 100,000
spare yen meant I couldn't go.</p>
<p>Thankfully, the ever-wonderful Brad Roberts has posted up most of the
<a href="http://d.puremagic.com/conference2007/speakers.html">slides from the various speakers</a> so the rest of us can take a peek. One of
particular interest<a class="fna" name="fna-1" href="#fn-1"><sup>1</sup></a>
is the set from <a href="http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf">Walter and Andrei's talk on the future
of D</a>.</p>
<p>I encourage you to read the full set of slides, but here's what I think of
it (for what that's worth.)</p>
<p>First up, some <em>very</em> welcome additions to the language that will
make every-day programming a lot nicer. There's function and template
overloading which will finally allow you to do this:</p>
<pre><code>void foo(int i);
void foo(T)(T* t);</code></pre>
<p>What can I say but "finally!"? Also on the topic of overloads are function
overload sets. Currently, if you import overloaded functions from more than
one module (for instance: you import two modules that both have a global
<code>toString</code> function), you need to either fully qualify the
particular overload you're interested in, or manually alias in each module's
overloads.</p>
<p>Function overload sets do away with this provided each overload is
distinct. It's a small thing, but it's the small things that make programming
in D so much more pleasant than in C or C++<a class="fna" name="fna-2"
href="#fn-2"><sup>2</sup></a>.</p>
<p>Another of my pet hates is going the way of spelling and grammar online:
having to qualify enumeration members. Now you'll be able to elide the enum's
name before a member in cases where the compiler already knows the enum's
type. Thank <em>god</em> for that.</p>
<p>Then there's the upgrade to <code>switch</code>. One thing I love about
D's <code>switch</code> is that by default it will loudly complain (by
crashing your program) if you don't have a case to handle the value you're
switching on. Walter takes it one step further with <code>final switch</code>
which will actually refuse to compile if you don't have a case for every
possible value.</p>
<p>Obviously more useful for enums and subsets of integers than, say,
strings. But that's OK. No one's perfect.</p>
<p>And while we're on upgraded constructs: <code>static foreach</code>. About
time. Not that you can't do it with a <code>range</code> tuple template, but
this is much cleaner<a class="fna" name="fna-4" href="#fn-4"><sup>4</sup></a></p>
<p>So that's the day-to-day stuff. What about the seriously cool stuff we can
dangle in front of C++ and Java programmers to make them cry on the
inside?</p>
<p>Well, first up we've got the construct that comes up every few months on
the newsgroup: type method extensions. Or, as Walter calls it, uniform
function call syntax.</p>
<pre><code>foo(a, args...);
a.foo(args...);</code></pre>
<p>Those two will now be interchangeable. And it'll work with built-in types
like <code>int</code>, too. Having suggested this myself a few times, I
couldn't be happier about this coming.</p>
<p>It seems that another idea that I've shared with many people is being
worked on: pure functions. The concept of "pureness" comes from functional
programming. A pure function is one whose output depends <em>only</em> on its
arguments, and has no side-effects.</p>
<p>Take, for instance, the following function:</p>
<pre><code>int foo(int a, int b)
{
return a + b;
}</code></pre>
<p>Yes, it's contrived, but stay with me. This function's result depends
entirely on its inputs, and has no side-effects; it's pure. What does this
mean?</p>
<ul>
<li>It means that the compiler only ever has to call it once. If it sees
the same function call in two places in a function, it can simply
compute the result once, and reuse it. You can't do this with regular
functions because the compiler can't guarantee that the function
doesn't have side-effects.</li>
<li>More interestingly, it means that the compiler can actually
cache results from the function for future re-use. It could even
theoretically go the whole hog and just pre-compute every possible
result at compile-time.</li>
<li>Best of all, because pure functions have no side-effects and don't
depend on or alter global state, they can be <em>automatically
parallelised</em>. Suddenly, it just got a whole lot easier to make
use of all those cores we have these days.</li>
</ul>
<p>But wait, there's more! After bitching and whining about it for years,
<code>struct</code>s are finally getting constructors and destructors!</p>
<p>That's fantastic. Know what's even better? They're getting a copy
operator overload, too. This (along with the awesome
<code>alias some_member this;</code> declaration) means that D will finally be
able to easily support the last major memory-management technique:
reference-counting. I can see this being huge in the game development
circles.</p>
<p>There are also more new operator overloads: we're also getting
<code>opImplicitCastTo</code> and <code>opImplicitCastFrom</code>. This means
we'll be able to construct custom types that can seamlessly "pretend" to be
other pre-existing types<a class="fna" name="fna-6" href="#fn-6"><sup>6</sup></a>.</p>
<p>This also ties into a new concept being introduced called polysemous
values: these are values that have an indeterminant type<a class="fna" name="fna-7" href="#fn-7"><sup>7</sup></a>. Things like
<code>cast(int)1 + cast(uint)2</code>, or a type with multiple implicit casts.
This allows the compiler to reason about values for which it can't immediately
determine their type, deferring the decision until later.</p>
<p>We're also getting a new array type that's distinct from slices; slices
will work the same as they do now, except you won't be able to modify their
<code>length</code> property to resize them, whilst you will be able to with
arrays. Anyone
who has been caught by obscure and baffling bugs when you start accidentally
resizing slices will appreciate this; it makes D's arrays that much tighter
and safer.</p>
<p>A feature that I actually poo-poohed a few days ago is getting in:
<code>struct</code> inheritance. Sorry, "inheritance." It means that structs
will be able to implement interfaces, complete with static checks to make sure
all the methods are there, but won't be castable down to that interface. Kind
of like C++ concepts for structs.</p>
<p>Another feature that's got me salivating in anticipation are static
function parameters. That's where you mark one or more parameters to a
function as being static, meaning that the value is "passed" at compile-time.
It allows you to write functions that execute partially at compile-time.
Think of it as a cross between CTFE and regular functions.</p>
<p>This also means you will be able to write functions that have different
behaviours depending on whether some of the arguments are known at
compile-time or not. That means you could use a slower but CTFE-compatible
algorithm to perform some of the function at compile-time without having to
worry about users accidentally using the slower version at runtime.</p>
<p>Then comes the big one: <abbr title="Abstract Symbol Tree">AST</abbr>
macros. These are kind of like templates except that instead of operating on
specific types of values, they operate on bits of code. The simple way to
think about it is this: when you pass something to a template, the compiler
goes off and works out what that expression means, then gives it to the
template. For macros, on the other hand, the compiler just hands the macro
the unparsed expression and says "here, <em>you</em> work this out."</p>
<p>I have a funny feeling <a href="http://www.prowiki.org/wiki4d/wiki.cgi?DonClugston">Don Clugston</a>'s already incredible <a href="http://www.dsource.org/projects/mathextra/browser/trunk/blade">BLADE</a> library is
going to be even more impressive once we get AST macros. If this keeps up, we
may even be able to finally kill FORTRAN<a class="fna" name="fna-8" href="#fn-8"><sup>8</sup></a>.</p>
<p>Now, as I mentioned in an earlier post, I was looking forward to writing a
neat shell-style variable expansion macro when all this came around. Except
Walter's gone and added it into the language itself.</p>
<pre><code>macro say(s) { ... }
auto a = 3, b = "Pi", c = 3.14;
say("$a musketeers computed $b to be $c\n");</code></pre>
<p>Not quite as flexible as what I had in mind, but still. Pants.</p>
<p>Other interesting additions include:</p>
<ul>
<li>the creation of a standard template library,</li>
<li>a <code>nothrow</code> contract on functions,</li>
<li>the order of function argument evaluation being defined,</li>
<li>three new string literal forms:
<ul>
<li>delimited strings,</li>
<li>code strings (which would have been <em>so</em> much more
useful before macros) and</li>
<li>heredoc strings, and</li>
</ul>
</li>
<li>a special <code>return</code> storage class for function arguments
that let you create both <code>const</code> and non-<code>const</code>
versions of a function without having to duplicate code.</li>
</ul>
<p><em>Whew!</em> Needless to say, I'm stoked about all this. To quote a
<a href="http://en.wikipedia.org/wiki/Big_Kev">famous (and sadly, very dead) Australian</a>: I'm excited!</p>
<p>This really
crystallises why I threw my lot in with D for me: because unlike C which is
basically dead, C++ which is bloated, arthritic and has eight heads and Java
which makes me want to beat myself over the head with a brick...</p>
<p>D makes programming fun. It doesn't just let me tell the computer what to
do, it makes it easy. It's like statically-typed Python in a lot of ways.</p>
<p>But I do have to disagree with Walter on one point: the future of D isn't
bright.</p>
<p></p>
<p>It's blinding.</p>
<div class="footnotes">
<p class="fn"><a name="fn-1" href="#fna-1">[1]</a>:
Not to say they aren't all interesting, mind you.</p>
<p class="fn"><a name="fn-2" href="#fna-2">[2]</a>:
The big things make programming in D more powerful, safe and
flexible. And they cure baldness, too<a class="fna" name="fna-3" href="#fn-3"><sup>3</sup></a>.</p>
<p class="fn"><a name="fn-3" href="#fna-3">[3]</a>:
Not speaking from personal experience, mind you.</p>
<p class="fn"><a name="fn-4" href="#fna-4">[4]</a>:
So clean that if you use it twice
a day, it'll make your teeth all sparkly.<a class="fna" name="fna-5" href="#fn-5"><sup>5</sup></a></p>
<p class="fn"><a name="fn-5" href="#fna-5">[5]</a>:
Just be careful not to get any on your gums... it's the tiny shards
of glass, y'see...</p>
<p class="fn"><a name="fn-6" href="#fna-6">[6]</a>:
It also vindicates the decision to use the <code>opX</code> naming
system instead of C++'s <code>operator X</code> notation; implicit
casting doesn't <em>have</em> a symbol.</p>
<p class="fn"><a name="fn-7" href="#fna-7">[7]</a>:
I would have been tempted to call them "quantum values" or
"entangled values" or even "boxed cats". But maybe that's just
me.</p>
<p class="fn"><a name="fn-8" href="#fna-8">[8]</a>:
Unlikely, but it's always nice to dream. I mean, some people
<em>voluntarily</em> use Java!</p>
</div>
<div class="quip">Blinded by the light; revved up like a Deuce, another runner
in the night... Madman drummers bummers, Indians in the summer with a teenage
diplomat and yes I do know all the words to this damn song thankyouverymuch.</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com3tag:blogger.com,1999:blog-1368731483244051508.post-29738668379776029732007-07-28T16:16:00.000+10:002007-07-28T16:27:13.372+10:00pragma(msg, "Gday!");<p>No, I'm not dead.</p>
<p>Just thought I'd drop a line to Pragma who has just chiselled himself out a new corner of Cyberspace over at <a href="http://pragma.solaries.net/">Phase Positive</a>.</p>
<div class="quip">In a hole in the ground there lived a hobbit...</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com1tag:blogger.com,1999:blog-1368731483244051508.post-28624393133775278622007-06-19T02:46:00.000+10:002007-06-19T02:58:34.590+10:00Const Wars<p><i>A long time ago, in an IRC channel far, far away...</i></p>
<h4 style="text-align: center;">Episode 5</h4>
<h5 style="text-align: center;">A NEW CONST</h5>
<p style="padding-left: 3em; padding-right: 3em;">
It is a period of civil war.
Rebel posters, striking from irc
and the newsgroups, strive to win
their final victory against the
evil Constant Empire.</p>
<p style="padding-left: 3em; padding-right: 3em;">
During this battle, Rebel agents
were horrified to discover that the
Empire's ultimate weapon, the D 2.0
Release, a new compiler with three
kinds of const, had been
released.</p>
<p style="padding-left: 3em; padding-right: 3em;">
Pursued by the Empire's sinister
agents, Princess Mutable races
against the clock to find a way to
destroy the terrible compiler to
save her people and restore
mutability to the galaxy...</p>
<h4 style="text-align: center;">Episode 5</h4>
<h5 style="text-align: center;">A NEW CONST</h5>
<p style="padding-left: 3em; padding-right: 3em;">
It is a period of civil war.
Rebel posters, striking from irc
and the newsgroups, strive to win
their final victory against the
evil Mutable Empire.</p>
<p style="padding-left: 3em; padding-right: 3em;">
During this battle, Rebel agents
were horrified to discover that the
Rebel's ultimate weapon, the D 2.0
Release, a new compiler with three
kinds of const, was feared and
hated.</p>
<p style="padding-left: 3em; padding-right: 3em;">
Pursued by the Empire's sinister
agents, Princess Invariant races
against the clock to find a way to
justify the badly needed compiler to
save her people and restore
type safety to the galaxy...</p>
<div class="quip">That's the wonderful thing about religion; you can use it to justify anything, with no requirement for facts or logic!</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com3tag:blogger.com,1999:blog-1368731483244051508.post-42871601322920053862007-06-14T17:40:00.000+10:002007-06-14T17:56:23.625+10:00Wrapping functions for fun and profit<p>Error handling sucks. I mean, I've got code to write! I don't want to
have to waste my time making sure my function calls actually worked. After
all, nothing <em>ever</em> goes wrong when I'm running it, so any problems are
the user's fault.</p>
<p>Or something along those lines. That's one thing that always annoyed me
about C-style libraries: you had to sit there writing all this code to handle
errors on <em>every single damn call</em>. I can't count the number of times
I've seen OpenGL examples where they never do a single error check, apparently
because it's too much work.</p>
<p>So when I started writing GL code in D, I realised pretty quickly that this
was sub-optimal. After all, you <em>want</em> to know when something's gone
wrong (if you don't find out, how can you ever fix it?) but having to write
all those <code class="d"><span class="Statement">if</span></code>s was out of
the question on account of me being supremely lazy.</p>
<p>One way around this is to have a function that takes the error code from a
function, and throws an exception if its something other than
<code>NO_ERROR</code>. Sadly, OpenGL doesn't use return values; it has a
separate function called <code>glError</code> that tells you if an error's
occured.</p>
<p>OK, we can deal with this; we just need a templated function that checks
for an error, throws an exception if there was one, or passes back what we
pass into it.</p>
<pre><code class="d">T glCheck(T)(T result)
{
<span class="Statement">if</span>( glError() == GL_NO_ERROR )
<span class="Statement">return</span> result;
<span class="Statement">else</span>
<span class="Statement">throw</span> <span class="Statement">new</span> GLException(<span class="Constant">"OH NOES!"</span>);
}</code></pre>
<p>And that <em>does</em> work. Well, except for functions that have <code
class="d"><span class="Statement">void</span></code> return types. That's
when it starts to get a little ugly; we need to have a different function that
we call afterwards.</p>
<p>And this is all well and good if you happen to like simple solutions to
problems. Not me, though. I wanted something that I could stick in front of
<em>any</em> GL call and have it do error checking. I also wanted to try and
remove the double closing paren problem (every time you nest an expression, it
gets just that tiny bit uglier).</p>
<p>So let's change things around a bit. Instead of a function that we pass
the GL call's result to, let's create a function that <em>wraps</em> the GL
call.</p>
<pre><code class="d">ReturnType!(Fn) glCheck(<span class="Type">alias</span> Fn)(ParameterTypeTuple!(Fn) args)
{
<span class="Type">alias</span> ReturnType!(Fn) returnT;
<span class="Type">static</span> <span class="Statement">if</span>( <span class="Statement">is</span>( returnT == <span class="Type">void</span> ) )
Fn(args);
<span class="Statement">else</span>
<span class="Type">auto</span> result = Fn(args);
glCheckError();
<span class="Type">static</span> <span class="Statement">if</span>( !<span class="Statement">is</span>( returnT == <span class="Type">void</span> ) )
<span class="Statement">return</span> result;
}</code></pre>
<p>What we're doing here is creating a function that has the exact same
signature as the function we want to call. When we call this wrapper
function, it calls the underlying function, checks for errors (throwing an
exception as necessary: that's the job of <code
class="d">glCheckError</code>), and returning the result.</p>
<p>Those <code class="d"><span class="Statement">static if</span></code>s are
there because you can't declare a variable of type <code class="d"><span
class="Statement">void</span></code> in D, which kinda sucks. You'd
use the above function like this:</p>
<pre><code class="d">glCheck!(glClear)(GL_COLOR_BUFFER_BIT);</code></pre>
<p>For those keeping count, that's one character longer than the
"pass-through" style. The nice thing is that this works uniformly with any
function, no matter its return type.</p>
<p>However, we can still improve this. For instance, since we have an alias
to the function being called, we can improve the call to <code
class="d">glCheckError</code> to this:</p>
<pre><code class="d">glCheckError((&Fn).stringof)</code></pre>
<p>This allows us to report the exact GL call that failed (normally, all we
would get is an exception telling us which error code we got). Even cooler,
however, is we can use this information to actually log our GL calls as they
happen:</p>
<pre><code class="d"><span class="Statement">version</span>( gl_LogCalls )
{
log.writef(<span
class="Constant">"%s"</span>,(&tFn).stringof[<span
class="Constant">2</span>..$]);
log.writef(<span class="Constant">"("</span>);
<span class="Type">static</span> <span class="Statement">if</span>( args.length > <span class="Constant">0</span> )
{
log.writef(<span class="Constant">"%s"</span>, args[<span class="Constant">0</span>]);
<span class="Statement">foreach</span>( arg ; args[<span class="Constant">1.</span>.$] )
log.writef(<span class="Constant">", %s"</span>, arg);
}
log.writeLine(<span class="Constant">")"</span>);
<span class="Statement">version</span>( gl_LogCalls_Flush )
log.flush();
}</code></pre>
<p>If we place that in our <code class="d">glCheck</code> function just before
we call the function itself, it gives us the ability to trace through our GL
code without having to hunt through functions. This can be really useful when
you've got some weird behaviour, and can't figure out what's causing it.</p>
<p>One last improvement: in OpenGL, there are times where calling <code
class="d">glError</code> can itself cause an error. The most obvious of
these are between <code>glBegin</code> and <code>glEnd</code> calls. You can
solve this by either building some logic in to <code>glCheck</code> to account
for <code>glBegin</code>/<code>glEnd</code> blocks, or you can do what I did
and split the function into two: <code>glSafe</code> which does the error
checking and <code>glRaw</code> which doesn't.</p>
<p>Before I go, one small note: if you are using DerelictGL, you need to
replace the <code class="d">Fn</code> in <code
class="d">ReturnType!(Fn)</code> and <code
class="d">ParameterTypeTuple!(Fn)</code> with <code class="d"><span
class="Statement">typeof</span>(Fn)</code> because of a weird bug with
specialising templates on aliases to function pointers, and replace the line
that logs the name of the function with:</p>
<pre><code class="d">log.writef(<span
class="Constant">"%s"</span>,tFn.stringof);</code></pre>
<div class="quip">Wrap me up, in your love, your love takes me higher...</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com7tag:blogger.com,1999:blog-1368731483244051508.post-31781998505524884122007-06-08T23:15:00.000+10:002007-06-14T17:48:25.151+10:00Mixins, CTFE and shell-style variable expansion<p class="note"><em>Edit</em>: Frits van Bommel <a href="http://while-nan.blogspot.com/2007/06/mixins-ctfe-and-shell-style-variable.html#comment-7398293466398128550">pointed
out</a> that I'd forgotten about declaration mixins, which have now been
added.</p>
<p>It didn't take all that long before <a href="http://www.php.net/">PHP</a>
started annoying me. Don't get me wrong; it's a great language for hacking
together dynamic web pages, but if I have to look at another full-blown CMS
written in it, I am going to scream.</p>
<p>That said, PHP did get a few things right. One of these is the syntax it
uses for variable expansion in strings. Basically, it's stolen almost
verbatim from the <a href="http://en.wikipedia.org/wiki/Bourne_shell"
>Bourne shell</a> and relatives:</p>
<pre><code class="php"><span class="Statement">$</span><span class="Identifier">life</span> <span class="Statement">=</span> <span class="Constant">42</span>;
<span class="Identifier">echo</span> "<span class="Constant">Meaning of life: </span><span class="Statement">$</span><span class="Identifier">life</span>";</code></pre>
<p>Which obviously expands to <code>Meaning of life: 42</code>. PHP adds to
this by allowing you to use braces to expand a more complex expression
involving member and array access.</p>
<p>Sadly, those of us in the statically-typed world have to make do with
rather less attractive options like C-style format strings...</p>
<pre><code class="c">printf(<span class="Constant">"Meaning of life: </span><span class="Special">%d</span><span class="Constant">"</span>, life);</code></pre>
<p>...C#-style format strings...</p>
<pre><code class="c#">WriteLine(<span class="Constant">"Meaning of life: {}"</span>, life);</code></pre>
<p>..."whisper" syntax...</p>
<pre><code class="d">Cout(<span class="Constant">"Meaning of life: "</span>)(life).newline;</code></pre>
<p>...or worst of all, the hideous monster that is C++'s
<code class="c++">iostream</code>s.</p>
<pre><code class="c++">cout << <span class="Constant">"Meaning of life: "</span> << life
<< endl;</code></pre>
<p>What would be really cool is a formatting function that uses PHP/shell
style inline expansion, optionally with C-style formatting options. Best of
both worlds. So, today I sat down and implemented such a formatter which
makes this possible:</p>
<pre><code class="d"><span class="Type">int</span> a = <span class="Constant">13</span>;
<span class="Type">int</span> b = <span class="Constant">29</span>;
<span class="Statement">mixin</span>(writeFln(
<span class="Constant">" a: $a"</span> <span class="Constant">"</span><span class="Special">\n</span><span class="Constant">"</span>
<span class="Constant">" b: $b"</span> <span class="Constant">"</span><span class="Special">\n</span><span class="Constant">"</span>
<span class="Constant">" a + b: ${a+b}"</span> <span class="Constant">"</span><span class="Special">\n</span><span class="Constant">"</span>
<span class="Constant">"in hex: $(x){a+b}"</span>));</code></pre>
<pre> a: 13
b: 29
a + b: 42
in hex: 2a</pre>
<p>Those already familiar with both <a
href="http://www.digitalmars.com/d/statement.html#MixinStatement">string
mixins</a> and <a
href="http://www.digitalmars.com/d/function.html#interpretation">CTFE</a>
will no doubt already have an idea how I accomplished this; you can skip to
the code at the end if you like. For those of you who would like to know how
D makes this possible, read on.</p>
<h4>Compile time function execution</h4>
<p>The first feature that D adds to make this possible is compile time
function execution or CTFE. Now this is basically just an extension of
regular constant folding. Imagine you have code like this:</p>
<pre><code class="d"><span class="Type">int</span> registry = <span
class="Constant">1700</span> + <span class="Constant">1</span>;</code></pre>
<p>You would expect any good compiler to be able to simplify this code since
both numbers are constant (and the compiler hopefully knows how to add two
numbers.) CTFE simply expands on this and allows you to use <em>function
calls</em> in constant-folding, provided they satisfy a stringent set of
requirements. The
<a
href="http://www.digitalmars.com/d/function.html#interpretation"
title="CTFE requirements">requirements</a>
are too long to list here, but suffice to say
that they all boil down to two things: stick to basic structural constructs
(no labelled breaks, gotos, nested functions, etc.), and don't do anything
that involves pointers or memory allocation.</p>
<p>For example, CTFE allows us to do things like this:</p>
<pre><code class="d"><span class="Type">char</span>[] repeat(<span class="Type">char</span>[] a, <span class="Type">uint</span> n)
{
<span class="Type">char</span>[] result;
<span class="Statement">for</span>( ; n>=<span class="Constant">0</span>; --n )
result ~= a;
<span class="Statement">return</span> result;
}</pre></code>
<p>It's worth noting that simple array operations like changing the length,
concatenation, etc. are allowed for CTFE.</p>
<h4>String mixins</h4>
<p>The other half of this magic trick are string mixins. In D, there are
actually four different mixins:</p>
<ol>
<li>
<p>"Regular" mixins, or as I call them, <em>scope mixins</em>. These will,
when you specify a template, mix the contents of that template into the
current scope. For example:</p>
<pre><code class="d"><span class="Type">template</span> foo()
{
<span class="Type">char</span>[] bar = <span class="Constant">"baz"</span>;
}
<span class="Type">void</span> main()
{
<span class="Statement">mixin</span> foo;
writefln(bar); <span class="Comment">// Outputs "baz".</span>
}</code></pre>
</li>
<li>
<p><em>Statement mixins</em>. These mixins take a list of statements (as
in D source code) as a compile-time constant string, and inserts them into
the souce at that location. For instance, we could replace the last line
of the previous example with:</p>
<pre><code class="d"><span class="Statement">mixin</span>(<span
class="Constant">"writefln(bar);"</span>); <span
class="Comment">// Outputs "baz".</span></code></pre>
</li>
<li>
<p><em>Expression mixins</em>. These are like the statement mixins,
except that they allow you to mix in any semantically complete expression.
That includes things like <code class="d"><span
class="Constant">"bar"</span></code>, <code
class="d"><span class="Constant">"12+34"</span></code>,
<code class="d"><span class="Constant">"a =
foo(PI)"</span></code> and even <code class="d"><span
class="Constant">"writefln(bar)"</span></code> (note the
lack of a semicolon!)
</li>
<li>
<p><em>Declaration mixins</em>. These are like statement mixins, except
instead of mixin in executable statements, they mix in declarations (like
functions, classes, imports, etc.).</p>
<p>Many thanks to Frits van Bommel for pointing out that I stupidly missed
this one.</p>
</li>
</ol>
<p>Those last three are collectively known as "<em>string mixins</em>" since
they take plain old strings of D source code. Now, you may be wondering how
mixing in plain D source could be useful. It isn't, until you combine it with
a CTFE function (or a template) that <em>produces</em> D source code from some
other format.</p>
<h4>Putting them together</h4>
<p>The idea now is quite straightforward. We're going to write a CTFE
compatible function that takes our format string and converts it into D source
code. We then feed the result of this function into a string mixin which
inserts our freshly generated code into our source file.</p>
<p>So what are we aiming for? Basically, we want to turn this:</p>
<pre><code class="d"><span class="Constant">"foo $bar baz"</span></code></pre>
<p>Into this:</p>
<pre><code class="d"><span class="Constant">"foo "</span>,bar,<span
class="Constant">" baz"</span></code></pre>
<p>There are various ways of doing this, but my personal favourite is to write
a simple state machine to process the string. So how would such a state
machine look in a CTFE function? Lots of weird, crazy syntax? Sadly, no.
It's actually pretty anticlimactic...</p>
<pre><code class="d"><span class="Type">char</span>[] ctfe_format_string(<span class="Type">char</span>[] fs)
{
State state;
<span class="Type">char</span>[] result;
<span class="Statement">foreach</span>( <span class="Type">char</span> c ; fs )
{
<span class="Statement">if</span>( state == State.Default )
{
<span class="Comment">// output character & look for '$'</span>
}
<span class="Statement">else</span> <span class="Statement">if</span>( state == State.PostDollar )
{
<span class="Comment">// work out if this is a variable or not...</span>
}
<span class="Statement">else</span> <span class="Statement">if</span>( state == State.Varname )
{
<span class="Comment">// write out the variable name...</span>
}
<span class="Comment">// ...</span>
}
<span class="Statement">return</span> result;
}</code></pre>
<p>That's pretty much it; the actual details are just ordinary string
manipulation code. There's really nothing terribly interesting to it at all.
Aside from that, there's a few convenience methods for joining the string
pieces together and dumping the result to <code>STDOUT</code>. You can check
out the details by grabbing <a href="#the-code">the source code</a>. In fact,
I encourage you to go read it now, just to see how stupidly simple this kind
of manipulation is.</p>
<p>I mean, look at this:</p>
<pre><code class="d"><span class="Comment">// Finish the variable expansion</span>
result ~= <span class="Constant">"))"</span>;</code></pre>
<p>That's about as complex as the code gets.</p>
<p>So, OK; we've got it splitting strings up. Yeah, it's cute, but can you do
anything <em>else</em> with it?</p>
<p>Perhaps the best example to date is Don Clugston's <a
href="http://www.digitalmars.com/d/archives/digitalmars/D/BLADE_0.2Alpha_Vector_operations_with_mixins_expression_templates_51617.html"
>BLADE</a> library which uses CTFE and string mixins to generate
near-optimal floating-point vector code from library code.</p>
<p>Another example is <a href="http://kirkmcdonald.blogspot.com/">Kirk
McDonald</a>'s <a href="http://pyd.dsource.org/">Pyd</a> which uses string
mixins behind the scenes. Or how about Gregor Richards' <a
href="http://www.digitalmars.com/d/archives/digitalmars/D/Compile-time_madness_Compile-time_compiler_49164.html">compile-time
brainf**k compiler</a>?</p>
<p>And there are other possibilities that haven't been explored yet. Like
compiling SQL or LINQ statements, or creating parsers out of BNF grammars.</p>
<p>So the next time you've got some recurring pattern that you can't quite
express concisely using ordinary code, think about how a little CTFE and
mixin magic might help things along.</p>
<div class="quip">"Don't worry about people stealing your ideas. If your ideas
are any good, you'll have to ram them down people's throats."
—<cite>Howard Aiken</cite></div>
<p><a name="the-code"></a>The source code for the formatter can be downloaded
from the D wiki <a
href="http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/shfmt"
title="source code for the formatter">here</a>, and is licensed under the
BSDv2 license.</p>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com3tag:blogger.com,1999:blog-1368731483244051508.post-8870575077839735732007-06-08T11:27:00.000+10:002007-06-08T11:48:14.800+10:00D 1.0 to be frozen in carbonite<p>So after much crying and gnashing of teeth, Walter has finally confirmed what I'm sure a lot of D users have been waiting to hear:</p>
<blockquote cite="http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=54300">
<p>It's getting pretty clear to me that the 1.0 series won't get any new features, just bug fixes, as the recent 1.015 release suggests.</p>
<p>The new features will all go into the 2.0 series.</p>
</blockquote>
<p class="bqcite">Walter Bright, <cite><a href="http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=54300">Re: Do we need a time-out in D evolution?</a></cite></p>
<p>This is somewhat mixed news. It's good in that we will now (hopefully) end up with a nice, stable compiler release and a less stable but cutting-edge experimental compiler release. It's bad in that it means more work for Walter; he introduced the largely unused <code>-v1</code> compiler switch so that he wouldn't have to maintain two compiler branches.</p>
<p>Interesting question: does this mean GDC is going to branch, too?</p>
<div class="quip">That's very funny. You know something? No new features for you!</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com0tag:blogger.com,1999:blog-1368731483244051508.post-51537754728805397962007-06-07T20:52:00.000+10:002007-06-08T00:45:09.140+10:00You can't touch this.<p>So, there seem to be quite a few people who are confused about the upcoming changes to <code>const</code>-ness in D 2.0. The topic came up, once again, in <a href="irc://irc.freenode.org/D">the #D IRC channel</a>, and I've been persuaded to write up how I understand it.</p><p>It is worth pointing out that this is all up in the air at the moment, meaning all of this could be rendered incorrect before I even finish writing it. Also, I'm not going to give any examples of what the code will look like, since the syntax appears to have recently changed, and I'm still not entirely sure what the impact is. Think of the examples as being "pseudo code."
</p><p>That said, the concept itself seems fairly stable, which is what I'm going to talk about. With that, on with the show.</p><p>Firstly, it's important to disregard any pre-conceived notions you may have about what the word <code>const</code> means. What it will mean in D 2.0 is very different to what it means in D 1.x, C, C++ or any other language you might know.</p><p>Now, with D 2.0 will come three kinds of <code>const</code>-ness. For the moment, we will call these "<span style="font-style: italic;">storage const</span>", "<span style="font-style: italic;">reference const</span>" and "<span style="font-style: italic;">reference </span><span style="font-style: italic;">immutable</span>."
</p><p>Storage const is the easy one; it simply means that whatever bits are being used to store a particular variable cannot be changed once they are initialised. For example, every <code>int</code> variable in your program has four bytes of memory allocated to it <span style="font-style: italic;">somewhere</span>, be it on the stack or in the static data segment. Storage const says that you can store a value into this <code>int</code>, but you cannot change it afterwards. One pretty obvious use of this would be:</p><pre><code>"storage const" PI = 3.1415926535897931;</code></pre><p>Unless you work for Xerox, you aren't likely to change the value of Pi. The same thing can be done with variables in functions:</p><pre><code>void doStuff(int a, int b)
{
"storage const" int c = a + b;
}</code></pre><p>This is fine since we set the value of <code>c</code> during initialisation. However, the following wouldn't compile:</p><pre><code>"storage const" int meaning_of_life = 42;
meaning_of_life = 72;</code></pre><p>Once a storage const variable has had its value set, there's no changing it. There's one other interesting question: what about reference types like pointers, arrays and objects? Remember that a reference type stores an address of some kind. A storage const pointer, for example, would have the pointer itself fixed, but what it points to is unaffected. For example:</p><pre><code>"storage const" int* stuff = new int;
(*stuff) = 23; // This is cool
(*stuff) = 19; // Still cool
stuff = new int; // This ain't cool at all.</code></pre><p>In this example, we're free to change what <code>stuff</code> points to, but we are not allowed to change <code>stuff</code> itself.
</p><p>Once you've wrapped your head around that, we can move on to "reference const".</p><p>Unlike storage const, reference const says <span style="font-style: italic;">nothing</span> about a variable's storage. Rather, it deal with what that variable points at. If we take the previous example and change <code>"storage const"</code> to <code>"reference const"</code>, we get:</p><pre><code>"reference const" int* stuff = new int;
(*stuff) = 23; // This isn't cool anymore.
(*stuff) = 19; // Neither is this.
stuff = new int; // This *is* cool.</code></pre><p>What reference const is saying is "Ok, you've got a pointer to something, but you <span style="font-style: italic;">aren't</span> allowed to change it; feel free to point at something else, though!" In a way, reference const can be thought of as a read-only <span style="font-style: italic;">view</span> of some data. You can look, but can't touch.</p><p>Another important thing is that reference const is <span style="font-style: italic;">transitive</span>. Take this, for example:</p><pre><code>"reference const" int** foo;</code></pre><p><code>foo</code> is a reference const pointer to a pointer to an <code>int</code>. Notice that we didn't say anything about the <code>int*</code> we're pointing to; just <code>foo</code> itself. That means we can't do this:</p><pre><code>(*foo) = new int;</code></pre><p>However, we <span style="font-style: italic;">also</span> can't do this:</p><pre><code>(*(*foo)) = 42;</code></pre><p>This can be kinda tricky to explain, so just think of it like this: once you go through a "reference const" reference (be it a pointer, array or object reference), <span style="font-style: italic;">all</span> references from that point onward are "reference const". Essentially, you can't change <span style="font-style: italic;">anything</span> beyond a reference const.</p><p>Go back over that, and make sure you understand what's going on. Once you've done that, we'll move on to the last and strongest form of <code>const</code>-ness: "reference immutable".</p><p>Now, reference immutable is <span style="font-style: italic;">very</span> similar to reference const; it applies to reference types and says "you can look, but can't touch." The important difference is that where reference const says "<span style="font-style: italic;">you</span> can't touch", reference immutable says "<span style="font-style: italic;">no one</span> can touch." Reference immutable is a guarantee to you and the compiler that <span style="font-style: italic;">nothing</span> can modify the data being pointed at. For instance, if you have a static string in your program stored in the data segment (a part of the executable itself), that string is reference immutable since no one is able to change it. In fact, a reference immutable piece of data may not even necessarily have an address in memory; if it never changes, the compiler could potentially just insert its value wherever it gets used.</p><p>From the user's end, there isn't any appreciable difference between something that's reference const and something that's reference immutable. The difference is on the <span style="font-style: italic;">creator's</span> end; you might get a reference const buffer that the owner keeps updating, or a reference immutable buffer that gets filled and then fixed.</p><p>So, the only question remaining is: how do these three concepts map to keywords in D 2.0? At the moment, it looks like this:</p><ul><li>"storage const" will be <code>final</code>,</li><li>"reference const" will be <code>const</code> and</li><li>"reference immutable" will be <code>invariant</code>.</li></ul><p>Let me just reiterate that I'm not saying anything about where these keywords go, where you put parenthesis, etc. I'm just trying to explain the concepts; don't take any of the code examples above literally.</p>
<p>One last thing I'd like to point out (as suggested by Oskar Linde): whilst reference const and reference immutable are part of a variable's type, storage const isn't; it only affects one particular variable. For example:</p>
<pre><code
>"storage const" int a;
"reference const" int* b;
int c = a; // You can do this; typeof(a) is int
int* d = b; // But can't do this; typeof(b) is "reference const" int*</code></pre>
<p>Hopefully, that's helped to clear things up, at least a little. If you have any questions or corrections, let me know and I'll try to clear it up.</p><div class="quip">Stop! Hammer time!</div>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com6tag:blogger.com,1999:blog-1368731483244051508.post-20069095591439538582007-06-07T15:42:00.001+10:002007-06-08T00:45:52.682+10:00Incidentally...<p>... <code>while(nan)</code> doesn't compile since <code>nan</code> isn't defined. Technically, it should be <code>while(real.nan)</code>, but that was a bit unwieldy.</p>
<p>As for what it does, it turns out that despite <code>nan</code> comparing false to everything <em>including</em> itself, it's effectively the same as <code>while(true)</code>. Go figure.</p>Dkhttp://www.blogger.com/profile/02909587337938463354noreply@blogger.com1