--- Log opened Tue Feb 17 00:00:05 2009
--- Day changed Tue Feb 17 2009
00:00 < dsrogers> I'm guessing it's related too trhsx
00:01 < mae> *Main Happstack.Server.SimpleHTTP> :t dir
00:01 < mae> dir :: (ServerMonad m, Control.Monad.MonadPlus m) =>
00:01 < mae>        String -> [m a] -> m a
00:01 < mae> dsrogers: is this the example app?
00:06 < h_buildbot> Build for ghc-6.10.1 OK. Test suite ran. 14/69 test cases failed. Check http://buildbot.happstack.com/ for details.
00:11 < mae> dsrogers: are you working on the example app?
00:25 < mae> dsrogers: what should we name the 'server par' version of webHSP in here: http://patch-tag.com/publicrepos/happstack/happstack/src/Happstack/Server/HSP/HTML.hs
00:25 < mae> server part *
00:26 < mae> i was thinking hspToSP
00:40 < dsrogers> you don't need it.
00:40 < dsrogers> I fixed that already
00:40 < dsrogers> I just generalized the type.
00:41 < dsrogers> I think it's just (MonadIO m) => HSP XML -> m Response
00:41 < dsrogers> and yes, it's the example app.
00:41 < dsrogers> it insists on being a concrete type for some reason.
00:41 < dsrogers> I don't know why
00:42 < mae> um
00:42 < mae> righgt
00:42 < mae> right *
00:42 < mae> because simpleHTTP takes a concrete type no?
00:43 < dsrogers> simpleHTTP is nowhere in this class.
00:43 < dsrogers> file.
00:47 < mae> well
00:47 < mae> there is no instance for FilterMonad Response m
00:47 < mae> hehe
00:47 < dsrogers> right...
00:47 < mae> what exactly is filter monad?
00:48 < mae> this is something you created, yets?
00:48 < mae> yes *
00:48 < dsrogers> yes.
00:48 < mae> the problem lies with fileServe i think
00:49 < dsrogers> FilterMonad is a typeclass for the methods getFilter, setFilter, composeFilter and applyFilter
00:49 < dsrogers> "things that modify responses" basically
00:49 < dsrogers> though it's not limited to responses.
00:49 < dsrogers> It's part of the implementation of FilterT.
00:49 < mae> fileServe :: MonadIO m => [FilePath] -> FilePath -> ServerPartT m Response
00:50 < dsrogers> not anymore.
00:50 < mae> ah so Filter can be used for gzip compression for instance, or for xslt
00:50 < dsrogers> you could...
00:51 < mae> dsrogers: is that type signature for fileServe correct?
00:51 < dsrogers> WebT uses it to create the response filter.
00:51 < dsrogers> no.
00:51 < mae> this is the problem
00:51 < mae> AppControl.hs uses fileServe
00:51 < dsrogers> it's fileServe :: (ServerMonad m, FilterMonad Response m, MonadIO m) => [FilePath] -> FilePath ->
00:51 < dsrogers>  m Response
00:51 < dsrogers> way more general
00:52 < mae> ok
00:52 < mae> so m Response
00:52 < dsrogers> which ServerPartT IO Response is just that.
00:52 < dsrogers> so it should work fine...
00:52 < dsrogers> but it doesn't
00:52 < mae> so remove the [] ?
00:52 < dsrogers> pardon?
00:53 < mae> heres what mine looks like
00:53 < mae>   , dir "public"  $ fileServe ["index.html"] "public"
00:53 < mae> i just fixed it
00:53 < mae> well not fixed
00:53 < mae> but
00:53 < mae> u know.
00:53 < mae> did you pull in geezusfreeek's patch?
00:53 < mae> or is this pre-singular dir ? :)
00:53 < dsrogers> pre-singular dir
00:54 < mae> ah
00:54 < dsrogers> I'm fixing that now
00:54 < mae> k
00:54 < mae> i was updating the sample app
00:54 < mae> but since your doing it i'll wait to see your code :)
00:54 < mae> i am still stuck in ServerPartT / WebT land in my head
00:59 < dsrogers> it's done.
00:59 < dsrogers> I'm just resolving conflicts now.
00:59 < mae> k
00:59 < mae> where are all these typeclasses / monads defined?
01:00 < dsrogers> SimpleHTTP
01:00 < dsrogers> they are documented there too
01:02 < dsrogers> you broke happstack-contrib when you changs where webUpdate and webQuery came from
01:02 < dsrogers> where are those now?
01:02 < dsrogers> Happstack.State.Util?
01:02 < mae> Happstack.Util
01:03 < dsrogers> um, where is Happstack.Util?
01:03 < mae> I guess to me they seemed logically well-placed since it is kind of a function which is supposed to integrate Server and State
01:03 < mae> in happstack
01:03 < mae> happstack/happstack
01:03 < mae> happstack/happstack/src
01:03 < mae> ; )
01:03 < dsrogers> then you also broke build-install-all
01:03 < mae> nope
01:03 < mae> i tested it
01:04 < mae> what error are you getting?
01:04 < dsrogers> because it builds Happstack-contrib before it builds Happstack.
01:04 < mae> yeah thats fine.
01:04 < dsrogers> and happstack-contrib wants to use webQuery
01:04 < mae> you must not have a recent patch
01:04 < mae> it doesn't depend on it
01:04 < dsrogers> it does now.
01:04 < mae> i replaced those with (liftIO . query)
01:04 < dsrogers> ahhh
01:05 < mae> and (liftIO . update)
01:05 < mae> there was only 2 spots
01:05 < dsrogers> hmm.
01:05 < dsrogers> I just pulled patches.
01:05 < mae> I mean, technically, it could depend on happstack
01:05 < dsrogers> I didn't get it.
01:05 < dsrogers> oooooo.
01:05 < dsrogers> I reverted your change when I resolved conflicts.
01:05 < mae> : )
01:05 < mae> happstack does not depend on happstack-contrib
01:06 < mae> since contrib is where code goes to die
01:06 < mae> or be useful to some people i guess :)
01:06 < mae> its kind of like purgatory
01:06 < dsrogers> yeah.
01:06 < dsrogers> it was just because of conflicts.
01:07 < mae> k
01:12 < mae> so um
01:12 < mae> semantically
01:12 < mae> the typeclass ServerMonad replaces ServerPartT
01:12 < mae> and the typeclass FilterMonad replaces WebPartT?
01:13 < dsrogers> kinda, yeah
01:14 < dsrogers> FilterMonad has a lot of new functionality.  WebT only had composeFilter.
01:14 < dsrogers> the other three are new.
01:14 < mae> ok
01:14 < dsrogers> There is also WebMonad.
01:14 < dsrogers> which has finishWith
01:14 < mae> so why typeclass? whats a use case where i will extend these typeclasses?
01:15 < dsrogers> WebT and ServerPartT both implement it.
01:15 < dsrogers> it's how I got existing code to compile with little or no changes.
01:15 < mae> ic
01:16 < mae> well see if you can wrap up a stopping point on that patch
01:16 < mae> i want to try to work on the example app some more tonight
01:18 < dsrogers> yeah.
01:18 < dsrogers> I'm at a stopping point now.
01:18 < dsrogers> the example apps are the parts that don't compile...
01:18 < mae> oh
01:18 < mae> thats no good
01:19 < dsrogers> they didn't compile before.
01:19 < mae> well i mean, in the end it has to pick a finite type
01:19 < dsrogers> nono, I fixed that.
01:19 < dsrogers> they are using arrays without msum
01:19 < dsrogers> err, lists
01:19 < mae> ah ok
01:19 < mae> so thats why it was getting upset
01:19 < mae> because lists are homogenous
01:19 < dsrogers> nooooo
01:20 < dsrogers> totally unrelated to the previous problem.
01:20 < mae> ? heh
01:20 < mae> oh, what was the prob?
01:20 < dsrogers> =<< binds more tightly than $ apparently
01:21 < mae> ah.
01:26 < dsrogers> there.
01:26 < dsrogers> patch sent.
01:27 < mae> applied / pushed
01:27 < dsrogers> great!
01:28 < dsrogers> all the examples don't compile anymore.
01:28 < dsrogers> I'm fixing that.
01:28 < dsrogers> that's what you get for pushing non-backwards compatible changes.
01:28 < dsrogers> :-P
01:28 < mae> how can this take better advantage of the new style?
01:28 < mae> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=1477#a1477
01:28 < mae> didn't you add some magick for withData?
01:29 < dsrogers> I added getData in the event you want to do something like withData inside the monad.
01:30 < dsrogers> so you would drop the withData wrapper and add in a:
01:30 < dsrogers> myE <- getData
01:30 < dsrogers> e <- maybe mzero return
01:30 < dsrogers> but there is nothing /wrong/ with that style.
01:31 < dsrogers> e <- maybe mzero return mbE, rather
01:32 < dsrogers> I like getData better because (gasp!) you might actually want to handle the failure to parse your data!
01:32 < mae> lol
01:32 < dsrogers> fileServe is neat.
01:33 < dsrogers> when I cleaned that up, I got to drop several parameters.
01:34 < dsrogers> you could clean it up more by embedding a ReaderT into the monad fileServe builds to hold all your common environment (like modification times and mime-types) to clean it up even further.
01:34 < dsrogers> though then you'd have to go all concrete and use a ServerPartT
01:35 < dsrogers> err, no you wouldn't..
01:35 < dsrogers> I should do this...
01:37 < h_buildbot> Build for ghc-6.8.3 OK. Test suite ran. 15/69 test cases failed. Check http://buildbot.happstack.com/ for details.
01:39 < mae> lol
01:39 < mae> i like what you've done but it will take some time to wrap my brain around :)
01:42 < mae> isn't this why you had to do ServerPartT in AppControl? : -- only accept a post method for adding a new guestbook entry
01:42 < mae> simpleHTTP :: (ToMessage a) => Conf -> ServerPartT IO a -> IO ()
01:42 < mae> shouldn't it be m a
01:42 < dsrogers> no.
01:42 < dsrogers> simpleHTTP must be done in IO
01:42 < dsrogers> I tried to generalize it.
01:42 < dsrogers> you can't.
01:42 < mae> right
01:43 < dsrogers> because then it would complain when appt was applied to simpleHTTP
01:43 < dsrogers> but it complains if you just take the type signature off.
01:43 < mae> heh
01:43 < h_buildbot> Build for ghc-6.10.1 OK. Test suite ran. 15/69 test cases failed. Check http://buildbot.happstack.com/ for details.
01:44 < dsrogers> you're thinking about it too hard, probably
01:45 < dsrogers> just delete all references to anyRequest, withRequest
01:45 < dsrogers> replace method f $ do ... with do methodM f ...
01:46 < dsrogers> and delete any arguments passing the request around and replace that with rq <- askRq
01:46 < dsrogers> delete your type signatures and let got sort it out.
01:46 < dsrogers> s/got/god/
01:47 < dsrogers> I've practically reached automatic mode on it so far.
01:47 < mae> heh
01:48 < mae> dsrogers: any reason getData returns Maybe
01:48 < dsrogers> because it might not parse.
01:48 < mae> wouldn't Either make more sense, (you could return an error)
01:48 < mae> you could handle validation in FromData
01:49 < dsrogers> the monad is ReaderT ... Maybe x
01:49 < dsrogers> you'd have to change the type of RqData
01:49 < dsrogers> it'd be nice to return an error though
01:49 < mae> ah
01:49 < dsrogers> the old implementation just assumes that your handler will give up when you fail to parse something
01:49 < mae> ok by parse you mean, before it even gets passed to fromData
01:50 < mae> i've been thinking about how we can handle form validation
01:51 < dsrogers> you should implement someting and prove it's useful before hacking around with rqData
01:51 < mae> true
01:51 < mae> and i guess your not forced to use the FromData typeclass
01:52 < dsrogers> but something that uses ReaderT ... Error a would be great!
01:52 < dsrogers> yeah
01:52 < mae> I could create FromDataWithValidation
01:52 < mae> and then do
01:52 < mae> withDataFn
01:52 < mae> hmm
01:52 < mae> but then can't use getData
01:52 < dsrogers> getDataFn
01:52 < dsrogers> that's what you want
01:55 < mae> ah
01:55 < mae> so
01:57 < mae> res <- getDataFn validateData
01:57 < mae> case res of
01:57 < dsrogers> exactly
01:57 < mae>   (Left errors) ->
01:57 < paulvisschers> Now that you are talking about  this, is there a nice way to do your validation atomically with whatever update method you want to perform?
01:57 < mae>   (Right answer) ->
01:57 < paulvisschers> especially when using (somthing like) formlets?
01:58 < mae> i am not sure what you mean by atomically
01:58 < mae> but if you mean that it only will complete the transaction if it is valid, then sure.
01:58 < paulvisschers> mae: you can actually omit the parentheses there
01:58 < mae> you validate it, then commit it.
01:59 < paulvisschers> I mean that it is a single action and no other state changing actions can interleave with it
01:59 < dsrogers> you'll need something other than getDataFn.  It assumes RqData.
01:59 < dsrogers> and you need to use something other than RqData
01:59 < mae> ic
01:59 < mae> needs more thought
01:59 < dsrogers> but getDataFun is pretty trivial.
02:00 < paulvisschers> so as to prevent a scenario where you validate something, but then something changes in the state and it becomes invalid, so it becomes invalid before you commit
02:00 < mae> well good day overall, lets try to get the kinks out / unbreak stuff / document now :)
02:00 < dsrogers> getDataValidationFun:: MyRqData a -> m (Either e a)
02:00 < mae> good job daniel!
02:00 < dsrogers> thanks
02:00 < dsrogers> paul: you can rollback, right?
02:01 < paulvisschers> dsrogers: I don't think so
02:01 < paulvisschers> dsrogers: Can you?
02:01 < mae> paulvisschers: you could always include the validation in the state event itself
02:01 < mae> i.e.
02:01 < mae> myInputAndValidationFunction
02:01 < mae> mkMethods ['myInputAndValidationFunction]
02:02 < dsrogers> is the ACID monad a monad transformer?
02:02 < paulvisschers> mae: That's what I have right now, but since validation is intimately tied to form generation, I need to return an html form on failure (with the filled in data and error messages for the user)
02:02 < dsrogers> (I've never actually used this stuff)
02:02 < mae> could be type (State (Either Success, Failure))
02:02 < dsrogers> I think I've fixed your problem though.
02:02 < mae> paulvisschers: have your state event return the errors in a list
02:03 < dsrogers> Is the monad that does the state transaction a monad transformer?
02:03 < mae> and then apply the visual tweaks at a higher level
02:03 < paulvisschers> mae: I could do that, but that would kind of defeat the purpose of my form library
02:03 < mae> hehe
02:03 < mae> not sure
02:04 < dsrogers> 'cause if so, there is no reason you can't add your monad to the ServerPartT monad stack now.
02:04 < mae> perhaps some of the heavy duty TH stuff can be replaced with more flexible typeclasses
02:04 < dsrogers> write a lifting instance, and ...
02:04 < paulvisschers> mae: I think it would be nice to get rid of the TH as much as possible
02:05 < paulvisschers> mae: And make the state stuff a little bit more convenient, since now it breaks all kinds of useful polymorphism
02:06 < mae> dsrogers: the monad where the meat is for State is I believe in http://patch-tag.com/publicrepos/happstack/happstack-state/src/Happstack/State/Monad.hs
02:06 < mae> paulvisschers: agreed, but it will take some time for us to learn the code
02:06 < mae> right now we are adopting it
02:06 < mae> ok gotta run yall, thanks!
02:12 < paulvisschers> dsrogers: so do you have any suggestions?
02:12 < dsrogers> yes.
02:13 < dsrogers> err, maybe.
02:13 < dsrogers> you might be able to embed your monad into ServerPartT now.
02:14 < dsrogers> but I haven't really used this stuff.
02:14 < dsrogers> I only know SimpleHTTP really well.
02:15 < paulvisschers> But will that guarantee atomicity?
02:15 < dsrogers> if it's possible it will.
02:16 < dsrogers> it it doesn't then the monad won't allow it.
02:16 < dsrogers> haskell is neat that way
02:17 < mae> it won't
02:17 < mae> the event system is asynchronous
02:17 < mae> i mean
02:17 < paulvisschers> but isn't it a problem that you need to do something like query SomeMethod in one part of the ServerParT and then do an update SomeOtherMethod later?
02:18 < mae> if you are running the update and validation stuff in the same thread, then you should be fine
02:18 < mae> because this will ensure correct ordering
02:18 < paulvisschers> since those will be separate state actions
02:18 < mae> no
02:18 < mae> because it will be sequenced
02:18 < mae> anything that runs in IO runs in sequence
02:19 < dsrogers> removing the [],s was the right thing to do.
02:19 < mae> + if you query something, that will be synchronous, so you don't have to worry about semaphores or any of that crap
02:19 < mae> dsrogers: I agree
02:19 < dsrogers> because it's very common to have only one part.
02:19 < dsrogers> the more I convert the more I appreciate how many []'s I'm deleting
02:20 < mae> paulvisschers: the atomicity is only guaranteed in the one server instance anyways, the multimaster uses optimistic locking
02:21 < mae> in any case
02:21 < mae> just kick the tires on the thing and don't worry about the problems until you know they exist :)
02:21 < paulvisschers> mae: I understand that the order is going to be okay for a single validation and update, but what if you have multiple users submitting forms at the same time, isn't it possible that you get something like validation1, validation2, update1, update2
02:21 < paulvisschers> ?
02:22 < paulvisschers> mae: Where update2 invalidates the first user's data, but that is already checked
02:22 < mae> i think i see what your saying
02:22 < mae> the only way to ensure transactional integrity with multiple operations is to roll it into one state event
02:23 < paulvisschers> mae: Right, but that isn't really nice since I'm returning html
02:24 < mae> well, again, does the templating/styling aspect have to be in the state event?
02:24 < mae> you could also pass a lambda into the state event
02:24 < mae> which returns the html
02:25 < mae> or depending on how you do it, it could even return a WebPartT
02:25 < paulvisschers> mae: How do you mean?
02:25 < paulvisschers> WebPartT?
02:26 < mae> What i mean to say is, you can setup the state event to take a lambda as an argument the lambda could be of type (a -> Html) for instance
02:26 < mae> which styles it
02:26 < mae> does this make any sense? :)
02:26 < paulvisschers> Won't you get a method too general error?
02:26 < mae> it makes sense in my head
02:26 < mae> a was just an example
02:26 < mae> I have no idea what your library looks like
02:27 < mae> I gotta go, don't give up!
02:27 < paulvisschers> mae: Ok bye
02:27 < paulvisschers> mae: it looks like http://serenity.paulvisschers.net:5001/doc/ btw
02:28 < paulvisschers> (that link might not work later)
06:32 < h_buildbot> Build for ghc-6.8.3 OK. Test suite ran. 14/69 test cases failed. Check http://buildbot.happstack.com/ for details.
06:37 < h_buildbot> Build for ghc-6.10.1 OK. Test suite ran. 16/69 test cases failed. Check http://buildbot.happstack.com/ for details.
09:33 < Saizan_> mae: have you tried passing a lambda to a state event? i don't think that can work since the arguments need to be serialized
09:34 < lanaer> away
09:34 < lanaer> er, ignore that
10:16 < wchogg> Hrmm...alright, looks like I'll have a few things to change for happs-tut with these SimpleHTTP changes.
10:18 < wchogg> On the other hand, all the changes seem good.
10:34 < mae> Saizan: ahh, yeah your right about the lambda
12:00 < mightybyte> Any suggestions for implementing a tagging system with IxSet for happstack state?
12:02 < Saizan> tagging system as in categorizing content with labels?
12:02 < mightybyte> Yeah
12:02 < Saizan> uhm, that's a many to many relationship
12:03 < mightybyte> One thing I would like to have is to be able to query on a subset of tags
12:04 < mightybyte> i.e. if a blog post is tagged with "tech", "politics", and "funny", to be able to find it with a search for posts with tags "tech" and "politics"
12:05  * Saizan wonders what the Ord a => Ord (Set a) instance do
12:05 < mightybyte> Do I just need to use the traditional database approach of having a third "linking" table connecting tags with posts?
12:06 < mightybyte> ...yeah, I was thinking about that.
12:06 < Saizan> inclusion is not a total order
12:16 < mightybyte> I was contemplating the possibility of having each tag represented as a bit in an n-bit number
12:16 < mightybyte> ...assuming that there will be a relatively small number of total tags (which works for my application).
12:19 < Saizan> that makes inclusion checking quite fast, but if you just store such a number for each element then a query is O(n) where n is the number of elements
12:21 < mightybyte> Yeah
12:21 < Saizan> i think a finger tree might be the right structure
12:22 < Saizan> since (Set a,union,empty) is a monoid
12:22 < mightybyte> Hmmmm...tough to know whether that would be better than several O(1) queries and then combining them.
12:23 < Saizan> ah, you can still use the bit-encoding for (Set a)
12:30 < mightybyte> But I guess a Set won't give me the inclusion checking that I'm looking for since it's being queried via Ord.
12:33 < dsrogers> yo.
12:33 < dsrogers> I'm looking at the other tutorials.
12:33 < dsrogers> we should update those for happstack 0.2
12:33 < dsrogers> well in march or whenever.
12:34 < dsrogers> death to WebT!
12:34 < mightybyte> I've been thinking about writing some new blog posts to do that
12:35 < Saizan> poor WebT ..
12:35 < mightybyte> survival of the fittest...
12:36 < mightybyte> dsrogers: I really like the sounds of the new monad machinery.
12:36 < Saizan> well, using ServerPartT when i don't care about the request is not using the fittest
12:36 < mightybyte> I think it will help clean up my code a lot.
12:37 < mightybyte> Saizan: Does it impose a performance penalty?
12:38 < dsrogers> mightybyte: it shouldn't.
12:38 < Saizan> we're using a 6-level deep transformer stack, another layer can't really hurt :)
12:39 < dsrogers> eh.
12:39 < dsrogers> haskell will take several of those away
12:39 < Saizan> i'm talking about having types that document the effects you're using
12:39 < mightybyte> Why isn't it the fittest to use a library that has a superset of the functionality you need?
12:39 < Saizan> and not more
12:39 < mightybyte> Saizan: Ahhh
12:39 < Saizan> otherwise we could just write everything in IO
12:40 < Saizan> however you always have to judge the tradeoff between fine granularity and convenience
12:40 < dsrogers> besides you can't say "this is six layers of transformers, thus is inefficient"
12:40 < mightybyte> Yeah
12:40 < dsrogers> it's hard to say what haskell will turn it into.
12:41 < dsrogers> eg, if you are at a leaf function and don't use most of those layers, haskell will probably entirely discard them.
12:41 < Saizan> s/haskell/GHC/
12:41 < Saizan> and that's probably not true
12:42 < Saizan> unrolling transformer stacks especially with a CPS transformation can give huge benefits
12:42 < Saizan> i'm not sure how much it matters here
12:42 < dsrogers> lol.  I think you just made my point...
12:43 < Saizan> i understood you as "GHC can optimize them away for you"
12:43 < dsrogers> I said, it's hard to say.
12:43 < dsrogers> and it's not necessarily inefficient.
12:43 < dsrogers> you have to measure.
12:44 < Saizan> ok, it's been measured that it can't optimize them for you :)
12:45 < dsrogers> why is that?  If I had a ServerPartT with nothing but IO statements, why would it even need the rest of the machinery?
12:45 < Saizan> because it's there, and return constructs all the levels even if with boring data
12:46 < dsrogers> ah
12:46 < Saizan> e.g. lots of mempty are going to be created and appended even if they don't matter at all
12:46 < mightybyte> Saizan: I see your point, but I've found working with ServerPartT awkward when I needed access to WebT, and vice versa.
12:49 < mightybyte> It seems like there should be a nice compromise.
12:51 < Saizan> now all the primitives use classes, so it's really the users' choice
12:53 < dsrogers> yeah...
12:53 < dsrogers> you can just use WebT if that's all you really needed...
12:53 < dsrogers> that's why my change was so compatible.
12:54 < dsrogers> Also, I want to create a Happstack.Server.Compat.  It's really the right way.  I can't stand the idea of breaking things needlessly.
12:55 < dsrogers> and it only needs to contain 7 or 8 trivial functions and a few import statements.
12:55 < dsrogers> it'll make porting code a lot easier.
12:55 < Saizan> it's not going to be fully compatible though
12:56 < dsrogers> indeed.
12:57 < dsrogers> but it's going to be really nice if you can change an import, substitute constructors as needed until your compile works.
12:57 < dsrogers> then remove compat and take out all the arrays
12:57 < dsrogers> err, lists
12:57 < dsrogers> and a lot of code will compile just fine with only a compat library.
12:58 < dsrogers> since a lot of people avoid explict constructors, apparently
13:04 < wchogg> I really appreciate the singluarization of a lot of the functions.  I was whining just a few days ago about all the lists.
13:10 < wchogg> Also, I'm not sure if I think a compat module would really be necessary.  I'm doing the conversion for happstack tutorial this morning, & so far it's pretty simple.
13:16 < dsrogers> wchogg: yeah, when I cleaned up all the example code I found the same thing to be true.
13:16 < dsrogers> also, check out ancient apis...
13:16 < dsrogers> happstack-data/examples/Foo.hs
13:17 < dsrogers> happstack-data/examples/test.hs
13:18 < dsrogers> those are two files I did not fix....
13:19 < dsrogers> also, there really are a nice set of examples in happstack-server/Examples
13:19 < dsrogers> those should be shown off more.
13:19 < Saizan>  test.hs has something to do with SimpleHTTP?
13:19 < dsrogers> *shrug*
13:22 < dsrogers> ah yeah,  Saizan, I have a typing problem.
13:22 < dsrogers> look in happstack/templates/project/src/AppControl.hs
13:22 < dsrogers> why does appHandler need a concrete type?
13:23 < dsrogers> (try taking the type off of that)
13:25 < Saizan> MR again?
13:26 < dsrogers> yep
13:26 < dsrogers> that did it.
13:26 < dsrogers> can you explain why that is?
13:28 < Saizan> well, when you've a definition with no formal parameters it can't be typeclass polymorphic without an explicit signature
13:29 < Saizan> btw, maybe a monomorphic signature might be less scary in an introductory example like that
13:34 < dsrogers> in this case, I couldn't make it typeclass polymorphic with an explicit signature.
13:35 < dsrogers> not that I disagree with you.
13:35 < dsrogers> but I want to understand it so I can throw in a gotcha in the release notes.
13:35 < dsrogers> MR wasn't as much of a problem before.
13:46 < dsrogers> I'd like to deprecate errorHandlerSP and simpleErrorHandler
13:46 < dsrogers> but simpleHTTP' doesn't provide example the same functionality.
13:51 < Saizan> what signature does ghci infer if you use NoMonomorphimRestriction?
13:51 < Saizan> MR wasn't such a problem before because we used less classes i guess
13:53 < dsrogers> it can't infer a signature.
13:53 < dsrogers> it totally fails to compile.
13:53 < dsrogers> and the error it spits out is very obscure.
13:54 < dsrogers> and don't mention the monomorphism restriction
13:54 < Saizan> ah, i understood that it compiled fine when removing the MR
13:54 < dsrogers> ohoh.
13:54 < dsrogers> double negative.
13:54 < dsrogers> sorry,
13:55 < dsrogers> yes, you're right.
13:55 < dsrogers> it compiles fine once you remove Mr.
13:55 < dsrogers> let me look
13:59 < Saizan> the problem with using signatures is that you've to give one to getEntries and postEntry too
14:00 < dsrogers> no you don't.
14:00 < dsrogers> you can just let those be general.
14:00 < dsrogers> appHandler is the only exported function.
14:00 < Saizan> without removing the MR, i mean
14:00 < Saizan> and giving a polymorphic signature to appHandler
14:00 < dsrogers> anyway, the type is (ServerMonad m, MonadPlus m, MonadIO m, FilterMonad Response m) => [m Response]
14:01 < dsrogers> perfectly normal type.
14:01 < dsrogers> but i think I get it now.
14:01 < Saizan> yes
14:01 < dsrogers> err, no I don't
14:01 < dsrogers> we export that type all the time...
14:01 < dsrogers> from all of our modules...
14:01 < Saizan> it's not a problem of the type per se..
14:02 < Saizan> and the fact that appHandler is exported or not doesn't matter
14:02 < dsrogers> what's the problem, then?
14:03 < Saizan> that appHandler doesn't have any formal parameter, though the type inferred for it is polymorphic with a typeclass context
14:03 < Saizan> in those cases the MR kicks in, which forces it to be monomorphic
14:03 < dsrogers> why is that?
14:04 < Saizan> the rationale is that you expect the evaluation of such definitions to be shared
14:05 < Saizan> but if they have a typeclass context they are probably going to be recomputed each time you instance them
14:05 < dsrogers> if you only ever use one instance, though, it shouldn't matter, right?
14:05 < Saizan> the MR forces you to declare that you want them to be polymorphic and thus not shared
14:06 < Saizan> though the MR is generally hated, because most of the time it's an useless annoyance
14:07 < Saizan> dsrogers: if you use that value only once sharing doesn't matter..
14:08 < Saizan> however you get fairly weird type errors in these cases..
14:08 < dsrogers> if you use it N times as the same instance does sharing matter?
14:09 < dsrogers> erm, obviously not.
14:09 < dsrogers> since I can just use it N times with a type sig...
14:09 < Saizan> i think you won't get them shared
14:09 < dsrogers> oh really?
14:09 < dsrogers> lame...
14:10 < Saizan> you'd have to look at the generated Core to be sure
14:13 < dsrogers> is this because no parameters means that there is no dictionary to be passed in?
14:15 < Saizan> without typeclasses no parameters means that such an expression has a definite value
14:15 < Saizan> with typeclasses that's no longer true, because there are those hidden dictionaries arguments
14:16 < Saizan> well, its value is a function, but then there's not much to share, since we don't evaluate under lambdas
14:17 < dsrogers> I'll add a note about this in the release notes, then.
14:18 < Saizan> btw "No instance for (FilterMonad Response m)" means that there isn't of the form "instance FilterMonad Response m where" literally
14:18 < Saizan> i.e. an instance that can work for any 'm'
14:19 < Saizan> i'm afraid that this will make using SimpleHTTP considerably harder for newbies :\
14:19 < Saizan> we should encourage the use of NoMonomorphismRestriction
14:20 < dsrogers> ok
14:21 < dsrogers> well. .. it can make your program blow up...
14:21 < Saizan> blow up?
14:21 < dsrogers> yeah, worst case, NoMR can cause an exponential increase when you don't use type sigs.
14:22 < Saizan> however, a reason why you didn't bump in this problem before might be that you defined the handlers in the same module where you passed them to simpleHTTP, that's enough for the typechecker to infer a ServerPartT IO type for all of them
14:22 < dsrogers> yeah...
14:23 < dsrogers> Issue #5 is trivial.  msum [ handle1, handle2 ...] >> addZipFilter
14:24 < dsrogers> addZipFilter = checkCanZip >> addZipHeader >> addZipBodyFilter
14:35 < Saizan> uhm, in which order are the filters applied?
14:35 < Saizan> do composeFilter f >> composeFilter g  gives me (f . g), not (g . f), right?
14:36 < dsrogers> g . f  f is applied first.
14:36 < dsrogers> 'cause it's bound first.
14:38 < Saizan> it's the Endo monoid that decides right?
14:38 < Saizan> 0:36     Saizan : > appEndo (Endo (+1) `mappend` Endo (*2)) $ 5
14:38 < Saizan> 20:36  lambdabot :   11
14:38 < Saizan> so (f . g)
14:40 < dsrogers> ah
14:40 < dsrogers> hmm.
14:40 < dsrogers> I don't think that's what we want here.
14:40 < Saizan> and looking at the old sources that's inconsistent with the old behaviour
14:40 < dsrogers> for is that the original behavior.
14:40 < dsrogers> *nor
14:41 < dsrogers> do I do this by fixing the monoid instance of setappend?
14:42 < dsrogers> ahh.
14:42 < dsrogers> Dual.
14:42 < Saizan> SetAppend (Dual (Endo a)) :)
14:42 < dsrogers> I add a Dual in there.
14:44 < Saizan> i'm tempted to specialize that stack.. for simplicity
14:52 < dsrogers> not a bad idea...
14:52 < dsrogers> I was thinking of adding two type synonyms.
14:53 < dsrogers> one for SetAppend (Dual (Endo a)) and one for Maybe (Either Response a, ...)
14:53 < dsrogers> it would save a lot of typing when using mapServerPartT...
14:57 < dsrogers> that would address most of that problem.
14:57 < dsrogers> especially since you almost never have to mess with the filter function at all.
14:57 < dsrogers> you're certainly not allowed to change it's type
14:59 < dsrogers> in any case.  I make patchy.
14:59 < dsrogers> happy patchy
15:00 < dsrogers> I like, a lot, how haskells type checking makes sure that if it compiles, it's probably correct.
15:05 < dsrogers> btw, originally WebT/ServerPartT could have been fixed with an additional constructor.  Effectively you need Nothing, JustLeftSet, JustLeftAppend, JustRightSet, JustRightAppend, (e.g. NoHandle, _, Escape, SetFilter, ComposeFilter)
15:06 < dsrogers> though I think there is a certain elegance to using a ReaderT ErrorT WriterT MaybeT stack.
15:15 < wchogg> Whee!  happs tut & happstack-helpers work with the new SimpleHTTP api
15:16 < dsrogers> yay!
15:16 < dsrogers> did they get cleaner?
15:17 < dsrogers> i.e. did you get rid of all anyRequest, withRequest, and withData's?
15:17 < dsrogers> and just use do blocks?
15:17 < wchogg> I haven't gotten rid of all the withData's yet
15:17 < dsrogers> were my release notes helpful, or did you just figure it out on your own?
15:17 < wchogg> But it's gotten a good bit more straightforward, I think, which is nice because I wanted to clean both of them up a bit anyway before the 0.2 release
15:18 < wchogg> actually your notes were most of what I needed
15:18 < dsrogers> sweet.
15:19 < dsrogers> I'm gonna write a gzip compression filter today
15:19 < dsrogers> *tonight
15:19 < dsrogers> just for fun.
15:20 < dsrogers> that'll be a nice new feature.
15:27 < dsrogers> simpleHTTP is now missing good implementations of protocol layer stuff.
15:28 < dsrogers> basic authentication, CRAM MD5, kerberos, gzip compression, and proper language encoding handling
15:30 < dsrogers> not to mention TSL.
15:30 < dsrogers> and SSL
15:33 < koeien> TLS, you mean :)
15:33 < koeien> i'd like to help out as well, but it seems that it's for 0.3 at least :)
15:35 < dsrogers> yeah..
15:36 < dsrogers> oh, virtual hosting.
15:36 < dsrogers> that should be easy.
15:36 < dsrogers> just add a guard for matching on the Host: parameter.
15:36 < dsrogers> *header
15:38 < dsrogers> a mod_rewrite like structure.
15:38 < dsrogers> that's just too useful.
16:28 < Saizan_> dsrogers: basic and digest authentientication has been implemented inside hackage-server, we should probably move that inside happstack
16:28 < dsrogers> ok
16:28 < Saizan_> its serveTarball is neat too
16:34 < dsrogers> Saizan: they ripped out basicAuth and generalized it.
16:34 < dsrogers> all we need to do is provide a function for the authentication and we're set.
16:35 < dsrogers> also, what is the "fail" behavior of ServerParT now?
16:35 < dsrogers> and what was the fail behavior before?
16:36 < Saizan_> now it's the one inherited from ErrorT
16:36 < Saizan_> i think?
16:36 < Saizan_> we should check.
16:36 < dsrogers> I just did.
16:37 < dsrogers> http://code.haskell.org/hackage-server/Distribution/Server/Auth/Basic.hs
16:37 < dsrogers> also, they don't implement CRAM-MD5, though they do implement hashed password storage.
16:38 < Saizan_> i meant we should check what fail "" :: ServerPartT m a gives us.
16:38 < dsrogers> oh.
16:38 < dsrogers> sorry, doing too many things at once...
16:38 < dsrogers> I don't have the old code around to compare...
16:39 < dsrogers> I think it got it from the definition of Monad.
16:39 < dsrogers> which causes the app to crash and burn, I believe.
16:39 < dsrogers> But ServerPartT has it's outermost layer as a ReaderT.
16:40 < dsrogers> does that lift up fail?
16:41 < Saizan_> it does
16:41 < dsrogers> I used deriving (Monad) so it should get it from ErrorT
16:42 < dsrogers> that means on fail it would be like calling "finishWith $ toResponse errMsg"
16:43 < Saizan_> i think it makes more sense for fail s to be mzero
16:44 < Saizan_> though that gives us no error
16:44 < dsrogers> indeed.
16:44 < dsrogers> and finishWith is not catchable.
16:44 < dsrogers> and I'd hate to see an authentication guard (or any guard) bypassed because of a pattern matching failure.
16:45 < dsrogers> speaking of which, I need to lift up "fail" when I lift up ErrorT.
16:46 < dsrogers> it would be nice to throw an ISE 500 error out.
16:47 < dsrogers> there is a big difference between "I don't want to handle this request" and "I tried to handle this request but failed"
16:48 < dsrogers> The ErrorT is the right behavior.  It gives something well determined, and doesn mix up our current mzero meaning with error handle
16:48 < dsrogers> *handling
16:49 < wchogg> dsrogers : is SimpleHTTP going to be more or less stable until 0.2?
16:49 < dsrogers> yes.
16:49 < dsrogers> Just bug fixes at this point.
16:49 < dsrogers> I'm going to change mapServerPartT to make it consistent with mapStateT
16:49 < wchogg> dsrogers : Awesome, gives me plenty of time to rewrite chunks of the happs tutorial
16:50 < dsrogers> Saizan: if they want something more sophisticated, they can add an ErrorT to the stack.
16:51 < Saizan_> mmh
16:51 < Saizan_> it's still a quite silent way to error out
16:51 < dsrogers> it'll show up in the browser...
16:51 < Saizan_> the filters will still be applied for example
16:52 < dsrogers> well we could fix that.
16:52 < dsrogers> by overriding fail.
16:52 < dsrogers> make it set return code 500, pretty print the error message into some html, ignore filters.
16:54 < dsrogers> that's a hell of a lot better than what we do now for a default 404
16:54 < Saizan_> that's ok i guess
16:55 < dsrogers> is it possible to ask happstack for it's version?
16:56 < Saizan_> cabal generates a Paths_happstack_server module with informations like that
16:56 < Saizan_> you can look at it under dist/build/autogen
16:56 < dsrogers> kk.
16:56 < dsrogers> I'll use that to make some nicer 404 and 500 templates.
16:57 < dsrogers> Like what apache does.  Prints it's version, hostname, administrator email, error message, etc
16:58 < dsrogers> we also clearly need an x-powered-by: happstack header.  :-)
17:02 < h_buildbot> Build for ghc-6.8.3 OK. Test suite ran. 15/69 test cases failed. Check http://buildbot.happstack.com/ for details.
17:02 < dsrogers> oh hey, progress
17:07 < h_buildbot> Build for ghc-6.10.1 OK. Test suite ran. 15/69 test cases failed. Check http://buildbot.happstack.com/ for details.
17:11 < dsrogers> some attention to uft8 and translations is in order as well.
17:11 < dsrogers> is there a message translation library on haskell?
17:11 < dsrogers> err, hackage?
17:23 < wchogg> dsrogers : if you modify mapServerPartT will that simplify the signature a little?
17:23 < dsrogers> yes
17:23 < dsrogers> a lot.
17:23 < wchogg> Ah, good.
17:23 < dsrogers> it's going to be ServerPartT m a -> ServerPartT n a
17:23 < dsrogers> instead of that big mess in the front.
17:24 < dsrogers> it would be nice to put some basic implementations for WriterT, ErrorT and ReaderT somewhere.
17:24 < dsrogers> and StateT
17:25 < dsrogers> at the very least so that people can copy them for the own use.
17:25 < dsrogers> I'm at work right now, so I'll fix that in a few hours though :-)
17:31 < dsrogers> that will let me deprecate errorHandlerSP
17:50 < stepcut> mae: it seems a bit much for 17 tests, but should grow nicely when we have hundreds
17:57  * dsrogers wonders what mae said
18:04 < stepcut> dsrogers: <mae> stepcut: this test hierarchy is masochistic :)  [22:21]
18:04 < stepcut> <mae> lots of import pushups
18:04 < stepcut>  
18:15 < dsrogers> what test framework are we using?
18:16 < stepcut> dsrogers: HUnit, with wrappers to also be able to run quickcheck or external scripts
18:16 < stepcut> dsrogers: currently it is setup so that each package provides it's only tests, so that if you install just happs-data, you can still run all the tests associated with it
18:18 < dsrogers> ah
18:18 < stepcut> dsrogers: but, each module also exports it's tests in a library so that we can have a top-level test suite that runs all the tests for all the modules, or tests that require multiple modules that are not normally related (such as a test that uses both happstack-server and happstate-state, which are now completely indepedent if i am not mistaken)
18:18 < dsrogers> ah
18:18 < dsrogers> so is someone looking at the 14 failures?
18:18 < dsrogers> they are in happstack-data, mostly.
18:18 < dsrogers> I don't know anything about that.
18:19 < stepcut> dsrogers: yes, someone has been looking into those, the ones in happstack-data seem to have been broken since the day igloo committed them. We have patches that fix the tests themselves, though we are still a bit mystified as to why someone would commit broken tests.
18:19 < dsrogers> lol
18:20 < dsrogers> who is igloo?
18:20 < dsrogers> err, when were they checked in?
18:20 < stepcut> dsrogers: the tests in happstack-state is more concerning to me, because I think it could cause real data loss
18:20 < stepcut> igloo was an older HAppS developer
18:20 < dsrogers> ah
18:20 < stepcut> Ian Lynagh. We was also the debian package maintainer for ghc
18:21 < dsrogers> was?
18:21 < stepcut> yeah, I think he is transitioning out of that role due to time limitations
18:21 < stepcut> ?
18:22 < dsrogers> ah
18:25 < stepcut> has anyone written a tutoral on how  MACID actually works?
18:30 < Saizan> i don't think so
18:30  * stepcut might
18:31 < Saizan> oooh, so you know that!
18:32 < stepcut> nope, but i would if I wrote a tutorial on it
18:33 < Saizan> ah :)
19:20 < wchogg> stepcut : Well, I'm hopding to explain more of the various nuts & bolts of things in more detailed chapters of happs-tutorial
19:24 < stepcut> wchogg: I am looking for something more low-level I think -- something that explains the actually binary format of the checkpoint files for example
20:54 < dsrogers> huh.  what I wrote is already consistent with StateT
21:13 < stepcut> dsrogers: excellent?
21:13 < dsrogers> kinda.
21:14 < dsrogers> I'm adding a type alias to at least make SetAppend (Dual (Endo a)) a little more fun to type
21:15 < stepcut> it's already pretty fun!
21:18 < wchogg> no, it fills me with fear & dread.
21:18 < stepcut> haha
22:30 < dsrogers> it's really not that bad.
22:30 < dsrogers> you almost always ignore it.
22:40 < wchogg> I was just kidding.  Don't think I was trashing your work.
22:40 < dsrogers> lol.
22:40 < dsrogers> you didn't offend me.
22:41 < wchogg> Eh, I play it safe on The Internet.
22:46 < dsrogers> am I the only one that reads "ServerPartT" as "Server Party>"
22:46 < dsrogers> ?
22:46 < stepcut> hahaha
22:46 < stepcut> I shall read it that way forever more
23:53 < stepcut> happstack has code that looks at secret command-line arguments. I don't think I like that much.
23:54 < stepcut> for example, in Happtack.State.Control there are some secret options
--- Log closed Wed Feb 18 00:00:16 2009