Hacker News new | past | comments | ask | show | jobs | submit login
Making a GTK Video Player with Haskell (lettier.github.io)
183 points by lettier on Sept 3, 2017 | hide | past | favorite | 39 comments



Very nice project keep going, would love to see more haskell projects arising from this. Code related: I'm by no means an haskell expert, but your main function in Main.hs looks a bit lengthy, usually i dont see haskell methods with 50+ lines, might be better to split them up and provide names for subfunctions.


The main function would read pretty much the same in any language. Slicing it into multiple functions doesn't really do anything that couldn't be achieved by adding a few comments.

I guess Haskell just doesn't do much to solve the problem of setting up GUIs, at least when it has to interface with a framework like Gtk+.


The GTK bindings it uses are pretty low level overall -- e.g. dealing with ManagedPtr's and whatnot. You could probably make it nicer and easier to read, at least, if you spent some time wrapping a few of those UI bindings with a couple data types and helpers, made it a little nicer, etc.

Overall there's going to be some unavoidable "setup gunk" though. You could make some of the code nicer, but the application is pretty small. For such a small little thing, I think abstracting away any further might end up in too much fluff, anyway.


The main function is 111 lines long but only roughly 30 lines of that are setup up code. The remaining 81 lines are the business logic that happens when a control has been interacted with.

Since when does initialising the GUI framework include all of your business logic and if it does should a non trivial application have a main function that is several thousands of lines long?


If you have good function names, you do not need comment.


If your imperative code is readable and well-commented, why break it up into single-use functions?


To expose state. I haven't actually read the code, but since you asked a really good question, I thought I would answer it generically :-)

Extract method is probably one of the most abused refactoring patterns around. As you correctly point out, there is no benefit for extracting single use functions and then leaving the code like that. It's just trading one set of notation (function names) for another (comments), while at the same time allowing you to confusingly arrange the code out of execution order.

You want to extract functions in order to reason about execution. You do this by exposing state in the form of the return values from the functions you have created. Whether you write unit tests, or (in a language like Haskell) use it to enforce type contracts, the point is that you have a tool for detecting when the inputs and outputs aren't matching up. This allows you to much more quickly zero in on defects.

There are a couple of caveats with this. First, some people read code linearly no matter what they are doing. Especially programmers without much experience often play computer (with or without a debugger) instead of reasoning using larger abstractions. Quite frequently the benefit of factoring code is lost because of this. It's important to understand the techniques that your team uses before you stick the code in the proverbial food processor.

Secondly, the main benefit of this kind of access is when you are restructuring code. The idea is that (to paraphrase Micheal Feathers) you put some of the code in a kind of vice, while you move the other code around. By exposing state, you can detect when the code you put in the vice starts to slip around. Many, many, many teams do little or no refactoring/restructuring of code. Some teams even have rules for limiting edits, because they feel that this will reduce breakage. On such teams, the effort of exposing state will be worthless.


So that developers can hold the entire state of the function in their head.

It doesn't seem to be the case here as it's mostly setting up callback methods according to my limited understanding of haskell.


Comments about why you are doing things and the wider context can still be useful.


Agreed. Sometimes when a function really needs to do so many things (perhaps acting as a sort of glue code) I just put smaller functions in the `where` clause. But this does mean that code can be slightly harder to read because the bindings in the where clause can refer to each other.


Is there any fully formed application made with Haskell out there?


Pandoc, the "universal document converter", is a good example of a large, feature-complete Haskell project in wide use.

https://pandoc.org/

Most people who use it aren't aware it's written in Haskell!



Those are languages


The Elm and Purescript compilers are written in Haskell though.


The examples mentioned in the other posts confirm my impression that Haskell is a good language for text processing and server applications but a pain for writing rich desktop applications.

One of the things I miss in Haskell is a way to compile to C, and a convenient declarative GUI which also compiles to C so that all code can be linked together, and distributed as a single binary. The GUI doesn't need to be native. Lisp has its own GUI (McCLIM), Smalltalk has one (Squeak), Rust has one (Conrod), why not Haskell?


I'm currently playing with Reflex, a wonderful functional reactive programming library that lets you compile the same code into into webapps with GHCJS (a JavaScript backend for GHC) or into standalone desktop apps (using WebKitGTK).

It's wonderfully expressive and doesn't feel like you're painfully imitating C++ in Haskell. On the contrary, it's very idiomatic.

https://github.com/reflex-frp/reflex

However, FRP is ... unusual, and takes a bit of time to get the hang of.

Here's a stripped-down todo app "tutorial" in Reflex:

https://gist.github.com/mrkgnao/1a5c06cc1e188f2238c8c11cb74e...

And this is a full-featured TodoMVC in Reflex:

https://github.com/reflex-frp/reflex-todomvc

--

FLTK is a GUI toolkit that has Haskell bindings. It's a very C++-like API, but the library is in heavy development.

https://github.com/deech/fltkhs

The developer is also quite friendly, and I believe there are good docs. Here are a few demos:

https://github.com/deech/fltkhs-demos

Also, GHC does have a C backend, afaik, although it's deprecated nowadays and only available if you build it yourself in "unregisterised mode", which people do when porting GHC to a new architecture.


Red uses DSL's to make it pretty easy. It's a REBOL-like language that's easy to parse and macro kind of like LISP. Here's an early demo of how that looks with examples:

http://www.red-lang.org/2016/03/060-red-gui-system.html

I don't know Haskell but I know Galois does DSL's like Ivory language with it. So, I imagine doing something like Red's GUI in Haskell would be worth exploring. Alternatively, building such a clean abstraction on top of a cross-platform library with messy stuff generated automatically from DSL version.


Most rich desktop APIs are very imperative and the Haskell bindings are often just a thin veneer on top. For an example of a really nice Haskell UI API, see threepenny-gui:

https://github.com/HeinrichApfelmus/threepenny-gui/blob/mast...


I think pretty much any Language is a pain to write GUIs in, a single property dialogue in photoshop is ~6k loc in C++...


Pascal (Delphi, Lazarus) and Visual Basic are exact counter examples. They demonstrate how easy and convenient GUI development can be.


I really hope I'm wrong, but if you're talking about VB.NET, then my personal experience with it has been the exact opposite of easy and convenient.

Edit: Okay, good, VB.NET is probably not the Visual Basic you were talking about. Thanks for the history lesson!


Why would some ridiculous plug in API mean that every language is a pain to write GUIs in?


To be fair. Good desktop applications pretty much require teams and are more about user acceptance than metrics you can capture in the type system. Or tests.


Besides the example stated here, there is also shellcheck: https://www.shellcheck.net/


GPU Database SQream DB's (http://www.sqream.com) main component is Haskell based, in two parts:

1. The open source SQL parser - HsSqlPpp https://github.com/jakewheat/hssqlppp, 35700 LOC + 3900 LOC of tests

2. The compiler and optimizer (proprietary) is roughly 55,000 Haskell LOC

Edit: And we use Pandoc and Quickcheck internally for a bunch of different things


Besides pandoc: xmonad, hledger, git annex, gitit, hakyll and probably quite a few more ;)


People have mentioned a few here, but I'd say that Haskell's current ecosystem is much more directed towards building infrastructure than user-facing apps. Indeed, most popular Haskell programs are command-line utilities rather than "applications" in the modern sense. Most companies that use Haskell also use it to make robust infrastructure rather than, say, user-facing apps or webpages.

I think it's hard to find many modern applications (I.e. some software package with a UI) made in anything outside of a few choice languages like JS, C++, C#, or Swift.


https://www.quora.com/What-is-the-largest-commercial-program...

I implemented a fractal zoomer, but it might be too simple to meet your vague "fully formed": https://github.com/serprex/Fractaler


llpp, depending on your definition of "fully formed".

And there is/was a tiling window manager, but everyone I know who used it at some point migrated away because the configuration was Haskell as well.


Xmonad!

Still use it with gnome and it's the only reason I can half read Haskell!


llpp is (mostly) written in OCaml.


still using it. only tiling wm I've found that plays well with desktop environments.


Pandoc, I use that heavily for homework.



I was hoping this would include an efficient H 265 decoder written in Haskell. That would have been neat.


That's not really a one month project... and most platforms will rely on hardware decoding anyway.


I didn't read it but figured it was just using a combination of GTK and ffmpeg or something. There's really nothing special here unless you're a fan of haskel looking for some validation of your language choice.


here are some related programs

https://wiki.haskell.org/Manatee




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: