[Haskell-cafe] Re: Haskell Speed

2005-12-23 Thread S Koray Can

Daniel Carrera wrote:
It looks like Haskell doesn't do very well. It seems to be near the 
bottom of the pile in most tests. Is this due to the inherent design of 
Haskell or is it merely the fact that GHC is young and hasn't had as 
much time to optimize as other compilers?


I don't think it's that bad. It depends on the particular test, but it's 
 almost comparable to Java, iirc. On some tests, it's terrible, though.


For example, another very slow language is Ruby. In Ruby's case, there 
is a design factor that will always make it slow. I wonder if Haskell is 
in a smilar situation.


Haskell's syntax and type system are powerful enough that technically 
there are a lot of optimizations possible without involving FFI. It may 
become ugly, though, and less and less safe e.g. if you have to use 
unsafeWrite's to update arrays to eliminate boundchecks, etc.


A lot of the benchmark problems (at least the ones GHC seems to do worse 
than usual, e.g. 
http://shootout.alioth.debian.org/gp4/benchmark.php?test=revcomp&lang=all) 
involve some sort of string processing. Idiomatic Haskell dictates that 
one uses a linked list of Char's because FastString is not  part of the 
language. That is a lot of overhead for values as small as one byte. 
Also, the input string is 25M characters long in the revcomp case, thus 
there's a lot of difference between reversing it with and without 
in-place updates. If you look at the OCaml implementations, they usually 
use references, in-place updates and compile with boundchecks disabled 
(but that is idiomatic ocaml code).


However, I don't think it is right to downplay these benchmarks. Such 
little tasks exist in one form or another in bigger programs. Perhaps we 
should include mutable arrays in 'idiomatic' Haskell as well. Otherwise 
it is similar to proposing std::getline() take a std::List as an 
argument from a performance point of view.


And it's not right to blame naive implementors, either. I couldn't have 
guessed that the see the difference between the two haskell 
implementations for sum-file would be so massive. It's a pity that the 
super-slow version could very well be the version your coworker would 
have written even if you wouldn't.


Cheers,
Koray
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Tutorial uploaded

2005-12-21 Thread S Koray Can

Daniel Carrera wrote:
As a newbie... I agree that a newbie should be able to write this fairly 
early on:


main = do
   x <- getLine()
   putStrLn ("The answer is " ++ show(fib(read(x



I'd agree for some definition of 'early'. I'll elaborate:

This entire discussion is about 'breaking a cyclic graph of conceptual 
dependencies'. Unfortunately, I don't think it can be done well in short 
amount of time.


The above code snippet contains typeclasses (show, read, monadic IO, 
lists), syntactic sugar (do, <-). When you say a 'newbie' should be able 
to write that early on, I'd interpret that as 'a newbie should be able 
to regurgitate this early on' because the next thing a newbie might want 
to do is try to divide the result of fib by a float and wonder why he 
can't do that, or try to debug his fib implementation by trying to 
insert a putStrLn. There are numerous ways to frustration unless the 
newbie is comfortable with typeclasses, monads, etc.


This happens all the time when somebody is learning a new language, but 
it's most problematic for haskell because the breadth of knowledge (of 
various concept of the language) a learner has to gather before he can 
dive deep (formulation, compilation, execution, debugging) into an 
actual (even trivial) program is larger than all popular languages out 
there.


In every language, the most powerful features make their ways into the 
most basic elements (as they should so that the entire language 
benefits, but then, lists are monads?!?!). Learners of C++ with a C 
background are not as much troubled by "cout << yadda << endl;" even 
though there is operator overloading, references and the streams class 
hieararchy in that statement. You can close your eyes and pretend that 
cout is just magic and re-visit that node when you are comfortable with 
classes. I don't think we can break cycles easily like that in Haskell.


The mental load is very high, and with concerns about language features 
vs complexity even in other languages (see 
http://lambda-the-ultimate.org/node/view/1155) I think we are observing 
a new phenomenon: languages worth learning from now on will be 
increasingly difficult (heck, even Perl is difficult now), and we'll 
have to do away with 'tutorials' mostly.


In fact what we have are not really tutorials (YAHT is a small book! 
compare that with http://www.ocaml-tutorial.org/). I think it's a tall 
order for a 'tutorial' to teach Haskell (which may be why we end up 
reading 4-5 of them). In fact Hudak's Haskell book was the first 
introductory language book I'd ever bought. That's why I think tutorials 
can have be frustrating and it takes a well edited book and .


Cheers,
Koray
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: module names

2005-12-20 Thread S Koray Can

Scherrer, Chad wrote:

module Main where
import A
import B
main = A.f >> B.f

  module A where
f = ...

  module B where
f = ...

in a single file. This example is straight from chapter 5 of the Report,
and no mention is made (that I could find) about modules needing to be
in separate files. But this won't load in ghci! (Even if ... is changed
to putStr "hi"). Eventually I figured out that it works fine if it's
split over three separate files.


The report says that they make up a single program, so that does not 
imply that they are in a single file. But, you are right: it's a good

idea to be explicit about this.


So here's what I'm trying to figure out: If every file corresponds to
exactly one module (is that true?), then why must the module name be
given again in the text of the file? When I'm using ghci, I have lots of
modules that I sometimes want to load "as Main", and sometimes I only
want them loaded as a dependency from another module. Currently, I have
to go into each file to change the "module Foo where" line to do this.


Section 9.5 of the report seems to show that  stands for the 
compilation unit and it defines a single module. I suppose the standard 
allows you to name your module freely no matter your filesystem allows, 
but ghc requires (afaik) that module M exist in M.hs or M.lhs.
Why not do this: name none of those modules Main.hs, and have an empty 
module Main.hs with only "import MainDeJour" and "main = 
MainDeJour.main" so you can just edit just that file.


Cheers,
Koray
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe