Re: Optional.orElseChain ?

2015-04-28 Thread Paul Sandoz
Hi Remi,

Chasing this up. I have not joined the dark-side just yet... but can you log an 
issue for this?

Thanks,
Paul.

On Apr 20, 2015, at 4:27 PM, Remi Forax fo...@univ-mlv.fr wrote:

 
 On 04/20/2015 01:39 PM, Paul Sandoz wrote:
 Hi Remi,
 
 I was gonna propose the same trick you mentioned in your last email :-)
 
 yes, it's the same as
  optional.map(Stream::of).orElseGet(() - Stream.empty())
 (I use orElseGet() because Stream.empty() is not a constant !).
 
 
 Similar tricks are possible for other cases like an equivalent of the 
 recently added ifPresentOrElse, but that was considered a little obtuse.
 
 
 On Apr 17, 2015, at 11:37 PM, Remi Forax fo...@univ-mlv.fr wrote:
 Hi guys,
 I was trying to write a code that uses Optional and I think one method is 
 missing.
 
 There is always one more (or four more including the primitive variants) :-)
 
 Yes, yet another one.
 
 Note that technically, the only thing you need is to be able to do pattern 
 matching on the two states,
 so if you have a way to do a flatMap() for the case with a value and a 
 flatMap() for the case with no value,
 you're done.
 
 Doing a flatMap for the case with no value is exactly what you have called 
 'or'.
 So it's yet another method to add but it's the last one :)
 
 
 We avoided supporting both the present and absent axes in the intermediate 
 operations (e.g. additional methods with a supplier on absence).
 
 This seems like a special intermediate operation, injecting an alternative 
 optional on absence, rather than associated with the orElse terminal 
 operations that return T:
 
   public OptionalT or(SupplierOptionalT mapper) {
   Objects.requireNonNull(mapper);
   if (isPresent()) {
   return this;
   } else {
   return Objects.requireNonNull(mapper.get());
   }
   }
 
 yes,
 
 
 But it has some terminal like qualities to it. It really only makes sense 
 once, or once after each flatMap. I am concerned that a bunch of these 
 sprinkled within a sequence of fluent calls might make it hard to reason 
 about.
 
 As such a static method might be more appropriate, but then it's easy for 
 someone to add one in their own code:
 
 static T OptionalT or(OptionalT a, Supplier? extends OptionalT b) {
 Objects.requireNonNull(a);
 Objects.requireNonNull(b);
 return a.isPresent() ? a : Objects.requireNonNull(b.get());
 }
 
 static T OptionalT or(OptionalT a, OptionalT b) {
 Objects.requireNonNull(a);
 Objects.requireNonNull(b);
 return a.isPresent() ? a : b;
 }
 
 Perhaps the non-obvious thing about these is a null return should not be 
 allowed.
 
 But mixing static methods and instance methods is not readable too,
 instance methods goes left to right and static methods goes right to left.
 
 
 I am somewhat on the fence here...
 
 If you only knew the power of the Dark Side :)
 
 
 Paul.
 
 Rémi
 


Re: Optional.orElseChain ?

2015-04-20 Thread Paul Sandoz
Hi Remi,

I was gonna propose the same trick you mentioned in your last email :-) 

Similar tricks are possible for other cases like an equivalent of the recently 
added ifPresentOrElse, but that was considered a little obtuse.


On Apr 17, 2015, at 11:37 PM, Remi Forax fo...@univ-mlv.fr wrote:
 Hi guys,
 I was trying to write a code that uses Optional and I think one method is 
 missing.
 

There is always one more (or four more including the primitive variants) :-)

We avoided supporting both the present and absent axes in the intermediate 
operations (e.g. additional methods with a supplier on absence).

This seems like a special intermediate operation, injecting an alternative 
optional on absence, rather than associated with the orElse terminal operations 
that return T:

  public OptionalT or(SupplierOptionalT mapper) {
  Objects.requireNonNull(mapper);
  if (isPresent()) {
  return this;
  } else {
  return Objects.requireNonNull(mapper.get());
  }
  }

But it has some terminal like qualities to it. It really only makes sense once, 
or once after each flatMap. I am concerned that a bunch of these sprinkled 
within a sequence of fluent calls might make it hard to reason about. 

As such a static method might be more appropriate, but then it's easy for 
someone to add one in their own code:

static T OptionalT or(OptionalT a, Supplier? extends OptionalT b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
return a.isPresent() ? a : Objects.requireNonNull(b.get());
}

static T OptionalT or(OptionalT a, OptionalT b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
return a.isPresent() ? a : b;
}

Perhaps the non-obvious thing about these is a null return should not be 
allowed.

I am somewhat on the fence here...

Paul. 


 Let suppose I want to load a type (like a class, an interface, etc) that can 
 come
 either by reflection, or by using ASM.
 I will write an interface TypeProvider that is able to load a Type and
 i will chain the different type providers like this:
 
  TypeProvider asmTypeProvider = ...
  TypeProvider reflectionTypeProvider = ...
  TypeProvider provider =
asmTypeProvider.chain(reflectionTypeProvider).orFail();
 
 so I've implemented TypeProvider like this:
 
 public interface TypeProvider {
  public OptionalType loadType(String name);
 
  public default TypeProvider chain(TypeProvider provider) {
return name - {
  OptionalType type = loadType(name);
  return type.isPresent()? type: provider.loadType(name);
};
  }
 
  public default TypeProvider orFail() {
return chain(fail());
  }
 
  public static TypeProvider fail() {
return name - Optional.empty();
  }
 }
 
 As you can see the code is not bad but the code of chain() could be simplified
 if there was a way on Optional to call a Supplier of Optional if an Optional 
 is empty.
 Currently, orElse() takes a value, orElseGet takes a lambda that will return 
 a value
 and there is no method that takes a lambda and return an Optional
 (like flatMap but but with a supplier that will be called if the Optional is 
 empty).
 
 If we add the method orElseChain(Supplier? extends OptionalT supplier)
 perhaps with a better name ?, then the code of chain is better:
 
  public default TypeProvider chain(TypeProvider provider) {
return name - loadType(name).orElseChain(() - provider.loadType(name));
  }
 
 Am i the only one to think that this method is missing ?
 
 regards,
 Rémi
 



Re: Optional.orElseChain ?

2015-04-20 Thread Remi Forax


On 04/20/2015 01:39 PM, Paul Sandoz wrote:

Hi Remi,

I was gonna propose the same trick you mentioned in your last email :-)


yes, it's the same as
  optional.map(Stream::of).orElseGet(() - Stream.empty())
(I use orElseGet() because Stream.empty() is not a constant !).



Similar tricks are possible for other cases like an equivalent of the recently 
added ifPresentOrElse, but that was considered a little obtuse.


On Apr 17, 2015, at 11:37 PM, Remi Forax fo...@univ-mlv.fr wrote:

Hi guys,
I was trying to write a code that uses Optional and I think one method is 
missing.


There is always one more (or four more including the primitive variants) :-)


Yes, yet another one.

Note that technically, the only thing you need is to be able to do 
pattern matching on the two states,
so if you have a way to do a flatMap() for the case with a value and a 
flatMap() for the case with no value,

you're done.

Doing a flatMap for the case with no value is exactly what you have 
called 'or'.

So it's yet another method to add but it's the last one :)



We avoided supporting both the present and absent axes in the intermediate 
operations (e.g. additional methods with a supplier on absence).

This seems like a special intermediate operation, injecting an alternative 
optional on absence, rather than associated with the orElse terminal operations 
that return T:

   public OptionalT or(SupplierOptionalT mapper) {
   Objects.requireNonNull(mapper);
   if (isPresent()) {
   return this;
   } else {
   return Objects.requireNonNull(mapper.get());
   }
   }


yes,



But it has some terminal like qualities to it. It really only makes sense once, 
or once after each flatMap. I am concerned that a bunch of these sprinkled 
within a sequence of fluent calls might make it hard to reason about.

As such a static method might be more appropriate, but then it's easy for 
someone to add one in their own code:

static T OptionalT or(OptionalT a, Supplier? extends OptionalT b) {
 Objects.requireNonNull(a);
 Objects.requireNonNull(b);
 return a.isPresent() ? a : Objects.requireNonNull(b.get());
}

static T OptionalT or(OptionalT a, OptionalT b) {
 Objects.requireNonNull(a);
 Objects.requireNonNull(b);
 return a.isPresent() ? a : b;
}

Perhaps the non-obvious thing about these is a null return should not be 
allowed.


But mixing static methods and instance methods is not readable too,
instance methods goes left to right and static methods goes right to left.



I am somewhat on the fence here...


If you only knew the power of the Dark Side :)



Paul.


Rémi





Let suppose I want to load a type (like a class, an interface, etc) that can 
come
either by reflection, or by using ASM.
I will write an interface TypeProvider that is able to load a Type and
i will chain the different type providers like this:

  TypeProvider asmTypeProvider = ...
  TypeProvider reflectionTypeProvider = ...
  TypeProvider provider =
asmTypeProvider.chain(reflectionTypeProvider).orFail();

so I've implemented TypeProvider like this:

public interface TypeProvider {
  public OptionalType loadType(String name);

  public default TypeProvider chain(TypeProvider provider) {
return name - {
  OptionalType type = loadType(name);
  return type.isPresent()? type: provider.loadType(name);
};
  }

  public default TypeProvider orFail() {
return chain(fail());
  }

  public static TypeProvider fail() {
return name - Optional.empty();
  }
}

As you can see the code is not bad but the code of chain() could be simplified
if there was a way on Optional to call a Supplier of Optional if an Optional is 
empty.
Currently, orElse() takes a value, orElseGet takes a lambda that will return a 
value
and there is no method that takes a lambda and return an Optional
(like flatMap but but with a supplier that will be called if the Optional is 
empty).

If we add the method orElseChain(Supplier? extends OptionalT supplier)
perhaps with a better name ?, then the code of chain is better:

  public default TypeProvider chain(TypeProvider provider) {
return name - loadType(name).orElseChain(() - provider.loadType(name));
  }

Am i the only one to think that this method is missing ?

regards,
Rémi





Re: Optional.orElseChain ?

2015-04-18 Thread Remi Forax


On 04/18/2015 01:58 AM, Andreas Lundblad wrote:

On Fri, Apr 17, 2015 at 03:01:29PM -0700, Steven Schlansker wrote:

On Apr 17, 2015, at 2:37 PM, Remi Forax fo...@univ-mlv.fr wrote:

As you can see the code is not bad but the code of chain() could be simplified
if there was a way on Optional to call a Supplier of Optional if an Optional is 
empty.
Currently, orElse() takes a value, orElseGet takes a lambda that will return a 
value
and there is no method that takes a lambda and return an Optional
(like flatMap but but with a supplier that will be called if the Optional is 
empty).

If we add the method orElseChain(Supplier? extends OptionalT supplier)
perhaps with a better name ?, then the code of chain is better:

  public default TypeProvider chain(TypeProvider provider) {
return name - loadType(name).orElseChain(() - provider.loadType(name));
  }

Am i the only one to think that this method is missing ?

We actually ran into the exact same problem, and wrote the following helper 
method:

public static X OptionalX unlessOpt(@Nonnull OptionalX first, 
SupplierOptionalX second) {
 return first.isPresent() ? first : second.get();
}

I don't think it's precisely the same as your solution, but it definitely 
indicates a missing method.

There are similar discussion here:
http://stackoverflow.com/questions/2456/get-value-from-one-optional-or-another

and here:
http://stackoverflow.com/questions/28818506/java-8-optional-orelse-optional


Thanks Andreas,
the second link provides a clever answer
(which as usually with StackOverflow is not the most voted answer :( ),
  return name - loadType(name).map(Optional::of).orElseGet(() - 
provider.loadType(name));


by mapping using Optional::of, it creates an Optional of Optional then 
orElseGet can be used
to unwrap it to either an Optional or if the Optional inside the 
Optional is empty by calling the supplier.


while this solution works, it creates an Optional of Optional just to 
workaround the fact that

there is no method orElseChain/orElseOptional.



-- Andreas


cheers,
Rémi




Optional.orElseChain ?

2015-04-17 Thread Remi Forax

Hi guys,
I was trying to write a code that uses Optional and I think one method 
is missing.


Let suppose I want to load a type (like a class, an interface, etc) that 
can come

either by reflection, or by using ASM.
I will write an interface TypeProvider that is able to load a Type and
i will chain the different type providers like this:

  TypeProvider asmTypeProvider = ...
  TypeProvider reflectionTypeProvider = ...
  TypeProvider provider =
asmTypeProvider.chain(reflectionTypeProvider).orFail();

so I've implemented TypeProvider like this:

public interface TypeProvider {
  public OptionalType loadType(String name);

  public default TypeProvider chain(TypeProvider provider) {
return name - {
  OptionalType type = loadType(name);
  return type.isPresent()? type: provider.loadType(name);
};
  }

  public default TypeProvider orFail() {
return chain(fail());
  }

  public static TypeProvider fail() {
return name - Optional.empty();
  }
}

As you can see the code is not bad but the code of chain() could be 
simplified
if there was a way on Optional to call a Supplier of Optional if an 
Optional is empty.
Currently, orElse() takes a value, orElseGet takes a lambda that will 
return a value

and there is no method that takes a lambda and return an Optional
(like flatMap but but with a supplier that will be called if the 
Optional is empty).


If we add the method orElseChain(Supplier? extends OptionalT supplier)
perhaps with a better name ?, then the code of chain is better:

  public default TypeProvider chain(TypeProvider provider) {
return name - loadType(name).orElseChain(() - 
provider.loadType(name));

  }

Am i the only one to think that this method is missing ?

regards,
Rémi



Re: Optional.orElseChain ?

2015-04-17 Thread Steven Schlansker

On Apr 17, 2015, at 2:37 PM, Remi Forax fo...@univ-mlv.fr wrote:
 As you can see the code is not bad but the code of chain() could be simplified
 if there was a way on Optional to call a Supplier of Optional if an Optional 
 is empty.
 Currently, orElse() takes a value, orElseGet takes a lambda that will return 
 a value
 and there is no method that takes a lambda and return an Optional
 (like flatMap but but with a supplier that will be called if the Optional is 
 empty).
 
 If we add the method orElseChain(Supplier? extends OptionalT supplier)
 perhaps with a better name ?, then the code of chain is better:
 
  public default TypeProvider chain(TypeProvider provider) {
return name - loadType(name).orElseChain(() - provider.loadType(name));
  }
 
 Am i the only one to think that this method is missing ?

We actually ran into the exact same problem, and wrote the following helper 
method:

public static X OptionalX unlessOpt(@Nonnull OptionalX first, 
SupplierOptionalX second) {
return first.isPresent() ? first : second.get();
}

I don't think it's precisely the same as your solution, but it definitely 
indicates a missing method.



Re: Optional.orElseChain ?

2015-04-17 Thread Andreas Lundblad
On Fri, Apr 17, 2015 at 03:01:29PM -0700, Steven Schlansker wrote:
 
 On Apr 17, 2015, at 2:37 PM, Remi Forax fo...@univ-mlv.fr wrote:
  As you can see the code is not bad but the code of chain() could be 
  simplified
  if there was a way on Optional to call a Supplier of Optional if an 
  Optional is empty.
  Currently, orElse() takes a value, orElseGet takes a lambda that will 
  return a value
  and there is no method that takes a lambda and return an Optional
  (like flatMap but but with a supplier that will be called if the Optional 
  is empty).
  
  If we add the method orElseChain(Supplier? extends OptionalT supplier)
  perhaps with a better name ?, then the code of chain is better:
  
   public default TypeProvider chain(TypeProvider provider) {
 return name - loadType(name).orElseChain(() - provider.loadType(name));
   }
  
  Am i the only one to think that this method is missing ?
 
 We actually ran into the exact same problem, and wrote the following helper 
 method:
 
 public static X OptionalX unlessOpt(@Nonnull OptionalX first, 
 SupplierOptionalX second) {
 return first.isPresent() ? first : second.get();
 }
 
 I don't think it's precisely the same as your solution, but it definitely 
 indicates a missing method.

There are similar discussion here:
http://stackoverflow.com/questions/2456/get-value-from-one-optional-or-another

and here:
http://stackoverflow.com/questions/28818506/java-8-optional-orelse-optional

-- Andreas