GlenKPeterson / Paguro

Generic, Null-safe, Immutable Collections and Functional Transformations for the JVM
Other
312 stars 24 forks source link

Make map creation less verbose #42

Closed viebel closed 3 years ago

viebel commented 3 years ago

It would be great to have a way to create a map without wrapping the keys and values in a tuple, similar to Java Map.of, as @ericnormand suggested in Clojureverse.

For example, instead of creating a nested map like this:

map(tup("booksByIsbn",
        map(tup("978-1779501127",
                map(tup("isbn", "978-1779501127"),
                    tup("title", "Watchmen"),
                    tup("publicationYear", 1987),
                    tup("authorIds", vec("alan-moore",
                                         "dave-gibbons")))))),
    tup("authorsById",
        map(tup("alan-moore",
                map(tup("name", "Alan Moore"),
                    tup("bookIsbns", vec("978-1779501127")))),
            tup("dave-gibbons",
                map(tup("name", "Dave Gibbons"),
                    tup("bookIsbns", vec("978-1779501127")))))))

we would be able to create it like that (a bit less verbose):

map("booksByIsbn",
    map("978-1779501127",
        map("isbn", "978-1779501127",
            "title", "Watchmen",
            "publicationYear", 1987,
            "authorIds", vec("alan-moore",
                             "dave-gibbons"))),
    "authorsById",
    map("alan-moore",
        map("name", "Alan Moore",
            ("bookIsbns", vec("978-1779501127"))),
        "dave-gibbons",
        map("name", "Dave Gibbons",
            "bookIsbns", vec("978-1779501127"))))
GlenKPeterson commented 3 years ago

If you look far enough back in git for this project, I remember having them in here at one point. But I took them out for Simplicity sake, but I can break that down into some reasons:

  1. How many overloads do you want to make for this function? Without many, it's not so useful. With many, it used to slow down the type inference for the IDE and I think for the compile.
  2. In general, I don't like syntax that works one way sometimes and another way other times. It makes source control diffs messy when you go from your 6-item map to a 7-item map and the syntax is all different.
  3. Many overloads for this function also increased the size of Paguro. This is a really small project. People have said they use it in Android projects where space is very tight.
  4. It was more to unit test.

So, it was a lot of complexity without a lot of value. It was also a little unsafe if you had a map with the same type for keys and values. Like a Map<String,String>, there was no visual indicator what were keys and what were values. The "tup()" shows the pairs unambiguously.

I understand that there are situations where what you are asking for is advantageous. It's not that hard to write your own functions:

public static Map<K,V> map(K k1, V v1) { return map(tup(k1, v1)); }
public static Map<K,V> map(K k1, V v1, K k2, V v2) { return map(tup(k1, v1), tup(k2, v2)); }

If you like brevity, you can even call them m() instead of map().

THat is why I'm closing this with a "wontfix."

viebel commented 3 years ago

Makes sense. Thank you for the clarification!