[Lift] Re: Reasoning Behind Box

2010-02-26 Thread Daniel Spiewak
Either would be the purely stdlib way to go, and Naftoli is right
that it would be a lot more verbose.  I would argue that the
difference isn't *so* substantial if you sprinkle in a type alias and
some implicit conversions (so that you can map/flatMap/filter over
something of type Either[Option[A], String]).

I am aware of the Failure case, and that's why I argue that Box
*isn't* a drop-in Option replacement.  API naming differences are
inconsequential, but adding another case to the ADT is a pretty
dramatic difference.  However, Lift seems to use Box *everywhere*,
even in places where it is only using it as if it were Option.

Daniel

On Feb 26, 1:17 am, Heiko Seeberger heiko.seeber...@googlemail.com
wrote:
 On 26 February 2010 08:09, Naftoli Gugenheim naftoli...@gmail.com wrote:

  Either -- but it's more verbose.
  I'm not so sure David will want to rewrite the entire lift anyway...

 Right now, I only would like to listen to Daniel, OK?

 Heiko

 Company: weiglewilczek.com
 Blog: heikoseeberger.name
 Follow me: twitter.com/hseeberger
 OSGi on Scala: scalamodules.org
 Lift, the simply functional web framework: liftweb.net

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Re: Reasoning Behind Box

2010-02-26 Thread Daniel Spiewak

 Back when I was the only Lift committer (okay, maybe SteveJ had commit
 rights back then... I don't remember) and I was working on the first
 Lift-based app, I was experiencing a nasty issue.  This was summer of 2007.
 This was circa Scala 2.4 and before Either was in the language.  One of the
 common patterns I kept running across was iterating through a series of
 pieces of user-input (both from the UI and from the REST interfaces) and
 having to return a not-answer (None) and the reason for the inability to
 complete the operation.  It was about the same time, moved away from pattern
 matching against Options in favor of using Options in for comprehensions.
 The first thing I tried was to use Options in conjunction with exceptions
 (yeah, I was still lost in Java-think) such that in the case of a None for a
 particular operation (loading an item from the database, etc.), I'd throw an
 exception, the caller would catch the exception and present the right thing
 to the user/caller.  It was ugly.

A valid point.  I would argue that this is the correct way to solve
this problem, but it's obviously not the cleanest.

 So, I finally bit the bullet and wrote my own set of classes that offered
 the kind of functionality that I was cobbling together with Option.  I
 originally called the class Can (a short name for something that contains or
 does container a unit of something... a can of soup, a can of beans.)  I
 patterned Can after Option (btw, Option is one of the worst names in the
 Scala libraries... explaining what an Option is to a Java or Ruby guy was
 one of my biggest stumbling blocks... Maybe would have been a much better
 name, but I digress.)

+1  For the record, the Option name comes from ML, while Maybe comes
from Haskell (and its heritage).  As I recall, Martin is a great fan
of ML, which is why most of Scala's functional features are heavily
inspired by that language.  In fact, the only functional feature I can
think of which Scala got from Haskell would be typeclasses.

    - The get method was too easy for Java (and Ruby) developers to get
    wrong.  Get is *FREAKING DANGEROUS*.  It's an exception waiting to happen.
    It should not be used except in the most extreme situation.  But with a
    nice, tasty, comforting, access-worthy name like get, it just begs to be
    invoked.  Something like 30% of our production-time defects resulted from
    mis-using Option.get.  This needed to be changed... so something that says
    danger like open_!  Oh, yeah, the ! says hmmm... why is that !
    there?  Should I be using this method?

Agreed.  This is maybe an education thing.  My biggest problem with
open_! is the highly unidiomatic use of mixed alpha-symbolic method
name.  Yes, I know Lift does it everywhere, but I can't think of any
other Scala library which does the same.  Maybe I'm being too
pedantic, but I cringe every time I see it in my code.  :-)

    - orElse orElse orElse... who named this method.  In terms of method
    naming the Else is a useless waste of 4 characters... the camel case 
 takes
    the eye away from the things that are being tested... there's no reason for
    the Else part.

The name for this method was devised a *long* time ago.  I don't
remember exactly when, but it was a part of research examining monads
in the abstract mathematical sense.  As a result, the goal was to name
the function something which would be unambiguous in the proverbial
global context.  They probably thought of or, but that's not
specific enough.  Thus, orElse.  Since almost all languages which have
monads also use Hindley-Milner type inference, it's not surprising
that the name has stuck.  Scala is really one of the few languages
which *can* go with something else.

 I proposed to the Scala team that they include the Failure subclass as part
 of Option.  They declined.  Mainly for two practical reasons: thousands of
 Some/None pattern matches would be broken and Martin has always wanted to
 optimize Option at the compiler level to be ref/null so there would be no
 necessary boxing of Options.  I took another run at Martin with the idea 14
 months ago when 2.8 was just on the drawing board and Martin once again
 declined.

I have to say, I'm with Martin on this one.

 Most FP trained folks who have looked at Box have vomited over the
 mathematical differences between Option and Box.  Tony Morris is the most
 notable example of this... he was so unable to control his rage at the
 abomination that is Box that we had to ban him from the Lift list (he's the
 first of two people that share that dubious honor).

I'm in rather interesting company, since I had a similar reaction when
I first saw Box.  Maybe not quite so violent, but in that general
vein.  To be clear, I have absolutely no problem with it as a separate
ADT unto itself.  In fact, were I in your shoes, I may have even come
up with something similar.  However, I would have made it a proper ADT
with four instances: Full(...), Empty, 

[Lift] Re: Reasoning Behind Box

2010-02-26 Thread Daniel Spiewak
 It sometimes seems to me that people are view-ing Option as an
 absolute term - a complete Maybe monad that everyone should obey.

Yeah, that's pretty much it.  :-)  Saying that you have a replacement
Option with totally different instances is like telling me that you
have a new definition for a derivative.  Maybe/Option are just
implementations of the same abstract mathematical concept (like two
different ways of writing the *same* definition of a derivative).  Box
is something which is obviously inspired by the Maybe monad, but seems
to have gone in a totally new direction with it.  I'm not saying that
direction is bad, but it's certainly not anything like Maybe.  It's
like looking at the problem of computing instantaneous rate of change
and coming up with a technique which maps things into a different
complexity domain.  Your results may be valid, but you're certainly
not going to end up with differential calculus as we know it.

Daniel

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Reasoning Behind Box

2010-02-25 Thread Daniel Spiewak
I'm sure this has been discussed before, but I'm curious as to the
rationale for the Box ADT.  I'm most distressed by the fact that it
seems to be masquerading as a drop-in Option replacement, and yet the
mathematical properties of the ADT are widely divergent.  What's more,
the API is very, very different, leading to a great deal of confusion
whenever I'm working with code which touches both ADTs (as I often
do).  Things like `or` vs `orElse`, `open_!` vs `get` and so on are
very confusing.  The implicit conversion Box[A] = Option[A] doesn't
help either, since it means I can easily forget and use Option methods
on Box values, accidentally triggering a conversion.

The whole `or` vs `orElse` thing is particularly annoying since I
spend a fair amount of time wading through research which discusses
the `orElse` function in its abstract monadic sense.  Given the
standard nature of the name (dating back long before Scala), I'm
surprised that Box went with something else.

I'm sure there are good reasons for all of this, I would just like to
know what they are.  :-)

Daniel

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Re: User Presence Heartbeat

2010-01-26 Thread Daniel Spiewak
 We can make fixes to the 1.0.x branch for you, but I am reluctant to make
 changes to the 1.0 version.

Very understandable.  We'll just bump up to the 1.0.2 release.  That
jump has been on the back burner for a while, so it's good to get an
excuse to push it through.  :-)

 You might look into having your session management system let Lift know that
 the session is going down.  Lift *should* be tied to the container's session
 and if it's not working, please get us a repro case and we'll fix it.

Looking into it now.  It's also possible that Spring Security isn't
killing off the session properly, in which case Lift is more than
justified in hanging onto whatever information it has left.  If it
turns out that the session is dying but Lift still isn't firing
Unlisten on its own, then I'll do what I can to get you a reproducible
test case.  Time is a little tight right now though, so I may not be
able to do much more than report the bug in a case-less state.

 Is this an issue that needs to be solved this week?  If not, I'll have more
 time next week and can putter around with Jetty and see what I can learn
 about what it does with comet, NIO, etc. and see if there's a better way to
 give you what you need.

The sooner the better, but we understand that you have other things to
do.  We're going to forge ahead with the Listen/Unlisten trick coupled
with some extra hooks in Spring Security working under the assumption
that we'll be able to make it solid enough for now.  If and when you
find a better way to do this, we'll switch to that technique moving
forward.

So in other words, feel free to putter as soon as you get the chance!
We would certainly appreciate anything you can come up with.

Daniel

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Re: User Presence Heartbeat

2010-01-22 Thread Daniel Spiewak
This seems to work very nicely.  Well, it gives me lots of spurious
events, but a little bit of filtering based on active ListenerId(s)
and I'm golden.  Unfortunately, I've already run into two main
problems:

* It seems to be somewhat non-deterministic as to whether or not every
listener is closed when the browser is shut down (Firefox 3.6).  It's
possible that just one listener is remaining active (hasn't been
Unlisten'ed), which would prevent my presence system from firing.  Is
this to be expected?  Do I just need to wait a little longer for the
connection to time out?

* The Unlisten event does not *ever* seem to fire when the user logs
out.  The logout action redirects the user back to the login page,
which obviously wouldn't have a long-poll.  Nevertheless, my system
still thinks the logged-out user is active.  It's possible that I'm
filtering something or perhaps associating the event wrong; it would
depend on whether session var changes propagate prior to the Unlisten
event.  Any ideas here?

Daniel

On Jan 12, 12:46 pm, David Pollak feeder.of.the.be...@gmail.com
wrote:
 I'm kind swamped today, but the simplest thing you can do is:

 private def notifyListen = {
   MyUserThingy.gotAListenEventFor(User.currentUser)
   false

 }

 private def notifyUnlisten = {
   MyUserThingy.gotAnUnlistenEventFor(User.currentUser)
   false

 }

 override def highPriority = {
   case Listen(_, _, _) if notifyListen = ()
   case Unlisten(_) if notifyUnlisten = ()

 }

 Each time the browser registers as a listener, you'll get a notification
 (the beginning of the long poll).  Each time the browser unregisters as a
 listener (the end of the long poll), you'll get a notification.

 This stuff is kinda internal and may change (although there's no plans to
 change the Listen/Unlisten logic).

 On Tue, Jan 12, 2010 at 10:25 AM, Daniel Spiewak djspie...@gmail.comwrote:



  We're already using the Comet support within Lift quite extensively
  across the board.  There are very, very few pages in our application
  which do not have a CometActor embedded in them at some level of
  nesting.

  Daniel

  On Jan 12, 12:08 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:
   You are already using Comet, or just Lift?

   -

   Daniel Spiewakdjspie...@gmail.com wrote:

   I'm looking to implement a user presence feature (think: Facebook or
   Gmail chat) in a Lift 1.0 application.  Ideally, I would like to avoid
   adding extraneous connections.  Is it possible to hook into the Lift
   Comet heartbeat which is already in use across our system?  I've
   looked at the source for CometActor, and it's just a little too
   obfuscated for me to figure this one out on my own.  :-)

   Alternatively, has anyone else implemented this sort of system in
   Lift?  If so, how did you go about it?  Any tips from the well-
   informed?

   Daniel
   --
   You received this message because you are subscribed to the Google Groups
  Lift group.
   To post to this group, send email to lift...@googlegroups.com.
   To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
  .
   For more options, visit this group athttp://
  groups.google.com/group/liftweb?hl=en.

  --
  You received this message because you are subscribed to the Google Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
  .
  For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.

 --
 Lift, the simply functional web frameworkhttp://liftweb.net
 Beginning Scalahttp://www.apress.com/book/view/1430219890
 Follow me:http://twitter.com/dpp
 Surf the harmonics

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] User Presence Heartbeat

2010-01-12 Thread Daniel Spiewak
I'm looking to implement a user presence feature (think: Facebook or
Gmail chat) in a Lift 1.0 application.  Ideally, I would like to avoid
adding extraneous connections.  Is it possible to hook into the Lift
Comet heartbeat which is already in use across our system?  I've
looked at the source for CometActor, and it's just a little too
obfuscated for me to figure this one out on my own.  :-)

Alternatively, has anyone else implemented this sort of system in
Lift?  If so, how did you go about it?  Any tips from the well-
informed?

Daniel
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: User Presence Heartbeat

2010-01-12 Thread Daniel Spiewak
We're already using the Comet support within Lift quite extensively
across the board.  There are very, very few pages in our application
which do not have a CometActor embedded in them at some level of
nesting.

Daniel

On Jan 12, 12:08 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:
 You are already using Comet, or just Lift?

 -

 Daniel Spiewakdjspie...@gmail.com wrote:

 I'm looking to implement a user presence feature (think: Facebook or
 Gmail chat) in a Lift 1.0 application.  Ideally, I would like to avoid
 adding extraneous connections.  Is it possible to hook into the Lift
 Comet heartbeat which is already in use across our system?  I've
 looked at the source for CometActor, and it's just a little too
 obfuscated for me to figure this one out on my own.  :-)

 Alternatively, has anyone else implemented this sort of system in
 Lift?  If so, how did you go about it?  Any tips from the well-
 informed?

 Daniel
 --
 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group 
 athttp://groups.google.com/group/liftweb?hl=en.
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: User Presence Heartbeat

2010-01-12 Thread Daniel Spiewak
Sweet, that looks like exactly what I need!  I'll post back here if
that doesn't work properly.

Daniel

On Jan 12, 12:46 pm, David Pollak feeder.of.the.be...@gmail.com
wrote:
 I'm kind swamped today, but the simplest thing you can do is:

 private def notifyListen = {
   MyUserThingy.gotAListenEventFor(User.currentUser)
   false

 }

 private def notifyUnlisten = {
   MyUserThingy.gotAnUnlistenEventFor(User.currentUser)
   false

 }

 override def highPriority = {
   case Listen(_, _, _) if notifyListen = ()
   case Unlisten(_) if notifyUnlisten = ()

 }

 Each time the browser registers as a listener, you'll get a notification
 (the beginning of the long poll).  Each time the browser unregisters as a
 listener (the end of the long poll), you'll get a notification.

 This stuff is kinda internal and may change (although there's no plans to
 change the Listen/Unlisten logic).

 On Tue, Jan 12, 2010 at 10:25 AM, Daniel Spiewak djspie...@gmail.comwrote:



  We're already using the Comet support within Lift quite extensively
  across the board.  There are very, very few pages in our application
  which do not have a CometActor embedded in them at some level of
  nesting.

  Daniel

  On Jan 12, 12:08 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:
   You are already using Comet, or just Lift?

   -

   Daniel Spiewakdjspie...@gmail.com wrote:

   I'm looking to implement a user presence feature (think: Facebook or
   Gmail chat) in a Lift 1.0 application.  Ideally, I would like to avoid
   adding extraneous connections.  Is it possible to hook into the Lift
   Comet heartbeat which is already in use across our system?  I've
   looked at the source for CometActor, and it's just a little too
   obfuscated for me to figure this one out on my own.  :-)

   Alternatively, has anyone else implemented this sort of system in
   Lift?  If so, how did you go about it?  Any tips from the well-
   informed?

   Daniel
   --
   You received this message because you are subscribed to the Google Groups
  Lift group.
   To post to this group, send email to lift...@googlegroups.com.
   To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
  .
   For more options, visit this group athttp://
  groups.google.com/group/liftweb?hl=en.

  --
  You received this message because you are subscribed to the Google Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
  .
  For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.

 --
 Lift, the simply functional web frameworkhttp://liftweb.net
 Beginning Scalahttp://www.apress.com/book/view/1430219890
 Follow me:http://twitter.com/dpp
 Surf the harmonics
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.