First (real) Yesod commit

OK, I’ve gotten the first real code commit to Yesod. There are a few decisions that I made with this commit:

  • I’d originally intended to put generic web utilities in a separate repository. I changed my mind with this one, deleted my webutils repository on github, and merged all the code into Yesod. This should make it easier to maintain.
  • The name given to this first bit of code is the “backend” code. This includes the definition of a request and a response, and the definition of an application (Request -> IO Response) and an adapter (something which runs an application).

The only adapter included in this commit is Standalone, which- as you might guess- runs a standalone server. I will include CGI in another commit, and then barring bug fixes, that’s about all I want in the backend code. I do want to have a FastCGI adapter, but I don’t want the fastcgi dependency to break building on systems without the C library, so I’d prefer to have a separate yesod-fastcgi repository. That would be a great project for anyone looking to contribute…

Also, I’ve included an “examples” directory. I’m hoping to keep this populated with more and more advanced examples as the framework progresses to give guidance to new users. Nonetheless, I do not expect that to be a replacement for good documentation; this framework will hopefully have both full Haddock documentation and more tutorial-oriented documentation at the appropriate time.

The next piece to work on will be the controller. So if anyone has any architectural ideas, speak now or forever hold or peace. The one thing I am thinking right now is: KEEP IT SIMPLE. It seems like everyone insists on using regexs or parsers for handling routing. I just have to ask: why? I’ve never heard of routing that does something much more complicated than dealing with a path like a filesystem path, ie separating on the slashes.

So here’s my idea: allow some kind of super-general function for advanced routing, but have a simplified interface for the usual case. If that sounds too vague, then just wait for the code to be available ;).


Tags: , ,

6 Responses to “First (real) Yesod commit”

  1. sclv Says:

    The reason you want a parser for routing is if you have a url that includes, e.g., a record number as part of it, or etc. Essentially any sort of restful url will mean that you’re pulling things besides strings out. So yeah, you split on slashes, but what you do with the data *between* the slashes is the trick.

  2. syjer Says:

    take a look at the Ella framework [1] for the routing, it’s quite interesting (even though I prefer the HVAC approach).


  3. sclv Says:

    Regexes are a terrible idea, I agree. Because they’re crummy almost-parsers. But a real lightweight parser, or hook to such, is a good idea. What if you want not just integers, but also doubles? Or integers in a certain range only? You want to tie the marshaling from the url directly into what you’re extracting from haskell, precisely to make things more type-safe. If you start generalizing your sketch slightly so that you have a polymetric version (i.e., (Parseable a => Part a)) then you’ll end up with what i’m talking about very rapidly. Also, if you do things carefully, you get reverse invocation for free — i.e. a fully accurate way to turn urls into haskell function calls that invoke them. And that’s not all that interesting, but it also lets you turn urls into, e.g., a javascript back end, and even maybe a simple form…

  4. sclv Says:

    Oh, I should note that the other thing about a parser mentality is that I think applicative choice () is much clearer and more expressive than a list. Composition becomes a nested set of execution paths — the exact manner in which they are joined is hidden. Controllers should, I think, have a syntax that encourages thinking of them as decision trees rather than as a flat set of alternatives. Additionally, it frees you up to conduct actions *while* traversing the tree, rather than only at the nodes of a list. This helps code reuse. E.g. if you have a messageboard, you only need to retrieve the basic information on a particular board/thread/whatever in one place rather than at each child node. If you structure your routes right you can also get some very clever caching that shakes out of this — cached values can become similarly not per-db-query or per-page, but span an appropriate subrange.

    It feels different working this way, but more functional, conceptually fusing elements of web frameworks that are declarative, but traditionally distinct, into a single pass. All the logic can become tightly integrated and compact.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: