Functional Programming

Functional Programming

Functional Programming

Nov 6, 2014

3.1 release changes

3.1 release changes

3.1 release changes

On September 28 we released 3.1 of the FP Complete public

services. We've discussed this a bit already, but in this blog

post, we want to share some of the more technical details of what

we've added.


Laundry list of features

We've added a whole bunch of new features to FP Haskell Center. Here are some of the most notable:

  • You can now access all features of the IDE for free

  • It's faster

  • More file type support: Literate Haskell, hs-boot, and C files

  • Git Shell allows you to run arbitrary Git commands on a fully interactive command line

  • In addition to GHCi runs of code, you can build and run binaries inside the IDE

  • Ability to pass arbitrary flags to deployment builds

  • View usages of an identifier

  • Better support for Template Haskell-included files (like Hamlet)

  • Modified data files immediately appear to your application (good for modifying a CSS file in a web app, for example)

  • Better session management, including logging out of all sessions

  • School of Haskell supports autorun and Disqus comments

Keep reading for a drill down of some of this list. And for some

lower-level, GHC-facing bits of our work, jump

ahead to the "faster" sections.


Open Publish model

As

announced previously, we've decided to make FP Haskell Center

even more open. Since our 3.1 release, all IDE features are turned

on for all users, with and without a paid account.


The new FPHC terms & conditions no longer restrict the free

community version to non commercial use. Even anonymous users can

access the full spread of features in the IDE, from type checking

to executable generation, and even Git repositories (though you'll

definitely want to log in to be able to use that properly).


There are two distinctions between our community and paid licenses now:

  • Commercial licenses provide more compute power.

  • Under community licenses, all commits made in the IDE will be

    published. Similar to the GitHub model, free projects are open

    projects. You'll need a commercial license for private projects,

    which can still be acquired by contacting FP

    Complete Sales. So now when you commit, you'll see this

    message:


    Committed changes are public

    Any new commits are now made public and will make your project

    public. Existing private projects will not be published until you

    make a new commit.


    NOTE: If you have an existing project with commits, it will remain private until your next commit.

Additionaly, there are now no restrictions on how you license

your published code. This means that although you give others the

right to view your published code, they receive no implicit license

to distribute your code or use it in derived works. You can still

explicitly license your code under an open source license if you

choose.


Autorun active code samples

Based on feedback (mainly from Edward Kmett), there's a new

directive in the code fence syntax in School of Haskell posts,

which will auto-run the code snippet when the page loads. This will

be especially nice for showing graphical web pages or to begin an

interactive process. The code is written as:


``` haskell active autorun
main = print "Hello, World!"
```

School of Haskell improvements

The School of Haskell now supports adding Disqus comments to your own tutorials (yet again suggested by Ed).

To enable this, go into your account settings under “Profile” and you can choose:

☑ Use site default (currently: no comments)

☐ Disable comments

☐ Use FP Complete's Disqus account

☐ Use your own Disqus account

Disqus account ID: [ ]

To use your own Disqus account, hit the “Use your own Disqus

account” checkbox and put your account id in the box. Then go into

your Disqus site settings under the “Advanced” tab and add

fpcomplete.com under the “Trusted Domains” text box.


GHC 7.8, new libraries

We've updated our default compiler version to GHC 7.8. We still

provide a 7.4 environment, but it is considered deprecated, and we

recommend users upgrade to 7.8. In addition, as usual, we've

updated our library set to the newest versions of upstream

packages, and will begin releasing unstable package snapshots next

month.


Defer type errors

Together with GHC 7.8 come some new compiler features. For the

most part, these are simply available to you without any IDE

support. We added one nifty feature though: You can now defer type

errors using the checkbox in the Messages tab:


☑ Enable suggestions ☑ Enable warnings ☑ Defer type errors

This will change type errors into warnings which are instead

thrown at runtime. A very useful way to keep getting type

information when you have a simple type error elsewhere in the

code.


This plays in very nicely with the new Type Holes feature. Now you can program Python in Haskell!

Improved root & filtering

In the “Root & Filtering” tab in Settings, there is a way to

change the root directory of your project, this is similar to doing

a cd in your terminal. This is useful if you have

several projects in one repository and you want to just compile the

modules within one directory, rather than everything in the whole

repository.


You can also ignore certain files using the blacklist input, e.g. src/Main.hs will hide that file from the list. This can be useful for hiding things from compilation.

This feature is still considered experimental.

Faster

You should notice a definite improvement in responsive in the

IDE. We've actually implemented many different changes to make this

happen. Our network communication layer, for example, has less

overhead involved, by removing some unnecessary parsing from our

reverse proxy machines. We've also refactored quite a bit of our

async architecture to provide better concurrency for backend

actions.


However, the biggest change comes to how we interact with GHC. We use GHC for a few different things in the IDE:

  • Type checking code

  • Provide information on identifier locations, types, usages, etc

  • Generating and running bytecode

Those first two bullets dovetail together rather nicely, though

the second can take more time than the first. However, the third

point doesn't play so nicely with the other two. The issue is that,

while GHC is running the bytecode, it can't continue to

compile new code. And this is definitely something we want to

allow. For example, a common use case it running a web application

in the IDE, while continuing to hack on it while it's running in

the background.


Before the 3.1 release, our solution was to have three copies of

GHC running for each project: one to do a quick typecheck, one to

extract type information, and one for running code. This meant you

would get error messages quickly, but couldn't always get type

information right away. It also meant your project required much

more memory, which overall slowed things down.


Our new architecture involves just a single GHC process running

for each project. We load code into this process, and it

typechecks, extracts information, and generates bytecode, all at

the same time. The trick is what happens when you press run? We

would like to use the bytecode already available in the current GHC

process, without tying that process up on just running the

bytecode.


The solution we ended up at is calling forkProcess.

However, it wasn't quite as simple as that. To quote

forkProcess's documentation:


forkProcess comes with a giant warning: since any other running

threads are not copied into the child process, it's easy to go

wrong: e.g. by accessing some shared resource that was held by

another thread in the parent.


Sure enough, we ran into exactly this bug almost immediately.

And fortunately, we have some very good news to report: it's fixed!

You can see more information in GHC trac tickets 9295 and 9296

(and check Phabricator for some

great reaction gifs). These changes have been merged upstream into

GHC. Since writing those patches, we've stress tested our IDE

significantly, and have no longer been able to reproduce any

forkProcess bugs, which looks incredibly encouraging.


Note, though, that there are still some issues around forkProcess. If you're planning on using it in your

own code, you should be aware that you can still run into problems,

especially with multithreaded code.


One other change we made was switching to a dynamically linked

GHC process. We'd wanted to do this for a while due to improved

memory usage. Ultimately, we had to make the switch due to a bug in C static initializers. Now we get the nice benefit that separate

processes on the same machine can share memory space for their

dynamic libraries.