Re: [Lift] Reasoning Behind Box

2010-02-26 Thread David Pollak
Daniel,

Thanks for asking the question and I hope the discussion will go better than
the last time we had an in depth discussion on the topic.  I'm going to
respond in a Prologue, History, Reactions, Code Examples and Conclusion.

*Prologue*

I'm not a classically trained CS guy.  I've never taken an FP-related CS
course in my life.  I've only done any real FP-related coding since November
2006.  I've only taken 3 CS courses in my entire life (360 assembler [almost
got thrown out because the teacher hated the fact that I always found bugs
in her homework assignments during the class in which she handed out the
assignments], data structures and algorithms [got accused of cheating on
mid-term because my sorting algorithm ran 10x faster than the next
fastest... turns out I randomized the incoming data {avoids O(n^2) issue in
QuickSort} and created faux-pointers and sorted those rather than the
structures {this was in Pascal}], and a database theory class [almost got
thrown out because the comments in my code were considered
"unprofessional"... rescued my grade by writing a hand SQL parser rather
than using Flex/Bison]).  The reason I say this is that I'm not going to
discuss ADTs, mathematical properties, or anything else.  I'm not qualified
or capable of having that kind of discussion.

I'm also lazy and pragmatic.  If a library works for me, I use it.  If a
library requires a lot of working-around, I ask for fixes and if I don't get
them, I write my own.  I did this with the NextStep Text object... it didn't
have what I needed for Mesa, the Next guys weren't happy about giving what I
needed... I wrote my own... then the Next guys rolled a lot of my concepts
into the NS Text object.  The same thing happened with the NextStep font
chooser... in fact, Mesa's font chooser was the first piece of open source
software I wrote... but I digress.

*History*

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.

I posted to the Scala mailing list and, well... there were not a lot of good
suggestions other than use Either (e.g., write my own Either library).  The
problem with Either is that it was not usable in for comprehensions and
pattern matching was becoming increasingly deprecated.  One of our advisors
(http://www.lukehohmann.com/ ) was particularly keen on keeping a low McCabe
complexity number for code (see
http://en.wikipedia.org/wiki/Cyclomatic_complexity ).  For comprehensions
offered a very low complexity where pattern matching explodes complexity.

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.)

Can became a better Option.  In addition to having Full/Empty (Some/None),
it also had Failure... a subclass that could contain information as to why
the Can did not contain anything.  From an object hierarchy standpoint, Can
and Option are identical at the first children: Full == Some.  EmptyCan ==
None.  The other problems I saw with Option were:

   - 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?"
   - orElse orElse orElse... who named this method.  In terms of method
   naming the "Else" 

Re: [Lift] Reasoning Behind Box

2010-02-25 Thread Heiko Seeberger
On 26 February 2010 08:09, Naftoli Gugenheim  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.



Re: [Lift] Reasoning Behind Box

2010-02-25 Thread Naftoli Gugenheim
Either -- but it's more verbose.
I'm not so sure David will want to rewrite the entire lift anyway...

-
Heiko Seeberger wrote:

Daniel,

I would like to look at this question from a solution oriented
perspective: Certainly you already noticed the third Box subtype Failure and
are aware of its usage. I agree with you, that Option vs Box is confusing
for Lift (and nowadays Goat Rodeo) adopters. As Scala and Lift are still
very young adoption is vital and hence I would like to know, what you
suggest: How could we only use Option *and* get something like Failure? Any
ideas?

Heiko

On 26 February 2010 05:40, Daniel Spiewak  wrote:

> 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.
>
>


-- 
Heiko Seeberger

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.

-- 
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.



Re: [Lift] Reasoning Behind Box

2010-02-25 Thread Heiko Seeberger
Daniel,

I would like to look at this question from a solution oriented
perspective: Certainly you already noticed the third Box subtype Failure and
are aware of its usage. I agree with you, that Option vs Box is confusing
for Lift (and nowadays Goat Rodeo) adopters. As Scala and Lift are still
very young adoption is vital and hence I would like to know, what you
suggest: How could we only use Option *and* get something like Failure? Any
ideas?

Heiko

On 26 February 2010 05:40, Daniel Spiewak  wrote:

> 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.
>
>


-- 
Heiko Seeberger

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.



Re: [Lift] Reasoning Behind Box

2010-02-25 Thread Naftoli Gugenheim
I'm assuming you know that it has a third, Failure state, and you're asking 
about the names.
I guess open_! is in keeping with the metaphor of a box (or originally, a can). 
The _! is Lift's way of saying, Danger! And I guess 'or' is just shorter. (Lift 
tends to put practicality before academic functionalness etc.)

-
Daniel Spiewak wrote:

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.

-- 
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.