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.

Reply via email to