Yes.  I never did understand why Google chose not to have Optional inherit
from Iterable
So that it could be used in for loops without the superfluous asSet
conversion.


On 10 July 2012 09:32, Dale Wijnand <[email protected]> wrote:

> Just throwing this out there, here's another way to use Guava's Optional:
>         for (String format : logFormat.asSet()) {
>             formatter.setPattern(format);
>         }
>
> as an alternative to
>         if (logFormat.isPresent()) {
>             formatter.setPattern(logFormat.get());
>         }
>
> which is somewhat similar to the "foreach" above.
>
> On Sunday, July 8, 2012 4:42:46 PM UTC+2, KWright wrote:
>
>> Even if you're being ironic, this is right, whether or not you meant for
>> it to be :)
>>
>> In the first case, p could just as well be a collection, or a stream, or
>> a future, or almost anything else that can be classed as a functor.  A
>> functor is most easily described as "anything with a map operation", and
>> `foreach` is nothing more than a map operation where you discard the
>> results.  (You may be more familiar with the term monad, which is most
>> easily described as "an extension of the functor concept that adds the
>> flatMap operation".)
>>
>> Let's consider that p represents a printer attached to your computer.
>>  Initially, you represent it as an Option[Printer], later it might be
>> several printers and so you use Set[Printer], still later still it could be
>> networked printers that have a high latency to enumerate and so you use
>> SetOfFutures[Printer] to take advantage of asynchronous logic.
>>
>> In all cases, the central logic remains totally unaltered even as the
>> type of `p` evolves:
>>
>> p foreach {
>>     myThing
>> }
>>
>>
>> nullable values just fail to deliver at this level of abstraction.
>>
>> *(note: SetOfFutures isn't a built-in type, but there are techniques to
>> flatten nested monads such as Set[Future[T]] and treat them as the
>> hypothetical SetOfFutures[T].  This sort of composability is one of the
>> driving forces towards using monads in the first place!)*
>>
>>
>>
>> On 8 July 2012 15:09, Reinier Zwitserloot wrote:
>>
>>> I completely agree:
>>>
>>> p foreach {
>>>     myThing
>>> }
>>>
>>> is ever so much cleaner and easier to follow compared to
>>>
>>> if (p != null) {
>>>     myThing
>>> }
>>>
>>> It's, frankly, a breath of fresh air.
>>>
>>>
>>> On Friday, July 6, 2012 5:05:51 PM UTC+1, KWright wrote:
>>>
>>>> More normally, you'd just map over your option:
>>>>
>>>> val p = Some(person)
>>>> p foreach { myMethod }
>>>>
>>>>
>>>> This works precisely because you're keeping the optional nature of such
>>>> constructs away from your functions, allowing them to just get on with
>>>> their job ab not have to muck about checking for null and suchlike.
>>>>
>>>> You DON'T weave monads through functions, you weave functions through
>>>> monads.  This is the crucial distinction between Option/Maybe and
>>>> nullability, but it can also be a tricky concept until your default mental
>>>> model of functions is that they're first-class entities in their own right,
>>>> and can be freely composed, manipulated, passed as arguments, etc.
>>>>
>>>> So it's your Option[Person] that accepts your method.  Not the other
>>>> way around.
>>>>
>>>>
>>>> On 6 July 2012 16:47, Cédric Beust ♔ wrote:
>>>>
>>>>> On Fri, Jul 6, 2012 at 4:28 AM, Reinier Zwitserloot wrote:
>>>>>
>>>>>
>>>>>>
>>>>>> On Friday, July 6, 2012 1:12:18 PM UTC+2, Dale Wijnand wrote:
>>>>>>>
>>>>>>> On the fly I can't think of a reason to return a List<Option<T>>,
>>>>>>> that's just ridiculous.
>>>>>>>
>>>>>>>
>>>>>> Why is that ridiculous? If I have a method which emits an Option<T>,
>>>>>> and I have a list of inputs and I run a map operation, I'll get a
>>>>>> List<Option<T>> out. Either Option is part of the type system (which also
>>>>>> means it can be used in generics too), or it's not. There's no 
>>>>>> halfwaysies
>>>>>> on this, IMO.
>>>>>>
>>>>>
>>>>> Right, it's not ridiculous. The overall idea is that once you start
>>>>> manipulating monadic values and you are using a language whose syntax and
>>>>> libraries supports monads pervasively, you are better off keeping these 
>>>>> and
>>>>> working with them than flattening them. Note that I abstracted away from
>>>>> Option: such API's don't accept just an Option<Person> in their API but a
>>>>> Monad<?>, which Option happens to satisfy (and a bunch of others).
>>>>>
>>>>> In Java, you will most likely need to flatten more often because all
>>>>> the API's accept non-monadic values, e.g. your API accepts a Person, not 
>>>>> an
>>>>> Option<Person>, so you have to extract the value before calling that API.
>>>>>
>>>>> --
>>>>> Cédric
>>>>>
>>>>>
>>>>
>>>>
>>>   --
> You received this message because you are subscribed to the Google Groups
> "Java Posse" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/javaposse/-/1IQ5RGMlnd4J.
>
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/javaposse?hl=en.
>



-- 
Kevin Wright
mail: [email protected]
gtalk / msn : [email protected]
quora: http://www.quora.com/Kevin-Wright
google+: http://gplus.to/thecoda
<[email protected]>
twitter: @thecoda
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not
regard them as "lines produced" but as "lines spent": the current
conventional wisdom is so foolish as to book that count on the wrong side
of the ledger" ~ Dijkstra

-- 
You received this message because you are subscribed to the Google Groups "Java 
Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to