News aggregator

Home - 純粋関数空間

del.icio.us/haskell - Wed, 02/06/2013 - 1:18am
Categories: Offsite Blogs

CfP: OdHac (Haskell Hackathon)

General haskell list - Tue, 02/05/2013 - 7:34pm
------------------------------------------------------------------------ OdHac International Haskell Hackathon May 3-5, 2013 Odessa, Ukraine http://haskell.org/haskellwiki/OdHac Co-organized with Provectus IT ------------------------------------------------------------------------ We are pleased to announce the upcoming Haskell Hackathon! The event will be held over 3 days, May 3-5, in Odessa, Ukraine. This is a great opportunity to meet your fellow haskellers in real life, find new contributors for your project, improve existing libraries and tools or even start new ones! To attend, please register at http://bit.ly/OdHacReg. Please propose projects at http://www.haskell.org/haskellwiki/OdHac/Projects Consider participating in our accommodation program: http://www.haskell.org/haskellwiki/OdHac/Accommodation
Categories: Incoming News

JP Moresmau: EclipseFP and performance

Planet Haskell - Tue, 02/05/2013 - 2:50pm
OK, ok, performance in EclipseFP could be better. I'll try to present a bit the challenges and why things are the way they are.

You see, EclipseFP used scion for a while, and scion was a long running process, which ended up eating loads of memory, and had a few issues due to the GHC API maintaining state and not releasing memory (I've written about this elsewhere). So I rewrote the whole Haskell backend with BuildWrapper, and I took opposite approach: BuildWrapper is an short-lived executable. You start BuildWrapper with some parameters, it does its stuff and outputs some JSON answer. And that's fine for a lot of operations. But people have started to complain that when they edit a source file, the feedback loop is quite slow, and they keep seeing that the synchronization job keeps on running all the time. That's because every time Eclipse says that the editor has changed (not every keystroke, luckily), EclipseFP goes back to BuildWrapper to analyze the source. So it fires the BuildWrapper executable (and only this can be slow if you have an over zealous anti virus running), which in turn builds up a GHC session, analyses the AST, writes it to JSON, and tears everything down. For small projects and fast machines, this is acceptable. But I eat my own dogfood, of course, and when working on BuildWrapper itself, I noticed things could be too slow for comfort. Sometimes it would take 4 seconds to analyze completely a file.

So I went the middle route. I create another command in BuildWrapper that makes the executable stay around and listen for more commands. More specifically, there is now a long running build command, that can repeatedly analyze a file while staying in the GHC session. It won't have the same issues as the long running scion because it's tied to the file you're editing. When you close the file in Eclipse, the executable dies. When you change something in the Cabal file, the executable restarts to it can take into account new modules, flags or dependencies. The synchronization job now runs in something like a quarter of the time, and even faster.

I believe we have a happy medium: most operations are short-lived and we don't need to worry about memory usage or stray processes, but where performance matters (when you're in the flow and writing Haskell and don't want to wait for the editor to catch up) we have a long running process that's efficient, but not too persistent.

This will be part of the upcoming 2.5.0 release of EclipseFP. Of course people are welcome to get the source and test it for themselves before the official release!
Categories: Offsite Blogs

Video! Duncan Coutts on Cloud Haskell

haskell-cafe - Tue, 02/05/2013 - 2:35pm
Back in October 2012 Well-Typed and Haskell expert Duncan Coutts delivered a talk on 'Cloud Haskell' at the 2K12 edition of the Haskell eXchange. Cloud Haskell takes Erlang's successful approach to distributed concurrency and implements it in Haskell as a library. We will look at what this means and what possibilities it opens up. You should also get a flavour of what distributed programming in Haskell is like. The initial Cloud Haskell idea and a prototype implementation were introduced last year. Since then we have been working on a new from-scratch implementation with a focus on robustness and flexibility Watch the video on the Skills Matter website - http://bit.ly/VB9tcy _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Faculty positions at DIKU, University of Copenhagen

General haskell list - Tue, 02/05/2013 - 6:30am
Have you ever felt like building a (novel) supercomputer, putting Haskell (or your own language) on it and make it solve "big" problems? Maybe you should apply for one of these faculty positions then: DIKU has 1-2 open faculty positions in computer systems and/or data management, which can be filled at all levels: full professor, associate professor and assistant professor. This is part of strengthening DIKU's activities in high-performance computing, "big" data management, and cloud computing. Candidates should have first-rate research and teaching credentials commensurate for the level of position they are applying for, with an emphasis on building and evaluating systems. Subjects include databases, distributed systems, parallel systems (including language design and compilation techniques), computer networks, security and cloud computing. Applications expressing an interest in bringing principled knowledge from algorithms and programming languages to bear and/or developing new such knowledge for pra
Categories: Incoming News

<package>-inplace is shadowed by package<package>-<hexstring>

haskell-cafe - Mon, 02/04/2013 - 11:51pm
Hi I am trying to write criterion benchmarks for the pretty library. Unfortunately, building the benchmark executable fails at some point during the development with the following error message: ---8<--- <command line>: cannot satisfy -package-id pretty-1.1.1.1-inplace: pretty-1.1.1.1-inplace is shadowed by package pretty-1.1.1.1-7bd0114e9691fca3d3447fc0133701cf --->8--- I don't understand the cause of the error, let alone what I am supposed to do next. Any help is much appreciated. Here are the steps that lead to the above quoted error. Sorry, if this is not the smallest counter example possible. As I said, I hardly understand what is going on. (the two patch files mentioned are attached to this email, virthualenv is version 0.2.1) ---8<--- git clone https://github.com/haskell/pretty.git cd pretty git apply /tmp/0001-hello-world-setup.patch export PATH=/opt/ghc-7.4.2/install/bin:/opt/haskell-platform-2012.4.0.0/install/bin:$PATH ~/.cabal/bin/virthualenv source .virthualenv/bin/activate cabal confi
Categories: Offsite Discussion

EventSource Broker

del.icio.us/haskell - Mon, 02/04/2013 - 11:20pm
Categories: Offsite Blogs

Yesod Web Framework: Using Ajax with a Scaffolded Site

Planet Haskell - Mon, 02/04/2013 - 11:16pm
Using Ajax with a Scaffolded Site

This is cookbook recipe, also available from the Wiki.

A common scenario is that part of an application requires Ajax, while the rest is based on dynamically generated HTML. The core functionality of Yesod includes everything you need to implement this, but the scaffolding leans more towards the HTML side, especially in its handling of login and its reporting of errors. However, the default functions can easily be overridden with more general ones which handle Ajax properly. This article explains how.

In what follows, I look at

  • Customising error handling to avoid sending HTML error pages in response to an Ajax request.
  • Customising authentication to avoid or mitigate redirections when responding to an Ajax request.
  • Testing using Yesod.Test.
  • An example handler and client-side code, to illustrate the choices on which the rest of the discussion is based.
A caveat

To give concrete examples, I have had to make choices about the way Ajax calls are done. To be specific, I use jQuery in about the simplest way possible, which means that:

  • Data is sent to the server as a set of form fields, with one parameter for each top-level attribute of the JavaScript object being sent.
  • The response can be text or JSON, as long as it is consistent with the setting of the dataType in the Ajax call on the client side.
  • For an error response, with an HTTP error status, reading the body as text is an easy option for the client.
  • The requests include a header X-Requested-With: XMLHttpRequest

You may want to make different choices, such as sending JSON data in all requests and responses. The details will change, but the main points I am talking about here will remain valid.

An example Yesod handler, and the corresponding client-side code, are given in the appendix at the end to illustrate these choices, and generally motivate the discussion.

I should also mention that issues #478 and #479 on GitHub discuss related issues, but not really the detailed scenario I have chosen here.

Error Handler

The first problem to look at is error handling. The example code shown later can raise a 404 error if the database entry is not found at all, and a permissionDenied error if the user is trying to use someone else's clipboard. Errors like these short-circuit the handler and return a result using the errorHandler function of the Yesod instance.

The scaffolded site is set up to use the default error handler. This produces a brief HTML message in a page formatted by defaultLayout, and is probably not what we want in response to an Ajax request!

To change it, we need to implement the errorHandler method of the Yesod typeclass, rather than using the default setting. It is normal Handler code, and takes an ErrorResponse (see the documentation for Yesod.Handler), so we need to write something like this in Foundation.hs:

import Network.HTTP.Types (mkStatus) import Network.Wai (Request(..)) import Data.Text (append, pack, unwords) import Control.Monad (when) ... instance Yesod App where ... errorHandler errorResponse = do $(logWarn) (append "Error Response: " $ pack (show errorResponse)) req <- waiRequest let reqwith = lookup "X-Requested-With" $ requestHeaders req errorText NotFound = (404, "Not Found", "Sorry, not found") errorText (InternalError msg) = (400, "Bad Request", msg) errorText (InvalidArgs m) = (400, "Bad Request", unwords m) errorText (PermissionDenied msg) = (403, "Forbidden", msg) errorText (BadMethod _) = (405, "Method Not Allowed", "Method not supported") when (maybe False (== "XMLHttpRequest") reqwith) $ do let (code, brief, full) = errorText errorResponse sendResponseStatus (mkStatus code brief) $ RepPlain $ toContent $ append "Error: " full defaultErrorHandler errorResponse

The critical part of this is recognising the Ajax call by the X-Requested-With header. If you are using a different Ajax setup, you might need to look for something different, of course, but this one works for jQuery.

In the Ajax case, we produce a plain text response, which is what I chose as easiest in our example scenario - if you prefer JSON, then feel free to produce it here. If the request is not Ajax, we call the defaultErrorHandler, which is what would have been used if we had not done any of this.

If you have been watching, you will have noticed that I also sneaked in some logging - it is entirely optional, but I think it is helpful.

Login

The other issue which arises when working with Ajax is the way redirection occurs when a user needs to log in during an Ajax request.

The first thing that happens is a redirection to the login page. This uses a 303 status code, and so cannot be trapped in JavaScript - the browser itself automatically follows it. So we will be redirected to a login page. More precisely, we arrive at the loginHandler of the YesodAuth instance. Our problem, just as in the error handler, is that we do not want it to generate an HTML login form if this happens when handling an Ajax request.

Therefore, in the YesodAuth instance, we implement the loginHandler, rather than accepting the default, again in Foundation.hs.

instance YesodAuth App where .... loginHandler = do tm <- getRouteToMaster master <- getYesod clearUltDest req <- waiRequest let reqwith = lookup "X-Requested-With" $ requestHeaders req when (maybe False (== "XMLHttpRequest") reqwith) $ do sendResponseStatus (mkStatus 403 "Forbidden") $ RepPlain $ toContent ("Login required" :: Text) let title = renderMessage master ["en"] MsgSiteTitle defaultLayout $ do setTitleI title mapM_ (flip apLogin tm) (authPlugins master)

As before, we recognise an Ajax request from the X-Requested-With header. For Ajax we produce an error instead of a login page, leaving the client-side code to decide how to tidy up and get the user to a place where they can log in.

There are a few subtleties here. Firstly, we use a 403 response in the Ajax case. 401 would not be a good choice, since it would be an invitation to do HTTP authentication, not session-based login. However 403 has the complication that it also gets used for other permissionDenied errors (see above). This is resolved by taking a little care to ensure that the two cases are unambiguously distinguished by the start of the message, so that the client code can handle them appropriately.

The next subtlety concerns the "ultimate destination" - see the Sessions chapter of the Yesod Book. The ultimate destination is set in a couple of places in Yesod, and only one of them is controlled by the setting of redirectToReferer (in the YesodAuth typeclass). In most situations we cannot avoid it being set. The problem is that a successful login is followed by a redirection to the ultimate destination, and in an Ajax situation, this can result in being redirected, using GET, back to a resource which should be accessed with POST or PUT, for example. To avoid this, we just clear the ultimate destination in all cases - if you want to be more selective, remember that it is stored in the session, so it survives between requests until it is cleared or used.

Finally, the call to defaultLayout generates the login form for the non-Ajax case. It is essentially copied from the default login handler declared in the YesodAuth typeclass in Yesod.Auth. I have moved few things outside, and I have used a site title set in our messages file(s) rather than the one from Yesod.Auth.Message. This is one place you can modify the HTML generated, for example by wrapping each authentication widget in a div with a recognisable id so that you can apply CSS styles.

Testing

It is a good idea to write some tests, and it is easy to do with Yesod.Test. To construct an Ajax request (of the sort I have been dealing with), we need to set up the parameters, and make an HTTP request which includes the correct X-Requested-With header. Here is one reasonably general function for doing it, which assumes that any data is provided as a Map whose keys mirror the attributes of the JavaScript object used on the real client:

import qualified Data.Map as Map ajaxRequest :: StdMethod -> B.ByteString -> Map.Map Text Text -> OneSpec conn () ajaxRequest method url datacontent = do let params = mapM_ (uncurry byName) $ Map.toList datacontent doRequestHeaders (renderStdMethod method) url [("X-Requested-With", "XMLHttpRequest")] params

doRequestHeaders is a very recent addition to Yesod.Test. If you want to use it at the moment, you will need to pick up the latest version from GitHub - you can simply make a local copy of Test.hs and import that.

Yesod.Test gives us a way of getting at the raw response body. Any decoding needs to be allowed for explcitly, which in our example means remembering that the body is utf-8 encoded.

We write two separate top-level specs, so that we can control the order - the ordering of the it specs within a single describe is probably not what you expect.

testdata = "A unicode string\x2122" url = "/clipboard/..." -- In a real example, get this from the server clipSpecs1 :: Specs clipSpecs1 = describe "The clipboard (part 1)" $ do it "can be set" $ do ajaxRequest PUT url $ Map.fromList [ ("clip", testdata) ] statusIs 200 clipSpecs2 :: Specs clipSpecs2 = describe "The clipboard (part 2)" $ do it "can be read, producing the utf-8 encoding of what we stored" $ do ajaxRequest GET url Map.empty bodyEquals $ map (chr . fromIntegral) (B.unpack $ encodeUtf8 testdata) statusIs 200

Actually that is not quite all: for our running example we need to log in in each it spec. A recipe for packaging that is the subject of another cookbook article.

Appendix: Example handler and client-side code

This simple handler, and matching JavaScript, motivates the assumptions made in the discussion above, and also just might help someone get started!

In this example, users have to be logged in, and by the time we reach the handler function, this has already been checked because of a suitable definition of isAuthorized in the Yesod instance in Foundation.hs. For more on authentication and authorization, see the Yesod Book.

Each user has a persistent clipboard for cutting and pasting things, which for our present purposes can be taken as unicode strings. The server simply stores the data and returns it to the client when requested, so we need read and write operations, which rather naturally map onto HTTP GET and PUT methods. They will act on entries in a database table, defined like this in config/models:

ClipBoard user UserId -- Who owns this clipboard data Text -- The data UniqueCbUser user

Elsewhere in the application, a single clipboard entry is set up for each user, but for this example we can just assume that it exists.

The route is

/clipboard/#ClipBoardId ClipboardR GET PUT

and the handler code is

module Handler.Clipboard ( getClipboardR, putClipboardR ) where import Import import Yesod.Auth (requireAuthId) import Control.Monad (when) checkEntry :: ClipBoardId -> Handler ClipBoard checkEntry cbid = do userid <- requireAuthId -- Auth already checked, but we need userid cb <- runDB $ get404 cbid when (clipBoardUser cb /= userid) $ permissionDenied "Incorrect user - did you invent the URL?" return cb getClipboardR :: ClipBoardId -> Handler RepPlain getClipboardR cbid = do cb <- checkEntry cbid return $ RepPlain $ toContent $ clipBoardData cb putClipboardR :: ClipBoardId -> Handler () putClipboardR cbid = do _ <- checkEntry cbid d <- runInputPost $ ireq textField "clip" runDB $ update cbid [ClipBoardData =. d]

There are a few things to notice here:

  • In the GET handler, the response is simply a utf-8 encoded string sent with type text/plain (toContent does the utf-8 encoding for Text).
  • The PUT handler uses an "Input Form" (see the Forms chapter of the Yesod Book). In this case there is a single parameter to decode as Text, but if we had sent a more complex structure on the JavaScript side, there would have been further form fields here.
  • Two errors can occur, both most likely caused by not following the official URL. In a real application, the URL would have been provided by the server, so these errors should not occur unless a user types a URL by hand.

Finally, glossing over the way the client gets hold of the URL, jQuery code can send data like this:

$.ajax ({ type: "PUT", url: "/clipboard/" + clipid, data: { clip: clipdata }, dataType: "text", success: function () { alert ("It worked") }, error: function (jqxhr) { alert ("error response: " + jqxhr.responseText); } });

and get it back again this way:

$.ajax ({ type: "GET", url: "/clipboard/" + clipid, dataType: "text", success: function (data) { alert ("The data was: " + data); }, error: function (jqxhr) { alert ("error response: " + jqxhr.responseText); } });
Categories: Offsite Blogs

Typeclassopedia - HaskellWiki

del.icio.us/haskell - Mon, 02/04/2013 - 8:50pm
Categories: Offsite Blogs

git-annex

del.icio.us/haskell - Mon, 02/04/2013 - 7:38pm
Categories: Offsite Blogs

Text.PrettyPrint.HughesPJ is sloooow (andwl-pprint-text is fast)

haskell-cafe - Mon, 02/04/2013 - 3:36pm
I was running into serious performance problems when printing moderately sized Doc and Xml data (HaXml goes via Doc). So I replace Text.PrettyPrint.HughesPJ with Text.PrettyPrint.Leijen.Text, and patched the HaXml printer in the same way. Now it is running much faster. This confirms some of the comments here: http://stackoverflow.com/questions/9761507/which-pretty-print-library If you want to see for yourself, here is a test case. It constructs and prints a document tree with about 10^4 nodes, rendered to an Xml document with 10^6 (nonblank) chars: https://github.com/jwaldmann/haskell-tpdb/blob/master/test/speed.hs Of the 4 output methods (fin the main program), only one takes < 1 second. Rendering via HughesPJ needs extra stack (!) and takes about 20 seconds. Rendering via Text.XML.HaXml.ByteStringPP seems much slower still (!) (ghc-7.6.2, pretty-1.1.1.0, HaXml-1.23.3, wl-pprint-text-1.1.0.0, amd64, fedora 18, kernel 3.7.4)
Categories: Offsite Discussion

Problems with code blocks in the description fieldin a .cabal file

haskell-cafe - Mon, 02/04/2013 - 2:30pm
Hi, I'm putting together a cabal package and I'd like to have some code examples in my description file. In particular I would like to have a code block containing markdown containing a code block of Haskell, like this: When I put the above code in my .cabal file and do `cabal haddock --executables` I get the following error: haddock: failed to parse haddock prologue from file: dist/doc/html/codeExtract/codeExtract/haddock-prolog31969.txt In general I can provoke the parse error from haddock whenever I have something inside curly braces. So the error seems to stem from haddock. I've tried to track down what happens inside haddock but I've run out steam. I'd like to know if there is anything I can do to be able to write something like the above as part of the description in my .cabal file. Thanks, Josef _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Call for Registration: MGS Spring School

General haskell list - Mon, 02/04/2013 - 12:22pm
************************************************************* Midlands Graduate School 2013 in the Foundations of Computing ************************************************************* The Midlands Graduate School is taking place 8 - 12 April 2013 at the University of Leicester, UK. EARLY REGISTRATION UNTIL 8th FEB at http://www.cs.le.ac.uk/events/mgs2013/ The early registration fee is 520 GBP and covers accommodation, meals, and lectures. The School provides an intensive course of lectures on the Foundations of Computing. It is very well established, having run annually for 10 years, and has always proved a popular and successful event. This year we have Philip Wadler, University of Edinburgh, as guest lecturer. Natasha Alechina, Modal Logic Venanzio Capretta, Coalgebras and Infinite Data Structures Paul Levy, Typed Lambda-Calculus Brian Logan, Multi-agent programming Uday Reddy, Category Theory Eike Ritter, Security and applied pi-calculus Georg Struth, Kleene Algebra Rick Thomas, Formal Lan
Categories: Incoming News

Call for Participation PLACES 2013 (March 23, Rome)

General haskell list - Mon, 02/04/2013 - 11:53am
PLACES 2013 (Programming Language Approaches to Concurrency and Communication-cEntric Software), colocated with ETAPS, will be held on 23 March in Rome. We have a very interesting programme (http://places13.di.fc.ul.pt/programme) of 10 state-of-the-art contributions on various topics relating to concurrency and communication. For registration and info, see the ETAPS web site: http://www.etaps.org/2013 Please join us in Rome! Wim Vanderbauwhede Nobuko Yoshida _______________________________________________ Haskell mailing list Haskell< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell
Categories: Incoming News

haskell build phase is very slow

haskell-cafe - Mon, 02/04/2013 - 11:15am
Hi Cafe, I came from the C/C++ world, recently I play with a haskell editor named yi-editor, I find haskell build phase is very slow: 1.Compile one .hs file is slow 2. When change a little, it will recompile many many files Compare to c, compile a c source file seems much quick then compile a haskell source file. And if i change a .c file, it only recompile the file i changed, and relink, it's awesome. How can i make my build phase more quick? Thanks! _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion