Convenience in the Haskell ecosystem

I feel like this has been a pretty productive conversation, with a couple of different actionable items that have come out of it. They’ve been summarized above atleast once, but I figured maybe I should re-summarize (along with ideas I’ve seen floating around in other posts)

I see a couple of different potential project ideas:

  • Some type of templating system for cabal/stack
  • cabal add <package> (for adding dependencies)
  • Some type of cabal gen-deps command which, from imported modules, can automatically insert all required packages into build-depends. (This seems like a natural extension of cabal add <package>)
  • A minimal fallback ide server for HLS (integrate dante into hls?)
  • A better story for editor support outside of vscode (like emacs)
  • Local Modules / Fixing the “duplicate field name/duplicate constructor” problem
  • Make code formatting tools easier to use

I dont know if something exists for this or not, but I can envision some type of “Haskell Convenience Committee” or “Haskell Tooling Committee”, or something! It would be nice if there was at least some type of Haskell Foundation official repo for tracking requests/conversations about reducing all the papercuts in the ecosystem.

These concerns are obviously very spread out amongst all the Haskell tooling; most of them would require the insight and cooperation of the various project maintainers to decide if the ideas are feasible, to help steer the ideas in a feasible direction, and to aid with guidance or implementation. But if there’s not already an official place for storing wish list items like stuff we’ve discussed here, I think it would be helpful to create one.

3 Likes

There may well be benefits to having something more official, but in the meantime there’s @tomjaguarpaw’s Tilapia, which aims to track a lot of these cross-project issues.

1 Like

That is correct: with stack script, if no packages are specified, all the required packages that are in the snapshot or are a GHC boot package are deduced by reference to the import statements in the source file. The base package associated with the version of GHC specified by the snapshot is always available.

1 Like

@vanceism7 That’s a really great summary, thanks!

I don’t recall this being discussed, though; could you elaborate please?

I second this. The whole point of the Haskell Foundation is to coordinate such things, after all.

Oh, I didn’t know about this. It doesn’t seem to be too well-known, unfortunately, which limits its usefulness. A good first step might be to make this more ‘official’.

Imho the best place for a lot of these things to live is as enhancement requests in the trackers for the individual projects. If its for projects that don’t yet exist, the issues section of the haskell tech proposals repo is a place to create tickets that might later involve into proposals seeking HF support Issues · haskellfoundation/tech-proposals · GitHub

This wasn’t discussed here, but I referenced it in the neohaskell conversation. One of the very annoying bits of Haskell for me is the whole issue with duplicate record fields and duplicate data constructors. It’s quite annoying that i can’t do:

data Person = Person
  { name :: Text, ... }

data Company = Company
  { name :: Text, ... }

-- Or
data Breakfast = Eggs | Banana

data Lunch = Sandwich | Banana

Without running into duplicate name errors. Even if you use the duplicate fields extension, you still run into ambiguous type errors. The only way to currently work around this is to move the types into separate modules, or add prefixes to the names, which is a big pain. Richards local Modules Proposal would give namespaces to these things by default, so you could access them like Person.name or Breakfast.Banana.

Yea that’s true, but I also think there’s some value to aggregating these types of requests, so there’s a centralized place where people find all the different initiatives being worked on to improve QOL.

I didn’t know about Tilapia either, that’s really cool. Making it an officially recognized haskell foundation repo is probably a good next step. I think we need to do more to make it known that we care about this as a community, and maybe help focus efforts towards fixing some of this stuff

4 Likes

Thanks for explaining!

I think this in turn could help initiatives that aim to attract and welcome new people to Haskell (and perhaps some to return). The technical advantages are one thing, and I personally find a lot to love in that – they’re great ‘selling points.’ They’re just not the only ones!

I could see Haskell promoting itself along the lines of:

You too can do an awful lot of (#@$ with Haskell from day one, check it out: [… ad hoc plotting … data parsing/wrangling … command line tools … http(s) APIs … blah blah blah …]

AND, if or when you’re interested in going deeper into [… highlighted advanced and active research topics …], Haskell’s got your back bro.

Obviously not necessarily in that tone, but does that make sense? What @bradrn was looking for in the OP, plus a few other easily-overlooked low-hanging fruit that Haskell as a general purpose language really can do exceedingly well at, while presenting an entry point to so much more.

I guess what I was getting at with the npx create-react-app post above was:

  • Providing an attractive gateway to the ecosystem for a selection of common projects (however basic they might seem), but maybe also a couple of ‘almost everything but the kitchen sink’ options?
  • The tool does not need to do everything for everybody (I guess it could be expanded on with other templates), it just needs to offer a few interactive questions that would provide a suitable environment for a potential new programmer (rather than leave them to their own devices amongst the myriad of options in Haskell multiverse).
  • A brief statement explaining the options in the interactive tool would be nice. e.g., cabal vs stack; nix vs not-nix.
  • A few closing statements after the tool has finished would also be nice. create-react-app used to (I guess it still does) leave you with some links and suggestions and so on. Bonus points if the basic project type has a brief-'n-cheerful tutorial associated with it that folk can follow along. But it wouldn’t hurt to setup the scaffold project as a minimal, working, project including comments that someone pretty new to Haskell could follow.

If this all sounds too much, or confused, or whatever – that’s cool. Just throwing it out there before I get distracted again. (Every time I’ve come back to this thread to flesh out what I had in mind I’ve found so many cool things I didn’t know existed to look into instead … :slight_smile: )

On the bright side? This could be orders of magnitude less complex than the actual create-react-app. That thing has to contend with Lovecraftian Horrors left, right, and from n-dimensions.

-e- TLDR: ‘Haskell, what is it good for?’ ‘Well, in fact … [a highlighted selection of general purpose app types, that will behave well, look beautiful, and can be refactored however you see fit].’ i.e., it’s not just for the 130+ IQ kids’ to toy around with and troll each other, although you can get in on that game if you want. :slight_smile:

3 Likes

Well, the other way is to use NoFieldSelectors (and access fields via puns, wildcards, dot syntax, or overloaded labels for optics). Admittedly this does nothing for constructors, but I’ve found duplication there a lot less of an issue in practice than with fields.

2 Likes

Ah, I suppose I missed my specific use-case with my example. The one area I ran into issue with this was record update syntax.

modifyCompany company =
  company { name = "some new name" }

modifyPerson person =
  person { name = "johnny boy" }

I typically use record dot syntax but it doesn’t save me from this scenario. I get ambiguous field errors and have to go through the trouble of redundant qualified imports where I import Person and Company separately to fix it.

I don’t run into duplicate data constructors as much, but it does happen to me there as well

Yeah, OverloadedRecordUpdate should fix this, but it seems to have had quite a few setbacks.

In the meantime, I’m fairly happy with modifyCompany Company{..} = Company{name = "some new name", ..}

1 Like

OverloadedRecordUpdate is highly experimental and can change without warning at any time and will.

3 Likes

Oh yeah, I actually forgot that it does already exist. I’ve been treating it as unimplemented until it stops being a RebindableSyntax hack.

1 Like

This is exactly what I’d love to be able to say!

Great idea! I’ll see if I can integrate this into my in-progress project builder tool. Any suggestions on what comments it could mention for Haskell?

EDIT: Just thought of one that’s really important: telling beginners how to add new packages! That could help a lot with avoiding the abomination that is cabal install --lib.

1 Like

Do beginners not know to add a package to their cabal file? That feels like cabal 101.

EDIT: You know what, I just looked at some cabal docs and this is nowhere to be seen prominently in the beginning. This should be in the README.

3 Likes

On the FP Discord, we deal with beginners all the time who have tried to cabal install libraries. I have a fair bit of sympathy for them — it’s the kind of thing which sounds like it should be right, but isn’t. (cabal install is really confusingly named for people who are unfamiliar with the Unix ecosystem.)

6 Likes

cabal install is a really nice tool for installing exes though. I use it all the time, even on NixOS!

2 Likes

Indeed, it’s great for exes. No surprise there — that’s exactly what it’s designed for! But using cabal install for libraries may have unexpected results, and cabal install --lib is basically guaranteed to break your Haskell installation unless you know exactly what it’s doing.

2 Likes

Oh cool, that I didn’t know about. Thanks for the tip! I’d still rather have an implicit module created for me automatically so I could just do

modifyCompany company = company { Company.name = "new name" }

Or if it just knew what record I wanted, I’d be ok with that too. Sounds like thats what OverloadedRecordUpdate does, but I suppose I should shy away from that for now

No, they dont. It took me a good long while to figure out how to add packages to cabal initially. The docs were scary and vast, and even once I figured out where to put them, it took me a while after that to figure out what exactly the package name was. I assumed at first maybe it was the module name, and then eventually learned its the name used in the url.

E.g: In https://hackage.haskell.org/package/yesod-persistent, the package is yesod-persistent.

I know that may sound dumb, but that was a big struggling point for me when I first started. I probably spent a day trying to figure out how to add dependencies. Other package managers like dart and cargo tell you in the packaging site how to install it.
e.g: https://crates.io/crates/quote
or flutter_form_builder | Flutter Package
or https://www.npmjs.com/package/react
or NuGet Gallery | Newtonsoft.Json 13.0.3

Obviously, in our current state, hackage can’t just drop a command like cabal add yesod-persistent because it doesn’t exist, but it’d be great to see that type of thing

2 Likes

I’ll note that Cabal does have a Getting Started guide. It should be more obviously advertised, though.

3 Likes