Live data from Hacker News

Leaving Haskell behind

journal.infinitenegativeutility.com

351–360 of 402 posts

Re: Leaving Haskell behind

#351
post #350

Earlier quoted context omitted.

I have seen this in the wild. The result often is that every function has a kitchen sink MyMonads constraint of which it only uses a tiny subset. It's death by a thousand cuts. If you make such a class for every monad combination you get insanely large amount of classes. It's simply unworkable. Which is why you get the kitchen sink monad pattern.

If you think it's fine that you can log from all functions in other languages, then what's the problem with adding that constraint to all your Haskell functions to allow this?

The problem is that you should always write your code to be idiomatic in the language. In this case I feel like the Idiomatic Haskell way has serious drawbacks.

For example, It's fine in C to manually allocate/free memory, it's the way you have to write C. It's not fine to do the same thing in Rust. Even though you of course could do that in Rust as well.

Re: Leaving Haskell behind

#352

Earlier quoted context omitted.

> Kotlin doesn't get enough love. Really??? It's probably the #1 language for new Android projects.

I presume they meant outside of Android development.

Yes. Many people say that Kotlin is only for Android but that's totally untrue.

Re: Leaving Haskell behind

#353

Earlier quoted context omitted.

Perhaps, but what you may not understand is that not ALL developers _want_ a purely functional language. For some, things like Kotlin hit a sweet-spot. One can lean a bit more into a functional style, or they can lean more into an OO style and it's acceptable. Some are very interested in thinking in terms of Functors, Applicatives, Readers, etc... some just want map/filter/reduce. That's what the Streams API did for…

As someone that has done some Haskell, and does Java for a living, I think their metaphor is extremely accurate. It's not about purity, it's about how the functional parts were grafted onto the language, and therefore don"t "interop" with the classical ways very well. In a good mixed paradim language like Rust, you can freely choose the correct paradigm for the problem, and can easily mix them. In Java, they are ofte…

To be fair, mixing higher order functions with effects (exceptions) is really hard without changing the type system completely. At that point you're moving into novel encoding territory.

Re: Leaving Haskell behind

#354

Earlier quoted context omitted.

Kotlin doesn't get enough love. It gets derided by some Java developers for being too cutesy and sugary and it's not talked much about by the kinds of people who love to talk about Haskell, Lisp or Rust (no shade to these languages), but to me it's the most pragmatic language I've used so far.

I really liked Kotlin in the beginning, but it's error handling story is non-existent. They removed the ONLY decent (not great, very flawed) complier validated method for error handling, checked exceptions, and gave us nothing in return. It'd be so easy to simply do exactly what Rust does. Kotlin already has the ADT stuff necessary, all we need is some kind of "bubbling" operator, like the ? in Rust. Because right no…

Different strokes... I think Java checked exceptions are a design flaw and the fact that no other language that I'm aware of has them is telling. Maybe it even was a good idea in the beginning, but it was just horribly abused by basically every library under the sun - no, I don't want to catch some low-level exception when I'm calling your library, thank you very much.

I don't mind making error handling part of compile-time checking (as long as you can opt out by something like unchecked exceptions), but that should be done in a way that is compatible with the regular type system. That way you can abstract over error handling in ways that using checked exceptions disallows.

IIRC, the stance of the Kotlin team is that if you want compile-time checked error handling, you should use Result types. Maybe the ergonomics aren't as good as in Rust, but if you use something like arrow, they're still decent.

Re: Leaving Haskell behind

#355
post #251

Earlier quoted context omitted.

> there's no way to list the dependencies of an SBT project (in order to set up an offline sandbox, in our case for reproducible building with Nix) Well, the same is true for Maven. I know because I've tried. Plugins can download arbitrary dependencies at execution time. That's where the point about Rice's theorem falls apart: it applies as much to maven as to Gradle because maven plugins can do whatever they want.

But that can't be runtime dependencies to your code? I've written a couple of Maven plugins and you must declare your dependencies explicitely even for those. Pulling in stuff dynamically would be possible but not very clever.

The maven surefire plugin downloads dependencies dynamically depending on the kind of tests it finds. Is it not very clever? I agree. But it's one of the most popular maven plugins.

Re: Leaving Haskell behind

#356
post #350

Earlier quoted context omitted.

If you think it's fine that you can log from all functions in other languages, then what's the problem with adding that constraint to all your Haskell functions to allow this?

The problem is that you should always write your code to be idiomatic in the language. In this case I feel like the Idiomatic Haskell way has serious drawbacks. For example, It's fine in C to manually allocate/free memory, it's the way you have to write C. It's not fine to do the same thing in Rust. Even though you of course could do that in Rust as well.

It's perfectly idiomatic Haskell to annotate all your functions with an effect you believe they should all have.

Re: Leaving Haskell behind

#357
post #160
post #23

Earlier quoted context omitted.

I've also used several languages and IMHO, Haskell's tooling is some of the worst. Language server breaks with random errors all the time for me, I'm always confused about whether I should have ghcup or stack manage my Haskell versions (and what the benefits and drawbacks are), and so on. I have a project I work on from time to time, and I'm 100% sure that the next time I'll open it up, it will stop working again. Py…

It's weird how personal this is. Sometimes I wonder if it comes down to familiarity. I've been using Python professionally since 2000 and have never run into issues with its tooling. It's even easier these days: "python -m venv" and then pip are all I need in 99% of use cases. For local development I use direnv + pyenv. I typically develop on macOS and deploy to either macOS or Linux. I previously gave pipenv a try b…

> I got so annoyed with bundler I wrote a simple shell script to provide the moral equivalent of Python venvs to gem:

This already exists: https://rvm.io/gemsets

Most people don't use it because they haven't felt the need. Bundler already makes sure it loads exactly the right versions of gems for your project, so there's no need to isolate them from each other.

Re: Leaving Haskell behind

#358
post #337

Earlier quoted context omitted.

In that same thread that you've linked, other people have later replied arguing for why they prefer Stack so... I don't really think that you've given an argument that is persuasive enough to someone who is new to Haskell. (And I'm not even that new to Haskell. It's just that I don't use it every day and when I come back to it and have to remember the weird incantations and dances I have to perform to make HLS not cr…

> In that same thread that you've linked, other people have later replied arguing for why they prefer Stack so... I merely stated that I have no trouble running old projects using stack. > I don't really think that you've given an argument that is persuasive enough to someone who is new to Haskell. Honestly, cabal improved a lot since the old ages. For a beginner, either stack or cabal should be very fine imo. > or w…

> I merely stated that I have no trouble running old projects using stack.

I was referring to the linked forum thread.

> Not sure why you would want to do that. Either you use stack and let it handle your ghc install, or you don't, and I really don't see why you would use stack only for compiler install.

What I mean is that when I start VS Code on my Haskell project again after a couple months, it tells me that it needs to donwload a new version of GHC. And I don't know why since I didn't change anything about my project. And when I try to click on update, it fails and the HLS extension crashes. I can't tell you where exactly this goes wrong, but it's obvious that these tools don't all work well together.

edit: Now I see that my wording was confusing. You quoted me as saying that I want HLS to overwrite my GHC version, but what I meant was that I want to prevent HLS (actually, I should have said the VS Code Haskell plugin) from doing that. The subject of "want" in that sentence you quoted is "HLS".

Re: Leaving Haskell behind

#359
post #262

Earlier quoted context omitted.

I haven't had that experience for newer code bases. Yes, there's some ancient "works only in my IDE" stuff but that's really not how modern Java is written. Yes, there is a disagreement about whether to use maven or gradle, but IMHO they both work reasonably well out of the box.

Right now, things are pretty good. But this is surprisingly recent. Gradle and Maven have both been good at managing dependency versions for a long time. Gradle has also been good at managing the Gradle version, via the wrapper, for a long time; Maven has equivalent wrapper now, but it's quite new, and support in the wider ecosystem is patchy (eg a TeamCity Maven build step can't use a wrapper, i don't think). Meanwh…

While what you say is true, the point about the JDK versions is mitigated a bit by the fact many things are backwards compatible. Although yes, if you jump from 8 to 17, you're going to run into some problems.

I'm not a huge fan of the gradle toolchain tool (I don't think gradle should be managing my JDKs and I would prefer if it could instead just fail the build if you use the wrong JDK version), but I do understand why it exists.

Re: Leaving Haskell behind

#360

Earlier quoted context omitted.

You misunderstand my problem. Add a logger to that fibonacci function. Potentially EVERY usage site now has to change, maybe even multiple layers. Adding a log in most languages is a local transformation. In Haskell it isn't, it can have codebase wide consequences.

If you wanted to log from fibonacci, you would pass a some logger instance down to this function. In Haskell, this could be a record or a typeclass instance. In other languages, it could be an object or a struct. There is no fundamental difference. All the layers above would still have to pass this through; explicitly or implicitly.

The difference is most language have global state. See rust for example. It's not common to inject a logger, a "world" object for IO or anything for which you need monads in Haskell at all.

You are arguing from a concrete technical standpoint: "But you need to do the same thing in other language if you want to mirror Haskell monads". Sure, you are right. That also completely glosses over the point I'm making. I simply feel like the way haskell does it is unergonomic, it would also be unergonomic to something equivalent in other languages.

I don't know what a good solution would be, maybe a constrained partial type signature? Let the compiler pick the smallest constraint from a larger space of available constraints that fits with the usage and simply let the type checker bubble it up until you actually care to specify it? GHC doesn't support this but it should be possible in theory.

Post reply on HN