<commit_before>#Notice
Read [README.md](README.md) before this file as that is the official introduction to UncleJim.
This file contains additional information for contributors, or maybe people who are considering opening an issue.

#Additional experimental features:
* An [Equator](src/main/java/org/organicdesign/fp/collections/Equator.java) and [ComparisonContext](src/main/java/org/organicdesign/fp/collections/Equator.java#L45) which work like `java.util.Comparator`, but for hash-based collections.
* [Memoization](src/main/java/org/organicdesign/fp/function/Function2.java#L59) for functions
* Unmodifiable interfaces which deprecate mutator methods and throw exceptions to retrofit legacy code and catch errors in your IDE instead of at runtime.
These were useful before the Clojure collections and Transformable were fully integrated, but may still provide a useful extension point for integrating your own immutable collections into the traditional Java ecosystem. 

#API Highlights

* Type-safe versions of Clojure's [immutable collections](src/main/java/org/organicdesign/fp/collections) (classes start with the word "Persistent")

* [Immutable Transformation Builder](src/main/java/org/organicdesign/fp/xform/Transformable.java)
(implementation is in [Xform](src/main/java/org/organicdesign/fp/xform/Xform.java))

* [Transformation Endpoints](src/main/java/org/organicdesign/fp/xform/Realizable.java)

* [Data Description Mini-Language](src/main/java/org/organicdesign/fp/StaticImports.java)

* Simplified Java 8 [functional interfaces](src/main/java/org/organicdesign/fp/function) that wrap checked exceptions

For complete API documentation, please build the javadoc:
`mvn javadoc:javadoc`

#Thank You
Some of the people I'm listing as contributors may not actually be aware of this project, but I found them inspiring in various ways.

The bulk of this project started as a simple question on StackExchange: [Why doesn't Java 8 include immutable collections?](http://programmers.stackexchange.com/questions/221762/why-doesnt-java-8-include-immutable-collections)  People's answers were a big help in figuring out what this project should and shouldn't do.

<NAME> [Scala Collections talk](https://www.youtube.com/watch?v=uiJycy6dFSQ&t=26m19s) was a huge inspiration to me.  I watched it over and over and tried to learn from his experience as much as possible.

<NAME>: For a brief review and suggestions.

<NAME>: for many lengthy email conversations about this project, encouragement to separate state from the transformation, and occasional light code review.

GreenJUG: for bearing with talks on early versions of this code two years in a row.

<NAME> (and <NAME> before that): for bearing with my newbie Clojure questions.

<NAME>: for providing encouragement, advice, and patiently listening to me drone on about this as we carpooled to user group meetings.

Context-sensitive equality: prefer Equator and Comparator to <code>equals()</code>, <code>hashcode()</code> and <code>compareTo()</code> ([<NAME>, <NAME>, <NAME>, <NAME>](http://glenpeterson.blogspot.com/2013/09/object-equality-is-context-relative.html), java.util.TreeSet, java.util.TreeMap)

Everyone whose ideas are collected in this project: I tried to put names in as close as possible to the contributions.

<NAME> for pointing out the EPL/GPL compatibility issue and work-around.

<NAME> for his book, Effective Java.

<NAME> for Clojure

#Build from Source

- Java 8 (tested with 64-bit Linux build 1.8.0_51).
- Maven (tested version: 3.19.0-26 64-bit Linux build)
- Maven will download jUnit for you
- First `mvn clean install` on: https://github.com/GlenKPeterson/TestUtils
- Then `mvn clean test` on UncleJim

#To Do
 - Update JavaDoc, esp. Im vs. Unmod
 - Bring unit test coverage back above 80%, or 85% if sensible.  This basically means to add any and all practical tests for PersistentHashMap, then remove unused code.
 - ?Make visio drawig of interface diagram?
 - Have an Ordered version of Transform as well as the (default) unreliable order.  Only the ordered version can be used for implementing things like equals() and hashCode()
 - Bring back the pointer-arithmetic version of drop()
 - Consider `max(Comparator<T> c, Iterable<? extends T> is)` and min()...  Actually, these probably belong on Transformable.
 - Add additional tuples and Functions up through 25 arguments
 - Study monadic thinking and ensure that Or is "monad-friendly".
 Ensure you can chain together functions in a short-circuiting way, without exceptions or other side-effects.
 - Add a [Persistent RRB Tree](http://infoscience.epfl.ch/record/169879/files/RMTrees.pdf) and compare its performance to the PersistentVector.
 - Re-implement Persistent collections from Algorithms and Purely Functional Data Structures without relying on a wrapped transient collection and without locking checks, then compare efficiency.

#Out of Scope

###Option<T> firstMatching(Predicate<T> pred);
Use with filter(...).head() instead

###T reduceLeft(BiFunction<T, T, T> fun)
reduceLeft() is like foldLeft without the "u" parameter.
I implemented it, but deleted it because it seemed like a very special case of foldLeft that only operated on items of the same type as the original collection.
I didn't think it improved readability or ease of use to have both methods.
How hard is it to pass a 0 or 1 to foldLeft?
It's easy enough to implement if there is a compelling use case where it's significantly better than foldLeft.
Otherwise, fewer methods means a simpler interface to learn.

###Transformable<T> forEach(Function1<? super T,?> consumer)
Java 8 has `void forEach(Consumer<? super T> action)` on both Iterable and Stream that does what
Transformable.forEach() used to do.  The old Transformable method overloaded (but did not override)
this method which is problematic for the reasons <NAME> gives in his Item 41.  Either make
use of the Java 8 `void forEach(i -> log(i))` or pass a constant function like
`i -> { print(i); return Boolean.TRUE; }` to
`Transformable<T> filter(Function1<? super T,Boolean> predicate)` instead. <commit_msg>Updated to-do.<commit_after>#Notice
Read [README.md](README.md) before this file as that is the official introduction to UncleJim.
This file contains additional information for contributors, or maybe people who are considering opening an issue.

#Additional experimental features:
* An [Equator](src/main/java/org/organicdesign/fp/collections/Equator.java) and [ComparisonContext](src/main/java/org/organicdesign/fp/collections/Equator.java#L45) which work like `java.util.Comparator`, but for hash-based collections.
* [Memoization](src/main/java/org/organicdesign/fp/function/Function2.java#L59) for functions
* Unmodifiable interfaces which deprecate mutator methods and throw exceptions to retrofit legacy code and catch errors in your IDE instead of at runtime.
These were useful before the Clojure collections and Transformable were fully integrated, but may still provide a useful extension point for integrating your own immutable collections into the traditional Java ecosystem. 

#API Highlights

* Type-safe versions of Clojure's [immutable collections](src/main/java/org/organicdesign/fp/collections) (classes start with the word "Persistent")

* [Immutable Transformation Builder](src/main/java/org/organicdesign/fp/xform/Transformable.java)
(implementation is in [Xform](src/main/java/org/organicdesign/fp/xform/Xform.java))

* [Transformation Endpoints](src/main/java/org/organicdesign/fp/xform/Realizable.java)

* [Data Description Mini-Language](src/main/java/org/organicdesign/fp/StaticImports.java)

* Simplified Java 8 [functional interfaces](src/main/java/org/organicdesign/fp/function) that wrap checked exceptions

For complete API documentation, please build the javadoc:
`mvn javadoc:javadoc`

#Thank You
Some of the people I'm listing as contributors may not actually be aware of this project, but I found them inspiring in various ways.

The bulk of this project started as a simple question on StackExchange: [Why doesn't Java 8 include immutable collections?](http://programmers.stackexchange.com/questions/221762/why-doesnt-java-8-include-immutable-collections)  People's answers were a big help in figuring out what this project should and shouldn't do.

<NAME> [Scala Collections talk](https://www.youtube.com/watch?v=uiJycy6dFSQ&t=26m19s) was a huge inspiration to me.  I watched it over and over and tried to learn from his experience as much as possible.

<NAME>: For a brief review and suggestions.

<NAME>: for many lengthy email conversations about this project, encouragement to separate state from the transformation, and occasional light code review.

GreenJUG: for bearing with talks on early versions of this code two years in a row.

Greenville Clojure (and <NAME> before that): for bearing with my newbie Clojure questions.

<NAME>: for providing encouragement, advice, and patiently listening to me drone on about this as we carpooled to user group meetings.

Context-sensitive equality: prefer Equator and Comparator to <code>equals()</code>, <code>hashcode()</code> and <code>compareTo()</code> ([<NAME>, <NAME>, <NAME>, <NAME>](http://glenpeterson.blogspot.com/2013/09/object-equality-is-context-relative.html), java.util.TreeSet, java.util.TreeMap)

Everyone whose ideas are collected in this project: I tried to put names in as close as possible to the contributions.

<NAME> for pointing out the EPL/GPL compatibility issue and work-around.

<NAME> for his book, Effective Java.

<NAME> for Clojure

#Build from Source

- Java 8 (tested with 64-bit Linux build 1.8.0_51).
- Maven (tested version: 3.19.0-26 64-bit Linux build)
- Maven will download jUnit for you
- First `mvn clean install` on: https://github.com/GlenKPeterson/TestUtils
- Then `mvn clean test` on UncleJim

#To Do
 - Update JavaDoc, esp. Im vs. Unmod
 - Remove SideEffect.java
 - Improve tests for Tuple so that I can generate good tests as I generate more Tuples.
 - Make a bunch more Tuple classes, and maybe bunch more Function classes.
 - Bring unit test coverage back above 80%, or 85% if sensible.  This basically means to add any and all practical tests for PersistentHashMap, then remove unused code.
 - ?Make visio drawig of interface diagram?
 - Have an Ordered version of Transform as well as the (default) unreliable order.  Only the ordered version can be used for implementing things like equals() and hashCode()
 - Bring back the pointer-arithmetic version of drop()
 - Consider `max(Comparator<T> c, Iterable<? extends T> is)` and min()...  Actually, these probably belong on Transformable.
 - Study monadic thinking and ensure that Or is "monad-friendly".
 Ensure you can chain together functions in a short-circuiting way, without exceptions or other side-effects.
 - Add a [Persistent RRB Tree](http://infoscience.epfl.ch/record/169879/files/RMTrees.pdf) and compare its performance to the PersistentVector.
 - Re-implement Persistent collections from Algorithms and Purely Functional Data Structures without relying on a wrapped transient collection and without locking checks, then compare efficiency.

#Out of Scope

###Option<T> firstMatching(Predicate<T> pred);
Use with filter(...).head() instead

###T reduceLeft(BiFunction<T, T, T> fun)
reduceLeft() is like foldLeft without the "u" parameter.
I implemented it, but deleted it because it seemed like a very special case of foldLeft that only operated on items of the same type as the original collection.
I didn't think it improved readability or ease of use to have both methods.
How hard is it to pass a 0 or 1 to foldLeft?
It's easy enough to implement if there is a compelling use case where it's significantly better than foldLeft.
Otherwise, fewer methods means a simpler interface to learn.

###Transformable<T> forEach(Function1<? super T,?> consumer)
Java 8 has `void forEach(Consumer<? super T> action)` on both Iterable and Stream that does what
Transformable.forEach() used to do.  The old Transformable method overloaded (but did not override)
this method which is problematic for the reasons <NAME> gives in his Item 41.  Either make
use of the Java 8 `void forEach(i -> log(i))` or pass a constant function like
`i -> { print(i); return Boolean.TRUE; }` to
`Transformable<T> filter(Function1<? super T,Boolean> predicate)` instead. 
{'fraction_non_alphanumeric': 0.08211191189570005, 'fraction_numerical': 0.00971738602315977, 'mean_word_length': 4.951807228915663, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 66, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1482475', 'n_tokens_mistral': 3505, 'n_tokens_neox': 3291, 'n_words': 1511}