Re: valhalla-dev Digest, Vol 6, Issue 3

Timo Kinnunen timo.kinnunen at gmail.com
Mon Dec 22 19:59:45 UTC 2014


Regarding “What's your story for the Collection method

   removeAll(Collection<?>)

in such a way that a removeAll method could be called from generic code 
like:

<any U> removeAllFrom(Collection<U> originalCollection,
                       Collection<? extends U> eltsToRemove) { ... }”:



What is the format that an accepted answer should be presented in? 


Here’s one answer, but I don’t know if that’s what you’re looking for:


static <@NonNull U> boolean removeAllFrom(Set<@NonNull U> originalCollection, Collection<? extends @NonNull U> eltsToRemove) {

if(eltsToRemove == null) {

  throw new NullPointerException();

}

boolean modified = false;

if(originalCollection.map.size() > eltsToRemove.size()) {

  for(Iterator<? extends @NonNull U> i = eltsToRemove.iterator(); i.hasNext();) {

    @NonNull U next = i.next();

    // boxing conversion of "next" if HashMap<T, Object>.remove(Object) is not any-fied

    modified |= originalCollection.map.remove(next) == Set.PRESENT;

  }

} else {

  for(Iterator<@NonNull U> i = originalCollection.map.keySet().iterator(); i.hasNext();) {

    @NonNull U next = i.next();

    // boxing conversion of "next" if Collection<? extends @NonNull U>.remove(Object) is not any-fied

    if(eltsToRemove.contains(next)) {

      i.remove();

      modified = true;

    }

  }

}

return modified;

}

(Feel free to replace @NonNull with the any keyword if you like)


That’s the implementation from a HashSet point-of-view after inlining calls to other HashSet instance methods and one static method from Objects. I see two places where a value type may need to be boxed depending on whether the method that’s being called is “any-aware”.


Is this what you’re looking for?









-- 
Have a nice day,
Timo.

Sent from Windows Mail





From: Brian Goetz
Sent: ‎Sunday‎, ‎December‎ ‎21‎, ‎2014 ‎17‎:‎47
To: Thomas W, valhalla-dev at openjdk.java.net, simon at ochsenreither.de





> 1)  List<int>.remove() disambiguation

Your solution here amounts to a deprecation mechanism with hints, which 
is an OK solution to the remove(int)/remove(Object) problem.  (I'm a 
little mystified, though, how everyone seem to assume that the remove 
overload conflict is the only problem that Peeling addresses itself to, 
and if somehow that one could be solved, the whole rest of the exercise 
is pointless.)

What's your story for the Collection method

   removeAll(Collection<?>)

in such a way that a removeAll method could be called from generic code 
like:

<any U> removeAllFrom(Collection<U> originalCollection,
                       Collection<? extends U> eltsToRemove) { ... }

> 3)  "Empty" values
> --------------------------
> - as somebody pointed out, we need a syntax that references 'empty' values
> by type;  null or zero.
> - I propose 'T.empty' for this purpose;   eg, int.empty references 0,
> Object.empty references null.

Minus ten points for digressing into syntax.  There are infinitely many 
possibly syntaxes for this, and they *all* will be suggested eventually, 
but unfortunately such discussions have a tendency to choke off actual 
useful discourse.  Right now, we're figuring out the right model, and 
there's more than enough work to do there.

> 4)  Map<int>.get() and "sentinel values"
> --------------------------------------------------------
> - null is a moderately good "sentinel value" for objects, but zero is not
> so good for numbers;
> - similar to the 'T.empty' syntax proposed above,  I propose a 'T.sentinel'
> syntax for "no element".
> eg, int.sentinel references -1, Object.sentinel references null.

The reason int can't be null is that we have no natural and efficient 
hardware representation for it; all 2^32 values in an 32-bit integer are 
used for integers.  So changing the syntax from "null" to "sentinel" 
doesn't help -- the real problem is, how do we represent it?  Ballooning 
all integers to 64 bits just to accommodate a special value is not going 
to fly.  And stealing "-1" as the "not to be used as an int" value 
similarly doesn't fly; -1 is also an important integer.

Applications and APIs are free to cut corners like "let's let -1 mean 
'no value'", but languages and VMs are not free to do this.

And, minus ten points more for another syntax digression :)

> 5)  Statics;  synchronizing to access these?
> ----------------------------------------------------------------
> - good point about SomeType<int> and SomeType<T extends Object> sharing the
> same statics;
> - but since they do not have class in common, what syntax/ or common object
> can they synchronize on?
> - possible proposal:   T.classLock,  which should be the base Class (but
> perhaps just typed as Object).

Agree that being able to denote "the class that hosts my static members" 
is desirable.  Syntax can wait.

> - I called my null-handling class "Optional" back at Java 5. Now some
> dropkick comes along and pollutes my namespace with these
> poorly-thought-out & incomplete FP ideas.

Thanks, I was that dropkick.

> 7)  Peeling and Layers
> --------------------------------
> - these ideas seem major & complex,  but solve only relatively moderate
> corner cases.

I think you're giving them too much weight, perhaps because they're new 
and scary.  These are not intended to be, to use your term, a "banner" 
feature; our hope would be that they almost never get used.  And yes, 
they currently have a lot of surface.  See separate note on the subject.

> - introducing a major new structural level into the Java language, breaking
> long-standing single Java types into separate parts is an enormous change;
> seemingly suitable for "mixins" or some really major language enhancement.
> - yet the parts/layers are not named/ or addressible, and the use of this
> structure will really be quite minor.


>
> Summary:  introducing a banner-level language feature to solve two
> problematic methods, with no other possible use, does not really seem the
> right design choice.
>
>
> 8)  Conclusions
> ----------------------
>
> Introduction of a simple "field-style" syntax on types extends the existing
> usage of ".class", to allow important new type-related expressions to be
> expressed in an easy & obvious way. It also gives minimal potential for
> conflict with existing syntax.
>
> I am much happier to avoid cast-based formulations, such as casting 'null'
> to int, to get zeros/nulls in a type-specific way. Introducing a
> well-defined syntax for "empty" and "sentinel" values could resolve most
> no-item & empty-value problems -- which is where null & null problems
> typically crop up -- in an effective manner.
>
> I absolutely think we need a type-specific method/ or syntax for null-safe
> equals;  this is a basic to writing most collections code. However, I'm
> less clear on what "the right" syntax should be here. Any takers?
>
> Look forward to your thoughts,
>
> Regards
> Thomas Whitmore
>


More information about the valhalla-dev mailing list