[web-devel] Hoogle Advice
michael at snoyman.com
Tue Jan 25 19:10:44 CET 2011
On Tue, Jan 25, 2011 at 7:14 PM, Jeremy Shaw <jeremy at n-heptane.com> wrote:
> On Jan 24, 2011, at 11:54 PM, Michael Snoyman wrote:
> * They are writing a site that involves very few of the features
> offered by a framework. For example, no routing, no persistence, no
> templating. In such a case, it's likely that a framework will simply
> get in their way.
> Yes. I think that is a pretty small subset of web applications?
Yes, I agree.
> * Haskellers tend to be an "opinionated" bunch, so it's not surprising
> that any random Haskeller may disagree with the design decisions of
> specific frameworks.
> I think that many random Haskellers start by assuming their ideas are better
> than everyone else's and don't even look to see if they disagree with the
> decisions of specific frameworks :p
I also agree. Or was that poking fun at a specific framework? ;)
> Can you honestly tell me that you think Happstack is that right tool
> for every site?
> Not for every site. But possibly for every site that Neil is going to be
> working on. Many of his 'complaints' about WAI are things which are
> addressed by Happstack to some degree:
> 1. statusOK vs status200 - happstack offers combinators like, ok, notFound,
> seeOther, unauthorized, etc. and a function 'resp' for setting the response
> code explicitly.
> 2. predefined list of headers like "content-type" - happstack includes many
> constants an Handler.hs (they could be exposed better though)
> 3. what happens when using 'ResponseFile' but the file is not found -
> happstack's documentation says what happens when serveFile or serveDirectory
> does not find the file
> 4. exception handling -- the happstack docs show how to integrate exception
> catching and handling into your ServerPartT (though they could be more
> explicit about what happens to uncatch exceptions)
Let's be honest here: none of those are "serious" problems with WAI:
docs need to be updated, function names are up for debate.
> 5. happstack-server currently supports lazy IO natively and should be a
> good match
WAI also supports lazy IO (responseLBS).
> 6. happstack has a showResponse function for debugging
> 7. the ServerPartT monad has a built-in FilterT monad which makes it easy
> to apply a function (Response -> Response) to modify the response.
In all honesty, this is an argument *against* frameworks, not for
them: at a WAI level, we don't need a FilterT monad, since an
application is just a function.
(And I can't believe I'm giving arguments against frameworks here, I
obviously think they're a good thing. I'm just trying to be fair.)
> 8. killing the running background threads in GHCi is really tricky. You
> need to basically track all the forkIO calls and save the threadIds so that
> you can come back and kill them later when you get Crtl+C. But, happstack
> does have support for doing that :) Also, the waitForTermination function
> that happstack provides also has support for Windows.
> So, given the fact that all the points Neil raised regarding WAI are
> addressed to some degree already in Happstack -- it seems like working with
> Happstack would not be a bad thing..
Personally: I think overall it *would* be a better approach. However,
remember that to each his own. My goal is to enable *whatever*
workflow someone wants to take. If there is a desire for a bare-metal
web programming approach using WAI (or something else), I'd like to
help facilitate it.
> That's one of the main reasons I've designed Yesod and WAI the way I
> have. By splitting the project up into so many pieces (Hamlet,
> Persistent, authenticate, etc), users get to pick and choose exactly
> what they want.
> Yes. Happstack is the same way.
Yes, and I'm a fan of that. I just wish that other frameworks (cough,
cough) could take a similar approach.
> It's very likely that Neil may end up reinventing a lot of the
> features of a framework in this Hoogle project. But I *still* think
> this is a good thing:
> Based on my familiarity with Neil's previous work on things like catch,
> super-o, and other projects, I am interested to see what he comes up with as
> well. He has a tendency to address important issues that other people have
> swept under the rug.
> * And even if none of that happens, it probably took him less time to
> rewrite the features he needed than go through either the Happstack or
> Yesod tutorials. For someone developing lots of sites, the learning
> curve is IMO worth it; for a one-off project, I doubt it is.
> I highly doubt that. It can't take more than an hour or two to go through
> the happstack tutorial. What I do think is true is that:
> 1. writing code is satisfying and feels productive
> 2. reading documentation is boring and doesn't feel productive
> 3. most programmers assume their code is like a beautiful flower, and that
> everyone else's is a putrid swamp of sewage.
> And hence they are happy to spend days reinventing something rather than
> spend an hour reading about an existing solution :p (This is not directed at
> Neil who actually asked for advice about what already existed. Though he may
> still feel that Happstack is a putrid swamp of sewage...)
Probably also very true. (Not the putrid swamp of sewage bit, the
> * If he is so inclined, he could release this "boilerplate" code into
> a separate package and, walla, we have a *new* Haskell framework,
> building on top of what we have already, that caters to a new
> Or, maybe it just reimplements what we already have with minor cosmetic
> differences, weaknesses compared to other frameworks due to have less real
> world usage, and a few improvements which could have been more easily added
> to existing frameworks.
> For example, let's consider what a framework is likely going to have for
> it's monad. For starters you are going to want easy access to the Request.
> So you'll have something like this:
>> type FrameworkT = ReaderT Request m a
> Then you'll realize you need some way to escape things early and return an
> error, so you might add the ErrorT monad transformer so you have a way to
> escape and return a Response.
>> type FrameworkT = ReaderT Request (ErrorT Response m) a
> Then you'll realize you need some way to modify the Responses to do things
> like add extra headers (for cookies, etc) or compress the Response, or
> whatever. So you might had a StateT that can hold filters to apply:
>> type FrameworkT = ReaderT Request (ErrorT Response (StateT (Response ->
>> Response) m)) a
>> setFilter :: (Response -> Response) -> FrameworkT m a
>> appendFilter :: (Response -> Response) -> FrameworkT m a
> And then you might decide that you want your FrameworkT monad to be an
> instance of MonadPlus, so you add in MaybeT:
>> type FrameworkT = ReaderT Request (ErrorT Response (StateT (Response ->
>> Response) (MaybeT m))) a
> And now you have created a new Framework monad that looks suspiciously like
> the ones that already exist in other frameworks. Happstack, Snap, and Yesod
> all have variations on this basic theme. For example, in Yesod it appears
> you ultimately came up with,
> type GHInner s m =
> ReaderT (HandlerData s m) (
> MEitherT HandlerContents (
> WriterT (Endo [Header]) (
> StateT SessionMap ( -- session
> We don't really need anyone to reinvent another variation of this out of
> ignorance. They should either blatantly rip it off, or tell us why it is
> wrong and come up with something better :p
I do not disagree here either.
> I don't like seeing a fractured community, but I think this is exactly
> the opposite effect: we're seeing new levels of integration of
> pre-existing tools than we saw before.
> Oh ?
> Anyway, I am not against the development of new frameworks. But I think it
> would be better if people started new frameworks because they have
> discovered why the current ones are fundamentally broken, rather than just
> assuming they are and then reinventing the same thing :) But, in practice,
> people are going to keep reinventing the wheel, so I'll just keep my eye on
> them and steal the good parts ;)
> - jeremy
> p.s. Nothing in this message is intended to be a personal attack on anyone
> specific. It more reflects years of hearing people say, "Oh I didn't realize
> happstack already could do that."
For the record, I didn't realize that Happstack could actually serve
web pages. I thought it could just create BBS games.
More information about the web-devel