Skip to content

Instantly share code, notes, and snippets.

@ochafik
Last active October 10, 2016 14:13
Show Gist options
  • Select an option

  • Save ochafik/51f3fe2b6905c557da4b6b7c00e4a4e4 to your computer and use it in GitHub Desktop.

Select an option

Save ochafik/51f3fe2b6905c557da4b6b7c00e4a4e4 to your computer and use it in GitHub Desktop.
Mutable -> Immutable transition library
import * as Immutable from 'immutable';
interface Mutable<C> {
immutable: C;
}
class Set<T> implements Mutable<Immutable.Set<T>> {
private builder?: Immutable.Set.Builder<T>();
constructor(private immutable = Immutable.Set<T>()) {}
add(value: T): boolean {
const newSet = this.getImmutable().add(value);
if (newSet === this.getImmutable()) return false;
return this.setImmutable(newSet), true;
}
addAll(...values: Iterable<T>): void {
// this.immutable = this.immutable.union(values);
this.getBuilder().union(values);
}
clear(): void {
this.immutable = Immutable.Set<T>();
}
protected getImmutable(): Immutable.Set<T> {
if (this.immutable == null) {
this.immutable = this.builder.build();
this.builder = null;
}
return this.immutable;
}
protected setImmutable(immutable: Immutable.Set<T>): void {
this.immutable = immutable;
this.builder = null;
}
protected getBuilder(): Immutable.Set.Builder<T> {
if (this.builder == null) {
this.builder = this.immutable.asMutable();
this.immutable = null;
}
return this.builder;
}
}
function asMutable<C>(col: C): Mutable<C> {
if (col == null) return null;
if (col instanceof List) return new Mutable.List(col);
if (col instanceof Set) return new Mutable.Set(col);
if (col instanceof Map) return new Mutable.Map(col);
throw new Error("Unsupported: " + col);
}
function withMutable<C, M extends Mutable<C>, R>(col: C, setter: (col: C) => void, callback: (mutableCol: M) => R): R {
const mutableCol = asMutable(col);
try {
return callback(mutableCol);
} finally {
setter(mutableCol.immutable);
}
}
/*
class Foo {
List<int> list;
foo(List<int> l) {
l..add(1)..add(2);
return 1
}
bar() {
print(foo(list));
}
}
*/
class Foo {
list: Immutable.List<number>;
foo(l: Mutable.List<number>) {
l.add(1);
l.add(2);
return 1
}
bar() {
console.log(withMutable(this.list, x => this.list = x, mutableList =>
foo(mutableList)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment