Haskell in the browser: setting up Yesod and Fay

20 maart 2014 - Door Cies Breijs  (2reacties)    Development

Credit: @bendangiffen

In this blog post I share my experiences with getting an example site up and running with Haskell, Yesod and Fay.

Why Haskell?

Developing and maintaining software is costly. Reducing those costs means that less is spent on development of the software and/or that it takes less to maintain it. In other words: there are great merits in increasing the efficiency of software development and maintenance. An important intangible benefit of this is that software developers love "to do more in less time, and to do it properly".

Haskell is a programming language that comes with in interesting set of features to make programmers more effective. Being a pure-functional programming language, it is quite different from the imperative and object-oriented languages (e.g.: C, C++, Java, Ruby, Python, PHP, Perl, JavaScript) that most programmers have prior experience with, and therefore it's often experienced as difficult. Yet the potential pay-off of being significantly more productive is attracting growing numbers give Haskell a try.

At Hoppinger we are currently evaluating how we can use Haskell to better serve our customers, with happier developers and smaller development budgets.

Yesod?

At Hoppinger we like web-frameworks; Symfony2 on PHP, Rails on Ruby... and Yesod on Haskell.

Yesod nicely brings the speed and type-safety of Haskell to the world of web application development, and features most of the conveniences that we have come to know and love from using Rails.

And... Fay?

Anyone who has developed serious in-browser applications with JavaScript —and has prior experience with general purpose programming languages— will be more-or-less acquainted to the JavaScript problem. Fay is a solution to that problem: it's a compiler that compiles a proper subset of Haskell to JavaScript. When combining this with a server-side web application written in Haskell, a developer can use a single language to develop modern web applications.

When using Fay it is possible to share code —such as data structures and templating functions— between the server-side and the client-side. This allows the type-checker to help developers to avoid whole categories of bugs when writing web applications. Fay has build in serialization/deserialization of Haskell data structures to/from JSON, which reliefs developers from creating and maintaining a significant amount of error-prone boilerplate code that is otherwise needed by most modern web applications.

Let's get it going...

The following guide should get a basic Yesod+Fay app started in development mode on any recent version of Ubuntu.

First make sure to be switched to the users that you want to use for development, and install Haskell Platform and cabal (which is, amongst other things, Haskell's package manager).

    sudo apt-get update
    sudo apt-get install haskell-platform

 

With the following command we can check the version of cabal.

    cabal -V

 

If this is not 1.18.x of larger we need to upgrade it with the following commands.

    cabal update
    cabal install Cabal cabal-install  # the library and the binary

 

At this point make sure ~/.cabal/bin is in your $PATH. You can do so with export ~/.cabal/bin:$PATH for your current session, or add it to your ~/.profile for all future sessions.

Now we're installing Yesod.

    cabal update && cabal install yesod-bin

 

Since the scaffold application also makes used of Postgres we need to install that too.

    sudo apt-get install libpq-dev postgresql

 

To avoid the "peer athentication error" do we need to fix the following config.

    sudo sed -Ei "s/^(local\s+all\s+all\s+)peer$/\1md5/" \
                 /etc/postgresql/9.1/main/pg_hba.conf

 

And finally create a user and database for this project.

    sudo -u postgres createuser -d -R -P \
              yesod-fay-example
    sudo -u postgres createdb -O \
              yesod-fay-example yesod-fay-example

 

Next is to initialize (scaffold) a new Yesod project. To do so go to the directory you want it to be created in (~/repos in my case).

    cd ~/repos

 

Now run the interactive yesod init command. Set the project name to yesod-fay-example and choose the pf (Postgress+Fay) app scaffold.

    yesod init

 

Next is installing (downloading and compiling) all the projects dependencies into a cabal sandbox. Cabal provides sandboxes as a way to localize packages to a project; this to avoid conflicting dependencies when working on several projects concurrently.

    cd yesod-fay-example
    cabal sandbox init
    cabal install --enable-tests --max-backjumps=-1 \
                  --reorder-goals \
                  . yesod-platform yesod-bin fay-base

 

We need to set an environment variable to point to the right path in the local sandbox directory. This is workaround needed up to cabal version 1.20.

    export HASKELL_PACKAGE_SANDBOX=`echo .cabal-sandbox/*conf.d/`

 

That was it. You should be able to get your development environment up and running with the following command.

    yesod devel

 

When pointing your browser to http://localhost:3000 you should be able to see the scaffolded site in action.

The example site with some compiled Haskell code from a browser

 It is minimal, but (for me) it works... And from here I was able to extend it into a larger application.

 

Conclusion

When looking at the code in the project directory we can observe several interesting things:

  • Code that will run in the browser will located in the fay/ directory. This gets compiled to JavaScript. Take note of the foreign function interface code (the ffi functions). On Fay's Github page you find several bindings to popular JavaScript libraries (e.g.: jQuery, Angular).
  • In the fay-shared/ directory you find code that is shared between the server-side and the browser-side of the app. This allows us to have type-safety that spans over the entire app. In the scaffold only the GetFib command is defined.
  • A special handler function, Handler/Fay.hs, for request from Fay code is defined; and in config/routes we see it is bound to the /fay-command url path. In this handler the readFromFay function is used to parse serialized (JSON) requests back to Haskell types.

While this guide shows how little is involved in getting Yesod and Fay up and running, it is possible to get started with just Yesod much faster. The company FPComplete has a web-base IDE named Haskell Center (demo video) for which you do not have to install any software at all -- and it has a community edition which is free. But at this moment it is not possible (yet) to use Fay on this platform.

Fay is not the only way to run Haskell in the browser, there are more roads to Rome. Another interesting approach —that I yet have to look at more closely— is Haste. When I have some experience with this I will certainly write another blog on it.

Image credit: Bendan Giffen (@bendangiffen). It shows data harvested from Wikipedia on the influences that programming languages have on each other. Whilst relatively unknown Haskell is shown to have been very influential thus far.

2 reacties op “Haskell in the browser: setting up Yesod and Fay

  1. Alain O'Dea

    I think @snoyberg recommends “yesod-platform” rather than “yesod-bin” to sidestep possible dependency issues.

  2. Cies Breijs Post author

    As you can see I also install yesod-platform (right before yesod-bin). Yet yesod-platform has no dependency on yesod-bin; understandible as yesod-bin is no runtime dependency as it is only used to initialize (scaffold) a new Yesod project into existance.

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

*

*

De volgende HTML-tags en -attributen zijn toegestaan: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>