digitalmars.D - Where statement
- bearophile (37/37) Jul 25 2010 Some people have proposed the introduction in Python of the 'where' stat...
- Trass3r (11/16) Jul 25 2010 You immediately give the counter-argument? ^^
- bearophile (6/17) Jul 25 2010 I try to give both pros and cons :-)
- Michel Fortin (11/18) Jul 25 2010 Is this really an improvement over using a delegate literal?
- Trass3r (1/7) Jul 25 2010 Even more clever.
- bearophile (4/11) Jul 25 2010 Cute :-) I have never seen this used in D code. I think you will need to...
- Michel Fortin (19/31) Jul 25 2010 Indeed, I forgot to add the (). Without it the type of 'c' is a
- Kagamin (2/6) Jul 25 2010 the where statement looks as a declaration statement, but scoped block a...
- Tomek =?UTF-8?B?U293acWEc2tp?= (7/22) Jul 25 2010 It exists in Haskell because functional languages can't describe sequenc...
- KennyTM~ (5/27) Jul 25 2010 No.
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): 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.5You 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: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.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.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:No. quadraticSum a b = let aSquared = a*a bSquared = b*b in aSquared + bSquaredSome 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