[web-devel] Hoogle Advice
Jeremy Shaw
jeremy at n-heptane.com
Tue Jan 25 18:14:50 CET 2011
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?
> * 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
> 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)
5. happstack-server currently supports lazy IO natively and should
be a good match
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.
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..
> 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.
> 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...)
> * 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
> audience.
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
IO
))))
:p
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 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."
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110125/1e00d5ea/attachment.htm>
More information about the web-devel
mailing list