<commit_before># Change Log

Bigger headings are better releases.  If you're upgrading, you might want to hit the biggest
releases on the way from an old version to a new one.  Fix any deprecation warnings at each major
release before upgrading to the next one.  The documentation next to each Deprecated annotation
tells you what to use instead.  Once we delete the deprecated methods, that documentation goes too.

# Release 3.0.14: RRB Tree
 - This is just a version number bump for the official release.

# Release 3.0.12: RRB Tree
 - Changed all OneOf classes to take a single Object argument, plus each of the classes they can hold.
 This great simplification is thanks to <NAME>!

# Release 3.0.11: RRB Tree
 - All OneOf classes now use a ZERO-BASED INDEX (used to use one-based).

#### Release 3.0: RRB Tree
Major changes:
 - Added Base___ for Im___ and Mutable___ interfaces to extend.  Mutable___ no longer extends Im___.
 - ImUnsortedSet renamed to ImSet and ImUnsortedMap renamed to ImMap to follow the java.util conventions more closely and for brevity.
   Mutable versions of both interfaces still contain the word "Unsorted" (verbose mutable names encourage immutability).
 - Renamed interfaces Function# to Fn#
 - Added an RRB Tree (still improving performance, but for insert at 0 in large lists it kills ArrayList)
 - Added foldUntil() to Transformable to replace the earlier version of foldLeft with a repeatUntil function parameter.
   Thanks to cal101 for inspiring this!
 - Removed a bunch of deprecated and unused items
 - Added JavaDoc to Git site
 - Changed toString to show entire collection
 - Added rrb() and mutableRrb() to StaticImports for constructing RRB Trees.
 - Moved AbstractUnmodMap, AbstractUnmodSet, and AbstractUnmodIterable from inner classes to top-level classes.
 - Option.of() is now Option.some() and it no longer returns None if you pass it a None.
 - Added StaticImports.xformChars(CharSequence).
 - Added "Union type" classes in oneOf package: OneOf2OrNone, OneOf3 and OneOf4.
 - Added Xform.dropWhile()

Here is a script to ease your upgrade from 2.1.1 to 3.0:
```bash
# USE CAUTION AND HAVE A BACKUP OF YOUR SOURCE CODE (VERSION CONTROL) - NO GUARANTEES
oldString='org.organicdesign.fp.LazyRef'
newString='org.organicdesign.fp.function.LazyRef'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.either.OneOf2'
newString='org.organicdesign.fp.oneOf.OneOf2'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.Option'
newString='org.organicdesign.fp.oneOf.Option'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.Or'
newString='org.organicdesign.fp.oneOf.Or'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='.foldLeft('
newString='.fold('
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='.typeMatch('
newString='.match('
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

sed -i -e 's/\<Function\([0-3]\)\>/Fn\1/g' $(egrep --exclude-dir='.svn' --exclude-dir='.git' -wrIl 'Function[0-3]' *)
```
If you subclassed OneOf, you can clean up your code.  From:
```java
public class String_Integer extends OneOf2<String,Integer> {
    String_Integer(String cre, Integer rev, int s) { super(cre, rev, s); }

    public static String_Integer str(String cre) { return new String_Integer(cre, null, 1); }
    public static String_Integer in(Integer rev) { return new String_Integer(null, rev, 2); }
```
to (MAKE SURE TO USE ZERO-BASED INDICES!):
```java
public class String_Integer extends OneOf2<String,Integer> {
    String_Integer(Object o, int s) { super(o, String.class, Integer.class, s); }

    public static String_Integer str(String cre) { return new String_Integer(cre, 0); }
    public static String_Integer in(Integer rev) { return new String_Integer(rev, 1); }
```

If you used the super::throw1 and super::throw2 methods, those have disappeared in favor of just using match everywhere.

Anywhere you have FunctionUtils unmmodSet, unmodList, unmodWhatever, you probably want to replace that with StaticImports.xform().

For instance:
```java
// Old 'n busted
UnmodList<Number> foo(List<Integer> is, List<Double> ds) {
    List<Number> ms = new ArrayList<>(is.size() + ds.size());
    ms.addAll(is);
    ms.addAll(ds);
    return FunctionUtils.unmodList(ms);
}

// New 'n awesome
ImList<Number> foo2(List<Integer> is, List<Double> ds) {
    return xform(is)
    // Little trick to tell Java's type system that we're making a List of Numbers.
                   .map(m -> (Number) m)
                   .concat(ds)
                   .toImList();
}

```

Manual upgrade tasks:
 - Do a clean build of your project
   - IntelliJ users right-click on the /src/java/ folder in your project and choose `Rebuild '<default>'`
   - Maven users: `mvn clean package`
 - There will be type errors where you pass a Mutable___ as an Im___.
   If the variable is myVar, simply change it to myVar.immutable() wherever errors show up.
     Unless you really wanted a Mutable___ in which case, you need to change the type signature.

##### Oops!
I'm sorry I ever made Mutable___ extend Im___.  It's an embarrassing rookie mistake.
I wasn't sure exposing mutable collections was worthwhile, I was "just trying them out" and suddenly found myself using them everywhere.
Well, they're fixed now.  ["Go forth and spread beauty and light!"](https://www.youtube.com/watch?v=9oRctV5Fygc&t=12m28s)

## 2017-05-04 Release 2.1.1
Fixed array class cast exception bug reported by @BrenoTrancoso https://github.com/GlenKPeterson/Paguro/issues/17
Thank you for finding and reporting this tricky issue!

### 2017-01-25 Release 2.1.0
Breaking Changes:
 - All "OneOf" classes are moved to org.organicdesign.fp.oneOf.  This includes
     - OneOf2 org.organicdesign.fp.either
     - Option and Or from org.organicdesign.fp

   OneOf2 now implements equals(), hashCode(), toString(), and has meaningful error messages
   which show the types of the union at runtime in `toString()` and in exception messages.
   Option was moved because it is essentially OneOfOneOrNone.
   Or was moved because it is an implementation of OneOf2.
   Presumably, there will be a OneOf2OrNone, OneOf3, OneOf3OrNone, etc.
 - `Option.patMatch()` and `OneOf2.typeMatch()` methods have been renamed simply `match()`.

Non-breaking Changes:
 - Added org.organicdesign.fp.type.RuntimeTypes.
   This takes types used for generic parameters at compile time and makes them available at runtime.
   Lets people develop programming languages without type erasure on the JVM and
   it comes in very handy at various times, like for OneOf_ (Union types, Or, etc.).
 - Paguro has gone from Functional Transforms in Java 7 to include unmodifiable (copy-on-write) collections like Guava to making Clojure collections and FP concepts convenient in pure-Java.
   Long-term, Paguro is intended to be the Java-compatibility (and maybe Kotlin compatibility?) layer for https://github.com/GlenKPeterson/Cymling
   The Cymling programming language basically splits the difference between Clojure (collections and xforms, assumption of immutability),
   ML (types without objects, records/tuples instead of Clojure's maps), and Kotlin (dot syntax, function syntax, null safety),
   Anyone who likes Paguro might want to keep an eye on Cymling development.

Upgrade Instructions:
You can use sed to fix imports for moved classes.
```bash
# USE CAUTION AND HAVE A BACKUP OF YOUR SOURCE CODE (E.G. VERSION CONTROL) - NO GUARANTEES
oldString='import org.organicdesign.fp.Option'
newString='import org.organicdesign.fp.oneOf.Option'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='import org.organicdesign.fp.Or'
newString='import org.organicdesign.fp.oneOf.Or'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='import org.organicdesign.fp.either.OneOf2'<commit_msg>Improved upgrade notes after upgrading a project from my day job.<commit_after># Change Log

Bigger headings are better releases.  If you're upgrading, you might want to hit the biggest
releases on the way from an old version to a new one.  Fix any deprecation warnings at each major
release before upgrading to the next one.  The documentation next to each Deprecated annotation
tells you what to use instead.  Once we delete the deprecated methods, that documentation goes too.

# Release 3.0.14: RRB Tree
 - This is just a version number bump for the official release.

# Release 3.0.12: RRB Tree
 - Changed all OneOf classes to take a single Object argument, plus each of the classes they can hold.
 This great simplification is thanks to <NAME>!

# Release 3.0.11: RRB Tree
 - All OneOf classes now use a ZERO-BASED INDEX (used to use one-based).

#### Release 3.0: RRB Tree
Major changes:
 - Added Base___ for Im___ and Mutable___ interfaces to extend.  Mutable___ no longer extends Im___.
 - ImUnsortedSet renamed to ImSet and ImUnsortedMap renamed to ImMap to follow the java.util conventions more closely and for brevity.
   Mutable versions of both interfaces still contain the word "Unsorted" (verbose mutable names encourage immutability).
 - Renamed interfaces Function# to Fn#
 - Added an RRB Tree (still improving performance, but for insert at 0 in large lists it kills ArrayList)
 - Added foldUntil() to Transformable to replace the earlier version of foldLeft with a repeatUntil function parameter.
   Thanks to cal101 for inspiring this!
 - Removed a bunch of deprecated and unused items
 - Added JavaDoc to Git site
 - Changed toString to show entire collection
 - Added rrb() and mutableRrb() to StaticImports for constructing RRB Trees.
 - Moved AbstractUnmodMap, AbstractUnmodSet, and AbstractUnmodIterable from inner classes to top-level classes.
 - Option.of() is now Option.some() and it no longer returns None if you pass it a None.
 - Added StaticImports.xformChars(CharSequence).
 - Added "Union type" classes in oneOf package: OneOf2OrNone, OneOf3 and OneOf4.
 - Added Xform.dropWhile()

# 3.0 Upgrade

Here is a script to ease your upgrade from 2.1.1 to 3.0.14:
```bash
# USE CAUTION AND HAVE A BACKUP OF YOUR SOURCE CODE (VERSION CONTROL) - NO GUARANTEES
oldString='org.organicdesign.fp.LazyRef'
newString='org.organicdesign.fp.function.LazyRef'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.either.OneOf2'
newString='org.organicdesign.fp.oneOf.OneOf2'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.Option'
newString='org.organicdesign.fp.oneOf.Option'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='org.organicdesign.fp.Or'
newString='org.organicdesign.fp.oneOf.Or'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='.foldLeft('
newString='.fold('
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='.typeMatch('
newString='.match('
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='.patMat('
newString='.match('
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='MutableUnsortedMap'
newString='MutableMap'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='MutableUnsortedSet'
newString='MutableSet'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

sed -i -e 's/\<Function\([0-3]\)\>/Fn\1/g' $(egrep --exclude-dir='.svn' --exclude-dir='.git' -wrIl 'Function[0-3]' *)
```
If you subclassed OneOf, you can clean up your code.  From:
```java
public class String_Integer extends OneOf2<String,Integer> {
    String_Integer(String cre, Integer rev, int s) { super(cre, rev, s); }

    public static String_Integer str(String cre) { return new String_Integer(cre, null, 1); }
    public static String_Integer in(Integer rev) { return new String_Integer(null, rev, 2); }
```
to (MAKE SURE TO USE ZERO-BASED INDICES!):
```java
public class String_Integer extends OneOf2<String,Integer> {
    String_Integer(Object o, int s) { super(o, String.class, Integer.class, s); }

    public static String_Integer str(String cre) { return new String_Integer(cre, 0); }
    public static String_Integer in(Integer rev) { return new String_Integer(rev, 1); }
```

If you used the super::throw1 and super::throw2 methods, those have disappeared in favor of just using match everywhere.
If you're relied on super::throwN, you may have to manually throw an exception:
```java
match(a -> a,
      b -> { throw new IllegalStateException("Can't call a() on a B"); });
```

Anywhere you have FunctionUtils unmmodSet, unmodList, unmodWhatever, you probably want to replace that with StaticImports.xform().

For instance:
```java
// Old 'n busted
UnmodList<Number> foo(List<Integer> is, List<Double> ds) {
    List<Number> ms = new ArrayList<>(is.size() + ds.size());
    ms.addAll(is);
    ms.addAll(ds);
    return FunctionUtils.unmodList(ms);
}

// New 'n awesome
ImList<Number> foo3(List<Integer> is, List<Double> ds) {
    // Have to specify StaticImports.<Number> to tell Java's type system that we're making a List of Numbers.
    // I think Kotlin can figure this out without hints.
    return StaticImports.<Number>mutableVec()
                   .concat(is)
                   .concat(ds)
                   .immutable();
}
```

Manual upgrade tasks:
 - Do a clean build of your project
   - IntelliJ users right-click on the /src/java/ folder in your project and choose `Rebuild '<default>'`
   - Maven users: `mvn clean package`
 - There will be type errors where you pass a Mutable___ as an Im___.
   If the variable is myVar, simply change it to myVar.immutable() wherever errors show up.
     Unless you really wanted a Mutable___ in which case, you need to change the type signature.

# 2.0 Releases

##### Oops!
I'm sorry I ever made Mutable___ extend Im___.  It's an embarrassing rookie mistake.
I wasn't sure exposing mutable collections was worthwhile, I was "just trying them out" and suddenly found myself using them everywhere.
Well, they're fixed now.  ["Go forth and spread beauty and light!"](https://www.youtube.com/watch?v=9oRctV5Fygc&t=12m28s)

## 2017-05-04 Release 2.1.1
Fixed array class cast exception bug reported by @BrenoTrancoso https://github.com/GlenKPeterson/Paguro/issues/17
Thank you for finding and reporting this tricky issue!

### 2017-01-25 Release 2.1.0
Breaking Changes:
 - All "OneOf" classes are moved to org.organicdesign.fp.oneOf.  This includes
     - OneOf2 org.organicdesign.fp.either
     - Option and Or from org.organicdesign.fp

   OneOf2 now implements equals(), hashCode(), toString(), and has meaningful error messages
   which show the types of the union at runtime in `toString()` and in exception messages.
   Option was moved because it is essentially OneOfOneOrNone.
   Or was moved because it is an implementation of OneOf2.
   Presumably, there will be a OneOf2OrNone, OneOf3, OneOf3OrNone, etc.
 - `Option.patMatch()` and `OneOf2.typeMatch()` methods have been renamed simply `match()`.

Non-breaking Changes:
 - Added org.organicdesign.fp.type.RuntimeTypes.
   This takes types used for generic parameters at compile time and makes them available at runtime.
   Lets people develop programming languages without type erasure on the JVM and
   it comes in very handy at various times, like for OneOf_ (Union types, Or, etc.).
 - Paguro has gone from Functional Transforms in Java 7 to include unmodifiable (copy-on-write) collections like Guava to making Clojure collections and FP concepts convenient in pure-Java.
   Long-term, Paguro is intended to be the Java-compatibility (and maybe Kotlin compatibility?) layer for https://github.com/GlenKPeterson/Cymling
   The Cymling programming language basically splits the difference between Clojure (collections and xforms, assumption of immutability),
   ML (types without objects, records/tuples instead of Clojure's maps), and Kotlin (dot syntax, function syntax, null safety),
   Anyone who likes Paguro might want to keep an eye on Cymling development.


Upgrade Instructions:
You can use sed to fix imports for moved classes.
```bash
# USE CAUTION AND HAVE A BACKUP OF YOUR SOURCE CODE (E.G. VERSION CONTROL) - NO GUARANTEES
oldString='import org.organicdesign.fp.Option'
newString='import org.organicdesign.fp.oneOf.Option'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='import org.organicdesign.fp.Or'
newString='import org.organicdesign.fp.oneOf.Or'
sed -i -e "s/$oldString/$newString/g" $(fgrep --exclude-dir='.svn' --exclude-dir='.git' -rIl "$oldString" *)

oldString='import org.organicdesign.fp.either.OneOf2'
{'fraction_non_alphanumeric': 0.11095913831424176, 'fraction_numerical': 0.009574286202769703, 'mean_word_length': 4.129494299912307, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 34, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3458045', 'n_tokens_mistral': 5644, 'n_tokens_neox': 5289, 'n_words': 2038}