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 … )
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.
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.
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", ..}
OverloadedRecordUpdate
is highly experimental and can change without warning at any time and will.
Oh yeah, I actually forgot that it does already exist. I’ve been treating it as unimplemented until it stops being a RebindableSyntax
hack.
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
.
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.
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.)
cabal install
is a really nice tool for installing exes though. I use it all the time, even on NixOS!
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.
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
I’ll note that Cabal does have a Getting Started guide. It should be more obviously advertised, though.
I hadn’t actually seen this. It is accessible within three clicks from the downloads page, but maybe that’s too many. I’d like to see it be more prominent, though it would invite the usual debates around whether all build tools are equals (personally, I’m increasingly resolute that in order to streamline the experience for new users, we need to kill Stack and better integrate Stackage in to Cabal…).
Tldr… I use base < 5
for essentially all my projects and generally stack for building. So as long as I have a matching HLS version it usually just works, but I agree HLS can be finicky to get working for a project sometimes.
+1 for a cabal add
command (like cargo has).
Exactly like that! Alas, by and large, Haskell beginners don’t know about Flora…
GHCup also has a one-click link to their “First Steps” guide which is very similar to Cabal’s Getting Started but covering more tools than just cabal.
Wow… I had no idea that existed. And it’s already pretty prominent on the GHCup homepage. I guess people (myself included) just don’t read things properly.