digitalmars.D - Where statement
- bearophile <bearophileHUGS lycos.com> Jul 25 2010
- Trass3r <un known.com> Jul 25 2010
- bearophile <bearophileHUGS lycos.com> Jul 25 2010
- Michel Fortin <michel.fortin michelf.com> Jul 25 2010
- Trass3r <un known.com> Jul 25 2010
- bearophile <bearophileHUGS lycos.com> Jul 25 2010
- Michel Fortin <michel.fortin michelf.com> Jul 25 2010
- Kagamin <spam here.lot> Jul 25 2010
- Tomek =?UTF-8?B?U293acWEc2tp?= <just ask.me> Jul 25 2010
- KennyTM~ <kennytm gmail.com> Jul 25 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
Jul 25 2010
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
You immediately give the counter-argument? ^^ Introducing a new keyword + whole new constructs gotta have substantial merit. The 2nd concept is perfect to me, some parentheses are no reason. Another possibility would probably be the following, but it's not as compact and nice: double c; { double a = retrieve_a(); double b = retrieve_b(); c = sqrt(a*a + b*b); }
Jul 25 2010
Trass3r:You immediately give the counter-argument? ^^<
I try to give both pros and cons :-) I think when expressions get even more complex 'where' can help.Another possibility would probably be the following, but it's not as compact and nice: double c; { double a = retrieve_a(); double b = retrieve_b(); c = sqrt(a*a + b*b); }
If 'c' has a very complex type, you really want to use 'auto', but you can't there. In functional-style programming types can be very complex and long to write, for example the result of a map(filter(lazy generator)). Bye, bearophile
Jul 25 2010
On 2010-07-25 08:33:53 -0400, bearophile <bearophileHUGS lycos.com> said: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(); }
Is this really an improvement over using a delegate literal? auto c = { auto a = retrieve_a(); auto b = retrieve_b(); return sqrt(a*a + b*b); }; -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 25 2010
Is this really an improvement over using a delegate literal? auto c = { auto a = retrieve_a(); auto b = retrieve_b(); return sqrt(a*a + b*b); };
Even more clever.
Jul 25 2010
Michel Fortin:Is this really an improvement over using a delegate literal? auto c = { auto a = retrieve_a(); auto b = retrieve_b(); return sqrt(a*a + b*b); };
Cute :-) I have never seen this used in D code. I think you will need to add () at the end when property get implemented fully. I hope the D compiler is able to inline that delegate. Bye, bearophile
Jul 25 2010
On 2010-07-25 09:48:21 -0400, bearophile <bearophileHUGS lycos.com> said:Michel Fortin:Is this really an improvement over using a delegate literal? auto c = { auto a = retrieve_a(); auto b = retrieve_b(); return sqrt(a*a + b*b); };
Cute :-) I have never seen this used in D code. I think you will need to add () at the end when property get implemented fully.
Indeed, I forgot to add the (). Without it the type of 'c' is a delegate (whether property is implemented or not is irrelevant). I just didn't test it properly before posting. Here's the revised version: auto c = { auto a = 1.0; auto b = 2.0; return a*a + b*b; }(); I've never seen this in use either, but it looks like a nice pattern for variables that require a complex initialization.I hope the D compiler is able to inline that delegate.
I think it does not currently. This bug report turns out to have a patch for this exact issue however: <http://d.puremagic.com/issues/show_bug.cgi?id=4440> Put your vote on it if you want. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 25 2010
bearophile Wrote:auto c = sqrt(a*a + b*b) where { auto a = retrieve_a(); auto b = retrieve_b(); }
the where statement looks as a declaration statement, but scoped block allows arbitrary statements.
Jul 25 2010
bearophile wrote: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)
It exists in Haskell because functional languages can't describe sequences (can't declare a temporary variable before the main expression because there's no "before"). But I don't know Haskell so I may be wrong. Anyway, where in D wouldn't bring enough return of investment to break even, IMHO. Tomek
Jul 25 2010
On Jul 25, 10 21:54, Tomek SowiĆski wrote:bearophile wrote: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)
It exists in Haskell because functional languages can't describe sequences (can't declare a temporary variable before the main expression because there's no "before"). But I don't know Haskell so I may be wrong.
No. quadraticSum a b = let aSquared = a*a bSquared = b*b in aSquared + bSquaredAnyway, where in D wouldn't bring enough return of investment to break even, IMHO. Tomek
Jul 25 2010









bearophile <bearophileHUGS lycos.com> 