Vavr: Make *Map factory methods safe

Created on 6 Oct 2016  路  10Comments  路  Source: vavr-io/vavr

Map(Object...) is unsafe. Stuart Marks explained in his JavaOne 2016 Session Collections Refueled how and why the Java language architects implemented JEP 269.

The essence regarding Map.of()is best described by this image:

jep 269 api overview

Javaslang needs to be safe. We will follow the decisions made in JEP 269 and therefore we will deprecate or *Map.of(Object...) methods and strongly discourage using them. Instead we will add methods

  • of(K k1, V v1)
  • of(K k1, V v1, K k2, V v2)
  • ...

up to 10 key/value pairs. For more than 10 pairs we need to use tuples:

  • of(Tuple2<? extends K, ? extends V>...)

Accordingly we will also deprecate ofEntries(Tuple2<? extends K,? extends V>...).

!BACK-COMPAT desigrefactorinimprovement 芦vavr-collection禄

All 10 comments

@ruslansennov Is this s.th. for you? No hurry here...

We haven't defined a standard for deprecation yet. Currently I use the following:

  • annotate methods with @Deprecated
  • add javadoc @deprecated <description>

Descriptions are one of or a combination of these:

  • Should not be used any more because ... (e.g. it is unsafe)
  • Will be removed in a future version.
  • ...

I'll try to implement this next week

Great :)

Let's take this code:

final TreeMap<String, Integer> tm = TreeMap.of(Tuple.of("one", 1), Tuple.of("two", 2));

Compilation fails with

Error: reference to of is ambiguous
  both method 
<K,V>of(javaslang.Tuple2<? extends K,? extends V>,javaslang.Tuple2<? extends K,? extends V>) 
in javaslang.collection.TreeMap and method 
<K,V>of(K,V) in javaslang.collection.TreeMap match

The problem can be solved something like this:

final TreeMap<String, Integer> tm = 
    TreeMap.<String, Integer>of(Tuple.of("one", 1), Tuple.of("two", 2));

but it is inconvenient.

Let's keep Map*::ofEntries(Tuple2, Tuple2) instead of Map*::of(Tuple2, Tuple2)
Same for Map*::ofEntries(Entry, Entry)

@ruslansennov Yes, aggreed! I should have seen that.

I'm trying to make API methods for Map*::ofEntries(Tuple2, Tuple2), but here we have same problem...

Map<Integer, Integer> map = SortedMap(Tuple.of(1, 2), Tuple.of(2, 4));

fails with

[ERROR] /home/ruslan/proj/javaslang/javaslang/src-gen/test/java/javaslang/APITest.java:[1178,35] reference to SortedMap is ambiguous
  both method <K,V>SortedMap(javaslang.Tuple2<? extends K,? extends V>,javaslang.Tuple2<? extends K,? extends V>) in javaslang.API and method <K,V>SortedMap(K,V) in javaslang.API match

We can change name of methods (to SortedMapFromEntries for example), but I don't like this idea.

Thanks Ruslan. Yes, we need to remove these ambiguities from API.

API will only have aliases for of(T) and of(T...) for the collections. Maps and sorted collections will have slightly different methods (Map will have of(KVKV), the sorted collections will have a variant with a Comparator).

See #1651

For now it will be sufficient to have these aliases.

@ruslansennov Need to double-check it but I think you finished this ticket already!

Done

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manu-m picture manu-m  路  6Comments

civitz picture civitz  路  6Comments

carnott-snap picture carnott-snap  路  4Comments

enelson picture enelson  路  5Comments

Vivek-Patil picture Vivek-Patil  路  3Comments