News aggregator

Douglas M. Auclair (geophf): June 2016 1HaskellADay Problems and Solutions

Planet Haskell - Fri, 07/01/2016 - 10:56am
  • June 29th, 2016: Today's #Haskell exercise is REALLY HARD! ... for Big Gov't. Can you solve it? A little bit of (well-typed) Prolog-like code gets us our #haskell solution for today 
  • June 28th, 2016: For today's #haskell problem we do ... NOTHING! But we are introduced to coding software for a huge bureaucracy  ... AAAAANNNDDD three System imports and we've got today's #haskell solution. Groovy! 
  • June 24th, 2016: #haskell problem today charts Stochastic Oscillators of a security  and includes a 'malus' problem: report generation 
  • June 23rd, 2016: Today we look at using #haskell to chart moving averages of a stock's prices https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D23/Exercise.hs https://twitter.com/logicalgraphs/status/743409829843243008 
  • June 21th, 2016: I pushed today's #haskell problem last night on git but did I announce it? sigh Complex roots of quadratic equations https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D21/Exercise.hs The #haskell solution gives us the Complex roots to any (Real) quadratic equation https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D21/Solution.hs
  • June 20th, 2016: Solving quadratic equations is on the plate for today's #haskell exercise https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D20/Exercise.hs It's not every day I code[formula] <*> [(-),(+)] <*> [q]Thank you, #haskell, for today's solution to do sohttps://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D20/Solution.hs
  • June 17th, 2016: My, my! Where has the day flown? Today's #haskell problem is to reinvent charting API! ... or not. https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D17/Exercise.hs
  • June 16th, 2016: Today's #haskell exercise looks at representing $TWTR data as candlesticks https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D16/Exercise.hs 
  • June 15th, 2016: For today's #haskell problem, we round out the Data.Matrix module with the definition of the identity matrix https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D15/Exercise.hs There are many ways to define the identity matrix. Today's #haskell solution does so with Cellular Automata Rule 16 https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D15/Solution.hs
  • June 14th, 2016: Yesterday we computed the matrix determinant, today we'll invert a matrix and use it to solve systems of equations https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D14/Exercise.hs Today's #haskell solution inverts a matrix BECAUSE WE FEEL LIKE IT! Yeah https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D14/Solution.hs
  • June 13th, 2016: For today's #haskell problem we *ahem* DETERMINE (eventually) to solve systems of equations https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D13/Exercise.hs The determinant is the sum of the products of the first row with the sub-matrix determinants, right? RIGHT! https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D13/Solution.hs
  • June 10th, 2016: Today's #haskell problem looks at box-and-whiskers charting of data https://github.com/geophf/1HaskellADay/blob/master/exercises/HAD/Y2016/M06/D10/Exercise.hs Boxes for realz, yo: https://en.wikipedia.org/wiki/Box_plot The #haskell solution has @geophf writing 'uncurry uncurry' and sincerely meaning it!
Categories: Offsite Blogs

Call for Papers: 2nd IEEE European Symposium on Security and Privacy (EuroS&P), April 26-28, 2017 in Paris

General haskell list - Fri, 07/01/2016 - 9:26am
===================================================================== IEEE EuroS&P 2017 Call for Papers ===================================================================== Since 1980, the IEEE Symposium on Security and Privacy has been the premier forum for presenting developments in computer security and electronic privacy. Following this story of success, IEEE initiated the European Symposium on Security and Privacy (EuroS&P), which is organized every year in a European city. The 2nd EuroS&P symposium will be held on April 26-28, 2017 in Paris. Dan Boneh will give a keynote speech on Thursday, April 27. For more information see below and on the official conference website: http://www.ieee-security.org/TC/EuroSP2017/ HIGHLIGHTS THIS YEAR ===================================================================== Keynote speaker: Dan Boneh, Stanford University Systematization of Knowledge (SoK) Track (new) Best Paper Award (new) Symposium held just before EUROCRYPT 2017 (also in central Paris)
Categories: Incoming News

Mark Jason Dominus: Don't tug on that, you never know what it might be attached to

Planet Haskell - Fri, 07/01/2016 - 9:00am

This is a story about a very interesting bug that I tracked down yesterday. It was causing a bad effect very far from where the bug actually was.

emacsclient

The emacs text editor comes with a separate utility, called emacsclient, which can communicate with the main editor process and tell it to open files for editing. You have your main emacs running. Then somewhere else you run the command

emacsclient some-files...

and it sends the main emacs a message that you want to edit some-files. Emacs gets the message and pops up new windows for editing those files. When you're done editing some-files you tell Emacs, by typing C-# or something, it it communicates back to emacsclient that the editing is done, and emacsclient exits.

This was more important in the olden days when Emacs was big and bloated and took a long time to start up. (They used to joke that “Emacs” was an abbreviation for “Eight Megs And Constantly Swapping”. Eight megs!) But even today it's still useful, say from shell scripts that need to run an editor.

Here's the reason I was running it. I have a very nice shell script, called also, that does something like this:

  • Interpret command-line arguments as patterns
  • Find files matching those patterns
  • Present a menu of the files
  • Wait for me to select files of interest
  • Run emacsclient on the selected files

It is essentially a wrapper around menupick, a menu-picking utility I wrote which has seen use as a component of several other tools. I can type

also Wizard

in the shell and get a menu of the files related to the wizard, select the ones I actually want to edit, and they show up in Emacs. This is more convenient than using Emacs itself to find and open them. I use it many times a day.

Or rather, I did until this week, when it suddenly stopped working. Everything ran fine until the execution of emacsclient, which would fail, saying:

emacsclient: can't find socket; have you started the server?

(A socket is a facility that enables interprocess communication, in this case between emacs and emacsclient.)

This message is familiar. It usually means that I have forgotten to tell Emacs to start listening for emacsclient, by running M-x server-start. (I should have Emacs do this when it starts up, but I don't. Why not? I'm not sure.) So the first time it happened I went to Emacs and ran M-x server-start. Emacs announced that it had started the server, so I reran also. And the same thing happened.

emacsclient: can't find socket; have you started the server? Finding the socket

So the first question is: why can't emacsclient find the socket? And this resolves naturally into two subquestions: where is the socket, and where is emacsclient looking?

The second one is easily answered; I ran strace emacsclient (hi Julia!) and saw that the last interesting thing emacsclient did before emitting the error message was

stat("/mnt/tmp/emacs2017/server", 0x7ffd90ec4d40) = -1 ENOENT (No such file or directory)

which means it's looking for the socket at /mnt/tmp/emacs2017/server but didn't find it there.

The question of where Emacs actually put the socket file was a little trickier. I did not run Emacs under strace because I felt sure that the output would be voluminous and it would be tedious to grovel over it.

I don't exactly remember now how I figured this out, but I think now that I probably made an educated guess, something like: emacsclient is looking in /mnt/tmp; this seems unusual. I would expect the socket to be under /tmp. Maybe it is under /tmp? So I looked under /tmp and there it was, in /tmp/emacs2017/server:

srwx------ 1 mjd mjd 0 Jun 27 11:43 /tmp/emacs2017/server

(The s at the beginning there means that the file is a “Unix-domain socket”. A socket is an endpoint for interprocess communication. The most familiar sort is a TCP socket, which has a TCP address, and which enables communication over the internet. But since ancient times Unix has also supported Unix-domain sockets, which enable communication between two processes on the same machine. Instead of TCP addresses, such sockets are addressed using paths in the filesystem, in this case /tmp/emacs2017/server. When the server creates such a socket, it appears in the filesystem as a special type of file, as here.)

I confirmed that this was the correct file by typing M-x server-force-delete in Emacs; this immediately caused /tmp/emacs2017/server to disappear. Similarly M-x server-start made it reappear.

Why the disagreement?

Now the question is: Why is emacsclient looking for the socket under /mnt/tmp when Emacs is putting it in /tmp? They used to rendezvous properly; what has gone wrong? I recalled that there was some environment variable for controlling where temporary files are put, so I did

env | grep mnt

to see if anything relevant turned up. And sure enough there was:

TMPDIR=/mnt/tmp

When programs want to create tmporary files and directories, they normally do it in /tmp. But if there is a TMPDIR setting, they use that directory instead. This explained why emacsclient was looking for /mnt/tmp/emacs2017/socket. And the explanation for why Emacs itself was creating the socket in /tmp seemed clear: Emacs was failing to honor the TMPDIR setting.

With this clear explanation in hand, I began to report the bug in Emacs, using M-x report-emacs-bug. (The folks in the #emacs IRC channel on Freenode suggested this. I had a bad experience last time I tried #emacs, and then people mocked me for even trying to get useful information out of IRC. But this time it went pretty well.)

Emacs popped up a buffer with full version information and invited me to write down the steps to reproduce the problem. So I wrote down

% export TMPDIR=/mnt/tmp % emacs

and as I did that I ran those commands in the shell.

Then I wrote

In Emacs: M-x getenv TMPDIR (emacs claims there is no such variable)

and I did that in Emacs also. But instead of claiming there was no such variable, Emacs cheerfully informed me that the value of TMPDIR was /mnt/tmp.

(There is an important lesson here! To submit a bug report, you find a minimal demonstration. But then you also try the minimal demonstration exactly as you reported it. Because of what just happened! Had I sent off that bug report, I would have wasted everyone else's time, and even worse, I would have looked like a fool.)

My minimal demonstration did not demonstrate. Something else was going on.

Why no TMPDIR?

This was a head-scratcher. All I could think of was that emacsclient and Emacs were somehow getting different environments, one with the TMPDIR setting and one without. Maybe I had run them from different shells, and only one of the shells had the setting?

I got on a sidetrack at this point to find out why TMPDIR was set in the first place; I didn't think I had set it. I looked for it in /etc/profile, which is the default Bash startup instructions, but it wasn't there. But I also noticed an /etc/profile.d which seemed relevant. (I saw later that the /etc/profile contained instructions to load everything under /etc/profile.d.) And when I grepped for TMPDIR in the profile.d files, I found that it was being set by /etc/profile.d/ziprecruiter_environment.sh, which the sysadmins had installed. So that mystery at least was cleared up.

That got me on a second sidetrack, looking through our Git history for recent changes involving TMPDIR. There weren't any, so that was a dead end.

I was still puzzled about why Emacs sometimes got the TMPDIR setting and sometimes not. That's when I realized that my original Emacs process, the one that had failed to rendezvous with emacsclient, had not been started in the usual way. Instead of simply running emacs, I had run

git re-edit

which invokes Git, which then runs

/home/mjd/bin/git-re-edit

which is a Perl program I wrote that does a bunch of stuff to figure out which files I was editing recently and then execs emacs to edit them some more. So there are several programs here that could be tampering with the environment and removing the TMPDIR setting.

To more accurately point the finger of blame, I put some diagnostics into the git-re-edit program to have it print out the value of TMPDIR. Indeed, git-re-edit reported that TMPDIR was unset. Clearly, the culprit was Git, which must have been removing TMPDIR from the environment before invoking my Perl program.

Who is stripping the environment?

To confirm this conclusion, I created a tiny shell script, /home/mjd/bin/git-env, which simply printed out the environment, and then I ran git env, which tells Git to find git-env and run it. If the environment it printed were to omit TMPDIR, I would know Git was the culprit. But TMPDIR was in the output.

So I created a Perl version of git-env, called git-perlenv, which did the same thing, and I ran it via git perlenv. And this time TMPDIR was not in the output. I ran diff on the outputs of git env and git perlenv and they were identical—except that git perlenv was missing TMPDIR.

So it was Perl's fault! And I verified this by running perl /home/mjd/bin/git-re-edit directly, without involving Git at all. The diagnostics I had put in reported that TMPDIR was unset.

WTF Perl?

At this point I tried getting rid of get-re-edit itself, and ran the one-line program

perl -le 'print $ENV{TMPDIR}'

which simply runs Perl and tells it to print out the value of the TMPDIR environment variable. It should print /mnt/tmp, but instead it printed the empty string. This is a smoking gun, and Perl no longer has anywhere to hide.

The mystery is not cleared up, however. Why was Perl doing this? Surely not a bug; someone else would have noticed such an obvious bug sometime in the past 25 years. And it only failed for TMPDIR, not for other variables. For example

FOO=bar perl -le 'print $ENV{FOO}'

printed out bar as one would expect. This was weird: how could Perl's environment handling be broken for just the TMPDIR variable?

At this point I got Rik Signes and Frew Schmidt to look at it with me. They confirmed that the problem was not in Perl generally, but just in this Perl. Perl on other systems did not display this behavior.

I looked in the output of perl -V, which says what version of Perl you are using and which patches have been applied, and wasted a lot of time looking into CVE-2016-2381, which seemed relevant. But it turned out to be a red herring.

Working around the problem, 1.

While all this was going on I was looking for a workaround. Finding one is at least as important as actually tracking down the problem because ultimately I am paid to do something other than figure out why Perl is losing TMPDIR. Having a workaround in hand means that when I get sick and tired of looking into the underlying problem I can abandon it instantly instead of having to push onward.

The first workaround I found was to not use the Unix-domain socket. Emacs has an option to use a TCP socket instead, which is useful on systems that do not support Unix-domain sockets, such as non-Unix systems. (I am told that some do still exist.)

You set the server-use-tcp variable to a true value, and when you start the server, Emacs creates a TCP socket and writes a description of it into a “server file”, usually ~/.emacs.d/server/server. Then when you run emacsclient you tell it to connect to the socket that is described in the file, with

emacsclient --server-file=~/.emacs.d/server/server

or by setting the EMACS_SERVER_FILE environment variable. I tried this, and it worked, once I figured out the thing about server-use-tcp and what a “server file” was. (I had misunderstood at first, and thought that “server file” meant the Unix-domain socket itself, and I tried to get emacsclient to use the right one by setting EMACS_SERVER_FILE, which didn't work at all. The resulting error message was obscure enough to lead me to IRC to ask about it.)

Working around the problem, 2.

I spent quite a while looking for an environment variable analogous to EMACS_SERVER_FILE to tell emacsclient where the Unix-domain socket was. But while there is a --socket-name command-line argument to control this, there is inexplicably no environment variable. I hacked my also command (responsible for running emacsclient) to look for an environment variable named EMACS_SERVER_SOCKET, and to pass its value to emacsclient --socket-name if there was one. (It probably would have been better to write a wrapper for emacsclient, but I didn't.) Then I put

EMACS_SERVER_SOCKET=$TMPDIR/emacs$(id -u)/server

in my Bash profile, which effectively solved the problem. This set EMACS_SERVER_SOCKET to /mnt/tmp/emacs2017/server whenever I started a new shell. When I ran also it would notice the setting and pass it along to emacsclient with --socket-name, to tell emacsclient to look in the right place. Having set this up I could forget all about the original problem if I wanted to.

But but but WHY?

But why was Perl removing TMPDIR from the environment? I didn't figure out the answer to this; Frew took it to the #p5p IRC channel on perl.org, where the answer was eventually tracked down by Matthew Horsfall and Zefrem.

The answer turned out to be quite subtle. One of the classic attacks that can be mounted against a process with elevated privileges is as follows. Suppose you know that the program is going to write to a temporary file. So you set TMPDIR beforehand and trick it into writing in the wrong place, possibly overwriting or destroying something important.

When a program is loaded into a process, the dynamic loader does the loading. To protect against this attack, the loader checks to see if the program it is going to run has elevated privileges, say because it is setuid, and if so it sanitizes the process’ environment to prevent the attack. Among other things, it removes TMPDIR from the environment.

I hadn't thought of exactly this, but I had thought of something like it: If Perl detects that it is running setuid, it enables a secure mode which, among other things, sanitizes the environment. For example, it ignores the PERL5LIB environment variable that normally tells it where to look for loadable modules, and instead loads modules only from a few compiled-in trustworthy directories. I had checked early on to see if this was causing the TMPDIR problem, but the perl executable was not setuid and Perl was not running in secure mode.

But Linux supports a feature called “capabilities”, which is a sort of partial superuser privilege. You can give a program some of the superuser's capabilities without giving away the keys to the whole kingdom. Our systems were configured to give perl one extra capability, of binding to low-numbered TCP ports, which is normally permitted only to the superuser. And when the dynamic loader ran perl, it saw this additional capability and removed TMPDIR from the environment for safety.

This is why Emacs had the TMPDIR setting when run from the command line, but not when run via git-re-edit.

Until this came up, I had not even been aware that the “capabilities” feature existed.

A red herring

There was one more delightful confusion on the way to this happy ending. When Frew found out that it was just the Perl on my development machine that was misbehaving, he tried logging into his own, nearly identical development machine to see if it misbehaved in the same way. It did, but when he ran a system update to update Perl, the problem went away. He told me this would fix the problem on my machine. But I reported that I had updated my system a few hours before, so there was nothing to update!

The elevated capabilities theory explained this also. When Frew updated his system, the new Perl was installed without the elevated capability feature, so the dynamic loader did not remove TMPDIR from the environment.

When I had updated my system earlier, the same thing happened. But as soon as the update was complete, I reloaded my system configuration, which reinstated the capability setting. Frew hadn't done this.

Summary
  • The system configuration gave perl a special capability
  • so the dynamic loader sanitized its environment
  • so that when perl ran emacs,
  • the Emacs process didn't have the TMPDIR environment setting
  • which caused Emacs to create its listening socket in the usual place
  • but because emacsclient did get the setting, it looked in the wrong place
Conclusion

This computer stuff is amazingly complicated. I don't know how anyone gets anything done.

[ Addendum 20160709: Frew Schmidt has written up the same incident, but covers different ground than I do. ]

[ Addendum 20160709: A Hacker News comment asks what changed to cause the problem? Why was Perl losing TMPDIR this week but not the week before? Frew and I don't know! ]

Categories: Offsite Blogs

Edwin Brady: Elaborator Reflection: Extending Idris in Idris

Planet Haskell - Fri, 07/01/2016 - 3:48am

A new paper by David Christiansen and myself, to appear in ICFP 2016. Abstract:

Many programming languages and proof assistants are defined by elaboration from a high-level language with a great deal of implicit information to a highly explicit core language. In many advanced languages, these elaboration facilities contain powerful tools for program construction, but these tools are rarely designed to be repurposed by users. We describe elaborator reflection, a paradigm for metaprogramming in which the elaboration machinery is made directly available to metaprograms, as well as a concrete realization of elaborator reflection in Idris, a functional language with full dependent types. We demonstrate the applicability of Idris’s reflected elaboration framework to a number of realistic problems, we discuss the motivation for the specific features of its design, and we explore the broader meaning of elaborator reflection as it can relate to other languages.

You can get the PDF here.


Categories: Offsite Blogs

ICFP 2016 Student Research Competition: Call forSubmissions

haskell-cafe - Fri, 07/01/2016 - 3:20am
====================================================================== CALL FOR SUBMISSIONS SRC at ICFP 2016 Nara, Japan 18-24 September 2016 http://conf.researchr.org/info/icfp-2016/student-research-competition Co-located with the International Conference on Functional Programming (ICFP 2016) ====================================================================== Student Research Competition ---------------------------- This year ICFP will host a Student Research Competition where undergraduate and postgraduate students can present posters. The SRC at ICFP 2016 consists of three rounds: * Extended abstract round. All students are encouraged to submit an extended abstract of up to 800 words outlining their research. * Poster session. Based on the abstracts, a panel of judges will select the most promising entrants to participate in the poster session which will t
Categories: Offsite Discussion

Deadline extended: Commercial Users of Functional Programming Call For Tutorials

haskell-cafe - Fri, 07/01/2016 - 3:11am
The 2016 Commercial Users of Functional Programming (CUFP) call for tutorials have passed the initial deadlines, but we have more seat for tutors. CUFP tutorial is a good opportunity if you have some idea you want to spread to the real world, say, your favorite programming language (Clojure, Erlang, F#, F*, Haskell, ML, OCaml, Scala, Scheme...), concepts (e.g. Lens, Liquid-Haskell, Proof Assistance, ...), applications (Web, high-performance computing, finance...,) tools and techniques (QuickCheck, Elm, ...), or theories. If you are interested, we kindly invite you to submit a proposal for the Call For Tutorials from here: http://cufp.org/2016/call-for-tutorials.html , before July 3rd. If you have any questions, please do not hesitate to contact us: Roman Gonzalez: roman< at >unbounce.com Takayuki Muranushi: muranushi< at >gmail.com best regards, Takayuki _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-b
Categories: Offsite Discussion

Packaging a library with a separate shared object

haskell-cafe - Fri, 07/01/2016 - 12:03am
Hi folks! I'm working on packaging Qtah (my Qt bindings) for upload to Hackage. This is somewhat complicated, as I have some C++ glue code that I build into a shared library that the Haskell library needs. Currently, my build hooks are as follows, in: https://gitlab.com/khumba/qtah/blob/packaging/qtah/Setup.hs - postConf: Generate Haskell code in src/ and C++ code in cpp/. - preBuild: Add cpp/ to HookedBuildInfo.extraLibDirs because the build phase needs this needs this. - buildHook: Run make to build the C++ code into libqtah.so before the Haskell code builds. - copyHook and instHook: Copy libqtah.so into InstallDirs.libdir (~/.cabal/lib/.../qtah-*/). This installs successfully, but ultimately doesn't work because the Haskell libHSqtah*.so that gets built can't find libqtah.so. The installation directory ~/cabal/lib/.../qtah-*/ isn't on libHSqtah*.so's RUNPATH (which makes sense, it's not known at link time). I could create a separate package for the C++ bits, but I'd rather not do that unles
Categories: Offsite Discussion

Christoph Breitkopf: Averaging unsigned numbers in Haskell

Planet Haskell - Thu, 06/30/2016 - 11:45pm
In performance sensitive code I needed the average of two unsigned shorts: uavg :: Word16 -> Word16 -> Word16 uavg a b = ... The naive implementation (a + b) `shiftR` 1 does not work if the addition overflows.

In a language with a less disciplined type systen, such as C, I'd probably have used a higher-precision type to hold the intermediate sum:

unsigned short uavg(unsigned short a, unsigned short b) { return (unsigned short) (((unsigned) a + b) >> 1); } But because numeric type conversion in Haskell is rather intrusive, I used the following code: uavg a b = (a `shiftR` 1) + (b `shiftR` 1) + (a .&. b .&. 1) That is correct and has no problems with overflow.

What I overlooked at this point is performance. At first glance, the code looks fast: it does no type conversion and uses only very fast operations. But that first look is deceiving. If you count operations, this version has 6 ops, and the type-cast version only 2. Even if you count the type conversions as operations, you still end up with only 5 ops.

So I ended up with this Haskell version of the C code above:

uavg a b = let a',b' :: Word a' = fromIntegral a b' = fromIntegral b in fromIntegral ((a' + b') `shiftR` 1) To me, this looks slower, probably because the fromIntegral's take as much space as the rest of the code combined. But it turns out to be at least twice as fast as the bit-twiddling version (on x64 at least).

Now, how to get the same performance with a more generic type signature?

Categories: Offsite Blogs

Announcing Blocks for CodeWorld

haskell-cafe - Thu, 06/30/2016 - 9:10pm
Hi everyone, (this is somewhat cross-posted from reddit) I'm announcing Blocks for CodeWorld, which is a functional based drag-and-drop programming environment. The project is part of Haskell Summer of Code. The aim of the project is to create a web application with which users can drag-and-drop blocks in order to create CodeWorld <https://code.world/> applications, The project is primarily educational based, and more advanced applications may be created with the regular CodeWorld text UI. The application uses Blockly to allow users to drag-and-drop blocks, which can then be snapped together in order to build programs, in a Scratch-esque manner. The generated code is Haskell, which is then sent to the regular CodeWorld server and compiled with GHCJS, the resulting JavaScript is then run on the site. Code is generated as students are introduced to programming concepts with the Blocks and will later be exposed to a more text based environment. The majority of the code, aside from Blockly, is in Haskell,
Categories: Offsite Discussion

Chris Smith: CodeWorld for Younger Ages!

Planet Haskell - Thu, 06/30/2016 - 8:46am

Most readers know about CodeWorld, my Haskell-based programming environment that I’ve been using for middle school education for a number of years.  I recently wrote a thorough post about the project and its characteristic choices.  I’ve had a lot of success teaching middle school students, of ages 12 and up.  But why not younger?

There are challenges in teaching younger ages.  Spelling and typing skill is a real limitation.  If it takes kids several minutes to correctly type “solidCircle”, they aren’t going to be having a good time.  Even at the middle school level, students spend a good part of their first few months struggling to match up parentheses.  (So much so that I’ve just implemented “rainbow brackets”, which colors each nested set of parentheses a different color, in the editor in hopes of helping at least a little!)  These have always given me something of a lower bound for the ages at which I can hope to reach students.

This summer, though, as part of the Summer of Haskell project, Stefan Jacholke has been implementing a different programming environment for CodeWorld that solves many of these problems.  He’s just announced his first prototype!

If you need some inspiration, here’s an example of a program to draw a few bears.

This is all great timing, because next week, I’m meeting with my first elementary school to talk about setting up a CodeWorld activity for younger students.  With luck, I’ll have my guinea pigs to try this in the fall.

Enjoy!


Categories: Offsite Blogs

Stefan Jacholke: Fun Blocks Prototype

Planet Haskell - Wed, 06/29/2016 - 4:00pm

After looking up the constituent technologies which will be used for the project, work on the initial prototype began. For the initial version, we want a simple user interface with which simple CodeWorld applications can be built. Thus we want a version where a user can:

  • Drag and drop blocks from the toolbox
  • Provide simple error feedback
  • Generate code for a valid CodeWorld application
  • Run the generated CodeWorld applications
  • Saving and loading

Some more advanced features which are omitted for this release are:

  • Support for functions
  • Support for lists
  • Advanced CodeWorld applications (animations, events)

Simply put, we want a visual block-based interface which can be used to build CodeWorld applications.

This project is educationally based. We want to introduce programming to younger students and make it easy for them to understand the concepts behind it. For more advanced projects students may use the regular CodeWorld text UI.

The initial prototype can be found at code.world/funblocks

Blockly

This project relies heavily on Blockly for the user interface. Blockly provides an editor where blocks can be dragged and dropped on a canvas. These blocks can then be interlocked with one another through a snapping behavior.

Blockly provides many features that make it easy to adapt to a new language. It even incorporates simple type checking, luckily, however, there is a project that improves Blockly’s type checking.

For the user-interface, the choice was made to keep the interface clean and simple. The idea is to have a simple toolbar on the left-side with blocks that can be dragged onto the canvas on the right.

Since the project uses Blockly, blocks can be snapped into each other. A block has a single output and may have multiple inputs, each having a type.

In the image above we can see a Translated block, taking a picture and two numbers, and outputs another picture that is translated according to the given x and y values.

Each block may have zero or more inputs and one output type. All blocks are typed, and the functions in CodeWorld work on immutable data structures. A function may take a color as an input to produce another modified color. This works well with a visual block interface and we can expressively see how the program flows.

Blockly provides a lot of features out of the box, though sometimes changes are necessary specifically for this project.

The largest has been to use Anthony’s, which provides some useful typing and polymorphic features though it also diverges from the main Blockly branch and is almost 300 commits behind.

Other changes have been required as well, such as:

  • implementing the let blocks
  • changing default methods of validation for numbers and function names
  • adding error highlighting

and other small changes and additions. Thus we maintain a separate fork of Blockly for this project.

CodeGen

When we build the program below:

we obtain the output code of:

main = drawingOf(rotated(colored(solidRectangle(7,5), white),(60 + 70) * 0.9) & solidCircle(4))

Which looks rather ugly, but code formatting will be addressed at a later stage.

Currently, the regular Blockly code generation paradigm is followed, where a code generation function is given for each block, that converts the block into code. For a single block, we convert all input blocks to code, which are then combined into a single block of code. This process is repeated for all top-level blocks.

For each block, a generation function is assigned, which looks something like this:

blockSector :: GeneratorFunction blockSector block = do startangle <- valueToCode block "STARTANGLE" CNone endangle <- valueToCode block "ENDANGLE" CNone radius <- valueToCode block "RADIUS" CNone return $ none $ "sector(" ++ startangle ++ "," ++ endangle ++ "," ++ radius ++ ")"

This approach has some disadvantages, such being:

  • Difficult to ensure code is consistent and that all types match.
  • Difficult to find errors when they occur
  • Having to define a block for every CodeWorld function

The first problem is alleviated with a different version of Blockly that supports polymorphic types. I’m using an updated version by Anthony that also support automatic coloring of Blocks. Hence the strategy currently taken is to prevent errors through the block based editor.

This version of Blockly fits this project great. Since we don’t have side-effects the type of the if-block should be of the same as the then or else expressions. In order to have a single if block, it must be polymorphic, and this is provided by the alternate Blockly.

Above we can see the if block matching the Text type; below we can see the if block matching the Picture type.

Regardless, the generated code is then displayed and syntax highlighted using CodeMirror.

The generated code is sent to the CodeWorld server, which compiles the code into JavaScript. The compiled code is then run in the browser and displayed on an HTML canvas.

Error handling

First priority is to prevent a large class of errors from ever occurring. This is done by only allowing certain connections between blocks, validating input, providing default blocks and so on. This makes it easy for the user to construct valid programs.

However, errors do happen. What happens when a block contains a disconnected input ?

In this version, we visually indicate at which block the error occurs and display an error message for the block. This can be seen in the picture below.

Some other errors, such as runtime errors will be addressed at a later stage. Luckily, we currently don’t have missing patterns or partial functions to check for.

Project Management

Project management falls in line with the way things are currently done with the regular CodeWorld site.

Blockly supports exporting the current workspace as XML. This XML is then sent to the server and a hash is returned. This hash identifies a CodeWorld FunBlocks application. For example code.world/funblocks#PN2GoG8W2OMugJrzTw0GKYA loads a drawing of a coordinate plane.

Google’s authentication API can be used to log in. Once a user is logged in he can then save and load his projects by name as well.

Issues / Problems

A large majority of the project is in JavaScript, this includes the Blockly library.

Originally I intended to keep the majority of the code in Haskell, however, this is difficult to do. Currently, there is a large part of additional code for Blockly and an additional JavaScript file that handles the user interface initialization and logic.

Most of the code that define the various types of Blocks are in a Haskell file. However, some more standard blocks such as the math number block (which included some validation) are modified from the regular Blockly code base. The let definition is also modified Blockly code.

Thus organisationally, similar features and code are split between the main project and the Blockly fork.

Another issue currently is the renaming of caller blocks for Let definitions. When a Let definition is renamed the callerb blocks should get renamed as well. This currently disabled as Blockly is sometimes calling the text input validator for the wrong block, which tries to rename all of foo’s blocks to bar.

The block type unification for the Let definition is also currently producing strange results and the issues on this are covered in the issue tracker.

Further Work

Currently, we are only able to build very simple programs. For more complicated applications such as animations, we require first class functions. We also need to cover more advanced data types. A starting point would be to cover lists and tuples.

For CodeWorld simulations, the user is required to supply his own world data type, and a user-friendly way is needed for the user to build these in the Blocks UI.

Some more advanced functional features such as pattern matching would make this easier, and it remains to be seen how this will be implemented.

Everything is currently on track, which might mean we will get to spend time on same of the more advanced features later.

GHCJS

Working on the project I’m exposed to GHCJS and JavaScript a lot and I really like what GHCJS is doing. JavaScript has a tendency to let anything almost work and I spend a lot of time debugging and finding JS errors when working on Blockly code.

Straight after starting out I decided to try and keep the bulk of the work in Haskell, which meant using GHCJS. The GHCJS ecosystem lacks good documentation and sometimes in order to accomplish things that are simple in JS, a lot of time has to be spent navigating through many files of GHCJS code and a bit of luck. One such is an example is when you want to assign a higher order function in JS:

Blockly.FunBlocks["block_number"] = function(block){...}

where we want to assign a function to do the code generation for the block indexed as “block_number”

Which involved looking at GHCJS callback source files , even though there are Stackoverflow questions regarding similar issues, the GHCJS project is fast moving and the libraries keep changing.

Haskell Summer of Code

I would like to say thanks for being part of this year’s Haskell Summer of Code as I’m enjoying working the project quite a bit. Thanks goes to all of those who made it possible as well.

I think the way the project is managed is quite good. We (me and my mentor, Chris Smith) are primarily communicating through emails and Github. Working on Github helps a lot and the issue system greatly helps manage the project. It helps when you want to have some idea or goal to work on or if you want to fix something quickly. It’s too easy to forget about a minor bug if it isn’t written down somewhere.

Chris has also been a great help testing new features, providing feedback, opening issues and reporting bugs (which sometimes are a lot, I apologize !) and providing overall direction for the project.

Categories: Offsite Blogs

FP Complete: Announce: safe-exceptions, for async exception safety

Planet Haskell - Tue, 06/28/2016 - 6:00pm

This blog post is an initial announcement of a new package, safe-exceptions (and Github repo). This is a follow up to a number of comments I made in last week's blog post. To quote the README:

Safe, consistent, and easy exception handling

Runtime exceptions - as exposed in base by the Control.Exception module - have long been an intimidating part of the Haskell ecosystem. This package, and this README for the package, are intended to overcome this. By providing an API that encourages best practices, and explaining the corner cases clearly, the hope is to turn what was previously something scary into an aspect of Haskell everyone feels safe using.

This is an initial release of the package. I fully expect the library to expand in the near future, and in particular there are two open issues for decisions that need to be made in the short term. I'm releasing the package in its current state since:

  1. I think it's useful as-is
  2. I'm hoping to get feedback on how to improve it

On the second point, I've created a survey to get feedback on the interruptible/uninterruptible issue and the throw naming issue. Both are described in this blog post.

I'm hoping this library can bring some sanity and comfort to people dealing with IO and wanting to ensure proper exception handling! Following is the content of the README, which can also be read on Github.

Goals

This package provides additional safety and simplicity versus Control.Exception by having its functions recognize the difference between synchronous and asynchronous exceptions. As described below, synchronous exceptions are treated as recoverable, allowing you to catch and handle them as well as clean up after them, whereas asynchronous exceptions can only be cleaned up after. In particular, this library prevents you from making the following mistakes:

  • Catching and swallowing an asynchronous exception
  • Throwing an asynchronous exception synchronously
  • Throwing a synchronous exception asynchronously
  • Swallowing asynchronous exceptions via failing cleanup handlers
Quickstart

This section is intended to give you the bare minimum information to use this library (and Haskell runtime exceptions in general) correctly.

  • Import the Control.Exception.Safe module. Do not import Control.Exception itself, which lacks the safety guarantees that this library adds. Same applies to Control.Monad.Catch.
  • If something can go wrong in your function, you can report this with the throw. (For compatible naming, there are synonyms for this of throwIO and throwM.)
  • If you want to catch a specific type of exception, use catch, handle, or try.
  • If you want to recover from anything that may go wrong in a function, use catchAny, handleAny, or tryAny.
  • If you want to launch separate threads and kill them externally, you should use the async package.
  • Unless you really know what you're doing, avoid the following functions:
    • catchAsync
    • handleAsync
    • tryAsync
    • impureThrow
    • throwTo
  • If you need to perform some allocation or cleanup of resources, use one of the following functions (and don't use the catch/handle/try family of functions):

    • onException
    • withException
    • bracket
    • bracket_
    • finally
    • bracketOnError
    • bracketOnError_

Hopefully this will be able to get you up-and-running quickly.

Request to readers: if there are specific workflows that you're unsure of how to accomplish with this library, please ask so we can develop a more full-fledged cookbook as a companion to this file.

Terminology

We're going to define three different versions of exceptions. Note that these definitions are based on how the exception is thrown, not based on what the exception itself is:

  • Synchronous exceptions are generated by the current thread. What's important about these is that we generally want to be able to recover from them. For example, if you try to read from a file, and the file doesn't exist, you may wish to use some default value instead of having your program exit, or perhaps prompt the user for a different file location.

  • Asynchronous exceptions are thrown by either a different user thread, or by the runtime system itself. For example, in the async package, race will kill the longer-running thread with an asynchronous exception. Similarly, the timeout function will kill an action which has run for too long. And the runtime system will kill threads which appear to be deadlocked on MVars or STM actions.

    In contrast to synchronous exceptions, we almost never want to recover from asynchronous exceptions. In fact, this is a common mistake in Haskell code, and from what I've seen has been the largest source of confusion and concern amongst users when it comes to Haskell's runtime exception system.

  • Impure exceptions are hidden inside a pure value, and exposed by forcing evaluation of that value. Examples are error, undefined, and impureThrow. Additionally, incomplete pattern matches can generate impure exceptions. Ultimately, when these pure values are forced and the exception is exposed, it is thrown as a synchronous exception.

    Since they are ultimately thrown as synchronous exceptions, when it comes to handling them, we want to treat them in all ways like synchronous exceptions. Based on the comments above, that means we want to be able to recover from impure exceptions.

Why catch asynchronous exceptions?

If we never want to be able to recover from asynchronous exceptions, why do we want to be able to catch them at all? The answer is for resource cleanup. For both sync and async exceptions, we would like to be able to acquire resources - like file descriptors - and register a cleanup function which is guaranteed to be run. This is exemplified by functions like bracket and withFile.

So to summarize:

  • All synchronous exceptions should be recoverable
  • All asynchronous exceptions should not be recoverable
  • In both cases, cleanup code needs to work reliably
Determining sync vs async

Unfortunately, GHC's runtime system provides no way to determine if an exception was thrown synchronously or asynchronously, but this information is vitally important. There are two general approaches to dealing with this:

  • Run an action in a separate thread, don't give that thread's ID to anyone else, and assume that any exception that kills it is a synchronous exception. This approach is covered in the School of Haskell article catching all exceptions, and is provided by the enclosed-exceptions package.

  • Make assumptions based on the type of an exception, assuming that certain exception types are only thrown synchronously and certain only asynchronously.

Both of these approaches have downsides. For the downsides of the type-based approach, see the caveats section at the end. The problems with the first are more interesting to us here:

  • It's much more expensive to fork a thread every time we want to deal with exceptions
  • It's not fully reliable: it's possible for the thread ID of the forked thread to leak somewhere, or the runtime system to send it an async exception
  • While this works for actions living in IO, it gets trickier for pure functions and monad transformer stacks. The latter issue is solved via monad-control and the exceptions packages. The former issue, however, means that it's impossible to provide a universal interface for failure for pure and impure actions. This may seem esoteric, and if so, don't worry about it too much.

Therefore, this package takes the approach of trusting type information to determine if an exception is asynchronous or synchronous. The details are less interesting to a user, but the basics are: we leverage the extensible extension system in GHC and state that any extension type which is a child of SomeAsyncException is an async exception. All other exception types are assumed to be synchronous.

Handling of sync vs async exceptions

Once we're able to distinguish between sync and async exceptions, and we know our goals with sync vs async, how we handle things is pretty straightforward:

  • If the user is trying to install a cleanup function (such as with bracket or finally), we don't care if the exception is sync or async: call the cleanup function and then rethrow the exception.
  • If the user is trying to catch an exception and recover from it, only catch sync exceptions and immediately rethrow async exceptions.

With this explanation, it's useful to consider async exceptions as "stronger" or more severe than sync exceptions, as the next section will demonstrate.

Exceptions in cleanup code

One annoying corner case is: what happens if, when running a cleanup function after an exception was thrown, the cleanup function itself throws an exception. For this, we'll consider action `onException` cleanup. There are four different possibilities:

  • action threw sync, cleanup threw sync
  • action threw sync, cleanup threw async
  • action threw async, cleanup threw sync
  • action threw async, cleanup threw async

Our guiding principle is: we cannot hide a more severe exception with a less severe exception. For example, if action threw a sync exception, and then cleanup threw an async exception, it would be a mistake to rethrow the sync exception thrown by action, since it would allow the user to recover when that is not desired.

Therefore, this library will always throw an async exception if either the action or cleanup thows an async exception. Other than that, the behavior is currently undefined as to which of the two exceptions will be thrown. The library reserves the right to throw away either of the two thrown exceptions, or generate a new exception value completely.

Typeclasses

The exceptions package provides an abstraction for throwing, catching, and cleaning up from exceptions for many different monads. This library leverages those type classes to generalize our functions.

Naming

There are a few choices of naming that differ from the base libraries:

  • throw in this library is for synchronously throwing within a monad, as opposed to in base where throwIO serves this purpose and throw is for impure throwing. This library provides impureThrow for the latter case, and also provides convenience synonyms throwIO and throwM for throw.
  • The catch function in this package will not catch async exceptions. Please use catchAsync if you really want to catch those, though it's usually better to use a function like bracket or withException which ensure that the thrown exception is rethrown.
Caveats

Let's talk about the caveats to keep in mind when using this library.

Checked vs unchecked

There is a big debate and difference of opinion regarding checked versus unchecked exceptions. With checked exceptions, a function states explicitly exactly what kinds of exceptions it can throw. With unchecked exceptions, it simply says "I can throw some kind of exception." Java is probably the most famous example of a checked exception system, with many other languages (including C#, Python, and Ruby) having unchecked exceptions.

As usual, Haskell makes this interesting. Runtime exceptions are most assuredly unchecked: all exceptions are converted to SomeException via the Exception typeclass, and function signatures do not state which specific exception types can be thrown (for more on this, see next caveat). Instead, this information is relegated to documentation, and unfortunately is often not even covered there.

By contrast, approaches like ExceptT and EitherT are very explicit in the type of exceptions that can be thrown. The cost of this is that there is extra overhead necessary to work with functions that can return different types of exceptions, usually by wrapping all possible exceptions in a sum type.

This library isn't meant to settle the debate on checked vs unchecked, but rather to bring sanity to Haskell's runtime exception system. As such, this library is decidedly in the unchecked exception camp, purely by virtue of the fact that the underlying mechanism is as well.

Explicit vs implicit

Another advantage of the ExceptT/EitherT approach is that you are explicit in your function signature that a function may fail. However, the reality of Haskell's standard libraries are that many, if not the vast majority, of IO actions can throw some kind of exception. In fact, once async exceptions are considered, every IO action can throw an exception.

Once again, this library deals with the status quo of runtime exceptions being ubiquitous, and gives the rule: you should consider the IO type as meaning both that a function modifies the outside world, and may throw an exception (and, based on the previous caveat, may throw any type of exception it feels like).

There are attempts at alternative approaches here, such as unexceptionalio. Again, this library isn't making a value statement on one approach versus another, but rather trying to make today's runtime exceptions in Haskell better.

Type-based differentiation

As explained above, this library makes heavy usage of type information to differentiate between sync and async exceptions. While the approach used is fairly well respected in the Haskell ecosystem today, it's certainly not universal, and definitely not enforced by the Control.Exception module. In particular, throwIO will allow you to synchronously throw an exception with an asynchronous type, and throwTo will allow you to asynchronously throw an exception with a synchronous type.

The functions in this library prevent that from happening via exception type wrappers, but if an underlying library does something surprising, the functions here may not work correctly. Further, even when using this library, you may be surprised by the fact that throw Foo `catch` (\Foo -> ...) won't actually trigger the exception handler if Foo looks like an asynchronous exception.

The ideal solution is to make a stronger distinction in the core libraries themselves between sync and async exceptions.

Deadlock detection exceptions

Two exceptions types which are handled surprisingly are BlockedIndefinitelyOnMVar and BlockedIndefinitelyOnSTM. Even though these exceptions are thrown asynchronously by the runtime system, for our purposes we treat them as synchronous. The reasons are twofold:

  • There is a specific action taken in the local thread - blocking on a variable which will never change - which causes the exception to be raised. This makes their behavior very similar to synchronous exceptions. In fact, one could argue that a function like takeMVar is synchronously throwing BlockedIndefinitelyOnMVar
  • By our standards of recoverable vs non-recoverable, these exceptions certainly fall into the recoverable category. Unlike an intentional kill signal from another thread or the user (via Ctrl-C), we would like to be able to detect that we entered a deadlock condition and do something intelligent in an application.
Possible future changesInterruptible vs uninterruptible masking

This discussion is now being tracked at: https://github.com/fpco/safe-exceptions/issues/3

In Control.Exception, allocation functions and cleanup handlers in combinators like bracket are masked using the (interruptible) mask function, in contrast to uninterruptibleMask. There have been some debates about the correctness of this in the past, notably a libraries mailing list discussion kicked off by Eyal Lotem. It seems that general consensus is:

  • uninterruptibleMask is a better choice
  • But changing the core library like this would potentially break too many programs

In its current version, this library uses mask (interruptible) for allocation functions and uninterruptibleMask cleanup handlers. This is a debatable decision (and one worth debating!). An example of alternatives would be:

  • Use uninterruptibleMask for both allocation and cleanup pieces
  • Match Control.Exception's behavior
  • Provide two versions of each function, or possibly two modules
Naming of the synchronous monadic throwing function

We may decide to rename throw to something else at some point. Please see https://github.com/fpco/safe-exceptions/issues/4

Categories: Offsite Blogs

Roman Cheplyaka: Install Fedora Linux on an encrypted SSD

Planet Haskell - Tue, 06/28/2016 - 2:00pm

I just replaced the SSD in my laptop with a bigger one and installed a fresh Fedora Linux on it, essentially upgrading from F23 to F24.

Here are a few notes which could be useful to others and myself in the future.

Verifying the downloaded image

How do you verify the downloaded image? You verify the checksum.

How do you verify the checksum? You check its gpg signature.

How do you verify the authenticity of the gpg key? You could just check the fingerprint against the one published on the website above, but this is hardly better than trusting the checksum, since they both come from the same source.

Here’s a better idea: if you already have a Fedora system, you have the keys at /etc/pki/rpm-gpg.

In my case, I imported /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-24-primary (yes, my F23 system already contained the F24 signing keys), and was able to check the checksum signature.

This protects you against a scenario when getfedora.org is compromised and the checksums/signatures/keys are replaced there.

Installing from a USB partition

Turned out the only optical disc in my house was damaged, and I didn’t have a USB stick big enough to burn the Fedora image either.

I did have an external USB drive with some free space on it, but it contained a lot of data, so I couldn’t just make it one big ISO partition.

There are several instructions on how to create bootable USB partitions, but most of them look fragile and complicated.

Luckily, Fedora makes this super easy.

  1. Install the RPM package livecd-tools (which is a packaged version of this repo)
  2. Create a partition big enough for the ISO and format it. Unlike many other instructions that tell you to use FAT, this one works with ext[234] just fine.
  3. livecd-iso-to-disk Fedora-Workstation-Live-x86_64-24-1.2.iso /dev/sdb1
Setting up disk encryption

I was impressed by how easy it was to set up full disk encryption. I just checked the box “Encrypt my data” in the installer, and it used a very sensible partitioning scheme close to what I used to set up manually before:

  • Unencrypted /boot partition
  • Encrypted partition with LVM on top of it
    • Three logical volumes on the encrypted LVM: root, /home, and swap.

The only thing that I had to do was to enable TRIM support:

  1. For LVM: set issue_discards = 1 in /etc/lvm/lvm.conf.
  2. For cryptsetup: change none to discard in /etc/crypttab.
  3. Enable weekly trims systemctl enable fstrim.timer && systemctl start fstrim.timer
Categories: Offsite Blogs

Functional Jobs: Senior Software Engineer (Haskell) at Front Row Education (Full-time)

Planet Haskell - Tue, 06/28/2016 - 10:35am
Position

Senior Functional Web Engineer to join fast-growing education startup transforming the way 3+ million K-8 students learn Math and English.

What you will be doing

Architect, design and develop new applications, tools and distributed systems for the Front Row ecosystem in Haskell, Flow, PostgreSQL, Ansible and many others. You will get to work on your deliverable end-to-end, from the UX to the deployment logic.

Mentor and support more junior developers in the organization

Create, improve and refine workflows and processes for delivering quality software on time and without incurring debt

Work as part of a very small (there's literally half a dozen of us!), world-class team of engineers with a track record of rapidly delivering valuable software to millions of users.

Work closely with Front Row educators, product managers, customer support representatives and account executives to help the business move fast and efficiently through relentless automation.

Why you should join Front Row

Our mission is important to us, and we want it to be important to you as well: millions of students learn math using Front Row every month. Our early results show students improve twice as much while using Front Row than their peers who aren’t using the program.

As an experienced engineer, you will have a massive impact on the company, product, and culture; you’ll have a ton of autonomy and responsibility; you’ll have equity to match the weight of this role. If you're looking for an opportunity to both grow and do meaningful work, surrounded and supported by like-minded professionals, this is THE place for you.

You will be working side by side with well known world-class personalities in the Haskell and Functional Programming community whose work you've likely used. Front Row is an active participant to the Open Source community and contributor to some of the most popular Haskell libraries.

A lot of flexibility: while we all work towards the same goals, you’ll have a lot of autonomy in what you work on. You can work from home up to one day a week, and we have a very flexible untracked vacation days policy

The company and its revenue are growing at a rocketship pace. Front Row is projected to make a massive impact on the world of education in the next few years. It's a once in a lifetime opportunity to join a small organization with great odds of becoming the Next Big Thing.

Must haves
  • You have experience doing full-stack web development. You understand HTTP, networking, databases and the world of distributed systems.
  • You have functional programming experience.
  • Extreme hustle: you’ll be solving a lot of problems you haven’t faced before without the resources and the support of a giant organization. You must thrive on getting things done, whatever the cost.
  • Soft skills: we want you to move into a leadership position, so you must be an expert communicator
Nice-to-haves
  • You have led a software development team before
  • You have familiarity with a functional stack (Haskell / Clojure / Scala / OCaml etc)
  • You understand and have worked all around the stack before, from infrastructure automation all the way to the frontend
  • You're comfortable with the Behavior-Driven Development style
  • You have worked at a very small startup before: you thrive on having a lot of responsibility and little oversight
  • You have worked in small and effective Agile/XP teams before
  • You have delivered working software to large numbers of users before
Benefits
  • Competitive salary
  • Generous equity option grants
  • Medical, Dental, and Vision
  • Catered lunch and dinner 4 times a week
  • Equipment budget
  • (onsite only) One flexible work day per week
  • (onsite only) Working from downtown SF, very accessible location
  • Professional yet casual work environment

Get information on how to apply for this position.

Categories: Offsite Blogs

Instances for (->) a (b :: * -> *)?

haskell-cafe - Tue, 06/28/2016 - 8:36am
Jim Pryor wrote: Then one defines a new type: newtype TwoArrow a b x = TwoArrow{unTA:: a -> b -> x} instance MyClass (TwoArrow a b) where ... Ditto for the composition. Alas, one is stuck with adding the dummy conversions TwoArrow/unTA at various places. The first instance of the curly-braces notation on this list in more than a decade! I think you are trying to build a monad with several pieces of environment. Assuming that just making a record with two different pieces (and making that record the single environment) doesn't work for you, you can find many solutions on Hackage. For example, various extensible effects libraries offer the desired functionality right out of the box. Or, if you really want to define a new class, why not to do something more general, like class Monad m => MonadMReader var r m | var m -> r where ask :: var -> m r to be used like data Var1 = Var1; data Var2 = Var2 do x <- ask Var1 y <- ask Var2 return $ x + y (and implement it, that is, define the insta
Categories: Offsite Discussion

Deadline extended: 21st International Conference on Engineering of Complex Computer Systems (ICECCS 2016), Dubai, United Arab Emirates, November 6-8 2016

General haskell list - Tue, 06/28/2016 - 4:06am
ICECCS is an A-ranked conference by the Computing Research and Education Association of Australasia (CORE) 2014 ranking (http://portal.core.edu.au/conf-ranks/?search=ICECCS&by=all&source=CORE2014&sort=atitle&page=1 ). Please kindly consider submitting papers to the conference, and please encourage your colleagues and students to submit too. --------------------------------------------------------------- 21st International Conference on Engineering of Complex Computer Systems (ICECCS 2016) || November 6-8, Dubai, United Arab Emirates || http://www.aston.ac.uk/eas/about-eas/academic-groups/computer-science/iceccs-2016/ Overview --------------------- Over the past several years, we have seen a rapid rising emphasis on design, implement and manage complex computer systems to help us deal with an increasingly volatile, globalised complex world. These systems are critical for dealing with the Grand Challenge problems we are facing in the 21st century, including health care, urbanization, education, energy, fi
Categories: Incoming News

Proposal for containers: Add 'lookup' function to Data.Set

libraries list - Mon, 06/27/2016 - 10:45pm
WHAT It is proposed to add a ‘lookup' function on 'Set' in the "containers" package. Feedback during the next two weeks is welcome. The function is almost indentical to the 'member' function but, in addition, returns the value stored in the set. WHY The point of this proposal is to facilitate program-wide data sharing. The 'lookup' function gives access to a pointer to an object already stored in a Set and equal to a given argument. The 'lookup' function is a natural extension to the current 'lookupLT', 'lookupGT', 'lookupLE' and 'lookupGE' functions, with obvious semantics. Example use case: In a parser, the memory footprint can be reduced by collapsing all equal strings to a single instance of each string. To achieve this, one needs a way to get a previously seen string (internally, a pointer) equal to a newly parsed string. Amazingly, this is very difficult with the current "containers" library interface. One current option is to use a Map instead, e.g., 'Map String String' which stores twice as
Categories: Offsite Discussion

Help to choose a library name

haskell-cafe - Mon, 06/27/2016 - 8:38am
Hi community, I'm writing a reactive programming library (yet another). I need it for the game Nomyx, but couldn't find the features I wanted from the existing libraries. Now the library is called Nomyx-Events. But I'd like to find a cool name that is not related to Nomyx... Some propositions: - Nomev - Noa Some French names: - Imprevu (French for unforseen, like in "unforseen event"). - Rendez-vous - Dejavu I like a lot Imprevu. How does it sound to English native speakers? Thanks _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
Categories: Offsite Discussion

The Haddock documentation is not showing up on the Hackage

General haskell list - Mon, 06/27/2016 - 5:28am
Hi, I uploaded a package named enchant on the Hackage last week, but the Haddock documentation is not showing up yet. The Status field says "Docs pending" and "Build status unknown". https://hackage.haskell.org/package/enchant-0.1.0.0 enchant uses c2hs as a build tool to generate the FFI binding and requires libenchant-dev to be installed on the machine. I wonder how I can tell these build requirements to the Hackage server. Regards, Kwang Yul Seo _______________________________________________ Haskell mailing list Haskell< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell
Categories: Incoming News

Philip Wadler: Brexit implies Techxit?

Planet Haskell - Mon, 06/27/2016 - 4:48am
In the wake of the EU referendum, there appears to be considerable information about its consequences that many might wish to have seen before the vote. Some of this concerns the negative impact of Brexit on technology firms. Among others, the BBC has a summary.I was particularly struck by one comment in the story, made by start-up mentor Theo Priestley (pictured above),.And Mr Priestley thinks that in the event of a Scottish independence referendum that leads to reunification with the EU, it's possible some start-ups could move north of the border, perhaps to rekindle "Silicon Glen" - a 1980s attempt to compete in the semiconductor industry.
Categories: Offsite Blogs