Console #145 -- An Interview With Marc Scholten of IHP - batteries-included web framework
Featuring Clappr, GeoPuzzle, and IHP
🤝 Sponsor
This space is reserved for sponsors that support us to keep the newsletter going! Want to support Console? Send us a note at osh@codesee.io
🏗️ Projects
Browse through open source projects on OpenSourceHub.io, add your project to get more exposure and connect with other maintainers and contributors!
🎬 Clappr
Clappr is an extensible media player for the web. It uses HTMLVideoElement by default, and you have the possibility to extend the default HTML5 playback to create a new media support, just like a plugin!
language: HTML stars: 6233 last commit: one month
repo: github.com/clappr/clappr
site: clappr.io
🧩 GeoPuzzle
GeoPuzzle is a geography game to arrange the pieces of the world! You need to drag the shape of the territory to the right place.
language: Python stars: 46 last commit: 2022
info: opensourcehub.io/tyvik/geopuzzle
site: geopuzzle.org
⚡ IHP
The fastest way to build type safe web apps. IHP is a new batteries-included web framework optimized for longterm productivity and programmer happiness
language: Haskell stars: 3859 last commit: 3 days
repo: github.com/digitallyinduced/ihp
site: ihp.digitallyinduced.com
Join thousands of other open-source enthusiasts and developers in the Open Source Hub Discord server to continue the discussion on the projects in this week's email!
An Interview With Marc Scholten of IHP
Hey Marc! Let us start with your background.
I started programming in 2010. In the first years of doing software development I was mainly working in the PHP space. I’ve been part of the Propel ORM core team back then. After a couple of years I moved more into the Rails ecosystem.
Rails showed me that many of the trends in the PHP ecosystem, like overuse of design patterns, services containers, making everything more flexible than it needs to be, favouring data mapper over active record, doesn’t really help you build a good scalable software architecture. In the end no method or class is doing anything specific, it’s all just needless abstraction in the name of single responsibility principle. Rails showed me a better way.
In 2015 I’ve started working with React and building more complex frontends. Mainly together with Rails in the backend. Around that time I also started using Nix and Haskell.
Four years ago, in 2016, I founded digitally induced. Our engineers assist our customers moving into the digital space with digital product development and comprehensive technical expertise.
In 2017 we already started working on our own custom Haskell framework. Initially, it was just to get live reloading (which was the hot new thing in the React world back then) working in Haskell. We already wanted to open source it in 2018, but then I got quite busy with building the company :). Then in June 2021, we finally released IHP onto the world. And we now set out to use IHP to drive the adoption of Haskell in the software world.
What made you transition into Haskell from Javascript?
Haskell initially got me interested because it was a whole different paradigm. I didn’t know anything about functional programming back then, so this naturally got me curious to learn.
What's an opinion you have that most people don't agree with?
Programming languages vary in power. There’s a great post by pg about this.
What’s your most controversial programming opinion?
Docker is the wrong solution to the right problem. The value is in software distribution, and there are better tools for that (even vagrant was better).
What would you say is wrong with Docker, and what is a better approach to these problems?
Docker has two problems:
- It's slow because of large images and an inefficient approach to building images.
- In development, it usually runs inside a VM when using macOS. This has bad effects on the developer experience because now you're basically dealing with two systems.If you have lot's of different dependencies nix is always a good choice.
Otherwise, follow the most simple approach:
If you have a stack, like a typical PHP stack, you'll get a lot of the same benefits of docker by writing a small script that makes sure that the right version of your PHP tools are installed via e.g. brew. Basically, moving the instructions out of your Dockerfile into a shell script that calls the different package managers you're using. And then starts the, e.g., mysql/postgres server and the PHP server. Also add direnv to the mix.The goal should be to have fast feedback loops in your development processes. This is very hard to archive with docker.
If you could dictate that everyone in the world should read one book, what would it be?
I’d not dictate any book to avoid violating individual liberty. But here’s a couple books I found insightful:
The Design of Everyday Things (Software is to be used by humans, so good design is an important facet of good software products)
The Innovator's Dilemma
Blue Ocean Strategy
Crossing the Chasm
If I gave you $10 million to invest in one thing right now, where would you put it?
digitally induced
What resources do you use to stay up to date on software engineering?
I mostly read hacker news.
How do you separate good project ideas from bad ones?
A good project solves a real valuable problem in a better way for at least one real person. There also needs to be a clear way for distribution, otherwise there’s likely no adoption of the solution.
Why was IHP started?
IHP was initially just an experiment to get live reloading into Haskell apps. Then it turned out that the result was pretty fun to use to build apps with. We started using it internally for our own projects and smaller client projects.
Are there any overarching goals of IHP that drive design or implementation?
We want to drive the adoption of Haskell in the software world. There’s a big trend in the software world of adopting more functional programming techniques (see e.g. recent Java releases). We’re also seeing growing usage of type systems again (see recent PHP releases, Typescript, Flow by FB). Haskell sits at the end of this trendline and I think it’s time for Haskell to gain more widespread adoption.
For that we designed IHP for non-Haskellers to use. All other Haskell frameworks are usually designed for people who are experts in Haskell. IHP is for the developers who like FP-techniques and also want type-safety, but don’t know about Haskell yet.
For those not in the Haskell ecosystem, what are some of these existing web frameworks?
Take a look at servant. It uses a lot of advanced Haskell type system magic to build very stable APIs. This is pretty good when you're already familiar with type families and are able to decipher Haskell's complex type error messages when things go wrong. This is not the right tool for starting out.
Take a look at e.g. the "Basics" section of the Yesod framework. Yesod is Haskell’s biggest web framework and many of the IHP components we're using (e.g. WAI, Warp, a lot of middlewares) have been developed by the Yesod team. Compare this to our “Getting Started”. You will see that Yesod doesn't really explain how to do real world CRUD work (what a lot of web development is about). It tells you all the technical details, but after reading the whole page you still cannot make an HTML form be saved to the database. If you're a Haskell expert, the technical details will be enough for you to get started. If you're just starting out, you will feel like you're not going anywhere and rethink your choice of picking Haskell.
What trade-offs have been made in IHP as a consequence of the above goals?
We sometimes drop type-safety at certain points to simplify the framework API. E.g. in early versions of IHP we had different types for un-persisted records and for persisted records. We had a `data NewProject` that didn’t have an id field, because the id is only set after it’s been inserted into the database.
While this catches a few edge case bugs, it really confuses developers. So we removed it. Most apps will never have any bugs because of this problem, but most apps we built have been affected by more complex type signatures because of this.
What is the most challenging problem that’s been solved in IHP, so far?
Early on we had a complicated issue with the IHP import structure. In Haskell, you cannot have import cycles, so when module A depends on module B, module B cannot depend on module A or on any module that depends on module A.
Here’s the concrete problem: Let’s say we have a project that consists of Posts and Comments.
Inside the Comments-Controller to render the new comment form we need to import the New Comment View from Web.View.Comments.New.
That View wants to display a link to the lists of all Posts. For generating the path to that route it needs to be aware of the routing configuration. So we import Web.Routes.
The Web.Routes module needs to know about the controllers so it imports all the Controllers. Including Web.Controller.Comments.
So we go this:
Web.Controller.Comments -> Web.View.Comments.New -> Web.Routes -> Web.Controller.Comments
We have hit a cycle in our imports.
It took us quite a while to rethink this to avoid this from happening. The solution is to make routing definitions independent from the action implementation, so that the Web.Routes module does not need to import the controllers.
We added a new Web.FrontController which imports all the controllers and the Web.Routes and then only when a route is added to the router via parseRoute, we expect the action implementation to be available.
Solving this problem took multiple iterations and weeks of thinking about possible solutions. The module structure of IHP is really under-appreciated because now it just works.
What is your typical approach to debugging issues filed in the IHP repo?
I start by creating a new IHP project where I try to reproduce the issue.
What is the main source of revenue for IHP?
IHP is already monetized with services like IHP Cloud and IHP Casts. Both are already generating revenue. Compared to the rest of digitally induced it’s still tiny, but we’re getting there :-)
The services business of digitally induced is the main part of what we’re doing. We help other companies build digital products.
I’m very excited about growing this next year. With IHP we can build software much faster in higher quality than other companies. Additionally, we have access to a very unique talent pool of developers who want to work with IHP and Haskell in production. This is great for our customers, who can have a shorter time to market, and great for our engineers, who can work with the most exciting technology.
Want to join the conversation about one of the projects featured this week? Drop a comment, or see what others are saying!
Interested in sponsoring the newsletter or know of any cool projects or interesting developers you want us to interview? Reach out at osh@codesee.io or mention us @ConsoleWeekly!