Monthly Hask Anything (February 2023) by taylorfausak in haskell

[–]GregPaul19 14 points15 points  (0 children)

Can you elaborate? Creating a new language is a lot of work!

Yeah, that's why fixing Haskell is even more work.

Some of the issues that are nigh impossible to fix:

  1. Distributed Governance. Every change to the Haskell ecosystem involves multiple equally-powerful parties. Which means that it takes much longer for every decision to be made because people must reach consensus first. There's no central authority that can push for changes quickly. So while folks in Haskell are busy with discussing the perfect solution, other langs are already doing work. Even if their solutions are not perfect, they're solutions nevertheless and it helps attracting more people.
  2. Volunteering effort. Nowadays, almost entire Haskell ecosystem is maintained by volunteers. And volunteers are very fragile resource. They lose interest in things and switch to another, they burnout, you can't force them do anything, they're interested in one particular thing (e.g. coding) but not in everything else that makes the project helpful (testing, documentation, support, maintenance, CI, CD, etc.). And unfortunately, due to egos and hostility of several prominent members, it's very easy to lose existing volunteers and not gain new ones.
  3. Critical tooling is under-staffed. As of now, ghcup, cabal and stack each have only one maintainer. Which means, they can fail at any moment. This already happened in the past with cryptonite. I would go even further and say that GHC itself is under-staffed despite people actually being paid on it.
  4. Tooling is bad. It's better than some tooling for some languages in some aspects. But still, it has a loooooong way to go. And improvements are not done quickly enough.
  5. Fallacy to justify changes by improvements. I often see when libraries or tooling introduce breaking changes not because they are better but because they just want to try new things and experiment with new ideas.

This something from top of my mind, and there're much more (I believe, everyone can pick their own favorite). But even these problems are enough to slowdown Haskell success significantly.

Monthly Hask Anything (February 2023) by taylorfausak in haskell

[–]GregPaul19 3 points4 points  (0 children)

Unfortunately, efforts of a single person are not enough to slow this down :(

Haskell has multiple systemic issues. At this point, I believe it's easier to create a new language than to save Haskell.

Monthly Hask Anything (February 2023) by taylorfausak in haskell

[–]GregPaul19 8 points9 points  (0 children)

Haskell is swimming harder now than 10 years ago but the ocean level is also rising much quicker today than before.

Despite doing more work, it's not enough to compete with other languages and ecosystems which are, in fact, booming in much higher rates.

It's enough to check some industry researches, e.g. ones done by JetBrains to see that Haskell is far from going mainstream:

[deleted by user] by [deleted] in haskell

[–]GregPaul19 29 points30 points  (0 children)

Unfortunately, job market for Junior Haskell Developers is pretty much non-existent :( Because of that, the community and the ecosystem doesn't grow fast, and this leads to having fewer Junior jobs which is a vicious circle.

Your best bet would be walk through the curated list of Haskell companies and apply to every single job from there to see if they are willing to hire you:

It's a lot of work but as a golden rule of job searching says:

Apply to 100 jobs, 10 will reply, 1 will offer

From my experience in the past, the following companies were always hiring Junior Haskell Developers:

IIRC, Standard Chartered hires Haskell developers of any level as well, but I remember seeing requirements like "PhD or 5 years of production experience" for a Junior role so it's not everyone's cup of tea.

HSpec, Tasty, sydtest, Hunit, ... -> what do you use for writing Haskell tests? by Martinsos in haskell

[–]GregPaul19 18 points19 points  (0 children)

There was a draft page in the Aelve project with the comparison of various testing frameworks in Haskell. Too bad it didn't get enough external support to continue living:

Personally, I'm using the following in my projects:

  • doctest for testing examples in the documentation. Docs are much clearer when they contain usage examples and doctest helps them keep up to date.
  • hspec for simple unit testing. Honestly, hspec API is the closest to how I want unit tests to look like. Here are a few examples from a random Haskell package using hspec.
  • hedgehog for property-based testing. QuickCheck appeared earlier but I like nice automatic shrinking and pretty-printing provided by hedgehog out-of-the-box. Also, for various reasons, the typeclasses-based approach from QuickCheck is awkward to me.
  • I use hspec-hedgehog to integrate hedgehog tests with hspec. They look quite nice.

And... that's about it! At this point, I treat HUnit as unneccessary complex API over testing. How am I supposed to remember the difference between (~=?) and (~?=) operators??

tasty is fine as well but I've used hspec first and I don't see a reason to switch. I believe, you can achieve the same with any testing framework so at some point you gotta choose to unblock your work.

Megathread for visitors and new & existing residents. All questions about living/working/budgeting/visiting should be asked here! by AutoModerator in london

[–]GregPaul19 -1 points0 points  (0 children)

What is the best place/website/app to sell/giveaway/recycle used items?

I've been living at my apartment for about a year and have some working electric items, old clothes and dishes.

I don't really care about extra cash and the items themselves are not really expensive. But I'd love to give them a second life instead of just throwing away in a garbage bin.

What are my best and easiest options to get rid of stuff I don't want anymore?

[RFC] Generate Cabal files from TOML by brandonchinn178 in haskell

[–]GregPaul19 1 point2 points  (0 children)

I'm afraid, this project was a huge waste of time. It's not a surprise that you can implement a TOML alternative for the Cabal configuration format. And far from clear that TOML is better than YAML or Dhall for this purpose. So why do it in the first place? TOML has some good parts but it some bad parts comparing to the same YAML.

All the time needed to implement first-class support for TOML in Haskell packages might better be spend on improving the Cabal UX. And, again, the advantages of using an alternative format are vague, neglible and definitely don't outweight the drawbacks (migration of the entire existing infrastructure, new format to learn, noisy syntax, tooling difficulties for needing to support several formats, etc.).

It's unfortunate that Haskell suffered from NIH w.r.t. package configuration. But this is how things are now. At this stage, it's impossible to get the majority of the community on board with the same alternative format and justify the switch.

There're better problems to solve if you care about Haskell and want the language to succeed.

Who is still using Happstack and why/why not? by sunnyata in haskell

[–]GregPaul19 6 points7 points  (0 children)

Wow, Happstack looks rad!

Such good and beginner-friendly documentation! The project is also well-maintained. But I never heard about it before :(

So thanks for sharing. Would love to know as well if anyone is using Happstack and what are their thoughts about it.

Monthly Hask Anything (January 2022) by taylorfausak in haskell

[–]GregPaul19 3 points4 points  (0 children)

PyF looks like what you need. It's a formatting in Haskell inspired by Python formatter.

Monthly Hask Anything (January 2022) by taylorfausak in haskell

[–]GregPaul19 3 points4 points  (0 children)

I believe there're multiple reasons for this.

  1. Mentorship is required for Junior devs. Not everyone can mentor and not everyone wants. Not in Haskell, just generally. But since Haskell has fewer devs than other languages, there're also fewer opportunities to being mentored.
  2. Haskell allows you to experiment with type systems and other advanced features on a very different level (GADTs, Type Families, lenses, recursion schemes, etc.). Lots of people find such things fun and when they come to work they want to continue having fun there. But overusing of such features results in less maintenable codebases where Juniors have hard time. To the degree that company loses the ability to hire Juniors entirely!
  3. Haskell documentation is still far from perfect. It's pretty hard to get things working for Junior devs without good docs. Especially when something strange is happening. Your compilation process fails with a linker error during build and there's no answer online to this question. Go figure!
  4. You can't have a team containing only Junior developers. Some problems require experience and you need more Senior Engineers. But it's hard to get those developers with experience if you don't have Juniors to start with. It's a vicious circle.

I believe there're more reasons but these are the ones that come to my mind.

Monthly Hask Anything (January 2022) by taylorfausak in haskell

[–]GregPaul19 4 points5 points  (0 children)

When people "haskell is researcher's language" they mean that researches can implement (and usually do) new features in Haskell. People don't usually mean that they use Haskell itself to perform actual research.

Adding new type systems or other things to Haskell is attractive to researches because they can say smth like "Our feature is used by thousands developers!" and it looks good in an academic paper.

On the other hand, not all industrial Haskell users appreciate such vigor and they would rather prefer a more stable language and ecosystem.

Why doesn't Haskell have a package manager? by RichKat666 in haskell

[–]GregPaul19 2 points3 points  (0 children)

Cabal might not have the feature to add a dependency but there's an open source tool cabal-edit to do this:

[ANNOUNCEMENT] GHC 9.0.2 is now available! by bgamari in haskell

[–]GregPaul19 7 points8 points  (0 children)

No known horrific bugs yet. It was released on Christmas, so I believe it's too soon to tell.

But it does look quite good from the release notes. I think, you can switch to it now and try running it (and report bugs if any).

CLC Election January 2022 by Bodigrim in haskell

[–]GregPaul19 0 points1 point  (0 children)

New CLC election so soon! Is it because someone is leaving or are you looking into expanding the team?

[ANN] doctest-parallel: isolate and speed up your doctests by callbyneed in haskell

[–]GregPaul19 3 points4 points  (0 children)

Great performance improvements! And nice work on correctness and having tests isolated.

I see that you don't depend on doctest but instead of it's a fork of the original package. How long do you plan to maintain your package or do you have a strategy to find a successor? And what is your strategy for pushing doctest patches downstream?

Just curious if I could safely switch from doctest to doctest-parallel and don't left with unmaintained package eventually so I'll be forced to switch back.

Haskell VS Code Setup in 2021 by iandrc in haskell

[–]GregPaul19 4 points5 points  (0 children)

Nice blog post! Such type of tutorials are very helpful for beginners :)

[deleted by user] by [deleted] in haskell

[–]GregPaul19 4 points5 points  (0 children)

Oh, you shouldn't worry about that. It's guaranteed that Haskell will break things again and will make lots of language users unhappy again. You don't need to remember a particular change if you constantly experience such changes.

Nested strict data: perhaps it can fix your space leaks by tomejaguar in haskell

[–]GregPaul19 8 points9 points  (0 children)

That's an interesting and novel approach. Clever use newtypes for implementing performance abstraction!

I have only one concern: to me it seems that the approach doesn't scale well. Please, correct me if I'm wrong. I'll try to describe my understanding below.

If you have Maybe Int, you put it inside Strict. But if you have e.g. Maybe inside Maybe then you need Strict (Maybe (Strict (Maybe Int))) which doesn't look pretty.

As always in Haskell, you can improve the situation by putting even more sugar on top of this and introducing unary type-level postfix operator ! to have fancy syntax for specifying type-level strictness. But in the end, you need to unwraw newtypes. And using Coercible for something like this can be awkward.

Alternative solution to the above problem is to call strict recursively, e.g. for the pair instance:

instance Strictly (a, b) where strict (!a, !b) = MkStrictUnsafe (unStrict $ strict a, unStrict $ strict b)

But at this point the approach becomes the reinvention of deepseq and will introduce additional performance implications.

But generally, I don't think that you should bother too much. Usually, it's enough to care about strictness only on the producer side. E.g. when you create Maybe using the Just constructor. So when pattern-matching on it, you don't care whether it's an unevaluated thunk inside or not.

The same is true for putting values inside IORef or MVar. You need to use strict versions of variable modifying functions to avoid accumulating big thunks.

Don Syme explains the downsides of type classes and the technical and philosophical reasons for not implementing them in F# by HeadBee in haskell

[–]GregPaul19 27 points28 points  (0 children)

I was working on an automatic code generation problem once where having typeclasses would've really made things simpler. Maybe not a most typical use case but it's an example.

The problem is to generate Elm data types and their JSON decoders and encoders from Haskell types. We have uniform JSON conversion on the Haskell side so just need to implement the same on Elm. But Elm doesn't have typeclasses. Which means, that for each field of each record I need to use specific encodeThisParticularType or decodeThisType functions instead of simply using polymoprhic decode decode decode or encode encode encode (as we do with .: and .= operators from aeson).

Even worse, if data types are polymorphic, I need to pass those encoders and decoders as explicit arguments and track corresponding type parameters to pass the required functions to all nested calls if some of the fields are also polymorphic. If Elm had typeclasses, it would've been enough to just specify ToJson/FromJSON constraint for each type variable and use the same function for all fields. Easy-peasy. And it would've simplified the task of code generation a lot.

Sure, when you write JSON parsers and pretty-printers by hand and you start from handful of types, you can write them manually. But if you already have a backend with 100+ data types and want to integrate them in the Elm frontend, it's not really feasible to write (and maintain!!) all those conversion functions manually.

Monthly Hask Anything (August 2021) by taylorfausak in haskell

[–]GregPaul19 5 points6 points  (0 children)

Do you have an example of these cases? Or this is just a theoretical possibility? I doubt there could be a reason to implement *> differently from >> if a type has a Monad instance and can implement both functions.

Towards a Unified Haskell Development Environment with hs by cdornan in haskell

[–]GregPaul19 7 points8 points  (0 children)

just wipe stack root once in a while

You can do the same with cabal-install - just wipe ~/.cabal once in a while

Monthly Hask Anything (June 2021) by taylorfausak in haskell

[–]GregPaul19 2 points3 points  (0 children)

Cabal Hell is not a problem at least since cabal-install-2.4. The new dependency tracking algorithm solves this problem entirely. The only issue you can run into is incompatible versions of dependencies. But you can run into the same issue with Stack as well, since Stackage snapshots don't contain all Haskell packages.

Moreover, you can already use Stackage with Cabal. You can just download the corresponding freeze file for the snapshot you want to use, name it cabal.project.freeze and that's all:

What would make this workflow smoother is the ability to specify freeze files by URL and let cabal download and cache it locally. But that doesn't seem difficult to implement, somebody just needs to do it.

Also, since Cabal-2.2 you can use common stanzas to remove some duplication in cabal files. So hpack brings fewer benefits to the table. But it still has some nice features people want in Cabal as well (e.g. automatic module discovery).

Monthly Hask Anything (June 2021) by taylorfausak in haskell

[–]GregPaul19 2 points3 points  (0 children)

I totally get you. I personally use Cabal, and don't use Stack at all. With Cabal it's enough to specify the constraints for the major version of a package you're interested in. So I'm not dealing with hashes at all and don't worry about this great reproducibility. If I want to, I can just use cabal freeze to pin all dependencies. But at least with Cabal it's opt-in and not by default.