Well, to make it short, I liked it! As suggestions, little things like first class functions and partial application can be easily introduced. For example the line: map (+1) [1..10] contains these concepts and it very short and expressive.
On the story side, why not introducing a character? This would help personalize the story. It would be nice if a real story is told also, beside the Haskell story, like a character building something or making a (evil) journey learning Haskell. Cheers, Corentin On Fri, Sep 14, 2012 at 11:18 PM, Andrew Pennebaker < andrew.penneba...@gmail.com> wrote: > A summary of the changes I've included so far: > > >> Under Declarative, you aren't creating a "named expression, 2 + 2", >> really. >> You are redefining (+). >> >> > Noted and reflected in the new version. > > >> Under Lazy, your example of binding fib 30 is not a good example of >> memoization. With memoization you typically call the underlying >> computation >> the first time, and memoize it for repeated retrieval later, not hardwire >> in >> values at compile time. Here you never ever call the real fib at all. On >> top >> of everything else, it'd be too easy to introduce a typo into one of your >> hardwired constant values. >> >> > Noted and reflected in the new version. After several comments to this > effect, I do not want to misrepresent memoization in the tutorial. > Sometimes it is useful to be slightly inaccurate in a tutorial in order to > help bridge the gap between someone with no experience in a something vs > the wealth of knowledge and complexity in the thing itself. This is not one > of those times, and fortunately, fixing the misrepresentation in my > tutorial is as easy as removing the hardcoded call. > > One thing I want to double check is that Haskell does, in fact, > automatically memoize all pure function calls. Is this true? > > I would still like to provide a performance comparison of the Fibonacci > code with and without memoization, for readers who enjoy numerical > evidence, using the Unix "time" command, but I don't know how to turn > memoization off. I guess I would have to reimplement the algorithm in a way > that can't make use of memoization. Any suggestions? > > Under Infinite, you should use "sieve (n:ns)" pattern matching instead of >> calling head. >> > > Thank you! I try to make use of Haskell pattern matching wherever I can. > Since I needed to refer to the whole list, as well as the head and tail, I > originally used "head" instead of pattern matching. Noted and reflected in > the new version. > > >> Under Type-Safe >> Subtle distinction, but returning () is not the same as returning nothing >> at all. >> > > True. Noted and reflected in the new version. What's the Haskell name for > () again? I fear explaining the exact type information of IO () may be too > much for a brief introduction to Haskell to cover. > > >> s/ommitted/omitted/ >> > > Noted and reflected in the new version. > > >> You've got an unusual indentation scheme. Consider adopting a more >> standard >> one for your tutorial. >> > > I'm in the camp of hard tabs rather than soft tabs, and that preference is > probably responsible for much of the difference in indentation scheme. > Unfortunately, HTML is terrible at representing hard tabs in <PRE> code > with a custom width preference; they all come out looking like some idiot > pressed space bar eight times. I could use JavaScript to remedy this, but > for now, I like to directly copy and paste my working code from .HS files > into <PRE> tags just in case. > > If tabs are *not* the issue, then maybe I'm not indenting far enough to > the right for some tastes? Or maybe it's my tendency to put "where" on its > own line, something a Perl obfuscater would detest. I dunno. If someone > would suggest a more idiomatic indentation scheme for my code so that I > know exactly what is different, I can take a look. > > >> In general, monotonically decreasing is not sufficient to prove you will >> hit >> a base case. For example, decreasing by 5 would still be monotonically >> decreasing, and could jump right over your base cases. >> (Not arguing that the code is incorrect, but rather than your explanation >> is >> a little misleading/incomplete.) >> > > Understood. Noted and reflected in the new version. > > Incidentally, when will Nat be available in Haskell? The Fibonacci > algorithm is designed to work only over natural numbers, and the best way > to express this in the type system is with Nat. But this type doesn't seem > available out-of-the-box for Haskell users. Unless I'm using my Haskell > Platform (GHC 7.0.3) is slightly outdated. Eh? > > >> Again, further confusion about what memoization really is. >> >> >> Under Records >> >> "Functions are already defined by their data structures; they are already >> semantically bundled..." doesn't seem to make sense. >> > > Noted and reflected... I'm trying to convey to an audience largely > composed of Java and C++ fanatics how Haskell records are much better than > OOP, how GADTs are more intuitive, robust, ... OOP doesn't even compare! > That's what I'm trying to get across in that bit. And it's hard to do this > in just a few sentences, especially when the reader isn't even familiar > with GADTs in the first place. > > "... acts on the specific constructor, blasting fools, murdering crowds..." >> makes it sound like fireOn actually has side effects. >> > > A truly fair point. Would you like to contribute a monad for blowing up > the moon? > > Another comment: > > >> "As a declarative language, Haskell manipulates expressions, eventually >> reducing expressions to values." > > >> Huh? In what sense do declarative languages manipulate expressions? >> Sounds like a classic syntax/semantics confusion, especially when >> interpreters and/or lazy evaluation (implementation issues, not language >> properties) are in the mix. > > > Noted and reflected in the new version. > > I'm trying to introduce the concept of declarative programming as opposed > to imperative programming. Declarative programming according to > Wikipedia<http://en.wikipedia.org/wiki/Declarative_programming> > : > > is a programming paradigm that expresses the logic of a computation >> without describing its control flow. > > > I believe this is done in Haskell and other declarative languages by > treating code as manipulable, reducible expressions, where imperative > languages would use machine instructions. > > --- > > Now, besides the code and the description of the code, I know we're not > English majors, but what do you think of the overall tone, pacing, etc.? Is > it entertaining? Is it humorous? Is it boring? Is it offensive? Is it too > brief or too laborious? > > Thanks all for your suggestions. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe