Peter Alexander: > auto newrange = filter!"a<5"(map!"2*a"(range)); > > At least I think that works??
It works: import std.stdio, std.range, std.algorithm; void main() { auto r = iota(20); auto n = filter!q{ a < 5 }(map!q{ 2 * a }(r)); writeln(n); } > The problem it's simply intractable to do lazy computation in D while > maintaining the 'correct' static typing. Both Perl6 and Scala have a "lazy stream" that you use like Haskell lazy lists. It is possible to implement something similar to D, recently someone has shown some code. > The problem with the D situation is that if I have a function: > > void foo(int[]) > > then it can't be called with: > > foo(map!"2*a"([1, 2, 3])); > > I'm forced to either: > (a) use eager computation by wrapping it in array(...) > (b) change foo to be a template This is why I have asked for functions like amap/afilter in Phobos, because in many situations in D you need an array instead of a lazy range. > Of course, if every function that accepts a range becomes a template > then you have the practical problem of managing the number of template > instantiations. Code bloat is still a real problem with heavy template > usage. Haskell has used typeclasses to avoid this :-) > Finally, map in Haskell just makes sense. You have a list of a's, a > function of 'a to b' and you get a list of b's out the other end. It's > simple, it's exactly what you want, and it just works. You can't say the > same in D. I agree. That has two good consequences: - It makes sense for the Haskell compiler too, so it is able to perform very complex optimizations that no D compiler today performs. - Being map so easy to write, to use and to understand, the programmer is able to write far more complex things. If writing a map requires a tens lines of complex D code, normal programmers usually don't want to write things much more complex (type-wise too) than a map. > * I say simple cases because Haskell compiler can do deforestation > optimisations, which are essentially intractable in D due to its > imperative roots. I think future D compilers will find some ways to further optimize D code that uses purity/immutability a lot. ----------------------- Andrei Alexandrescu: >> Where D still loses when compared to Scala is functional code syntax: >> >> val newcol = collection filter {x=>x<5} map {x=>2*x} > > Yoda this wrote. > >> or maybe >> >> val newcol = for(x<-collection if(x<5)) yield 2*x > > Too baroque. > >> vs >> >> auto newrange = filter!((x){return x<5;})(map!((x){return 2*x;})(range)); > > auto newrange = filter!"a<5"(map!"2*a"(range)); Python lazy iterators syntax wins over both languages: >>> collection = xrange(20) >>> [2 * x for x in collection if x < 5] # eager [0, 2, 4, 6, 8] >>> newcol = (2 * x for x in collection if x < 5) # lazy >>> list(newcol) [0, 2, 4, 6, 8] > We should probably add a specialized lambda syntax. Do you mean something like C# lambdas? > I wonder what Scala/Haskell idioms we should borrow for D. Haskell has several nice ideas, but I think it's not easy to copy them without changing D a lot. Still, being open toward this idea is an improvement for D designers :-) -------------------------------- Andrei Alexandrescu: > You want Haskell capability with D performance. You can't have that. We live in a world where JavaScript is sometimes only 3-4 times slower than D code, and where LuaJIT compiles dynamically typed Lua floating-point-heavy programs and runs them in a total amount of time lower than just running a binary produced by DMD. So be careful when you say something is impossible :-) In the works there is a dialect of Haskell meant for faster programs: http://www.haskell.org/haskellwiki/DDC > D's map is superior to Haskell's. There is no contest. Some aspects of D map are superior, and some aspects of Haskell map are superior to D ones. > (In addition, Hakell's map forces ONE higher-order function > representation, whereas D works with a function alias, function, or > delegate.) I think this is an advantage of Haskell. I think Haskell doesn't need those things, it's more uniform. > D also allows things that are essentially impossible in Haskell, such as > quicksort. The point of this discussion is to look for ways to improve D. bashing Haskell is off topic and bad. ----------------------- Timon Gehr: > Pattern matching, if it can be incorporated in a good way. There are ideas to improve switch a bit: http://d.puremagic.com/issues/show_bug.cgi?id=596 > Generators? This is an idea: http://d.puremagic.com/issues/show_bug.cgi?id=5660 > The range concept is very important in D code, some syntactic sugar like > this would help a lot. Right. Bye, bearophile