On 8 June 2015 at 16:02, Eric MacAdie <[email protected]> wrote: > Thanks for the info. > > I was trying to instantiate Lists like this: > def ee = [] > def rr = [1,2, "hello", ] > > But I guess that's not going to happen.
Not that easily anyway. > > I know that if I used << or + on an immutable list, it would return an > ArrayList. I was thinking that I could intercept those through > metaprogramming on the java.util.Collections$UnmodifiableRandomAccessList > class. > > I will look at those other libraries. But I just noticed that when people > talk about Groovy supporting functional programming, immutable data seems to > be ignored. People mostly talk about using closures on lists and maps. I was > just wondering how far you could go using what Groovy provides out of the > box. It depends on how much of a fundamentalist you want to be. Closures on data structures enable one to program in a functional style. As a nice bonus, one can use composition, currying (actually partial application), trampolining, or memoization on Closures themselves, and a couple of AST transformations such as @Immutable or @TailRecursive. As for functional data structures you should probably look elsewhere. Some other things might be a bit surprising as well, like `final` local variables (try it). Cheers, Dinko > > = Eric MacAdie > > > On Mon, Jun 8, 2015 at 5:20 AM, Dinko Srkoč <[email protected]> wrote: >> >> On 8 June 2015 at 06:32, Eric MacAdie <[email protected]> wrote: >> > >> > Has anyone ever tried to intercept the constructors for ArrayList? >> > >> > I would like to intercept them, and call asImmutable() on them, to be a >> > bit more functional. And just general curiosity. >> > >> > According to the shell, there are three constructors for ArrayList: >> > >> > groovy:000> ArrayList.class.getConstructors() >> > ===> [public java.util.ArrayList(java.util.Collection), public >> > java.util.ArrayList(), public java.util.ArrayList(int)] >> > >> > [...] >> > But I cannot figure out how to intercept the >> > java.util.ArrayList(java.util.Collection). Here are a couple of attempts: >> > >> > java.util.ArrayList.metaClass.constructor = { java.util.Collection arg >> > -> >> > println "Intercepting Collection call, here is arg: >> > ${arg.class.name}" >> > constructor = ArrayList.class.getConstructor( java.util.Collection ) >> > println "just made constructor: ${constructor}" >> > constructor.newInstance( arg ).asImmutable() >> > } >> > [...] >> >> That code actually works. Example: >> >> ArrayList.metaClass.constructor = { Collection arg -> >> def ctor = ArrayList.getConstructor(Collection) >> ctor.newInstance(arg).asImmutable() >> } >> >> def xs = new ArrayList([1, 2, 3]) >> assert xs == [1, 2, 3] >> assert xs[0] == 1 >> xs[0] = 42 // throws UnsupportedOperationException >> >> Also, the easiest way to make an empty immutable list is to use >> `Collections.emptyList()` (your example with parameterless >> constructor): >> >> def nil = Collections.emptyList() >> assert nil == [] >> nil << 42 // throws UnsupportedOperationException >> >> All that said, changing ArrayList constructors to make immutable lists >> may not be the best approach to go all functional for a couple of >> reasons. Some of them might be: >> >> * you can't use list literals (`[1, 2, 3]` is still not immutable) >> >> * working with lists will pretty soon get you back to plain mutable ones: >> >> def immut1 = new ArrayList([1, 2]) >> def immut2 = new ArrayList([3, 4]) >> def mut = immut1 + immut2 >> mut[0] = 42 >> assert mut == [42, 2, 3, 4] >> >> * having immutable but not persistent data structures may be expensive >> because you have to do a lot of defensive copying. >> >> If you really wanted immutable structures in the functional sense, it >> might be best to use an existing library, perhaps clj-ds[1] (Clojure's >> data structures without Clojure), or FunctionalGroovy[2] - a port of >> FunctionalJava[3] to Groovy. >> >> Cheers, >> Dinko >> >> [1]: https://github.com/krukow/clj-ds >> [2]: https://github.com/mperry/functionalgroovy >> [3]: http://www.functionaljava.org/ >> >> > = Eric MacAdie >> > > >
