11 ms·
Show HN: Motif – Scala-like pattern matching with Java 8
- stormcrowsx 11y agoHard to read in comparison to Scala. It's impressive that it was accomplished but some things just aren't meant to happen in Java 8.
- leothekim 11y agoIf you've ever endured the compilation time of a Scala codebase that has more than, say, 2000+ classes, then you might think that some things just aren't meant to happen in Scala either. I used Scala for 4+ years at a company that spent a non-trivial amount of time and resources speeding up its Scala builds (way more than 2000+ classes), sometimes doing sadly controversial things[1] to achieve that speedup. It was a real quality-of-life issue, and one of the reasons that compelled me to leave. I'm using Java 8 now, and yes it has its warts and is nowhere near Scala wrt functional goodness, but I'm glad to be compiling and iterating a lot more quickly with the ability to use even a subset of the Scala stuff I missed. [1] https://groups.google.com/d/msg/pants-devel/mcdllXQsYNg/96ZGYu2fT0MJ https://groups.google.com/d/msg/pants-devel/mcdllXQsYNg/96ZG...
- lmm 11y agoIf you stick to the same kind of subset in Scala, then compilation isn't that much worse than Java, IME. It's only when you're using a lot of implicits and/or a lot of type inference that compile times go through the roof. (and FWIW I'd say that 2000+ classes - that's what, 600KLOC? - implies a project that should be split up with clear boundaries (i.e. separate release cycles, documented public APIs between them), if only for developer comprehensibility. How big is a Java project that provides the same amount of functionality, and how long does it take to compile? Crikey, 2000 classes...)
- ionforce 11y agoSome companies, like Twitter and Facebook, are doing this development pattern of mono repo... So even if there are architectural lines to be found, they are eschewing that in favor of keeping versions and APIs closer together. I can't say I understand that strategy completely but I have also never worked on machinery the size and complexity of Facebook or Twitter.
- rco8786 11y agoStill at that company, and still enduring long compile times.
- emergentcypher 11y agoWay more than 2000 classes? How many LOC is that? How much time did it take to compile, and how much time does the same 2000+ classes take to compile in Java?
- leothekim 11y agoAs a point of reference, compiling ~200 Scala classes at a time would take ~2.5 minutes on average. At my last job, compiling >2000 Java classes took about 10-15 seconds with an ant script doing a top-down build. Unfortunately I don't remember LOC, but I don't remember the average Scala file being overly large at my Scala job, or the average Java file being unusually short at my Java job.
- carterehsmith 11y agoQuestion - I don't know much about Scala - how often does one need to do a full build? I am talking regular development cycle, ie make a change, save/compile, check if it works etc. I mean typically a compiled language will have some 'incremental compile' to compile just the file you edited. Does that work with Scala?
- AdieuToLogic 11y ago> Question - I don't know much about Scala - how often does one need to do a full build? Not often at all. > I am talking regular development cycle, ie make a change, save/compile, check if it works etc. sbt[1] supports incremental compilation and projects such as Play[2] leverage this to support "on-the-fly" recompilation while the container remains running. 1 - http://www.scala-sbt.org/0.13/docs/Understanding-Recompilation.html http://www.scala-sbt.org/0.13/docs/Understanding-Recompilati... 2 - https://www.playframework.com https://www.playframework.com
- AdieuToLogic 11y ago> As a point of reference, compiling ~200 Scala classes at a time would take ~2.5 minutes on average. Odd... I just did a full compile of a Scala project I work on which has: - 259 source files - Contains dozens of macros[1] - Results in 2097 classes (includes companion objects and anonymous types) And it took 75 seconds on my laptop. As I mentioned in another reply, doing a full recompile is rarely needed but was done now to provide quantified metrics. 1 - http://docs.scala-lang.org/overviews/macros/overview.html http://docs.scala-lang.org/overviews/macros/overview.html
- stormcrowsx 11y agoScala's compilation time is not an excuse to write ugly hard to maintain code in Java 8. If you don't like Scala compilation time then write Java 8 but keep it idiomatic and easy to read don't drag parts of Scala into it that don't fit.
- subtenante 11y agoFunny, I happened to code something just today very similar, but a lot lighter (just two classes, Match for consuming only, and MatchMap for mapping the optional. No when/get, just a when taking two parameters : the predicate and the mapping function. public class MatchMap<T, U> { private final Optional<T> opt; private final U defaultValue; private final AtomicReference<U> result = new AtomicReference<U>(); private MatchMap(Optional<T> pOpt, U pDefault) { super(); opt = pOpt; defaultValue = pDefault; } public MatchMap<T, U> whenMatch(Predicate<T> pPred, Function<T, U> pMapFn) { if (result.get() != null) { return this; } Optional<T> lFiltered = opt.filter(pPred); if (lFiltered.isPresent()) { result.set(pMapFn.apply(lFiltered.get())); } return this; } public MatchMap<T, U> whenEquals(T pExact, Function<T, U> pMapFn) { return whenMatch(t -> pExact.equals(t), pMapFn); } public U resolve() { return Optional.ofNullable(result.get()) .orElse(defaultValue); } public static <T, U> MatchMap<T, U> of (Optional<T> pOpt, U pDefault) { return new MatchMap<T, U>(pOpt, pDefault); } } The class Match is very similar, but takes consumer instead of Function and has some logic to allow several matches to be executed (if several predicates are ok), or only allow the first match to be executed.
- gizmo385 11y agoI'd love to see how code using your version compares to code using the OP's version. Got any similar examples?
- subtenante 11y agoI use it especially for enums so it's like: MatchMap.of(someOptional, defaultValue) .whenEquals(MyEnum.VALUEX, v -> someFn(p1, p2)) .whenEquals(MyEnum.VALUEY, v -> otherFn(p1, p2)) .resolve();
- johnlcox 11y agoI haven't tried it with enums, but it should still be possible with Motif. I'll have to add some tests. match(enumValOpt) .when(some(eq(MyEnum.VALUEX))).then(() -> someFn(p1, p2)) .when(some(eq(MyEnum.VALUEY))).then(() -> otherFn(p1, p2)) .orElse(defaultValue) .doMatch(); It's a little longer than your example since there is support for more than just Optional, but it's pretty similar.
- ch_123 11y agoThe javaslang library has a similar construct: http://javaslang.com/javadoc/1.2.0/javaslang/control/Match.html http://javaslang.com/javadoc/1.2.0/javaslang/control/Match.h...
- qqueue 11y agoThe Cambrian explosion of java 8 functional libraries like this is fun to watch. Others I've come across: - http://javaslang.com/ http://javaslang.com/ - https://github.com/aol/cyclops https://github.com/aol/cyclops - http://totallylazy.com/ http://totallylazy.com/ - https://github.com/poetix/octarine https://github.com/poetix/octarine - (good ol') http://www.functionaljava.org/ http://www.functionaljava.org/ The syntax for these libraries is always a little wonky though. If only these libraries also had some sort of syntax preprocessor to make it more palatable. You could call it, I don't know, Scala, or something.
- bwanab 11y agoExactly. I want to like these things, but they're just way to painful on the eyes.
- dangerlibrary 11y agowhoosh? http://www.scala-lang.org/ http://www.scala-lang.org/
- incepted 11y agoHe said he wanted something that's not painful on the eyes.
- emergentcypher 11y agoI hardly see how Scala is more painful on the eyes than good old Java.
- incepted 11y agoRandom example from a popular project: def bimap[C, X[_, _], D](g: Bijection[C, D])(implicit F: Bifunctor[X], evF: F[B] =:= Id[B], evG: G[A] =:= Id[A]): Bijection[X[A, C], X[B, D]] = bijection( F.bimap(_)(to(_), g.to(_)): Id[X[B, D]] , F.bimap(_)(from(_), g.from(_)): Id[X[A, C]] )
- jlebrech 11y agohttps://en.wikipedia.org/wiki/Motif_(software) https://en.wikipedia.org/wiki/Motif_(software)