News aggregator

PSA: If you're serializing floating point numbers,don't use binary

haskell-cafe - Tue, 02/09/2016 - 12:19pm
Serialization of floating point numbers with binary is fantastically slow and incorrect if you’re using NaNs, see https://github.com/kolmodin/binary/issues/64 <https://github.com/kolmodin/binary/issues/64> https://github.com/kolmodin/binary/issues/69 <https://github.com/kolmodin/binary/issues/69> I recently spent half a day debugging performance problems because of this, and since backwards compatibility with older formats is required, this problem is probably not going to be solved. We decided to switch to cereal for this reason. With some patches <https://github.com/GaloisInc/cereal/pull/46> cereal was 30x faster for the data we were serializing (scientific computing, mostly Doubles packed in nested records containing vectors). The size of the serialized data is also roughly 3 times smaller – with binary a Double takes at least 25 bytes of space instead of 8. With Float it’s even worse, 25 bytes instead of 8._______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >has
Categories: Offsite Discussion

Joachim Breitner: GHC performance is rather stable

Planet Haskell - Tue, 02/09/2016 - 9:17am

Johannes Bechberger, while working on his Bachelor’s thesis supervised by my colleague Andreas Zwinkau, has developed a performance benchmark runner and results visualizer called “temci”, and used GHC as a guinea pig. You can read his elaborate analysis on his blog.

This is particularly interesting given recent discussions about GHC itself becoming slower and slower, as for example observed by Johannes Waldmann and Anthony Cowley.

Johannes Bechberger’s take-away is that, at least for the programs at hand (which were taken from the The Computer Language Benchmarks Game, there are hardly any changes worth mentioning, as most of the observed effects are less than a standard deviation and hence insignificant. He tries hard to distill some useful conclusions from the data; the one he finds are:

  • Compile time does not vary significantly.
  • The compiler flag -O2 indeed results in faster code than -O.
  • With -O (but not -O2), GHC 8.0.1 is better than GHC 7.0.1. Maybe some optimizations were promoted to -O?

If you are interested, please head over to Johannes’s post and look at the gory details of the analysis and give him feedback on that. Also, maybe his tool temci is something you want to try out?

Personally, I find it dissatisfying to learn so little from so much work, but as he writes: “It’s so easy to lie with statistics.”, and I might add “lie to yourself”, e.g. by ignoring good advise about standard deviations and significance. I’m sure my tool gipeda (which powers perf.haskell.org) is guilty of that sin.

Maybe a different selection of test programs would yield more insight; the benchmark’s games programs are too small and hand-optimized, the nofib programs are plain old and the fibon collection has bitrotted. I would love to see a curated, collection of real-world programs, bundled with all dependencies and frozen to allow meaningful comparisons, but updated to a new, clearly marked revision, on a maybe bi-yearly basis – maybe Haskell-SPEC-2016 if that were not a trademark infringement.

Categories: Offsite Blogs

ICFP 2016 Second Call for Papers

General haskell list - Tue, 02/09/2016 - 8:09am
ICFP 2016 The 21st ACM SIGPLAN International Conference on Functional Programming http://conf.researchr.org/home/icfp-2016 Second Call for Papers Important dates --------------- Submissions due: Wednesday, March 16 2016, 15:00 (UTC) https://icfp2016.hotcrp.com (now open) Author response: Monday, 2 May, 2016, 15:00 (UTC) - Thursday, 5 May, 2016, 15:00 (UTC) Notification: Friday, 20 May, 2016 Final copy due: TBA Early registration: TBA Conference: Monday, 19 September - Wednesday, 21 September, 2016 (note updated conference dates) Scope ----- ICFP 2016 seeks original papers on the art and science of functional programming. Submissions are invited on all topics from principles to practice, from foundations to features, and from abstraction to application. The scope includes all languages that encourage functional prog
Categories: Incoming News

ICFP 2016 Second Call for Papers

haskell-cafe - Tue, 02/09/2016 - 8:09am
ICFP 2016 The 21st ACM SIGPLAN International Conference on Functional Programming http://conf.researchr.org/home/icfp-2016 Second Call for Papers Important dates --------------- Submissions due: Wednesday, March 16 2016, 15:00 (UTC) https://icfp2016.hotcrp.com (now open) Author response: Monday, 2 May, 2016, 15:00 (UTC) - Thursday, 5 May, 2016, 15:00 (UTC) Notification: Friday, 20 May, 2016 Final copy due: TBA Early registration: TBA Conference: Monday, 19 September - Wednesday, 21 September, 2016 (note updated conference dates) Scope ----- ICFP 2016 seeks original papers on the art and science of functional programming. Submissions are invited on all topics from principles to practice, from foundations to features, and from abstraction to application. The scope includes all languages that encourage functional prog
Categories: Offsite Discussion

Combining ST with STM

haskell-cafe - Tue, 02/09/2016 - 5:43am
Hi friends, I have an STM transaction that needs some private, temporary state. The most obvious way is to simply pass pure state as arguments, but for efficiency, I would like this state to be some kind of mutable array, like STArray. I know, STM has TVars and TArray, but since this state is private to the transaction, I am wondering if using TVars/TArrays for private state might be overkill that will unnecessarily slow down the STM commit process. The private state is, by definition, not shared, so including it in the STM log and commit process is, as far as I can tell, pointless. ST and STArray still appear to be the most appropriate tools for the private state, because STRefs and STArrays really, really are private. So this basically means I want to interleave ST and STM in a "safe" way. That is, if the STM transaction retries, I want the ST state to be vaporised as well. Ideally, I would love to be able to say something like this:
Categories: Offsite Discussion

Matrices as Applicatives and Monads

haskell-cafe - Tue, 02/09/2016 - 4:02am
I have been writing code encoding matrices here <https://github.com/Strikingwolf/Learning/blob/master/haskell/src/math/Matrix.hs> as a learning experience. However, I cannot figure out a method to make Matrix an instance of Applicative and Monad. I believe it is possible, but I cannot find an implementation. For context my form of Matrix does not have a requirement to be of integers, it is just a 2-Dimensional array in essence. Thank you in advance for any help you may provide :) _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

[ANN] aeson 0.11.0.0

haskell-cafe - Mon, 02/08/2016 - 11:22pm
Hi haskellers, As a new co-maintainer of aeson I'm happy to announce aeson 0.11.0.0[1]. v0.10 had a number of issues and v0.11 aims to fix all of these. I'm happy to see that all known regressions have been fixed, and I didn't have to write any code myself! ;) Going 0.9 to 0.11 should be no work for most users. I've built all packages in stackage nightly[2] and out of 222 only one needs a non-trivial change (sorry pagerduty maintainers!) Please help out by letting us know if we missed something, including if something should be added to the CHANGELOG[3]. A big thanks to everyone who contributed code to this release: Bryan O'Sullivan Bas van Dijk Oleg Grenrus Herbert Valerio Riedel Ben Weitzman Daniel Díaz RyanGlScott David Johnson Artyom Cale Gibbard Mikhail Glushenkov Ondrej Palkovsky Tim Bodeit mrkkrp And a thank you to everyone else who helped in other ways! All the best, Adam [1] https://hackage.haskell.org/package/aeson-0.11.0.0 [2] https://github.com/bos/aeson/issues/355 [3] https://github.co
Categories: Offsite Discussion

Call for PhD students: Logical Methods in Computer Science (Vienna, Austria)

General haskell list - Mon, 02/08/2016 - 9:44pm
(* Apologies if you got multiple copies of this email *) Funded Doctoral Positions in Computer Science [http://logic-cs.at/phd/] TU Wien, TU Graz, and JKU Linz are seeking exceptionally talented and motivated students for their joint doctoral program LogiCS. The LogiCS doctoral college focuses on interdisciplinary research topics covering (i) computational logic, and applications of logic to (ii) databases and artificial intelligence as well as to (iii) computer-aided verification. THE PROGRAM LogiCS is a doctoral college focusing on logic and its applications in computer science. Successful applicants will work with and be supervised by leading researchers in the fields of computational logic, databases and knowledge representation, and computer-aided verification. FACULTY MEMBERS M. Baaz A. Biere R. Bloem A. Ciabattoni U. Egly T. Eiter C. Fermueller R. Grosu A. Leitsch M. Ortiz R. Pichler S. Szeider H. Tompits H. Veith G. Weissenbacher The LogiCS faculty comprises 15
Categories: Incoming News

ANNOUNCE: hoppy, qtah

haskell-cafe - Mon, 02/08/2016 - 8:11pm
Are you sick and tired of the ease with which Haskell code flows onto the page? Even the thrill of binding to a C library losing its lustre? Look no further! I present to you a tool restoring the good old days of pointer arithmetic, manual memory management, and hours lost to the debugger: Hoppy is a new C++ FFI generator for Haskell. It takes Haskell code that describes a C++ API, and generates C++ and Haskell code to allow the two languages to interact. It supports a good subset of C++, including functions, classes, variables, enums and bitflags, operator overloading, constness, and simple templates. Adding a function takes only a few lines of code, and you normally don't need to write C++ yourself. For example, a definition for std::string is: c_string :: Class c_string = addReqIncludes [includeStd "string"] $ classAddFeatures [Assignable, Comparable, Copyable, Equatable] $ makeClass (ident1 "std" "string") (Just $ toExtName "StdString") [] [ mkCtor "new" []
Categories: Offsite Discussion

Functional Programming Group at the University of Kansas: The Remote JSON library

Planet Haskell - Mon, 02/08/2016 - 6:00pm

JSON-RPC is a simple and well supported protocol for remote procedure calls over HTTP, supporting both synchronous remote methods calls and asynchronous notifications. We want to access JSON-RPC from Haskell, but in a principled way. This blog post discusses the design and user-facing interface of remote-json, a new library for JSON-RPC that makes use of the remote monad design pattern

To give an example from the specification, consider calling a method subtract, with the arguments 42 and 23.

<figure class="highlight">--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} <-- {"jsonrpc": "2.0", "result": 19, "id": 1}</figure>

Here, --> is the data sent from client to server, and <-- is what the server responds. The packet being sent is a simple JSON object, as is the reply from the server.

The JSON-RPC protocol supports batching (sending several method calls and notifications at the same time) and is easy to debug, because it is straightforward to read JSON structures. Furthermore, by using JSON-RPC we can implement our clients in Haskell, and be agnostic about what language or framework the server is written in.

There are at least five existing Haskell libraries that support JSON-RPC. So why a new library? We wanted to build our own because we saw a way of simplifying the API considerably, while still allowing access to all the capabilities of JSON-RPC. Specifically, by using the remote monad design pattern we can automate taking advantage of the batch capability, amortizing the cost of the remote call. Rather than have separate entry points for batched and singleton calls, a single entry point can provide both batched and singleton calls. The library also acts as a case study of using the remote monad.

Basic Design of the JSON-RPC API

We center our design around the RPC monad.

<figure class="highlight">-- The monad data RPC :: * -> * deriving (Monad, Applicative, Functor) -- The primitives method :: FromJSON a => Text -> Args -> RPC a notification :: Text -> Args -> RPC () -- the remote send send :: Session -> RPC a -> IO a</figure>

This is a classical remote monad design - a restricted monad, a small number of primitives for this monad, and a send function. Session is an abstract handle to the web server we want to talk to; we’ll come back to how to generate a Session shortly.

This API gives an (aeson) Value-based access to JSON-RPC. Adding specific primitives gives stronger typing. As an example, consider providing say notifications, that make the remote server say things, a temperature method that returns the remote server’s temperature, and an uptime method that returns the uptime of a specific service.

<figure class="highlight">say :: Text -> RPC () say msg = notification "say" $ List [String msg] temperature :: RPC Int temperature = method "temperature" None uptime :: Text -> RPC Double uptime nm = method "uptime" $ List [String nm] -- provided utilities for generating Args, and parsing the Value result of a method. List :: [Value] -> Args None :: Args</figure>

As an example we have our typed API for temperature, uptime and say, saying “Hello, World!”, getting the temperature, and the uptime of “orange”.

<figure class="highlight">example :: Session -> IO () example s = do (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

send can be used multiple times if needed, acting as translation between our IO monad, and the remote RPC monad. Furthermore, the following JSON-RPC interaction with the server would be a valid trace of interactions for the above example.

<figure class="highlight">--> {"jsonrpc": "2.0", "method": "say", "params": ["Hello, "]} // No reply --> {"jsonrpc": "2.0", "method": "temperature", id: 1 } <-- {"jsonrpc": "2.0", "result": 99, "id": 1} --> {"jsonrpc": "2.0", "method": "say", "params": ["World "]} // No reply --> {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } <-- {"jsonrpc": "2.0", "result": 3.14, "id": 1}</figure>

In this interaction:

  • notifications are methods without id’s, and do not have replies, and
  • methods use an id to tag a result.

This usage is reasonable, but we can do better. We want to bundle together notifications and methods, to amortize the cost of network traffic, but without comprising the API. Specifically, we want users to just write code using send, and the RPC library to figure out the best bundling possible.

The Remote Monad

In the remote monad theory, there are two key concepts:

  • Splitting the monadic primitives into commands and procedures.
    • Commands do not have a result value (typically () in Haskell), and
    • Procedures have a result.

    There are restrictions on commands and procedures, specifically that they must be serializable.

  • Choosing a bundling strategy. There are two strategies that were documented in the original paper and one new bundling strategy that we are investigating.
    • Weak - a bundle of a single command or a single procedure, or
    • Strong - a bundle of a sequence of commands, optionally terminated by a procedure, or
    • Applicative - a bundle of a sequence of commands and procedures, held together using an applicative functor.

By factoring our primitives into commands and procedures, we can automatically split up a monadic computation into maximal bundles, and then use a transport layer to send, execute and get the result from each bundle. The good news is there is a library, called the remote-monad, that has a plug-and-play API. If we provide the best bundling transport we can, then the library can pick the best way of splitting up the monadic computation into our bundles.

Considering JSON-RPC, the concept of notification and method map straight onto the remote monad concepts of commands and procedures. This makes things straightforward.

Weak Bundles

You can create a JSON-RPC instance using weakSession, which takes an encoding of how to send values to a remote server, and returns a Session.

<figure class="highlight">weakSession :: (SendAPI :~> IO) -> Session</figure>

SendAPI :~> IO is a natural transformation.

<figure class="highlight">newtype f :~> g = Nat (∀ a. f a -> g a)</figure>

Specifically, SendAPI :~> IO is a functor morphism between SendAPI and IO, and isomorphic to ∀ a. SendAPI a -> IO a. Operationally, this transformation is how you run SendAPI, using IO. SendAPI is a deep embedding of both synchronous and asynchronous communications of JSON Value.

<figure class="highlight">data SendAPI :: * -> * where Sync :: Value -> SendAPI Value Async :: Value -> SendAPI () </figure>

So, calling send with the RPC monadic remote commands factors up the specifics commands, and calls the natural transformation argument with either Sync or ASync. With the weakSession, every primitive causes its own Sync or ASync; there is no complex bundling.

You can write your own matcher for SendAPI, or use remote-json-client, which provides a function that, when given a URL, returns the SendAPI to IO natural transformation using the wreq library.

<figure class="highlight">clientSendAPI :: String -> (SendAPI :~> IO)</figure>

Putting this together, we get

<figure class="highlight">main :: IO () main = do let s = weakSession (clientSendAPI "http://www.wibble.com/wobble") (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

Having selected the weak remote monad, we have the weakest JSON-RPC interaction - four transactions.

<figure class="highlight">// (1) --> {"jsonrpc": "2.0", "method": "say", "params": ["Hello, "]} // No reply // (2) --> {"jsonrpc": "2.0", "method": "temperature", id: 1 } <-- {"jsonrpc": "2.0", "result": 99, "id": 1} // (3) --> {"jsonrpc": "2.0", "method": "say", "params": ["World "]} // No reply // (4) --> {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } <-- {"jsonrpc": "2.0", "result": 3.14, "id": 1}</figure> Strong Bundles

The strong remote monad bundles together commands, where possible, to amortize the cost of the remote call. In our example above, we have two notifications, and a method call. We want to combine them together. We do so by using the strongSession combinator.

<figure class="highlight">main :: IO () main = do let s = strongSession (clientSendAPI "http://www.wibble.com/wobble") (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

Now, we get a two transactions, which conforms to the JSON-RPC specification.

<figure class="highlight">--> [ {"jsonrpc": "2.0", "method": "say", "params": ["Hello. "]} , {"jsonrpc": "2.0", "method": "temperature", id: 1 } ] <-- [ {"jsonrpc": "2.0", "result": 99, "id": 1} ] --> [ {"jsonrpc": "2.0", "method": "say", "params": ["World "]} , {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } ] <-- [ {"jsonrpc": "2.0", "result": 3.14, "id": 1} ]</figure>

The same RPC send command gives better bundling, solely from changing the strategy from a weakSession to a strongSession. Now, the JSON-RPC specification says

  • “The Server MAY process a batch rpc call as a set of concurrent tasks, processing them in any order and with any width of parallelism.”

This is where it gets interesting. The RPC monad reflects the concurrency policy of the the server, up to method calls. If you wish to insist on sequentiality, then use the weakSession.

Applicative Bundles

One obvious question is “can we improve this reflection of concurrency, and bundle method calls as well as notification?” Yes! For example, Haxl, a Haskell DSL for database access, uses an even stronger bundling strategy, which we call the applicative bundling strategy. In this strategy, methods that are expressed using applicative functors can be bundled together, as well as commands that can already be bundled.

The remote-json library supports applicative bundling. Again, the details are abstracted by the library, and again the monad and applicative functor reflect the concurrency semantics of the server. We’ve added a new remote command uptime that returns the uptime of a specific machine, to aid the demonstration of batching, and reworked the computation to use applicative.

<figure class="highlight">main :: IO () main = do let s = applicativeSession (clientSendAPI "http://www.wibble.com/wobble") (t,u) <- send s $ say "Hello, " *> (pure (,) <*> temperature <* say "World!" <*> uptime "orange") print (t,u)</figure>

The packet now includes two notifications and two methods. (Remember, a notification is a JSON-RPC method that has no id tag.)

<figure class="highlight">--> [ {"jsonrpc":"2.0","params":["Hello,"],"method":"say"} , {"jsonrpc":"2.0","method":"temperature","id":2}, , {"jsonrpc":"2.0","params":["World!"],"method":"say"} , {"jsonrpc":"2.0","params":["orange"],"method":"uptime","id":1} ] <-- [ {"result":65,"jsonrpc":"2.0","id":2} , {"result":68.28,"jsonrpc":"2.0","id":1} ]</figure>

When Applicative do arrives with GHC 8, we can take immediate advantage of this, and start using do-notation to write out remote applicative functors. In fact, we can interperse our usage of monads and applicative RPC, and the package will choose the best bundling it can for the specific strategy.

Summary

We have written a remote monad for JSON-RPC. The library automatically bundles inside send to attempt to amortize the cost of the remote procedure call. It simplifies making multiple requests, without resorting to specialized variants of send. These idea has been used before. For example, Haxl lead the charge of using the applicative bundling strategy, and Oleg implemented a remote monad in OCaml several years ago. And we’ve been using predecessors to remote-json for several years now. Feel free to try remote-json, and if you are adventurous, remote-monad. Or roll your own remote monad. Once you know the pattern, it’s quite straightforward!

In a future blog post, we will look at our JSON-RPC server.

Enjoy!

Justin Dawson and Andy Gill

Resources and Related Work Existing JSON-RPC packages Our Publications about the Remote Monad
  • A. Gill, N. Sculthorpe, J. Dawson, A. Eskilson, A. Farmer, M. Grebe, J. Rosenbluth, R. Scott, and J. Stanton, “The remote monad design pattern,” in Proceedings of the 8th ACM SIGPLAN Symposium on Haskell. New York, NY, USA: ACM, 2015, pp. 59–70.

Categories: Offsite Blogs

Including a "XXX_stub.h" file from another Haskelllibrary?

haskell-cafe - Mon, 02/08/2016 - 3:34pm
Hello -cafe! Let's say I have two Haskell libraries, `A` and `B`. `A` uses the FFI, `foreign export` to be precise, to make a Haskell function available to C land. This generates a "stub" C header file with a corresponding C function declaration. `B` has some C code in it and needs to include the stub header that was generated when compiling `A`, in order to call the function that I 'foreign export'ed in A. When I "naively" include the stub header file for the module in A that contains the 'foreign export' statement, inside one of the C files of the `B` library, the said header can't be found. Is what I want to do at all possible? If yes, how could I make this work? Thanks!
Categories: Offsite Discussion

Joachim Breitner: Protecting static content with mod_rewrite

Planet Haskell - Mon, 02/08/2016 - 10:39am

Since fourteen years, I have been photographing digitally and putting the pictures on my webpage. Back then, online privacy was not a big deal, but things have changed, and I had to at least mildly protect the innocent. In particular, I wanted to prevent search engines from accessing some of my pictures.

As I did not want my friends and family having to create an account and remember a password, I set up an OpenID based scheme five years ago. This way, they could use any of their OpenID enabled account, e.g. their Google Mail account, to log in, without disclosing any data to me. As my photo album consists of just static files, I created two copies on the server: the real one with everything, and a bunch of symbolic links representing the publicly visible parts. I then used mod_auth_openid to prevent access to the protected files, unless the users logged in. I never got around of actually limiting who could log in, so strangers were still able to see all photos, but at least search engine spiders were locked out.

But, very unfortunately, OpenID did never really catch on, Google even stopped being a provider, and other promising decentralized authentication schemes like Mozilla Persona are also phased out. So I needed an alternative.

A very simply scheme would be a single password that my friends and family can get from me and that unlocks the pictures. I could have done that using HTTP Auth, but that is not very user-friendly, and the login does not persist (at least not without the help of the browser). Instead, I wanted something that involves a simple HTTP form. But I also wanted to avoid server-side programming, for performance and security reasons. I love serving static files whenever it is feasible.

Then I found that mod_rewrite, Apache’s all-around-tool for URL rewriting and request mangling, supports reading and writing cookies! So I came up with a scheme that implements the whole login logic in the Apache server configuration. I’d like to describe this setup here, in case someone finds it inspiring.

I created a login.html with a simple HTML form:

<form method="GET" action="/bilder/login.html"> <div style="text-align:center"> <input name="password" placeholder="Password" /> <button type="submit">Sign-In</button> </div> </form>

It sends the user to the same page again, putting the password into the query string, hence the method="GET" – mod_rewrite unfortunately cannot read the parameters of a POST request.

The Apache configuration is as follows:

RewriteMap public "dbm:/var/www/joachim-breitner.de/bilder/publicfiles.dbm" <Directory /var/www/joachim-breitner.de/bilder> RewriteEngine On # This is a GET request, trying to set a password. RewriteCond %{QUERY_STRING} password=correcthorsebatterystaple RewriteRule ^login.html /bilder/loggedin.html [L,R,QSD,CO=bilderhp:correcthorsebatterystaple:www.joachim-breitner.de:2000000:/bilder] # This is a GET request, trying to set a wrong password. RewriteCond %{QUERY_STRING} password= RewriteRule ^login.html /bilder/notloggedin.html [L,R,QSD] # No point in loggin in if there is already the right password RewriteCond %{HTTP:Cookie} bilderhp=correcthorsebatterystaple RewriteRule ^login.html /bilder/loggedin.html [L,R] # If protected file is requested, check for cookie. # If no cookie present, redirect pictures to replacement picture RewriteCond %{HTTP:Cookie} !bilderhp=correcthorsebatterystaple RewriteCond ${public:$0|private} private RewriteRule ^.*\.(png|jpg)$ /bilder/pleaselogin.png [L] RewriteCond %{HTTP:Cookie} !bilderhp=correcthorsebatterystaple RewriteCond ${public:$0|private} private RewriteRule ^.+$ /bilder/login.html [L,R] </Directory>

The publicfiles.dbm file is generated from a text file with lines like

login.html.en 1 login.html.de 1 pleaselogin.png 1 thumbs/20030920165701_thumb.jpg 1 thumbs/20080813225123_thumb.jpg 1 ...

using

/usr/sbin/httxt2dbm -i publicfiles.txt -o publicfiles.dbm

and whitelists all files that are visible without login. Make sure it contains the login page, otherwise you’ll get a redirect circle.

The other directives in the above configure fulfill these tasks:

  • If the password (correcthorsebatterystaple) is in the query string, the server redirects the user to a logged-in-page that tells him that the login was successful and instructs him to reload the photo album. It also sets a cookie that will last very long -- after all, I want this to be convenient for my visitors. The query string parsing is not very strict (e.g. a password of correcthorsebatterystaplexkcdrules would also work), but that’s ok.
  • The next request detects an attempt to set a password. It must be wrong (otherwise the first rule would have matched), so we redirect the user to a variant of the login page that tells him so.
  • If the user tries to access the login page with a valid cookie, just log him in.
  • The next two rules implement the actual protection. If there no valid cookie and the accessed file is not whitelisted, then access is forbidden. For requests to images, we do an internal redirect to a placeholder image, while for everything else we redirect the user to the login page.

And that’s it! No resource-hogging web frameworks, not security-dubious scripting languages, and a dead-simple way to authenticate.

Oh, and if you believe you know me well enough to be allowed to see all photos: The real password is not correcthorsebatterystaple; just ask me what it is.

Categories: Offsite Blogs

RebindableSyntax, ifThenElse, and pattern matching

haskell-cafe - Sun, 02/07/2016 - 9:08pm
In a custom prelude, I have written the following definitions: data Truth = True | False ifThenElse :: Truth -> a -> a -> a ifThenElse True x _ = x ifThenElse False _ x = x (==) :: a -> a -> Truth (==) = ... I'm replacing Bool with my own Truth type. Clients will be built with RebindableSyntax, so that they will use these definitions for desugaring. However, if I write this: f :: Text -> Text f "r" = "rrr" f other = other I get a build error indicating that GHC expected the (==) operator to return a value of type Bool, rather than Truth. Shouldn't pattern matching desugar to use overloaded ifThenElse in these situations? Or is it expected that use of GHC.Types.Bool is hard-coded even with RebindableSyntax enabled? Thanks, Chris _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

[ANNOUNCE] GHC 8.0.1 release candidate 2

glasgow-user - Sun, 02/07/2016 - 8:13pm
Hello everyone, The GHC Team is very pleased to announce the second release candidate of the Glasgow Haskell Compiler 8.0.1 release. Source and binary distributions as well as the newly revised users guide and Haddock documentation can be found at http://downloads.haskell.org/~ghc/8.0.1-rc2/ This is the second in a series of release candidates leading up to the 8.0.1 release and fixes many of the issues reported in -rc1. These fixes include, * A re-rewrite of the pattern checker by George Karachalias. The new checker should have far more predictable performance characteristics while sacrificing minimal reasoning power. This should resolve a large number of the issues felt in -rc1. * Richard Eisenberg has been hammering out all manner of type-application- and TypeInType-related issues (#11335, #11416, #11405). There is still more work to do here, however (e.g. #11471). * Matthew Pickering has restored support for multi-clause pattern synonyms (#11367) * A latent bug
Categories: Offsite Discussion

Incredibly slow type-level Nub

haskell-cafe - Sun, 02/07/2016 - 3:37pm
Dear Cafe, I have faced a type-level performance problem (with GHC 7.10.3). I am trying to implement type-level Nub which removes duplicates from a type-level list. My implementation [1] with an example of a list of length 20 takes forever to compile. If you reduce the size of the example list (e.g. to 15 items), it will compile faster. Also, if you remove the Nub application from exampleVals, it compiles instantly (this is how I know the problem is in Nub). My question is how can I speed up type-level Nub? And less importantly why exactly is it this slow? The practical application for this is building automatic tests [2] for servant-swagger. There I am interested in generating exactly one test for each distinct type. Kind regards, Nick [1] https://gist.github.com/fizruk/06458fe8b62a1e562af1 [2] http://hackage.haskell.org/package/servant-swagger-1.0.2/docs/Servant-Swagger-Test.html _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org
Categories: Offsite Discussion

New gtk2hs 0.12.4 release

gtk2hs - Wed, 11/21/2012 - 12:56pm

Thanks to John Lato and Duncan Coutts for the latest bugfix release! The latest packages should be buildable on GHC 7.6, and the cairo package should behave a bit nicer in ghci on Windows. Thanks to all!

~d

Categories: Incoming News