02:09:47 <tazjin> stepcut/stepkut: I think needs to be a default ToSURI instance for Text, using seeOther with showURL is a bit annoying with unpacking etc.
02:10:03 <stepkut> hmm
02:12:08 <stepkut> instance ToSURI Text.Text where toSURI = toSURI . Text.unpack
02:12:09 <stepkut> instance ToSURI LazyText.Text where toSURI = toSURI . LazyText.unpack
02:12:09 <stepkut>  
02:12:13 <stepkut> those instances already exist..
02:12:31 <tazjin> Hmm, where? ;O
02:12:32 <stepkut> are they not working for some reason?
02:12:39 <stepkut> Happstack.Server.SURI
02:13:27 <tazjin> Hmm, let me investigate
02:17:07 <tazjin> Works on my other box, looks like I've stepped into dependency hell somewhere
07:22:16 <stepkut> happstack-clientsession demo, http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-clientsession/demo/demo.hs
07:22:48 <stepkut> that deriving statement on line 33 is a bit out of control though
07:24:21 <Entroacceptor> deriving AllEverything
07:30:14 <stepkut> need to do a bit more cleanup and then make another release of happstack-clientsession
09:58:46 <donri> stepcut: wouldn't it be more consistent with happstack to call it ClientSessionMonad instead of Monad as prefix?
10:08:00 <donri> should we drop sessionPart now, seems redundant
10:09:22 <donri> why do you have a show constraint on sessionData
12:21:22 <donri> stepcut: apparently OverloadedStrings extend default declarations
12:23:06 <donri> e.g. default (Text) should do it
12:34:24 <hpaste_> donri pasted it works! at http://hpaste.org/67484
15:44:03 <stepkut> donri: oops, the Show and MonadIO constraints there were for debug purposes, and, as expected, I forgot to remove them
15:44:34 <donri> :)
15:45:27 <stepkut> removed.. along with sessionPart
15:45:41 <donri> are you sure RWST is a good idea when we're not using its writer?
15:45:52 <stepkut> ClientSessionMonad might be more consistent with Happstack.. but Happstack is inconsistent with mtl :-/
15:46:09 <stepkut> well, I was using the writer for a while
15:46:21 <donri> it is, but i'd prefer to remain consistent within happstack for happstack packages (or fix happstack at some point)
15:46:36 <stepkut> I would rather fix happstack at some point
15:47:32 <donri> btw what does view mean in viewStateT'`
15:47:34 <donri> ?
15:47:48 <stepkut> it means I haven't thought of a better name yet
15:47:51 <donri> :)
15:48:19 <donri> i liked with[Client]Session...
15:49:13 <stepkut> are you familiar with view patterns at all? http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns
15:49:20 <donri> vaguely
15:49:58 <stepkut> same here
15:50:04 <stepkut> but it felt vaguely similar
15:50:17 <donri> i don't see the connection...
15:50:36 <donri> it's more like a sort of "lift"
15:51:29 <stepkut> it looks a bit like lift but has a very different  feel in my opinion
15:52:31 <stepkut> a view allows you to apply a function to make a value look different temporarly for the purpose of pattern matching
15:53:26 <stepkut> with viewStateT' there is a similar idea that you are temporarly warping the universe so that the internal state of ClientSessionT is now exposed via MonadState
15:54:43 <stepkut> I would expect something named. withSession to be like, withSession :: (sessionData -> m a) -> ClientSessionT sessionData m a
15:54:57 <donri> i was thinking it's kinda like, liftIO $ do (IO stuff...)
15:55:45 <donri> so we have, liftState $ do (MonadState for sessionData)
15:56:31 <stepkut> gotta run, bbl
15:56:45 <donri> k :)
18:21:49 <stepkut> yeah I think liftSessionStateT or something is right
18:22:20 <stepkut> so, the RWST got in there because it is almost right
18:23:22 <stepkut> if all you care about is tracking if put was called or not, then you could have, RWST SessionConf Bool sessionData
18:23:41 <stepkut> and then do, tell True, when the data dirtied
18:24:24 <stepkut> but that assumes you do not need to be able to know if it was dirtied until outside of the runRWST
18:24:30 <stepkut> and, it turns out we need to know inside
18:28:30 <donri> stepkut: also you changed "Decoded st" and "Modified st" to be a tuple (ChangeStatus, s) instead, but the "s" doesn't exist in some states?
18:28:53 <stepkut> donri: yeah.. i am not sure about that either
18:29:14 <stepkut> that was a result of trying to use the Writer as well
18:30:01 <stepkut> well making it a Monoid was for writer. Making 's' always there was for the 'get' instance
18:30:11 <stepkut> but I am not convinced it is the right choice yet
18:31:18 <stepkut> it seems less right because I have to use emptySession some places because there is no real session data
18:33:54 <stepkut> the issue is that if there is not always some state there, then the MonadState instance has to do something funky for 'get'
18:35:03 <donri> not really more funky than in acid-state where you pass an empty state to openLocalState
18:35:18 <stepkut> either get has to return a Maybe value, or it needs to return emptySession if there is no session data there
18:35:43 <donri> i think i had it be mzero at some point
18:35:51 <donri> but i think people expect the session to be "always there"
18:35:57 <donri> without fail
18:36:55 <stepkut> right. That is why I did not get returning 'Maybe' and why the tuple version has it always there
18:37:21 <stepkut> but this works just as well, data SessionData sessionData = Unread | Decoded sessionData | Modified sessionData  | Expired
18:37:26 <stepkut> aka, what we had before
18:37:42 <donri> oh i see you're passing emptySession in runClientSessionT
18:37:46 <stepkut> yeah
18:37:47 <donri> yea that's basically the same effect as what I did
18:38:08 <stepkut> I am switching back something closer to what we had before right now
18:38:26 <stepkut> I just went on a long excursion to get there :p
18:38:50 <stepkut> I knew what I commited last night was not optimal. but it was way past my bedtime
18:39:03 <donri> (Unread, emptySession) has strange semantics :P
18:39:25 <stepkut> yeah
18:42:31 <donri> ACTION is sort of thinking maybe we should rename most references of ClientSession to simply Session
18:42:37 <donri> for example, we have RouteT not WebRoutesT
18:43:24 <stepkut> I remember running into a problem recently where I wished I hadn't used the RouteT name already (or maybe it was MonadRoute)
18:43:36 <donri> heh OK
18:43:39 <donri> fair
18:43:42 <stepkut> the issue with just Session is that we do intend to have ServerSession as well?
18:43:58 <donri> yea, but how often in the same modules? qualified imports aren't *that* bad
18:44:28 <donri> (though i wish haskell had renamed imports like python... import Foo (bar as fooBar)
18:44:50 <stepkut> one issues is that when reading the code, it can be hard to tell if you are seeing Client vs Server session with out looking at the imports? Unless it is imported qualified even though only one is used
18:45:03 <stepkut> yeah, Agda has renamed imports.. 'tis great
18:45:08 <donri> true, but you should probably look at imports when reading code :)
18:45:21 <stepkut> I would like to implement acme-http in Agda just to see how good/bad it performs
18:45:28 <donri> probably bad
18:45:30 <stepkut> there are too many imports
18:45:37 <stepkut> I try to ignore them as much as possible
18:45:40 <donri> i mean surely agda isn't as optimized as ghc?
18:46:06 <stepkut> well, last I checked, Agda spit out haskell code that GHC compiles. Though there is work on a native backend as well
18:46:12 <donri> aha
18:46:27 <donri> and agdas IO whatever that is uses ghc's IO manager too?
18:47:29 <stepkut> I expect so
18:47:34 <stepkut> for now anyway
18:47:55 <alpounet> let's port happstack to agda!
18:47:55 <stepkut> tricky part might be use forkIO in agda
18:48:06 <alpounet> the final code would take 3 years to compile
18:48:09 <stepkut> alpounet: :)
18:48:46 <donri> what about idris, isn't idris partly performance-oriented
18:49:00 <stepkut> It would be neat to use Agda to prove things about the Happstack.. but I am not sure how to do that in a useful way
18:49:12 <stepkut> I have heard of idris, but not investigate it yet
18:49:20 <stepkut> too busy fixing HSX and stuff :-/
18:49:24 <donri> well it's strict by default i think
18:49:41 <donri> while still being a pure functional language with dependent types
18:49:54 <donri> and no unicode silliness ;)
18:52:03 <donri> i recall mekeor is our resident idrisian?
18:52:25 <stepkut> Haskell has unicode silliness :)
18:52:45 <donri> yes, optional and  rarely used :P
18:55:49 <stepkut> well. it is optional in Agda.. just not rarely used..
18:55:57 <donri> :)
18:56:47 <donri> i like reading the unicode, not so much writing it
18:57:10 <donri> i have vim set up to pretend some things are unicode in haskell
19:08:52 <mekeor> donri: i am idirsian, yes.
19:09:23 <mekeor> and yes, idris is eager by default, IMO unfortunately.
19:10:04 <donri> mekeor: maybe you should look at agda then
19:11:02 <mekeor> donri: yes, i wanna do that. the only thing agda lacks at, is, AFAIK, type-classes.
19:11:08 <mekeor> that's a bummer. really a bummer.
19:11:38 <donri> duno, these languages are interesting toys IMHO, and type classes just complicate things
19:12:29 <stepkut> but type-classes are broken anyway :p
19:13:27 <mekeor> stepkut: why?
19:13:37 <mekeor> (should we discuss that on #agda, actually?)
19:14:00 <stepkut> http://www.bitc-lang.org/pipermail/bitc-dev/2012-April/003315.html
19:17:46 <stepkut> hmm
19:17:53 <mekeor> thanks, i'll take a look at that.
19:18:15 <stepkut> there are two ways to implement: liftSessionStateT :: (Monad m, MonadTrans t, Monad (t m)) => SessionStateT sessionData m a -> t m a
19:18:42 <stepkut> one introduces a new type class (similar to MonadIO) but runs the 'SessionStateT sessionData m a' directly
19:18:56 <stepkut> the other one is more general, but requires some trickiness
19:19:12 <stepkut> well, not really trickiness
19:19:19 <stepkut> I'll do that way I think
19:20:03 <stepkut> I guess it has a side-effect that it forces the data to be decoded, even if you don't actually use it
19:20:59 <stepkut> but.. there is little reason to use liftSessionStateT if you don't actually intend to call get/put
19:21:19 <stepkut> so, I think have one less type-class makes it worthwhile
19:24:49 <donri> more important to not encode unless modified
19:25:25 <donri> preferably without an Eq constraint :)
19:25:27 <stepkut> yeah
19:26:41 <donri> does liftSST stay inside the parent monad? like, can you do askRq inside the lift
19:27:14 <stepkut> donri: the type is:
19:27:16 <stepkut> liftSessionStateT :: (Monad m, MonadTrans t, MonadClientSession sessionData (t m), Monad (t m)) => SessionStateT sessionData m a -> t m a
19:27:34 <donri> if so, people might end up wrapping their root handler in it and unecessary decoding could be an issue
19:27:42 <stepkut> so the SST can do whatever the 'm' does, but not what the 't' does
19:27:50 <donri> aka. liftSST $ msum [...]
19:28:49 <donri> could you do that for the same effect as writing a MonadState instance for your handler type?
19:28:49 <stepkut> ah
19:29:03 <stepkut> ?
19:29:44 <donri> well if you don't like having to use liftSST and don't mind get/put being "stolen" for sessions inside your serverparts
19:30:00 <stepkut> ah
19:30:16 <stepkut> if you newtype your app monad, then you can make get/put do whatever you want
19:30:20 <stepkut> i am pretty sure
19:30:38 <stepkut> so if you want get/put to get and put the session state.. you can
19:30:41 <donri> sure, but can you do: simpleHTTP nullConf $ liftSST $ msum [...]
19:30:51 <stepkut> i dunno
19:30:55 <stepkut> you can try in a minute
19:32:35 <stepkut> pushed
19:32:43 <stepkut> now things are more like they were before :p
19:32:59 <stepkut> almost back to where we started, but better
19:33:02 <stepkut> I hope
19:33:31 <donri> or for that matter, could you do something like, liftSST $ do rq <- askRq; put $ rqPeer rq -- to store the client's IP in the session
19:33:57 <donri> or do you have to do, rq <- askRq; liftSST $ put $ rqPeer rq
19:34:24 <stepkut> I think both should work
19:34:34 <stepkut> you can try it and see :)
19:34:36 <donri> in that case i say it's worth the type class to not decode unecessarily
19:34:50 <stepkut> we can provide both
19:35:05 <stepkut> we just need to have two names
19:35:13 <donri> what good does that do?
19:35:19 <donri> i thought the point was less complicated source :)
19:35:30 <stepkut> for some definition of complicated!
19:35:49 <donri> or do you mean it imposes the need for another constraint in the user's code?
19:35:50 <stepkut> though.. in this case it is mostly just a matter of adding one more type class to your deriving list
19:36:46 <stepkut> it would add a MonadLiftSessionStateT  class which you would propogate around your code in various ways
19:37:23 <stepkut> unless I can fold it into the MonadClientSession class somehow
19:39:33 <stepkut> which I do not think I can
19:42:06 <hpaste_> stepcut pasted LiftSST class at http://hpaste.org/67503
19:42:22 <stepkut> so  the class would look like that, and in the demo App would have to direct that class as well
19:43:15 <hpaste_> stepcut annotated LiftSST class with liftSessionStateT at http://hpaste.org/67503#a67504
19:43:59 <stepkut> the liftSessionStateT version can be lifted into any monad transformer that provides, MonadClientSession sessionData (t m), but at the cost of forcing a decode
19:45:40 <stepkut> if we had, class MonadClientSession sessionData m | m -> sessionData where getSession :: m (SessionData sessionData), then we could avoid forcing a decode
19:45:51 <stepkut> but that leaks some stuff out that we do not really want exposed I think
19:51:24 <donri> is there a difference between your MonadTrans instance and what generalized newtype deriving would produce?
19:52:41 <stepkut> i doubt it.. that is probably a left over artifact
19:52:56 <stepkut> or maybe it can't derive it?
19:53:57 <donri> i mean for SessionStateT
19:54:06 <donri> isn't that exactly how GeneralizedNewtypeDeriving works
19:54:16 <donri> asking because actually curious :)
19:56:02 <stepkut> the SessionStateT can be derived -- fixing that now
19:56:25 <stepkut> for some reason the ClientSessionT one can not
19:56:43 <donri> well you have two levels of lift there
19:56:55 <stepkut> yeah
19:57:11 <donri> a derived instance would lift you into the reader sessionconf right?
19:57:27 <stepkut> I guess
19:59:09 <stepkut> so, for the liftSST thing we now have three options: introduce a new class, always decode when you call liftSST, or add a version of getSession to MonadClientSession that returns (SessionData s) instead of 's'
20:00:20 <stepkut> i pushed a patch for the MonadTrans thing
20:01:20 <stepkut> aside from the liftSST thing.. is there anything else we want to change?
20:01:22 <donri> i wonder if deriving works for method-less classes like Happstack
20:01:23 <stepkut> or think about?
20:01:45 <donri> duno, still reading through the source :)
20:02:11 <stepkut> it can
20:02:25 <stepkut> in the demo.hs I derive Happstack
20:03:47 <donri> also we need some redundant imports for haddock cross-linking
20:04:00 <donri> -Wall will complain but what do you do :(
20:04:18 <stepkut> I wonder if we should re-export anything.. like getDefaultKey?
20:04:34 <stepkut> ... or what the 'right' way to generate a Key is in the first place
20:04:57 <stepkut> what are the redundant imports that are needed ?
20:05:20 <donri> getKey and getDefaultKey for sessionKey docs
20:05:26 <stepkut> ah
20:05:39 <donri> i had those imported first but removed when i got warnings for redundant imports
20:06:00 <donri> but now i see in the built haddocks on the site that they're needed
20:06:39 <donri> at least if we want them linked, which is a good thing to have
20:06:46 <stepkut> you can use their qualified names in the haddock source I believe
20:07:05 <stepkut> though I am not sure if that works for cross-linked stuff
20:07:07 <donri> does it render unqualified?
20:07:13 <stepkut> maybe only modules in the same package
20:07:17 <stepkut> http://stackoverflow.com/questions/9113120/haddock-hyperlinks-and-without-warning-about-redundant-imports
20:07:21 <stepkut> no. it renders qualified
20:07:57 <stepkut> also.. I have never gotten it to work.. in part because there was a bug I think, but also because I was probably trying to do it cross-packages
20:08:18 <donri> well this is cross-packages
20:08:35 <stepkut> right
20:08:59 <stepkut> so, the redundent imports might be the only option.. though if we re-export them, then they won't be redundent anymore :p
20:09:20 <donri> true
20:09:48 <donri> maybe export Key also
20:10:00 <stepkut> yeah
21:15:23 <donri> yay new hsp/hsx
21:15:41 <stepkut> donri: boo to new hsp/hsx
21:16:09 <stepkut> hsp does not build
21:16:39 <stepkut> among other things there is an issue with code being rendered as ((x : y) : z) instead of (x : y : z)
21:16:44 <stepkut> I blame that on you :p
21:17:04 <donri> :)
21:17:18 <donri> i thought src-exts would simply pass it through unaltered more or less
21:17:49 <donri> i.e. parse a concrete syntax tree for infix expressions, not abstract
21:18:11 <stepkut> dunno
21:19:34 <stepkut> anyway, I really gotta finish this menu editor
21:53:23 <tazjin> stepkut: Where's the Crash Course repo again?
21:53:46 <stepkut> darcs get http://src.seereason.com/happstack-crashcourse
21:53:55 <stepkut> the link is on the front page if you need it again: http://www.happstack.com/docs/crashcourse/index.html
21:54:48 <tazjin> Oh, I see
21:55:02 <tazjin> I'll probably add a part about Hamlet & the other Shakespearean languages
21:55:32 <stepkut> nice
21:55:50 <stepkut> tazjin: if you have any questions about the build system.. let me know. it is a bit wacky
21:56:01 <stepkut> I would love to clean that up .. but it gets the job done for now
21:56:13 <tazjin> ;D
21:56:24 <tazjin> one of these -- !MUSTFIX! things that somebody finds 15 years later
21:56:29 <stepkut> :p
22:14:24 <stepkut> donri: some how having ClientSession introduce *two* new type classes seems excessive
22:17:40 <donri> heh yea
22:17:51 <donri> can't the one handle it?
22:18:42 <donri> gotta sleep