Haskeller Interest in Declarative GUI?

I’m curious to what extent the Haskell community cares about declarative GUI.

As some may know, I’m a big proponent of monomer (with associated gripes about getting it to work on Windows, and the pace of development / support on the lib). It has been, and I assume rightly, derided as “Elm with more steps”, but even then, it’s extremely useful as such for the ease with which one can build a GUI app.


On the other hand, how do Haskellers generally feel about declarative GUI?

I personally think declarative GUI is a big opening for Haskell; i.e, declarative GUI with Haskell can get around having to screw around with Electron or Tauri and provide a very easy way to get apps running.

I’d hypothesize that declarative GUI is potentially a big boon for FP education; i.e, Haskell-ML syntax provides very composable and terse GUI widgets and also provides an introduction to the functional mode of thinking, while simultaneously allowing us to hide effectful code and IO away behind the library.


Any thoughts here?

11 Likes

There’s been almost everything from fudgets to FRP implemented in Haskell, each with their group of backers saying that approach will be “the next big thing”…and yet here we all are (for more information, see A History of Haskell ).

Since the various “revolutions” didn’t happen, perhaps an approach based on “evolution” could be made, starting with a simple foundation to which more is cautiously added over time. But in addition to time, it also requires patience, certainly more than one person or a small group could sustain.

But with the advent of the HF…“this time could be different” : a HF-backed (re)exploration of the options (or implementations) for GUIs in Haskell may have more success. But you’ll have to ask the HF about the possibility/feasibility of starting up such an endeavour.

2 Likes

I think what we need isn’t a library or framework that “solves” the GUI problem in Haskell, or even seeks to solve the GUI problem.

I’d consider the plethora of competing GUI libraries and frameworks to demonstrate that GUI in Haskell is a research topic, and hopefully one that won’t be resolved any time soon; the research is a good thing.

A “standard” GUI library in Haskell, I think, would be cross platform on all the major platforms supported by Haskell, and also provide a declarative GUI framework. Its role wouldn’t be to be “solves the GUI problem”, but simply to be a minimum and something that newbies can be directed to, and ideally, something Haskell courses can be taught in.


Given my requirements, it seems what I’m really looking for is gloss, which aims to be easy to use and unaggressive, while being pretty damn battle-tested. But gloss, as far as I understand, doesn’t come with libraries for building GUIs, unless you count Yampa.

1 Like

Rather than start another argument over what exactly qualifies (or not!) as being “declarative” in Haskell, let’s just have such a library:

[…] be a minimum and something that newbies can be directed to, and ideally, something Haskell courses can be taught in.


As for gloss…perhaps it could be the starting point for convergence: over time, other GUI libraries can switch over to using its features as needed. But that would also make gloss a essential dependency for those projects: they will only do that if they see gloss as a viable long-term option, one which is well-supported (being “battle-tested” is just the “bare minimum” these days).

Sorry, misspoke, late here.

At least you have a reason:

…I don’t >_<

1 Like

This is interesting:

animate :: Display              -- ^ Display mode.
        -> Color                -- ^ Background color.
        -> (Float -> Picture)   -- ^ Function to produce the next frame of animation.
                                --      It is passed the time in seconds since the program started.
        -> IO ()

…that (function) argument of type (Float -> Picture) is reminiscent of an early definition for Fran’s Behavior type:

So some of the early FRP techniques Fran introduced could be reused with the (more) “pure” form of gloss. But I’m absolutely sure that won’t be “declarative” enough for some…

I think it’s wonderful. I tried to use monomer, in fact! I think I got scared by the lenses I think.

But perhaps I should revisit…

1 Like

I really like using Elm for web development and would love to use something similar for developing GUI apps in Haskell.

3 Likes

I think Monomer might be your friend here: monomer: A GUI library for writing native Haskell applications..

3 Likes

Thanks, I will definitely check Monomer out.

2 Likes

You might be interested in reflex.

2 Likes

I went through Reflex’s documentation and found it foreboding, but I didn’t realize they had a walkthrough.

Re: monomer, the two drawbacks with monomer is that it’s uncertain what its pace of development is as the developer has been missing for two months.

The other deal is that while it aims to be easy to use, there’s packaging issues as there’s a deliberate design choice by the author not to provide default fonts.

On Windows, SDL doesn’t work out of the box via Mingw because of issues with GHC’s Windows Clang support (no stack protector), and you’ll have to make do with an older SDL from the Mingw website. There also seems to be an ongoing issue with freetype; I think the best solution is to just get the library to compile, then, from official project pages, download the appropriate libraries and place them in the executable’s folder.

In general, for the asset distribution issue:

Cabal can include assets via a lesser known feature, but I haven’t been able to get that working.

Flatpak is a standard packaging mechanism.

File-embed is a very easy, albeit smelly, way to make sure the packages are present; the font can be entered as a ByteString to the library, and the assets can be deployed by the monomer app with user direct calls to System.IO or equivalent file deployment tools.

Another option is to use Conduit or other networking libraries for asset management.

Finally, umm, there’s Nix, as always. :grinning:

===

But if you can get it working, and like it, it’s great. I think the developer has an idea of focusing on building a widget ecosystem; combined with Elm architecture, it seems to be extremely promising.

1 Like

It’s only for source distributions. You can’t really use that for packaged binaries.

Linux AppImage are quite good. You can build them from cabal and stack projects, embed all the dynamic libs you need, embed (or not!) assets and they don’t need any “package daemon” like snaps or flatpaks.

I’m working on what I hope can be my first library, “Kisevalter” (get it? Spymaster = Asset Manager). I got file-embed as a dependency, built so far a function on top of it to package a Traversable of name-data pairs into top-level definitions, am about to work on getting it to convert a Traversable into a map of name-pair definitions, then utilities for Sha512, asset file propagation and confirmation, web download and confirmation, and so on.

It’s pretty babyish and smelly, but if you’re working with libraries intended to be accessible, you’ll get users who don’t get Crypton, can’t use Template Haskell, and so on.

I use something like that in my engine:

-- that traversable collection
data Collection a = Collection
  { base     :: Base.Collection a -- can be nested
  , milkyway :: a
  }
  deriving stock (Show, Functor, Foldable, Traversable, Generic1)
  deriving Applicative via (Generically1 Collection) -- yay, haskell!

-- generate a bunch of patterns from an asset directory
Static.filePatterns Static.Files "data/cubemaps"

sources :: Collection Source
sources = Collection
  { base     = Base.sources -- delegate
  , milkyway = Source.File (Just "background") MILKYWAY_KTX2 -- use the patterns
  }

The sources can be a bit more flexible. And the collection itself can be generated too, with sources filled automatically.

But it works. And the loader is just traverse CubeMap.load sources :blush:

1 Like

so the gui toolkit I’m hoping to dig into using the haskell binding for is DearImgui, which is pretty declarative in its sheer simplicity

An interesting alternative that wasn’t talked about yet is gi-gtk-declarative by @owi.

Layered over the procedural bindings automatically generated by haskell-gi/gi-gtk, it offers a nice declarative interface to gtk.

Hiding a lot of Gtk idiosyncrasies (signals, properties, containers-children relationships woes…) behind pleasant functional alternatives, widgets trees declaration becomes quite elegant, if I must say so.
Furthermore, the App.Simple framework provides a very ELMy/Reacty interface to manage UI update on data update, user interactions or arbitrary Pipe producers events.
It’s the “classic” duo of (approximately, I don’t remember the specifics)

  • render/view: AppState → UI
  • update: AppState → MyAppEvent → AppState

It takes care of diffing the current UI state with a pseudo-virtual DOM (new properties values, new children…) and proceed with doing the dirty GTK work necessary to update the view behind the scene.

In practice, it looks like this.

You might have guessed from the tone of this comment, but my time with it was quite delightful. GTK is a mature multiplatform toolkit, and this interface makes it palatable.

Now, everything is not perfect; the library isn’t maintained anymore and only supports GTK3, not the latest GTK4. Also need some fiddling to build with recent GHC. Not having the knowledge and time to contribute then, I reluctantly switched the frontend of a project to relm4, a similar Rust library.

With some guidance (wink wink @owi), I’d gladly try to help with a port to gtk4 and recent compiler.

Anyway, if you are okay with gtk3, it is worth investigating!

4 Likes

Ummm, I can’t get it to run with recent GHCs with cabal. I think it should work on stack, but from what I’ve heard from other GUI nuts, it’s out of maintenance.

If you want to port it and get it working out of the box, and if @fjvallarino doesn’t come back, you’ll probably own the “easy, minimum declarative GUI” space.

1 Like

If you use nix or NixOS, a ‘nix-shell’ should, after some time, put you in a working dev environment.
It will take a while, tho, as it depends on an old nixpkgs snapshot that isn’t binary-cached anymore. The whole ancient world (GHC 8.4 included) will be rebuilt before your eyes. Behold!
Porting to current toolchain/dependencies is a priority before looking at the GTK4 effort.

1 Like