goto
Daniel Keep
daniel.keep.lists at gmail.com
Thu Feb 5 22:37:17 PST 2009
Andrei Alexandrescu wrote:
> I was coding a simple Euclidean distance function with limit:
>
> double euclideanDistance(Range)(Range a, Range b, double limit)
> {
> limit *= limit;
> double result = 0;
> for (; !a.empty; a.next, b.next)
> {
> enforce(!b.empty);
> auto t = a.head - b.head;
> result += t * t;
> if (result >= limit) goto thatsit;
> }
> enforce(b.empty);
> thatsit:
> return sqrt(result);
> }
>
> How would an elegant goto-less approach look like? It should not
> duplicate code, e.g. the call to sqrt.
>
>
> Andrei
The goto approach looks a bit messy because it isn't immediately clear
what the relationship between a and b's lengths are.
Personally, I'd do it like this:
double euclideanDistance(Range)(Range as, Range bs, double limit)
{
limit *= limit;
double result = 0;
foreach( ab ; zip(as, bs, ZipStyle.EnforceLength) )
{
auto t = ab._0.head - ab._1.head;
result += t * t;
if (result >= limit) break;
}
return sqrt(result);
}
Of course, if we had foreach support for tuple unpacking...
double euclideanDistance(Range)(Range as, Range bs, double limit)
{
limit *= limit;
double result = 0;
foreach( a, b ; zip(as, bs, ZipStyle.EnforceLength) )
{
auto t = a.head - b.head;
result += t * t;
if (result >= limit) break;
}
return sqrt(result);
}
:D
-- Daniel
More information about the Digitalmars-d
mailing list