This is maybe a big ask, but could anyone who has been a long time Haskell user give some bullet points on major language developments since ~2015 or so?
I was deep into Haskell and used it as my primary language from 2012-2015, but switched over to Rust around that point. I've been thinking about trying a mid-size hobby project in Haskell to get updated on the new state of the art.
Some things I have heard tangentially (and may be misremembering):
- Field accessors (i.e. `myObject.field` instead of `field myObject`)
- Monad hierarchy refactoring (monad of no return)
- LiquidHaskell making some inroads
How is package management these days? Is cabal hell still a thing? How's the IDE situation?
Cabal's been fundamentally redesigned to have "Nix-style" builds. This has solved most of the problems I remember encountering with the tool. These days, I only have issues when packages have incorrect or incompatible version bounds on dependencies.
Tooling has improved massively in general. ghcup can install and manage versions of Cabal/Stack/GHC/etc automatically. The Haskell language server provides reasonable editor-agnostic IDE functionality; I've been using it for a while now and have found it to be useful and solid.
The language itself has had a bunch of small quality-of-life improvements. The foundation still feels the same—not a major change like jumping to dependent types or something—but lots of rough edges have been sanded off.
I've been using Haskell for over a decade now and I'm very happy with the progress of the language and the ecosystem over the last several years.
We use Stack together with Nix to pin all dependencies. That works very well.
Is cabal hell still a thing?
No.
How's the IDE situation?
Much better than it was. Haskell Language Server (HLS) has been a game changer. It works very well and can be used with different editors (easy to install for VS Code for example).
By default this will mean that Stack will use Nix to download non-Haskell dependencies. E.g. GHC and external C libraries will be downloaded by Nix.
This allows you to pin all dependencies that you have, including the compiler and external libraries (make sure to pin a specific version of nixpkgs though). And it will give developers a reproducible build environment.
It is also possible to take this Nix integration even further and make Stack download all Haskell dependencies from Nix as well. However, this requires to write a custom `stack-shell.nix` file, so I would only recommend this for people who are already familiar with Nix.
This file must then be configured in `stack.yml`
Example `stack.yml`:
# Using a `ghc-*` resolver means that stack won't try to download and build any packages itself,
# instead it will only use the packages that are shipped with the compiler.
# In `./nix/stack-shell.nix`, we ensure that the compiler indeed ships all the packages we
# need.
resolver: ghc-9.0
packages:
- "."
# This makes stack pick up our nix environment for building by default.
nix:
enable: true
shell-file: nix/stack-shell.nix
path: ["nixpkgs=./nix/nixpkgs-pinned.nix"]
Comments
This is maybe a big ask, but could anyone who has been a long time Haskell user give some bullet points on major language developments since ~2015 or so?
I was deep into Haskell and used it as my primary language from 2012-2015, but switched over to Rust around that point. I've been thinking about trying a mid-size hobby project in Haskell to get updated on the new state of the art.
Some things I have heard tangentially (and may be misremembering):
- Field accessors (i.e. `myObject.field` instead of `field myObject`)
- Monad hierarchy refactoring (monad of no return)
- LiquidHaskell making some inroads
How is package management these days? Is cabal hell still a thing? How's the IDE situation?
Cabal's been fundamentally redesigned to have "Nix-style" builds. This has solved most of the problems I remember encountering with the tool. These days, I only have issues when packages have incorrect or incompatible version bounds on dependencies.
Tooling has improved massively in general. ghcup can install and manage versions of Cabal/Stack/GHC/etc automatically. The Haskell language server provides reasonable editor-agnostic IDE functionality; I've been using it for a while now and have found it to be useful and solid.
The language itself has had a bunch of small quality-of-life improvements. The foundation still feels the same—not a major change like jumping to dependent types or something—but lots of rough edges have been sanded off.
I've been using Haskell for over a decade now and I'm very happy with the progress of the language and the ecosystem over the last several years.
We use Stack together with Nix to pin all dependencies. That works very well.
No.
Much better than it was. Haskell Language Server (HLS) has been a game changer. It works very well and can be used with different editors (easy to install for VS Code for example).
Could you elaborate on the path you took here? Sounds interesting
Stack comes with built-in Nix integration: https://docs.haskellstack.org/en/v2.9.1/nix_integration/
By default this will mean that Stack will use Nix to download non-Haskell dependencies. E.g. GHC and external C libraries will be downloaded by Nix.
This allows you to pin all dependencies that you have, including the compiler and external libraries (make sure to pin a specific version of nixpkgs though). And it will give developers a reproducible build environment.
It is also possible to take this Nix integration even further and make Stack download all Haskell dependencies from Nix as well. However, this requires to write a custom `stack-shell.nix` file, so I would only recommend this for people who are already familiar with Nix. This file must then be configured in `stack.yml`
Example `stack.yml`:
# Using a `ghc-*` resolver means that stack won't try to download and build any packages itself, # instead it will only use the packages that are shipped with the compiler. # In `./nix/stack-shell.nix`, we ensure that the compiler indeed ships all the packages we # need. resolver: ghc-9.0
packages: - "."
# This makes stack pick up our nix environment for building by default. nix: enable: true shell-file: nix/stack-shell.nix path: ["nixpkgs=./nix/nixpkgs-pinned.nix"]