Truth values and a couple other things

While trying to think about how I could tackle the section on numerical types in "Type basics" I found out that I couldn't reason properly about it without knowing to which extent types would be discussed in the previous sections. That led me to "jump the gun" and attempt writing the bulk of the section myself. Apfelmus, please forgive me if that bothers you in any way (for instance, if you had a draft of your own being prepared) - in any case, just as I took some liberties with your outline feel free to do the same and turn my text upside down if you feel the need to :) I will use this message to register some issues that are roaming in my mind lest I forget to mention them: * Since we are reorganizing and rewriting most of the first chapters anyway it could be a good opportunity to standardize the style of code blocks. One option would be just using <source> tags everywhere to get syntax highlighting (with recent changes to the Wikibooks CSS files <source> is also bundled with the standard grey background box). There would be a couple possible issues to consider, though. We would probably have to do some template engineering, although I don't think that would be too troublesome. Another source of annoyance would be that GHCi printouts, ubiquitous on the early chapters, wouldn't be subject to the same standardization. Finally, there is the didactic concern of whether highlighting can be distracting for complete newbies during the first few modules (I do not have a really strong position on the subject but feel that "plain" plain text does have some charm due to sheer simplicity and transparency). * One thing that occurred to me while writing about guards: is it even accurate to speak of our if/else and related constructs as "control structures"? Even if it is correct, is there any better term to use - one that does not have such imperative undertones? Regards, Daniel Mlot

Daniel Mlot wrote:
While trying to think about how I could tackle the section on numerical types in "Type basics" I found out that I couldn't reason properly about it without knowing to which extent types would be discussed in the previous sections. That led me to "jump the gun" and attempt writing the bulk of the section myself. Apfelmus, please forgive me if that bothers you in any way (for instance, if you had a draft of your own being prepared) - in any case, just as I took some liberties with your outline feel free to do the same and turn my text upside down if you feel the need to :)
Sure, no problem. :) Eric Kow once remarked that the wikibook is a "do-ocracy" which means that by doing something, like writing a chapter or making a change, you automatically get the right to do it. By the way, a principle that has helped me in my writing is that I try to keep it really short, even minimize the number of words I use to make a point. Great for clarity and readability, though a bit dry at times. I always imagine that I'm writing for a reader whose attention is really low and lasts only one additional paragraph, which is probably indeed the case for any reader after a certain amount of time. :)
I will use this message to register some issues that are roaming in my mind lest I forget to mention them:
* Since we are reorganizing and rewriting most of the first chapters anyway it could be a good opportunity to standardize the style of code blocks. One option would be just using <source> tags everywhere to get syntax highlighting (with recent changes to the Wikibooks CSS files <source> is also bundled with the standard grey background box). There would be a couple possible issues to consider, though. We would probably have to do some template engineering, although I don't think that would be too troublesome. Another source of annoyance would be that GHCi printouts, ubiquitous on the early chapters, wouldn't be subject to the same standardization. Finally, there is the didactic concern of whether highlighting can be distracting for complete newbies during the first few modules (I do not have a really strong position on the subject but feel that "plain" plain text does have some charm due to sheer simplicity and transparency).
The GHC user's guide uses different colors: green for source listings and red for GHCi examples (or the other way round). The only reason I don't use <source> tags is because I'm too lazy to type them out. :) The <code> tags are already too much for my taste.
* One thing that occurred to me while writing about guards: is it even accurate to speak of our if/else and related constructs as "control structures"? Even if it is correct, is there any better term to use - one that does not have such imperative undertones?
Strictly speaking, there is no control flow in Haskell, so the term "control structure" does not apply. I'd call it "case analysis" or "definition by cases" instead. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On 05/29/2010 04:58 PM, Heinrich Apfelmus wrote:
Eric Kow once remarked that the wikibook is a "do-ocracy" which means that by doing something, like writing a chapter or making a change, you automatically get the right to do it.
I think I will quote you both in my user page :)
By the way, a principle that has helped me in my writing is that I try to keep it really short, even minimize the number of words I use to make a point. Great for clarity and readability, though a bit dry at times. I always imagine that I'm writing for a reader whose attention is really low and lasts only one additional paragraph, which is probably indeed the case for any reader after a certain amount of time. :)
As you probably noticed already, I am slightly more inclined to flowery, colourful language. Thankfully as of late I have been able to keep myself under check and not get too prolix. In any case, the book would certainly profit from some extra conciseness - some existing passages grow really tiring just because the same idea is reiterated one time too many. ---- About the writing of "Truth Values" and the reworking of "Type Basics" (which I started yesterday) there are two main outstanding questions: 1. In "Truth Values" your outline included introducing True/False pattern matching when discussing the boolean operators. At first I thought it wasn't a good idea, as explained on the Talk page. But now, after having a closer look at "Type Basics" and the examples therein, I realize that not introducing an idiom this elementary idiom early on might be pedagogically problematic, as it may induce newbies to do very simple things in obtuse ways (like defining something like (||) with guards). In that case, a brief example - with (||), not, etc. could easily be added to the Boolean operations section, but I am not sure on what would be a clear, simple and not misleading way of introducing pattern matching at this point (discussing the general PM concept would likely not work, and saying "you can define functions with multiple definitions in terms of cases for (quasi-literal?) values of the arguments" could get too confusing (mainly the "quasi-literal" part - which really means literals and argument-less constructors, but obviously we can't go that far at this point of the book). 2. I am starting to believe that "Type Basics" should be divided in two. More specifically, the first part would retain the introduction, the experiments of :t, the presentation of Char and String and the section about functional types. The second part would have the final section about type signatures in code and the new section on number types. Finally, "Lists and Tuples" would be sandwiched between the two parts. Reasons for the splitting include: * The examples on the final section make use of tuples and string concatenation. While we could just reduce them to simple Int/Char/Bool functions, I fear that simplifying the examples too much would weaken their didactic value in illustrating to readers how signatures are important in practice. The move would also help to make the intentional forward references in that uppercase example less scary. * Both the existing demonstration of type inference (which involves the signature of (==) ) and the discussions of numerical types involve polymorphism. It would make sense to have them at the same place, as a "background topic" of a module. Moreover, placing the second part after "Lists and Tuples" would allow us to introduce polymorphic types and type variables with lists and tuples, which is probably more intuitive and easier for a newbie to grasp, and then expand a bit the concept with the other discussions. * Sheer length. "Type Basics" currently weighs at 27k, and with the addition of the whole numerical types discussion it could easily get to the 40k range - which would certainly be very bad for readability. Having the number types discussion on a less crowded module would also give us more space to present very useful and practical things, such as the different division operators or functions like fromInt. As usual, the only thing I can't find out is a good pair of names for the modules. In any case, since the division is slightly arbitrary perhaps we should simply stick to "Type Basics I" and "Type Basics II". Regards, Daniel Mlot

Daniel Mlot wrote:
About the writing of "Truth Values" and the reworking of "Type Basics" (which I started yesterday) there are two main outstanding questions:
1. In "Truth Values" your outline included introducing True/False pattern matching when discussing the boolean operators. At first I thought it wasn't a good idea, as explained on the Talk page. But now, after having a closer look at "Type Basics" and the examples therein, I realize that not introducing an idiom this elementary idiom early on might be pedagogically problematic, as it may induce newbies to do very simple things in obtuse ways (like defining something like (||) with guards). In that case, a brief example - with (||), not, etc. could easily be added to the Boolean operations section, but I am not sure on what would be a clear, simple and not misleading way of introducing pattern matching at this point (discussing the general PM concept would likely not work, and saying "you can define functions with multiple definitions in terms of cases for (quasi-literal?) values of the arguments" could get too confusing (mainly the "quasi-literal" part - which really means literals and argument-less constructors, but obviously we can't go that far at this point of the book).
I like Graham Hutton's way of introducing pattern matching a lot. (chapter 4.4. of Programming in Haskell). He starts with the obvious not False = True not True = False repeats the "complete case analysis" concept with True && True = True True && False = False False && True = False False && False = False Then, he introduces wildcards True && True = True _ && _ = False and variables True && b = b False && _ = False as a way to keep the number of cases down. Finally, he mentions the common pitfall that b && b = b _ && _ = False does not work and notes the correct solution b && c | b == c = b | otherwise = False The point is that a handful of simple examples are the most concise and clear way of introducing pattern matching (or any other concept); there is no need for "the most general explanation" because humans learn very well from concrete examples that can be repeated and adapted. (One could say that this is an instance of the "show, not tell" tenet.)
2. I am starting to believe that "Type Basics" should be divided in two. More specifically, the first part would retain the introduction, the experiments of :t, the presentation of Char and String and the section about functional types. The second part would have the final section about type signatures in code and the new section on number types. Finally, "Lists and Tuples" would be sandwiched between the two parts.
Sounds good. :) Personally, I would cut a lot to make it shorter and more "digestible", though; which might make a split unnecessary. The more elaborate discussion can always be taken up again in the subsequent "Elementary Haskell" track. In other words, I would do the following: * Cut the introduction. Make "5 < False does not make sense" the sole motivation for types. * :type is a very useful skill and can stay as it is. * Ditto for function types, in particular multiple arguments. However, I think the openWindow example is not so good because it's actually a "pseudo" example; the real example would have to live in the IO monad. * Replace type signatures and type inference by two very short paragraphs that basically only say "This is what a type signature looks like and you should use it, too." "Type inference happens when you don't put a type signature there." Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On 06/03/2010 04:31 PM, Heinrich Apfelmus wrote:
Daniel Mlot wrote:
2. I am starting to believe that "Type Basics" should be divided in two. More specifically, the first part would retain the introduction, the experiments of :t, the presentation of Char and String and the section about functional types. The second part would have the final section about type signatures in code and the new section on number types. Finally, "Lists and Tuples" would be sandwiched between the two parts.
Sounds good. :)
Personally, I would cut a lot to make it shorter and more "digestible", though; which might make a split unnecessary. The more elaborate discussion can always be taken up again in the subsequent "Elementary Haskell" track.
I just created the proposed "Type basics II" module. The changes I did so far are sort of in between my approach and yours (not that they were really in conflict to begin with, but anyway), as I will now explain...
In other words, I would do the following:
* Cut the introduction. Make "5< False does not make sense" the sole motivation for types.
While I agree that the introduction does need streamlining, I am not so sure about eliminating it completely, as it can be useful for making it easier for readers to amalgamate all the other discussions in this part of the book around the key conceptual issue - that types are a way of incorporating meaning into values. That is why I kind of like the abstract "real world" example, even if in its current form it is a bit too overcooked to drive the point home.
* :type is a very useful skill and can stay as it is. * Ditto for function types, in particular multiple arguments. However, I think the openWindow example is not so good because it's actually a "pseudo" example; the real example would have to live in the IO monad.
Agree about openWindow; it would probably be better if we could find a more workable real life example. On the other hand, given that the reader is not supposed to know or understand what the types actually are anyway, just putting "IO Window" in the signature would be no worse than, say, "Foobar" or "Hippogriff" :)
* Replace type signatures and type inference by two very short paragraphs that basically only say "This is what a type signature looks like and you should use it, too." "Type inference happens when you don't put a type signature there."
I shortened (though not that much) the final sections so that they could fit into the first "Type basics". The detailed rundown of an inference example was simplified (so that we are not forced to explain polymorphism) and the examples and exercises with forward references were eliminated (by the way, I am keeping a copy of deleted sections in http://en.wikibooks.org/wiki/User:Duplode/Haskell_leftovers for reference and to make eventual reincorporation of materials easier). As for Type basics II, as of now it is a lightweight discussion on how the type system handles numbers, written in a style similar to that of Truth values. Typeclasses are introduced, focusing on their implications for polymorphism. Some essential "concrete" facilities for number manipulation are presented, but for now I am assuming that systematic presentation of, say, arithmetic operators will be deferred to the cheat sheet modules or similar places. Finally, a question about Next Steps the module. Do you see a place for it in the overall scheme of things? My question is largely motivated by the fact I am finding it rather difficult to picture a way to incorporate pattern matching into the "soft", largely conceptual modules about the type system (I am counting "Truth values" and "Lists and tuples" among these) without breaking their flow. That leads me to consider introducing piece-wise function definitions or even (x:xs) and (x,y) in a separate context. The function composition operator is another potentially useful thing in "Next Steps" (because it fits well with the idea of stimulating creative usage of Prelude functions) that would be difficult to move to an earlier point of the book. That case is less serious, though, as there is the option of just moving it to "More on Functions". Regards, Daniel Mlot

Daniel Mlot wrote:
Heinrich Apfelmus wrote:
* Cut the introduction. Make "5< False does not make sense" the sole motivation for types.
While I agree that the introduction does need streamlining, I am not so sure about eliminating it completely, as it can be useful for making it easier for readers to amalgamate all the other discussions in this part of the book around the key conceptual issue - that types are a way of incorporating meaning into values. That is why I kind of like the abstract "real world" example, even if in its current form it is a bit too overcooked to drive the point home.
Ah, it's just that in my experience, conceptual explanations usually do not work so well for introducing someone to a new concept for the first time. Usually, a hands-on approach that simply uses the concept gives better results: the student needs to figure out the concept himself, and usually does so in order to memorize the material anyway. I think Brent Yorgey has put it most brilliantly in his remark on the "Monad Tutorial Fallacy": http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-... In other words, the concept is synthesized from its particular examples, not the other way round.
Finally, a question about Next Steps the module. Do you see a place for it in the overall scheme of things? My question is largely motivated by the fact I am finding it rather difficult to picture a way to incorporate pattern matching into the "soft", largely conceptual modules about the type system (I am counting "Truth values" and "Lists and tuples" among these) without breaking their flow. That leads me to consider introducing piece-wise function definitions or even (x:xs) and (x,y) in a separate context.
Since the current Next Steps chapter is mainly about the alternative ("expression" vs "declaration") syntax to guards, where, and pattern matching, it should be moved to the second part of the beginners' track. Concerning the flow, I think that thanks to the modularity of the wikibook, we don't need to worry much about it. Simply making a new chapter on pattern matching seems fine to me.
The function composition operator is another potentially useful thing in "Next Steps" (because it fits well with the idea of stimulating creative usage of Prelude functions) that would be difficult to move to an earlier point of the book. That case is less serious, though, as there is the option of just moving it to "More on Functions".
Either "More on Functions" or the cheat sheet texts, I'd say. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On 06/10/2010 09:37 AM, Heinrich Apfelmus wrote:
Ah, it's just that in my experience, conceptual explanations usually do not work so well for introducing someone to a new concept for the first time. Usually, a hands-on approach that simply uses the concept gives better results: the student needs to figure out the concept himself, and usually does so in order to memorize the material anyway.
I think Brent Yorgey has put it most brilliantly in his remark on the "Monad Tutorial Fallacy":
http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-...
In other words, the concept is synthesized from its particular examples, not the other way round.
On a general note, these considerations are related to an important point about the Wikibook as a whole (or at least my vision for it). One important differential of the Beginner's Trail when compared with other Haskell tutorials is leanness. The immediate consequence of that is practical: For instance, I went through most of it in about ten days, and got a reasonably good initial understanding of how Haskell works (at least for a complete newbie to functional programming). Certainly things wouldn't advance as quickly for me with, say, "Real World Haskell". Beyond mere expediteness, however, a book painted with broad strokes provide room for readers to complete the picture by acting on their curiosity, testing alternatives and developing their personal understanding and insights. This approach goes nicely with recognizing the "monad tutorial fallacy" and avoid converting analogies and running examples into straitjackets. (By the way, I would like to keep those things in mind when writing; so if you find any of my texts get bogged into excess detail and verbosity please warn me so I can fine tune my approach.) Back to "Type Basics", it seems the underlying problem (or why the text doesn't quite fit with the perspectives we are discussing) is the lack of strong examples that go beyond the mechanics and illustrate the point of having (and taking advantage of) a good type system. Of course, whether it is worth it to tackle this conceptual point upfront at such an early point (assuming readers with very little experience in functional programming) is up for debate. And finally: I still have not given up completely on that introduction :-) Maybe if all references to databases and actual computation are removed (retaining only, say, a paper phone book) an useful (or at least nice) simple analogy may be presented - one that does not try to explain anything concrete, but just provide food for thought. When I feel inspired enough I will attempt a draft for you to judge whether my point is valid.
Finally, a question about Next Steps the module. Do you see a place for it in the overall scheme of things? My question is largely motivated by the fact I am finding it rather difficult to picture a way to incorporate pattern matching into the "soft", largely conceptual modules about the type system (I am counting "Truth values" and "Lists and tuples" among these) without breaking their flow. That leads me to consider introducing piece-wise function definitions or even (x:xs) and (x,y) in a separate context.
Since the current Next Steps chapter is mainly about the alternative ("expression" vs "declaration") syntax to guards, where, and pattern matching, it should be moved to the second part of the beginners' track.
Perfect - chances are it will end up being split and redistributed between "More on Functions" and "Control Structures", except the part on function composition.
Concerning the flow, I think that thanks to the modularity of the wikibook, we don't need to worry much about it. Simply making a new chapter on pattern matching seems fine to me.
I have some ideas on how to do an early introduction to pattern matching to put in the slot currently occupied by "Next Steps", and will attempt a draft over the following few days.
The function composition operator is another potentially useful thing in "Next Steps" (because it fits well with the idea of stimulating creative usage of Prelude functions) that would be difficult to move to an earlier point of the book. That case is less serious, though, as there is the option of just moving it to "More on Functions".
Either "More on Functions" or the cheat sheet texts, I'd say.
The general concept of function composition would be key in illustrating how important is having a good vocabulary of functions, so it would make sense to have it in the cheat sheet module. The usage of the (.) operator might be delayed to "More on Functions" if need be. Regards, Daniel Mlot
participants (2)
-
Daniel Mlot
-
Heinrich Apfelmus