Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Haskell web framework IHP aims to make web development type-safe and easy (infoq.com)
88 points by _query on Oct 19, 2020 | hide | past | favorite | 33 comments


I've tried this out a few days ago. I have some basic theoretical Haskell knowledge, but not much practical experience. However I do have some significant Nix experience.

Ended up not even going through the beginner tutorial, as the installer/scaffold process required me to do things that I didn't like:

- forced scaffolding of projects with some quite blackboxy generated shell scripts inside

- use of nix, yet requiring me to install 'make' and 'direnv' system-wide (why? just let me use a shell.nix)

- required me to use cachix.org as a system-wide nix substituter, which I don't want to do for security reasons (just allow me to build everything myself)

All in all this looked promising, but ended up being too magical for my taste. I'd like to be able to start using IHP 'from scratch' instead - with my own Cabal/Nix/Bazel build machinery. This is a critical requirement for libraries/frameworks that I use.

Your mileage may vary though - if you're okay with RoR-like scaffolding and blackboxness, then you might feel at home here, and at least you get a nicely typed language in return.


IHP is really optimized for getting stuff done and shipped very fast. There are many existing haskell frameworks already that give you lots of options and make you decide on everything.

We try to have a single standard way of doing things to allow you to focus on actually building things instead of solving technical problems.

This standard setup allows us to also e.g. offer a standard deployment process: https://twitter.com/digitallyinduce/status/13134104697854074...


Please don't get it wrong,but I never understood 'getting stuff done and shipped very fast'. You can't get stuff done, if you don't understand. Too much magic works good for typical 'hello world' apps, but when things go south, it adds significant delay in debugging/fixing.


Why, they do understand.

They just have made an opinionated framework that decides a lot of things for you. You can't reconfigure that, but also don't have to. A framework is best used when you go with the flow, build something similar to what the authors had in mind, and don't mind their particular technical decisions. You concentrate on getting "stuff", that is, business logic, done.

The more flexibility and precision you need, the better choice a set of libraries becomes. It offers no handholding, and assumes you know what you're doing — but that's what you were after with all these "let me decide myself" requests, weren't you?


I do understand that, and I do want someone to hold my hand when it comes to Haskell library choices :). But it would be nice to be able let me replicate all the deployment/development setup aspects in a style that doesn't have an impedance mismatch with existing projects (especially monorepos!). It's fine if it occasionally breaks, it's unsupported, without warranty, I'm on my own, etc. Just let this be an option for people with Opinions on deployment/build systems, but no such Opinions on Haskell software engineering.


I think replicating RoR in Haskell is explicitly the goal of IHP.

I don't have a problem with them making opinionated choices for projects, I really don't want to have to wade through library choices and configuration each time I start a project.

Granted I started out as a Rails dev...


> I really don't want to have to wade through library choices and configuration each time I start a project.

I think this is a false dichotomy. You certainly can have an opinionated way to setup a project that 90% of people use at first, with some way to customize things as you go along, or at least a way to replicate the standard setup with whatever tooling is more conducive to the user's vision.

Flask is a good example of this. You start out with a minimal single-file app, with a somewhat magical tool (`flask`) that will take care of starting a debug server for you and whatnot. As you go along, you can grow your app according to the official manual ('project layout', 'growing big' manual pages, using blueprints and application factories and other typical Flask patterns), or you can do something that fits more to your existing codebase. You can also keep using the `flask` tool, or write your own equivalent. Or skip it entirely and express everything as Python scripts.

Even with the quite more complex and scaffoldy Django, you're very much able to rejigger a scaffolded app easily into whatever structure you want, as long as you're ready to dust off the “Forbidden PYTHONPATH and DJANGO_SETTINGS tricks” book.


I wholeheartedly agree. I do not like projects who assume they get to dictate my build process, my environment, or my system configuration. Just ship code, and let projects integrate your code in whatever way they are used to. That way, the marginal cost of introducing a new component into an existing system is really low, not to mention a much gentler learning curve.


what do you think of rails?


This looks well done, but having used Haskell professionally on multiple web projects, I have to take issue with some of the design choices.

Templating? Haskell provides such a wonderfully clean way to generate HTML via combinators and do notation. You don't need a quasi quoter to get a DSL. See Lucid. All templating does is remove control features (like forM, for example). [1]

They've reinvented common operators. For example, (|>), which is great, I've used it in Elm, but the Haskell version of this is (&) from Data.Function.

These are just a few examples. They're ignoring Haskell conventions to make it more familiar to people coming from other backgrounds, even when the community conventions are strictly better or equal. Rails was a nightmare for me, it was impossible to tell what was a language feature and what came from the framework. I suspect this will equivalently speed up initial development while slowing understanding.

[1] https://mmhaskell.com/blog/2020/3/16/lucid-another-html-opti...


> Templating? Haskell provides such a wonderfully clean way to generate HTML via combinators and do notation. You don't need a quasi quoter to get a DSL. See Lucid. All templating does is remove control features (like forM, for example).

IHP's templating HSX is targeted at people with a react background that are familiar with JSX syntax. In the background it compiles down to blaze-html and can be used together with e.g. forM_ (which we have aliased to forEach). It's just a more familiar syntax on top of blaze html.

Some internal IHP functions are even still implemented with the blaze combinators: https://github.com/digitallyinduced/ihp/blob/master/IHP/View...

> They've reinvented common operators. For example, (|>), which is great, I've used it in Elm, but the Haskell version of this is (&) from Data.Function.

The |> just looks more beautiful to us :) Take a look at the gorgeous expressiveness of this: https://twitter.com/digitallyinduce/status/12990709068542484...

> They're ignoring Haskell conventions to make it more familiar to people coming from other backgrounds,

Yes, IHP is the haskell framework for builders :-)


> IHP's templating HSX is targeted at people with a react background that are familiar with JSX syntax. In the background it compiles down to blaze-html and can be used together with e.g. forM_ (which we have aliased to forEach). It's just a more familiar syntax on top of blaze html.

Ok, but then your users will write views without understanding what they're doing. All the magic will make them feel confused and powerless when they do anything outside of the blessed path. They can't extrapolate that forM_ works for any monad in the future.

> The |> just looks more beautiful to us :) Take a look at the gorgeous expressiveness of this

Agreed, I wish we all used |> instead of &, but that operator is called & in Haskell. You're crippling your users' ability to read other code-bases in the future. And that same code would be plenty readable with &, don't you agree? Your example doesn't even show your operator, you're replacing it with a unicode character. I could make vim do the same for &.

> Yes, IHP is the haskell framework for builders :-)

There's so much more to "building" than the first month of development! Easing someone into the Haskell ecosystem is much more important than helping them get a CRUD app running that they don't know how to customize. Haskell is an order of magnitude more productive for me than other languages (ruby), because of its differences.


> All the magic will make them feel confused and powerless when they do anything outside of the blessed path.

Maybe, but what are the chances they chalk it up to a normal and acceptable learning path?

> They can't extrapolate that forM_ works for any monad in the future.

I think it's important people know that, but how much does it matter for IHP's intended audience?

> Agreed, I wish we all used |> instead of &, but that operator is called & in Haskell. You're crippling your users' ability to read other code-bases in the future

I think this is an important point, but I'm not sure how much it would matter for most.

> And that same code would be plenty readable with &, don't you agree?

Most would assume & means something with boolean and I bet. I find & readable, but even Haskellers on my team didn't really seem to take to it.

> There's so much more to "building" than the first month of development!

People don't really value the long term but default I've found. Then once they have committed to something to a degree, they don't change from it.

If IHP makes it easy enough to get to the point of feeling like one should keep using it rather than starting over...

Maybe the extra learning challenge will feel "normal", worth it, and otherwise motivated.

> Haskell is an order of magnitude more productive for me than other languages (ruby), because of its differences.

I can relate to this, but coming from Python. Others who aren't sold on Haskell by it's usually toured virtues are probably likely to be sold by getting someone spun up to hack away on more quickly.

I find making a lot of these arguments kind of funny since I typically find myself arguing from your position :)


> They can't extrapolate that forM_ works for any monad in the future.

To be fair, this is a problem with Haskell as well; forM_ is more properly known as for_, which works with any Applicative, even if it isn't a Monad. :)


> Take a look at the gorgeous expressiveness of this: https://twitter.com/digitallyinduce/status/12990709068542484...

a: The image is https://pbs.twimg.com/media/Egc0d5KXcAYdskO.jpg

b: That's hideous, especially the doublewidth characters.

c: I didn't even know unicode had east-asian-width=2 duplicates of '←', '→' and '▷'.

d: The string "|>" does not appear in your purported example.


The image is probably using natively supported font ligatures.


seems very likely that it's Fira Code


I have been learning Haskell through IHP. It's the best and actually simplest web framework I have ever tried.

The developer experience is the best I ever had for a MVC-style framework. And I got to learn Haskell without banging my head too much against the wall. Really enjoyed it :)

I really needed something like IHP to get started with Haskell. It's fun and easy and the documentation is very easy to follow.

I see some argue that they wish to make more custom choices regarding the setup. That is precisely what I don't want and that's why IHP is a great fit for me.

In terms of simplicity I think the choice of supporting only Nix and Postgres actually are strengths at this point. That lets them streamline the development of the framework without supporting the minor preferences of every individual. And these choices should work really well for most web developers.

Some may disagree on this, and maybe IHP is not for them, but I don't think it shouldn't discourage those who considers trying it out and form their own opinion.

I was prepared for great hardships learning Haskell as most of the resources are very academic and I'm mainly just a simple application builder. IHP was just what I needed to fill that gap, and it made it really fun :)

I am tweeting about the whole thing, coding Haskell for 100 days: https://twitter.com/larsparsfromage


IHP is the best web framework experience I have had. I think a lot of aspiring haskeller's will have worked their way through a text like Learn You a Haskell For Great Good or similar and then be looking to fool around with an actual project.

IHP uses nix to cut out all the work of setting up ghc/stack/cabal which can be quite tricky for a beginner, it has just added haskell language server integration, it starts your postgres servers, it spares you from having to remember your SQL syntax, and means you can start writing haskell code instantly while getting immediate feedback on your hacking from GHCi and visually through the live reloading of the web app in your browser.

I've found the [hsx||] quasiquotes quite fun to work with and type safety has sped up development by preventing bugs that can easily crop up when you're linking forms to databases.

I like the design choices in IHP, and for me, at the moment, I like the focus on server side web app development, which encourages you to be more sparing/judicious in the use of javascript.

With IHP being opinionated about the models/views and routing it means I can focus on integrating some of the other really cool haskell libraries that exist into web apps. (I'm also trying to keep a log of my experiences here on an https://ihpcafe.ihpapp.com if you want to read along with someone figuring out function type signatures ;) )


This is the first Haskell web development framework (granted, I haven’t looked at very many) that would actually make me interested in trying web dev in Haskell. Coming from a Django/PHP background, it seems it provides a lot of desirable functionality and type-safety out of the box while also being relatively comprehensible for a Haskell newbie.


A few years back, I used Yesod. It was very nice because of the type-safety from top to bottom. Especially nice in combination with esqueleto.

https://www.yesodweb.com/book


Esqueleto and persistent are quite nice. Their one downside is SqlPersistT. The abstraction makes sense, but once you have people putting that thing as the base Monad in your stack, you're in trouble. Its nature means it holds a transaction (and therefore connection!) open during the entire action if used that way. This will cause big problems, like causing requests to queue on your connection pool if some other IO/parts of the code are slow and hogging the connection.


Did you try Opaleye? This guy seems to prefer it: https://williamyaoh.com/posts/2019-12-14-typesafe-db-librari...


I had not heard of Opaleye yet.


Many people in the IHP community are beginning their haskell journey with IHP.

Check out e.g. 100 days of haskell by Lars Ulvestad: https://driftercode.com/blog/hundred-days-of-haskell-day-one...

Started around 60 days ago, and now here's the soon-to-be-production app: https://twitter.com/larsparsfromage/status/13149985667761725... :)


I tried this a couple weeks ago and while the process was rather smooth (as a newcomer to Haskell), the process to add authentication to the application was not explained at all in the docs -- they just have you copy and paste a bunch of code. Hopefully that can be improved in the future :)


Good point! We're working on improvements to this :-) We actually had a conversation about this in the office a couple hours ago.

There's also an GH issue for this already: https://github.com/digitallyinduced/ihp/issues/467


Awesome. Keep up the good work!


I gave this a shot, to see if it'd be better than writing my API with Servant and then building a client separately. It looks really cool and there's been a lot of work put into it, so I had to see for myself.

I kind of wish it didn't depend on Nix and Cachix and stuff like that, compared to deploying as a Stack template. I can see how it simplifies setup of a lot of the environment but considering the various issues I had trying to run it through WSL2, it left me at a point where I couldn't really understand what was going wrong.

I'm back to messing around with Servant, but that's also because I'm not the target user for rapid web dev in this case. I want to learn Haskell my own way.


I work with commodity LAMP-style hosting mostly, so I'm not familiar with this sort of framework. How involved is setting up and running a Haskell web server? Is it a fully bespoke thing that needs to be figured out, or is it just like an image you install? Is this stuff generally hosted on standard clouds (e.g. AWS)? IMO the server setup seems to be the biggest issue with these sorts of boutique web frameworks, but I'd love to learn more if I'm incorrect.


IHP apps are generally deployed on standard Cloud such as AWS. In the big picture you need to build the binary and CSS+JS and then copy the files onto your production server. There you just need to start the binary and pass some options (such as the DB connection) via env parameters.

Check the deployment guide for more details: https://ihp.digitallyinduced.com/Guide/deployment.html

There's also IHP Cloud which is basically "netlify for haskell". Here's a video of deploying a IHP haskell app in 60 seconds: https://twitter.com/digitallyinduce/status/13134104697854074... More infos here: https://ihpcloud.com/


While IHP looks nice, it will certainly take a while to get into a similar shape to scalajs, in any case, I'm happy to see more work on the typed side for web development.

For anyone interested, Web Development is already Type-Safe and Easy by leveraging scala-js.org, being an amazing project.

It was the first project in the area to get amazing IDE support for free, where even TypeScript took a while to catch-up, and I still personally believe the auto-completion /refactor/navigation support is better in scalajs.

For people not familiar, take a look to this js to sjs comparison: https://www.scala-js.org/doc/sjs-for-js/

My preferred tech stack is now https://scalablytyped.org (like definitelytyped for Scala), https://slinky.dev/ (a small react wrapper), and https://material-ui.com/, which makes me work on the frontend at an incredible speed, while being confident on a low-bug rate.


Jsx is a plague. What's wrong with simply nesting function calls like in elm and fsharp? Someone goes this far to learn a rather eccentric language you think they care about superficial familarities?




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: