Where statement

bearophile bearophileHUGS at lycos.com
Sun Jul 25 05:33:53 PDT 2010


Some people have proposed the introduction in Python of the 'where' statement. It is quite used in Haskell:

printFreqsBySize genome keySize = do
        ht0 <- htNew keySize
        ht <- hashGenome genome keySize ht0
        l <- htToList ht
        htFree ht
        return $ map draw (sortBy sortRule l) ++ [""]
    where
        genomeLen = S.length genome
        draw :: (S.ByteString, Int) -> String
        draw (key, count) = printf "%s %.3f" (S.unpack key) pct
            where pct   = (100 * (fromIntegral count) / total) :: Double
                  total = fromIntegral (genomeLen - keySize + 1)



In some situations it improves readability of complex epressions. It also keeps the namespace clean because here "a" and "b" names are local to the where block. So only "c" exist when the 'where' block ends:

c = sqrt(a*a + b*b) where:
    a = retrieve_a()
    b = retrieve_b()

That is equivalent to:

c = (retrieve_a() ** 2 + retrieve_b() ** 2) ** 0.5


Another of its possible usages in Python is to define Ruby-like blocks (that is multiline lambdas):

obj.onclick.setcallback(f) where:
    def f(x, y):
        # callback body here ...


D lambdas can be multiline, so that's not a problem.
But it can be useful to write more readable expressions when they are complex:

auto c = sqrt(a*a + b*b) where {
    auto a = retrieve_a();
    auto b = retrieve_b();
}


In this case you can write a single expression in D too:
import std.math;
auto c = (retrieve_a() ^^ 2 + retrieve_b() ^^ 2) ** 0.5;


With a single expression you don't need brackets:

double d = sqrt(x*x + y*y) where
    double x = computeX();

Bye,
bearophile


More information about the Digitalmars-d mailing list