News for hackers. Stuff that matters.
Re:Real World Haskell by miguendes on Friday November 06, 2020 @04:17AM (#25006251)
Interesting. I've been programming in python for more than 4 years and I'd like to try something different.

I took a haskell class back in the day but just the basics, didn't even learn monads.

My goal is not to master the language itself but learn enough to make a better programner.

One thing that has been holding me back is the lack of real world examples. I get demotivated when only solving toy problems.

This looks like a great resource. I have heard a lot about Haskell From First Principles but there's too much stuff in there.

Re:Real World Haskell by _query on Friday November 06, 2020 @04:38AM (#25006366)
To build some real world web applications check out IHP: https://ihp.digitallyinduced.com/

It's a truly batteries-included way to get started with building real world haskell web apps in minutes.

Re:Real World Haskell by dmix on Friday November 06, 2020 @05:16AM (#25006531)
Wow, if that matures, ie gets some real world adopt by serious companies it would be the best thing around.

Much like using Rust and Haskell for web I'd much prefer deferring as much to something like Vue and the server APIs (no sever side rendering for that yet so I mostly just IRL use nuxt.js for toy projects). Something Servant (Haskell) does a clean job of. But you can never completely do away with static heavy lifting

This one takes a more modernized Rails or Elixir's Phoenix approach which is really interesting and looks highly usable.

Community size and quality is everything for real life software (something I remember Clojure had early on and now Rust has in spades, best of breed sort of libraries to choose from) so I hope it gets some adoption to see where it goes. I'll give it a shot to toy around with when I get some time.

Re:Real World Haskell by vindarel on Friday November 06, 2020 @12:04PM (#25009133)
> Make sure you have good internet and can wait up to 30 minutes to complete the download [of version 16.10.2020]. We highly suggest to make sure your coffee machine is working before starting the update.

Wow!

Re:Real World Haskell by _query on Friday November 06, 2020 @12:22PM (#25009281)
If you have good internet connection it's usually downloaded a lot faster. We have switched the nixpkgs version in that version, so a lot of tooling had to be redownloaded. E.g. in our getting started video we install it on a fresh empty macbook: https://www.youtube.com/watch?v=PLl9Sjq6Nzc&feature=youtu.be The full download there takes around 9 minutes on a slow home office internet connection (it's speed up in the video, but you can see the real-world time at the top right).

We mainly added the warning in that release because usually the update process is very smooth and takes only one minute, e.g. see this tweet: https://twitter.com/mittie/status/1322574176792825861

Re:Real World Haskell by miguendes on Friday November 06, 2020 @09:11AM (#25007671)
That's quite interesting. Thanks for mentioning it!
Re:Real World Haskell by anentropic on Friday November 06, 2020 @09:01AM (#25007625)
Step 1: install nix

hmm, no thanks

Re:Real World Haskell by _query on Friday November 06, 2020 @10:30AM (#25008285)
We did a blog post a while ago sharing why we decided to use nix for all package management aspects of the framework. Take a look: https://ihp.digitallyinduced.com/blog/2020-07-22-why-ihp-is-...
Re:Real World Haskell by anentropic on Monday November 09, 2020 @02:19PM (#25038613)
From the blog post...

> Additionally Nix is very hard to install. This is a stumbling block for a lot of people. Especially when using certain macOS systems you cannot even install nix at all. Luckily most of the nix problems, like the macOS issues will be solved with time.

Great choice

Re:Real World Haskell by justmyname on Friday November 06, 2020 @09:46AM (#25007921)
Install nix? Already done. What's the second step?
Re:Real World Haskell by wtetzner on Friday November 06, 2020 @10:02AM (#25008047)
Why is installing nix any worse than installing some language-specific package manager?
Re:Real World Haskell by whateveracct on Friday November 06, 2020 @10:37AM (#25008347)
Nix causes a visceral negative reaction in some people.
Re:Real World Haskell by theCodeStig on Friday November 06, 2020 @11:49PM (#25013277)
Why?
Re:Real World Haskell by otabdeveloper4 on Saturday November 07, 2020 @03:45AM (#25013879)
It's a complete end-to-end solution with an opinionated approach and unstructured documentation.

That is, the learning curve is very steep.

That said, for new projects I'm doing packaging and containerization in nix, because I don't have the time or mental energy to deal with half-assed solutions anymore.

Re:Real World Haskell by whateveracct on Saturday November 07, 2020 @10:03PM (#25022452)
> I don't have the time or mental energy to deal with half-assed solutions anymore.

Exactly. I'd rather solve a problem in Nix then try some working, but half-baked alternative.

Re:Real World Haskell by labawi on Sunday November 08, 2020 @06:35AM (#25025052)
I looked at nix a while ago, concluded the versioning/chesumming is - a given sum should represent kind-of the same thing, but can mean really anything.

There was even a post on how to have a stable version for a tracking branch.

Now, I wouldn't mind, if it were explained exactly what guarantees the hashing provided, but there seemed to be pervasive misconception on what it provides.

Re:Real World Haskell by girishso on Friday November 06, 2020 @04:32AM (#25006345)
You might want to give a try to Elm. Most of the Haskell goodies but way simpler, except no type classes and too restrictive.
Re:Real World Haskell by tasuki on Friday November 06, 2020 @07:31AM (#25007143)
+1 for Elm to learn Haskell. It is indeed way simpler, and has very friendly error messages. It lets you concentrate on grokking the basics: no side effects, pattern matching, recursion, currying.

After some time you start wondering why you have to type `List.map` and `Maybe.map` and `Set.map` when they all do the same thing. Then you'll be ready for some Haskell :)

Re:Real World Haskell by cies on Friday November 06, 2020 @05:19AM (#25006540)
Then PureScript also deserves a mention. It has several frameworks (some akin to the one built in in Elm). If you want to do this in Haskell (which is a lot harder) you may want to look at Miso.
Re:Real World Haskell by tiew9Vii on Friday November 06, 2020 @07:57PM (#25012498)
Not used Elm since early 2014 and heard it’s changed a bit since then.

Elm was a great Trojan horse. It limited feature set made it quick to learn and get familiar with the syntax.

When sufficiently proficient in Elm you then find yourself missing some of the features of Haskell i.e. higher kinder types. At that stage Purescript / Haskell is a natural transition as they feel familiar but with more functionality.

Re:Real World Haskell by miguendes on Friday November 06, 2020 @09:11AM (#25007668)
Thanks for the suggestion. I've heard people suggesting Elm on reddit but in terms of learning materials there isn't much compared to haskell. But I think that shouldn't be much of a problem.

I know that Elm works great for front end but how is it for desktop and backend stuff?

Re:Real World Haskell by piaste on Friday November 06, 2020 @09:17AM (#25007722)
> I know that Elm works great for front end but how is it for desktop and backend stuff?

It isn't. It's explicitly designed as a purely web front-end language, that's its scope.

Of course, many Elm users like to run another ML-family language in the backend as well. Haskell's Servant backend library, the one used in this article, has a project to automatically generate Elm client code [1]. Elixir is popular as well.

But in general, I'd say that any backend framework that can provide an OpenAPI spec will work well, as you'll be able to auto-generate most if not all of the Elm client code (which is normally dull work and one of the main complaints about Elm).

[1] https://github.com/haskell-servant/servant-elm

Re:Real World Haskell by tasuki on Friday November 06, 2020 @09:50AM (#25007940)
Yes, no desktop and backend. It might be possible to use Elm outside of web frontend, but probably wouldn't be much fun.

> in terms of learning materials there isn't much compared to haskell.

To whet your apetite, see https://elm-lang.org/

Then read through the excellent https://guide.elm-lang.org/ - not very long but absolutely enough to hit the ground running.

Re:Real World Haskell by girishso on Friday November 06, 2020 @10:51AM (#25008470)
Agreed official elm guide is more than enough to get “started” with real world examples.
Re:Real World Haskell by dmix on Friday November 06, 2020 @05:03AM (#25006481)
Learning Haskell sideways is a good approach. There are so many usecases in JS as well and Typescript has made it all the better (but not nearly so restrictive).
Re:Real World Haskell by WJW on Friday November 06, 2020 @08:03AM (#25007298)
I wrote a blog post some time ago on writing a small URL shortener in Haskell at http://www.wjwh.eu/posts/2019-11-01-haskell-shorturls.html. Still a toy example, but more "real world" than recursion exercises :)
Re:Real World Haskell by the5avage on Friday November 06, 2020 @05:38AM (#25006625)
> One thing that has been holding me back is the lack of real world examples. I get demotivated when only solving toy problems.

I looked at haskell a few months ago and had a similar problem.

While I don't mind the toy problems, all those toy problems have something in common...

They can be easily solved with recursion. There are probably patterns to deal with other problems and this would have been more interesting to me.

I just had to think to myself: "If all you have is recursion every tutorial looks like a parser" ;)

Re:Real World Haskell by chongli on Friday November 06, 2020 @05:57AM (#25006698)
Recursion is equivalent to iteration. You can solve any problem you like with it.

The problem with those tutorials is that they’re trying to do two things at once: 1) teach you Haskell and 2) advocate for Haskell.

I’m currently working as a full time assistant for one of the first year computer science courses at my university. This course is taught in a teaching dialect of Racket which does not allow mutation or side effects of any kind.

That doesn’t stop the profs from creating assignments with real world applicability such as graffiti stroke recognizers and decision tree learning algorithms. The key is that they’re not trying to make Racket look good, so the patterns of recursion can get pretty ugly at times.

Re:Real World Haskell by the5avage on Friday November 06, 2020 @10:48AM (#25008439)
> Recursion is equivalent to iteration. You can solve any problem you like with it.

Maybe my comment was somehow badly written, because you (and the only other reply from chriswarbo) clearly misunderstood me.

I know that recursion is equivalent to iteration^^

My point was that some problems fit the one or the other better.

Look at fft for example. The algorithm is easy with recursion but hard with iteration. For other problems its the opposite.

Re:Real World Haskell by tasuki on Friday November 06, 2020 @01:29PM (#25009933)
Which problems are hard to solve with recursion instead of iteration?
Re:Real World Haskell by the5avage on Friday November 06, 2020 @04:05PM (#25011137)
I found something like splitting a string into words not very intuitive...

Also the classical (recursive) fibonacci function everyone shows has accidental complexity of O(2^n). If you want a sane version it looks definitely more complicated than the iterative version.

I never saw a recursive version of bresenham's line plotting algorithm so this might be a good candidate as well ;)

Re:Real World Haskell by chongli on Friday November 06, 2020 @05:19PM (#25011710)
I found something like splitting a string into words not very intuitive...

Just use a couple of accumulators (one for the current word, one for the list of completed words).

Also the classical (recursive) fibonacci function everyone shows has accidental complexity of O(2^n).

That's moving the goalposts. If you want a really fast fibonacci function then the classical iterative algorithm [which is O(n)] is not what you want either. Better to use matrix exponentiation which you can implement nicely with recursion using a divide-and-conquer approach similar to mergesort, giving you fibonacci with time O(log(n)).

I never saw a recursive version of bresenham's line plotting algorithm so this might be a good candidate as well ;)

There's nothing special about Bresenham's line algorithm that would make it particularly challenging to implement with recursion.

Re:Real World Haskell by a1369209993 on Friday November 06, 2020 @11:01PM (#25013126)
> splitting a string into words not very intuitive

It seems okay?

  split :: String -> [String]
  split s = w s "" where
    w [] "" = []
    w [] a = [reverse a]
    w (' ':ss) "" = w ss ""
    w (' ':ss) a = reverse a : w ss ""
    w (c:ss) a = w ss (c:a)
If you're done then you're done (and dump the accumulator), if it's a space get rid of it (and dump the accumulator), otherwise add it to the acuumulator. That the accumulator is stored backward is a bit wierd, but seems more a consequence of linked lists than recursion per se.
Re:Real World Haskell by the5avage on Saturday November 07, 2020 @03:10AM (#25013766)
Yeah it's ok ;) Going back to my original comment this code is exactly what I meant with "patterns to deal with other problems". You clearly used a pattern (accumulator) with wich you are familiar.

Do you agree that most imperative programmers would not come up with this solution on their own, if you didn't teach them the "accumulator pattern"?

For me personally a tutorial with a lot code like that would be interesting.

Showing me another version of a recursive descent parser doesn't teach me anything, because I know how to write it (with recursion!!!) in an imperative language...

Re:Real World Haskell by chongli on Saturday November 07, 2020 @06:32AM (#25014496)
Do you agree that most imperative programmers would not come up with this solution on their own, if you didn't teach them the "accumulator pattern"?

Background: I’m currently working as a full time assistant for the first year computer science course at my university. We have around 1800 people enrolled in the class including over 1000 first year CS students. Many of our first years were exposed to imperative programming in high school, either at home or with a high school CS class.

The course we teach is based on the book HTDP and uses a purely functional teaching dialect of Racket. Many of our students struggle to figure out how to use the different recursion patterns such as accumulative recursion and mutual recursion.

I’m not the GP but I will answer your question anyway: yes, I agree that most imperative programmers would not come up with that solution. I have witnessed it myself first hand.

Where I disagree is with any implication or suggestion that they should, given no prior functional programming experience. Accumulative recursion is a standard pattern in functional programming but if you’re an imperative programmer you may not have ever needed to learn it. Therefore, I think it would be unreasonable to expect you to come up with it on the fly.

Re:Real World Haskell by a1369209993 on Saturday November 07, 2020 @12:54PM (#25016826)
> You clearly used a pattern (accumulator) with wich you are familiar.

No, I didn't, and please refrain from imputing thought processes without evidence. I didn't even think the word "accumulator" until I got to the last paragraph and needed a term to describe the second argument to w.

> Do you agree that most imperative programmers would not come up with this solution on their own

If we assume most imperative programmers are idiots as a special case of most people are idiots, sure. I'm not sure that's a good assumption or particularly relevant, though.

> Showing me another version of a recursive descent parser doesn't teach me anything

Ah, I think I misunderstood your point, then:

> > Which problems are hard to solve with recursion instead of iteration?

> I found something like splitting a string into words not very intuitive...

I assumed you meant that "splitting a string into words" was a example of a problem that was hard to solve with recursion (which I found rather puzzling, because as my example shows, it really isn't), rather than that it wasn't a good/intuitive example to illustrate recursion in the general case (which makes a quite a bit more sense, and I'm afraid I don't have a immediate solution to, sorry).

Re:Real World Haskell by the5avage on Sunday November 08, 2020 @03:00AM (#25023996)
> No, I didn't, and please refrain from imputing thought processes without evidence.

There where at least two other replies talking about accumulators. I call that pattern, like it or not.

Have you even heard of programming patterns?

> If we assume most imperative programmers are idiots as a special case of most people are idiots, sure.

The other reply from chongli seems to disagree with you ;)

Also suggesting that I'm stupid is no constructive style of argumentation.

> rather than that it wasn't a good/intuitive example to illustrate recursion

You are still misunderstanding me but a genius like you are should be able to figure that out.

I now understand what my teacher meant when he said:

"Haskell is a genius language but I don't like the community,"

Re:Real World Haskell by Eugeleo on Sunday November 08, 2020 @09:42AM (#25026065)
Hey, another Haskeller here!

> There where at least two other replies talking about accumulators. I call that pattern, like it or not.

It's true that you use this way of programming so often in functional languages that it earned itself a name, so that it's easier to talk about it. However calling it a 'pattern' feels weird (to me), even though it technically is one.

The equivalent of accumulators in imperative languages would be the 'pattern' of having some variables outside of the loop and mutating them from within the loop. Maybe you can appreciate that it feels weird calling this a 'pattern' — and now you can better understand how I feel about accumulators being called a pattern.

Skipping back to your original question: I write Haskell for living and teach two high-school classes in another functional language, and the only two 'patterns' regarding recursion I can think of are accumulators and mutual recursion. So, you know almost everything there is to know already! :-) [0]

Let me add that you use recursion very rarely in day-to-day programming; mostly you try to spare yourself writing the recursion explicitly and you instead use map, filter and foldr/foldl (sometimes called reduce) to do the recursion for you. Especially the folds are super-powerful (AFAIK you can write any recursive function using folds, should you wish to do so), and often under-appreciated.

> Haskell is a genius language but I don't like the community

IMHO the community around Haskell is (in general) great; the people are always eager to help. I'm a self-learned Haskeller and I couldn't have done it without the community. Come join us at r/haskell or the IRC and see for yourself :-)

[0]: Why do I say this? I remember my old days when I was learning Swift and encountered one new design pattern every day. Factory, Facade, ... I decided to get 'em all (why reinvent the wheel?), I was always anxious that I was coding something that could be better served by a ready-made design pattern. So I just wanted to let you know it's nothing like this with recursion, and that you can save yourself the anxiety (if you are anything like me).

Re:Real World Haskell by the5avage on Sunday November 08, 2020 @11:54AM (#25026985)
Hey thanks for the nice reply. I know you can't generalize like that. There are probably a lot friendly Haskellers around ;)

I was just angry when I wrote my last comment, because I had to read this:

>> as a special case of most people are idiots

which is so low in multiple ways. It's also just wrong, because by definition most people have average intelligence. Even if you think this is true, a smart person would not use it as an argument^^

It's on my todo-list to dive a bit into haskell, when I find time.

Re:Real World Haskell by a1369209993 on Monday November 09, 2020 @12:08PM (#25036911)
> It's true that you use this way of programming so often in functional languages that it earned itself a name, so that it's easier to talk about it. However calling it a 'pattern' feels weird (to me), even though it technically is one.

> The equivalent of accumulators in imperative languages would be the 'pattern' of having some variables outside of the loop and mutating them from within the loop. Maybe you can appreciate that it feels weird calling this a 'pattern' — and now you can better understand how I feel about accumulators being called a pattern.

That's a fair point, actually. I read "patterns" as "design patterns" a la the book of same name, based on the implied^Wlater stated title "accumulator pattern", but I agree it does fit a weaker notion of "pattern" such as "less-than-maximally-entropic (aka compressible in the information-theoretic sense) feature of code".

Re:Real World Haskell by chriswarbo on Friday November 06, 2020 @09:46AM (#25007913)
> While I don't mind the toy problems, all those toy problems have something in common...

> They can be easily solved with recursion.

As a sibling mentions, recursion is pretty much required in pure functional programming. There is no notion of time or sequencing: everything we write is a definition. If we don't call another function, then our program will finish; if we don't use recursion (either directly, indirectly via functions like `map`, or via a chain of mutually-recursive definitions) then our program's behaviour will be fixed by the structure of our code (e.g. the number of calls we write). That's fine for simple calculations, but most useful programs depend on the structure of their data (e.g. processing lines in a file, etc.); that requires recursion, since we can't hard-code the right number of calls ahead of time.

Re:Real World Haskell by flubert on Friday November 06, 2020 @02:33PM (#25010401)
General recursion is equivalent to goto. It is nicer when recursion can be wrapped up in a higher level combinator (map, fold, etc.) or other even higher level abstraction. That's one thing the array languages (APL, J, etc.) got right.
Re:Real World Haskell by chriswarbo on Friday November 06, 2020 @03:08PM (#25010675)
> General recursion is equivalent to goto.

Yes, but goto requires a whole bunch of machinery in order to make any sense. It (a) needs a notion of time/sequencing, (b) needs a notion of statement and (c) needs a notion of labelling.

(a) and (b) are often taken as given in imperative programming languages (e.g. C, assembly, etc.), but Haskell has none of them. It's hard to ascribe any meaning to "goto" in Haskell; other than some embedded language like ST or something.

> It is nicer when recursion can be wrapped up in a higher level combinator (map, fold, etc.) or other even higher level abstraction.

I agree, but I was counting those as (indirect) recursion for the purposes of explaining the parent's observation.