Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scala.Option enhancement #661

Closed
scabug opened this issue Mar 20, 2008 · 8 comments
Closed

scala.Option enhancement #661

scabug opened this issue Mar 20, 2008 · 8 comments

Comments

@scabug
Copy link

scabug commented Mar 20, 2008

There are some fundamental functions missing on scala.Option. Please find them in the attached patch.

@scabug
Copy link
Author

scabug commented Mar 20, 2008

Imported From: https://issues.scala-lang.org/browse/SI-661?orig=1
Reporter: @tonymorris
Attachments:

@scabug
Copy link
Author

scabug commented Mar 20, 2008

@ingoem said:
Thanks for the effort, we will discuss these.

Personally, I think we should be careful not to bloat the API with special purpose methods. Many things can be expressed with map and flatMap already. Since Option is an Iterable, it interacts with other collections. Function somes, e.g., can be written as:

val someSet: Set[Option[Int]] = ...
val set = someSet.flatMap(x=>x)

This has the benefit that we maintain the collection type, in this case Set.

Other methods such as ifNone don't add much. If we are going to add it, we probably need to add ifSome to Option and ifEmpty and ifNotEmtpy to collections. Saving just a few key strokes doesn't justify this.

On the other hand, I sometimes also wish I could express things with Options more concisely. I don't see a good way to do it though.

@scabug
Copy link
Author

scabug commented Mar 20, 2008

@dragos said:
The flatMapN methods look more like folds to me. I think the same functionality can be obtained using for comprehensions:

  for (a <- optionA; b <- optionB; c <- optionC) yield f(a, b, c)

I wouldn't add ifNone and iif, they seem to small to warrant the loss of performance and clarity.

@scabug
Copy link
Author

scabug commented Mar 20, 2008

@tonymorris said:
Thanks for taking a look guys. I'm not particularly adamant about the inclusion of all of these functions, however, I will make some points for you to consider:

  • I agree that "bloating the API" should be avoided, however, when dealing with pure functions, users do not care about the number of those functions. They care about the interactions between functions that may side-effect upon each other. Consider java.lang.String with all its pure functions. No user has ever objected to the sheer number of these functions. I'd argue that a user of scala.Option would do same. Therefore, "bloating the API" has the definition of introducing functions that potentially side-effect on each other such that the class is significantly more difficult to reason about as each function is introduced. scala.Option does not have this problem.

  • That a function can be written with a lower-order logic does not make its inclusion too trivial to necessitate. Writing software is all about creating a logical theorem (C-H Isomorphism) and if part of that proof has already been done, then I will simply not have to write it (and potentially make an error in doing so). The key question that should arise is "how often are users going to require this particular proof?". This brings up my next point.

  • join is absolutely essential to Option (and any type that has flatMap for that matter). All monads have a join and users should not have to kludge it with .flatMap(identity). Option needs join.

  • Option does have ifSome - it's just called foreach instead. If the collections don't have ifEmpty and/or ifNotEmpty, then they need them. In fact, this function can be generalised to a Foldable/catamorphism. Maybe Adriaan Moors is working on that.

  • flatMapN is called "monad lifting"; folding is something else. I agree that we could achieve the same with for-comprehensions, but I'd still advocate the inclusion of the specific functions.

  • What performance is lost in using ifNone and iif? They are certainly not a loss in clarity - since they can be shown to improve clarity (my earlier point about logical theorem).

@scabug
Copy link
Author

scabug commented Mar 23, 2008

@ingoem said:
Replying to [comment:3 dibblego]:

Thanks for taking a look guys. I'm not particularly adamant about the inclusion of all of these functions, however, I will make some points for you to consider:

  • I agree that "bloating the API" should be avoided, however, when dealing with pure functions, users do not care about the number of those functions. They care about the interactions between functions that may side-effect upon each other. Consider java.lang.String with all its pure functions. No user has ever objected to the sheer number of these functions. I'd argue that a user of scala.Option would do same. Therefore, "bloating the API" has the definition of introducing functions that potentially side-effect on each other such that the class is significantly more difficult to reason about as each function is introduced. scala.Option does not have this problem.

I disagree. Bloating an API has not necessarily to do with (interacting) side-effects. Code should be readable. Introducing methods that do the same as can be achieved by other means in already short and equally well readable ways, or introducing methods with cryptic names bloats an API, IMHO. Most methods in java.lang.String add something new and their names are quite meaningful. That's why I think nobody complains.

There are already lots of different ways to achieve things in Scala. Sometimes this is good, sometimes, we should just say no, it's enough.

  • That a function can be written with a lower-order logic does not make its inclusion too trivial to necessitate. Writing software is all about creating a logical theorem (C-H Isomorphism) and if part of that proof has already been done, then I will simply not have to write it (and potentially make an error in doing so). The key question that should arise is "how often are users going to require this particular proof?". This brings up my next point.

  • join is absolutely essential to Option (and any type that has flatMap for that matter). All monads have a join and users should not have to kludge it with .flatMap(identity). Option needs join.

Yes, I also think join should be there for all Iterables. Maybe we should wait for type constraints in Scala, until we may add this method to the Iterable trait (not all the collection objects).

(BTW, "... is essential to ...", "all ... have ..." and "... needs ..." don't add much to a discussion most of the time. They don't say anything about the why's.)

  • Option does have ifSome - it's just called foreach instead. If the collections don't have ifEmpty and/or ifNotEmpty, then they need them. In fact, this function can be generalised to a Foldable/catamorphism. Maybe Adriaan Moors is working on that.

What's the point of writing coll ifEmpty { doSometing() } versus if (coll.isEmpty) doSomething() and how should this be generalized? Maybe I just miss your point.

  • flatMapN is called "monad lifting"; folding is something else. I agree that we could achieve the same with for-comprehensions, but I'd still advocate the inclusion of the specific functions.

Just another way to achieve things.

  • What performance is lost in using ifNone and iif? They are certainly not a loss in clarity - since they can be shown to improve clarity (my earlier point about logical theorem).

How can they be shown to improve clarity? iif is a cryptic name, opt ifNone can be written as if (opt == None).

Anyways, I think commonly used classes like Option might be exceptions here and the threshold for introducing slightly cryptic but useful methods might be a bit lower than for other classes. Given the recent discussions about Scala's fold operators and so on we should be careful though.

@scabug
Copy link
Author

scabug commented Apr 1, 2008

@ingoem said:
We will leave Option as it is now. Join will be added as flatten to Iterable once we have general type constraints.

@scabug
Copy link
Author

scabug commented Jan 14, 2009

@odersky said:
Milestone 2.7.1 deleted

@scabug
Copy link
Author

scabug commented Apr 12, 2011

@SethTisue said:
I opened a separate ticket, #4474, about at least adding flatten/join

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant