Voldemort declarations inside structs with ctor initialization

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Tue May 27 11:52:25 PDT 2014


On Tue, May 27, 2014 at 08:17:26AM -1000, Andrei Alexandrescu via Digitalmars-d wrote:
> On 5/27/14, 7:51 AM, Meta wrote:
> >On Tuesday, 27 May 2014 at 17:22:43 UTC, Andrei Alexandrescu wrote:
> >>I think there was either or both a discussion and a bug report on
> >>this, but can't find either. Basically we need to clarify what it
> >>means to compare two function literals for equality. -- Andrei
> >
> >I remember the thread where the consensus seemed to be that hashing
> >was the way to go. I think it's just that nobody ever implemented it.
> 
> Hmmm, are you sure? What about alpha renaming? -- Andrei

If we want to be technically correct, we would have to define function
literal comparison as being true iff the two functions produce an
identical computation. So:

	(x) => true

would have to be equal to:

	(x) => solveFermatsLastTheorem()

But unfortunately, this kind of equivalence is unsolvable in the general
case (it requires solving the halting problem), and infeasible except
for the most trivial cases (the compiler has to spend way too much time
to compute equivalence).

Hashing gives a crude first approximation that's both easy to implement,
fast, works in the cases where this issue came up in the first place,
and doesn't require solving unsolvable problems.

Alpha-renaming is not hard to support if the compiler just assigns each
declared identifier in the function literal to a numerical id. So a
literal like:

	(xcoor,ycoor) => sqrt(xcoor*xcoor, ycoor*ycoor)

and

	(x,y) => sqrt(x*x, y*y)

would both get translated to:

	(id1, id2) => sqrt(id1*id1, id2*id2)

and so they would compare as equal. This does require a little more
effort on the part of the compiler, though -- you'd have to walk the AST
of the function body.

I wouldn't go any farther than this, because this quickly approaches the
no-man's land of whether (x) => x+x+x should compare equal to (y) => y*3
(if floating-point is involved the two functions may *not* in fact be
equivalent, for example), whether to compare equal if two different
functions get optimized to the same assembly code (which may differ
depending on compiler / compile flags), etc..

Honestly, I don't see the need even for alpha-renaming -- I can't
imagine a use case where you'd want to do something like that. I think
straight up hashing of the function body is Good Enough(tm).


T

-- 
Once bitten, twice cry...


More information about the Digitalmars-d mailing list