<div dir="ltr"><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large">+1 for Christopher's email</div><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large">Richard, I disagree with  "But it could indeed be explained to an intermediate programmer in another language just learning Haskell." Your explanation is good but it assumes you have already explained "types of kind *" and the boxed vs unboxed distinction. Admittedly the latter should be understood by most Java programmers but I doubt that intermediate programmers in other languages do. If I did have to explain "$" I would say, for now think of it in terms of it's pre 8.0 type. Alternatively avoid mentioning "$" to beginners. I don't believe it is in Hutton's book or any of Bird's although I might be wrong.</div><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large"><br></div><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large">Most intermediate programmers in another language struggle a lot with learning monads, witness all the monad tutorials. Absorbing monads is central, there is a lot that has to be explained before that. Minimizing that material would be a good thing. </div><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large"><br></div><div class="gmail_default" style="font-family:'times new roman',serif;font-size:large">I have mixed feelings about a beginner's prelude best summarized by saying the proposed beginner's prelude should be the standard prelude and the current one should be an advanced prelude. If we have a beginner's prelude I feel we are saying that this is a hard to understand research language and we hope that someday you have enough education, energy and tenacity to get to the point where you understand it. If we do it the other way we are saying you have what you need but if you want more there is lots!</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 5, 2016 at 3:05 PM, Christopher Allen <span dir="ltr"><<a href="mailto:cma@bitemyapp.com" target="_blank">cma@bitemyapp.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Changing the name doesn't fix the issue. The issue is the noise and the referent, not the referrer. There's a habit of over-focusing on names in programming communities. I think it'd be a mistake to do that here and risk missing the point.<br><br>You can make all of the keywords in the Java example salient early on, but you cannot make the implementation details you're exposing in the type of ($) relevant unless they already have a year or two of Haskell under their belts. Listing out the keywords:<br><br>1. public<br><br>2. class<br><br>3. (class name)<br><br>4. static<br><br>5. void<br><br>6. (method name)<br><br>7. (method arguments)<br><br>Explaining public, class, static, and void usually happens pretty soon after the basics in a Java course. Importantly, they're things you _need_ to know to get things done properly in Java. The same is not true of what is mentioned in the type of ($).<br><br>The implicit prenex form and forall are irrelevant for learners until they get to Rank2/RankN which is very much beyond, "I am learning Haskell" and into, "I am designing an API in Haskell for other people to use". * vs. # is something many working and hobbyist Haskellers I've known will scarcely know anything about.<br><br>There is a big difference, to my mind, between what is being exposed here in Java versus what is being exposed in the type ($). Consider that the boxed/unboxed distinction exists in Java but needn't come up in any beginner tutorials.<span class=""><br><br>>Types of kind * have values represented by pointers. This is the vast majority of data in Haskell, because almost everything in Haskell is boxed.<br><br></span>We can't assume Haskell learners know what pointers are. This, again, creates unnecessary noise for learners by forcing exposure to things that are irrelevant for a very long time.<div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Fri, Feb 5, 2016 at 12:13 PM, Richard Eisenberg <span dir="ltr"><<a href="mailto:eir@cis.upenn.edu" target="_blank">eir@cis.upenn.edu</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div style="word-wrap:break-word"><div>Perhaps it will aid the discussion to see that the type of ($) will, for better or worse, be changing again before 8.0.</div><div><br></div><div>The problem is described in GHC ticket #11471. The details of "why" aren't all that important for this discussion, but the resolution might be. The new (hopefully final!) type of ($) will be:</div><div><br></div><div>> ($) :: forall (r :: RuntimeRep) (a :: *) (b :: TYPE r). (a -> b) -> a -> b</div><div><br></div><div>Once again, it's easy enough to tweak the pretty-printer to hide the complexity. But perhaps it's not necessary. The difference as far as this conversation is concerned is that Levity has been renamed to RuntimeRep. I think this is an improvement, because now it's not terribly hard to explain:</div><div><br></div><div>---</div><div>1. Types of kind * have values represented by pointers. This is the vast majority of data in Haskell, because almost everything in Haskell is boxed.</div><div>2. But sometimes, we don't care how a value is represented. In this case, we can be polymorphic in the choice of representation, just like `length` is polymorphic in the choice of list element type.</div><div>3. ($) works with functions whose result can have any representation, as succinctly stated in the type. Note that the argument to the function must be boxed, however, because the implementation of ($) must store and pass the argument. It doesn't care at all about the result, though, allowing for representation-polymorphism.</div><div><br></div><div>In aid of this explanation, we can relate this all to Java. The reference types in Java (e.g., Object, int[], Boolean) are all like types of kind *. The primitive types in Java (int, boolean, char) do not have kind *. Java allows type abstraction (that is, generics) only over the types of kind *. Haskell is more general, allowing abstraction over primitive types via representation polymorphism.</div><div>---</div><div><br></div><div>Could this all be explained to a novice programmer? That would be a struggle. But it could indeed be explained to an intermediate programmer in another language just learning Haskell.</div><div><br></div><div>For point of comparison, Java is widely used as a teaching language. And yet one of the simplest programs is</div><div><br></div><div>public class HelloWorld</div><div>{</div><div>  public static void main(String[] args)</div><div>  {</div><div>    System.out.println("Hello, world!");</div><div>  }</div><div>}</div><div><br></div><div>When I taught Java (I taught high-school full time for 8 years), I would start with something similar to this and have to tell everyone to ignore 90% of what was written. My course never even got to arrays and `static`! That was painful, but everyone survived. This is just to point out that Haskell isn't the only language with this problem. Not to say we shouldn't try to improve!</div><div><br></div><div>We're in a bit of a bind in all this. We really need the fancy type for ($) so that it can be used in all situations where it is used currently. The old type for ($) was just a plain old lie. Now, at least, we're not lying. So, do we 1) lie, 2) allow the language to grow, or 3) avoid certain growth because it affects how easy the language is to learn? I don't really think anyone is advocating for (3) exactly, but it's hard to have (2) and not make things more complicated -- unless we have a beginners' mode or other features in, say, GHCi that aid learning. As I've said, I'm in full favor of adding these features.</div><span><font color="#888888"><div><br></div><div>Richard</div></font></span><div><div><div><br></div><div><div>On Feb 5, 2016, at 12:55 PM, Kyle Hanson <<a href="mailto:me@khanson.io" target="_blank">me@khanson.io</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr">I am also happy the discussion was posted here. Although I don't teach Haskell professionally, one of the things I loved to do was show people how simple Haskell really was by inspecting types and slowly putting the puzzle pieces together. <div><br></div><div>Summary of the problem for others:</div><div><pre style="white-space:pre-wrap">From <b style="font-family:-webkit-standard">Takenobu Tani</b></pre><pre style="white-space:pre-wrap">Before ghc7.8:

  Prelude> :t foldr
  foldr :: (a -> b -> b) -> b -> [a] -> b

  Prelude> :t ($)
  ($) :: (a -> b) -> a -> b

  Beginners should only understand about following:

    * type variable (polymorphism)


After ghc8.0:

  Prelude> :t foldr
  foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

  Prelude> :t ($)
  ($)
    :: forall (w :: GHC.Types.Levity) a (b :: TYPE w).
       (a -> b) -> a -> b</pre></div><div><br></div><div><br></div><div>With this change it looks like I will no longer be able to keep `$` in my toolbox since telling a beginner its "magic" goes against what I believe Haskell is good at, being well defined and easy to understand (Not well defined in terms of Types but well defined in terms of ability to precisely and concisely explain and define whats going on).</div><div><br></div><div>It looks like where the discussion is going is to have these types show by default but eventually have an Alternative prelude for beginners.</div><div><br></div><div>From <b style="font-family:-webkit-standard">Richard Eisenberg:</b></div><div><pre style="white-space:pre-wrap">- It's interesting that the solution to the two problems Takenobu pulls out below (but others have hinted at in this thread) is by having an alternate Prelude for beginners. I believe that having an alternate beginners' Prelude is becoming essential. I know I'm not the first one to suggest this, but a great many issues that teachers of Haskell have raised with me and posts on this and other lists would be solved by an alternate Prelude for beginners.
</pre></div><div>I don't like the idea of fragmenting Haskell into "beginners" and "advanced" versions. Its hard enough to get people to believe Haskell is easy. If they see that they aren't using the "real" prelude, Haskell will still be this magic black box that is too abstract and difficult to understand. If they have to use a "dumbed down" version of Haskell to learn, its not as compelling.</div><div><br></div><div>There is something powerful about using the same idiomatic tools as the "big boys" and have the tools still be able to be easy to understand.... by default. Adding complexity to the default Haskell runs the risk of further alienating newcomers to the language who have a misconception that its too hard.</div><div><br></div><div>Admittedly, I am not well informed of the state of GHC 8.0 development and haven't had time to fully look into the situation. I am very interested to see where this conversation and the default complexity of Haskell goes.</div><div><br></div><div>--</div><div>Kyle</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 5, 2016 at 8:26 AM, Tom Ellis <span dir="ltr"><<a href="mailto:tom-lists-haskell-cafe-2013@jaguarpaw.co.uk" target="_blank">tom-lists-haskell-cafe-2013@jaguarpaw.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Fri, Feb 05, 2016 at 05:25:15PM +0100, Johannes Waldmann wrote:<br>
> > What's changed?<br>
><br>
> I was referring to a discussion on ghc-devs, see<br>
> <a href="https://mail.haskell.org/pipermail/ghc-devs/2016-February/011268.html" rel="noreferrer" target="_blank">https://mail.haskell.org/pipermail/ghc-devs/2016-February/011268.html</a><br>
> and mixed up addresses when replying.<br>
<br>
</span>I'm glad you did, because this is the first I've heard of it!<br>
<div><div>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>
_______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br></blockquote></div><br></div></div></div><br></div></div><span class="">_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
<br></span></blockquote></div><br><br clear="all"><span class=""><div><br></div>-- <br><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr">Chris Allen<br><div><span style="font-size:12.8000001907349px">Currently working on </span><a href="http://haskellbook.com" target="_blank">http://haskellbook.com</a></div></div></div></div></div></div>
</span></div>
<br>_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div>