Rust comes out of the box with a
Result<T, E> type in its standard library. For those not familiar with it, it is a union-like enum type where
T is a type parameter denoting the kind object held in a
Result in the success case (
E is a type paramter denoting the kind of error object held in the failure case (
Result::Err<E>). In Scala, this is represented in the standard library as
Either[+A, +B], where the the success and error type params are swapped (traditionally, the one on the left stands for error and the one on the right is…well, right).
Result comes with really good support for what I call “early return on error”. That is, you can use
and_then (flatMap in some other languages) to transform them, and if there’s an error at an intermediate step, the chain returns early with a
1 2 3 4 5 6
But .. what happens when you have multiple
Results that are independent of each other, and you want to accumulate not only their collective success case, but also all their collective errors in the failure case?
A heterogeneous list (henceforth “HList”) is a useful abstraction that is implemented in many statically-typed functional programming languages. Unlike normal list-like structures (e.g.
Array), a heterogenous list is able to hold elements of different types (hence heterogenous) and expose those types in its own type signature.
Now, you might be thinking “Isn’t that just a tuple?”. The answer is: in a way. Indeed, in terms of data structure, a given implementation of HList is usually really nothing more than deeply nested pairs (tuple of 2 elements) that each hold an element of arbitrary type in its 1st element and knows that its 2nd element is itself an HList-like thing. While it may seem convoluted, HList buys us the ability to abstract over arity, which turns out to be extremely useful, as you can see from this Stackoverflow answer by Miles Sabin, the creater of the Shapeless library, which provides an HList implementation in Scala.
Given that description and justification for the existence of HLists, let’s take a look at how to use Frunk’s implementation of HList in Rust.
It’s been a while since the last major release of Enumeratum, and in 1.4.0, minor changes include Play 2.5 support, integration library version bumps, and small internal refactorings. More excitingly though, the latest version adds support for a new kind of enumeration,
ValueEnum, as well as an integration with the Circe JSON library.
Points of interest:
- Unlike other value enum implementations, Enumeration’s value enums perform uniqueness checks at compile time to make sure you have unique values across your enum members.
- Circe integration allows you to send and receive JSON data between your front end and your server using the same code
In Episode 1 of this series on Scala and computer vision, we created a basic Akka-Streams-powered webcam feed app. To bring it to the next level, we will dig a little deeper into the OpenCV toolset and bring in feature detection as well as video stream editing.
We will build on the foundations from the previous post and continue with the usage of Akka Streams, modeling our application as a series of small transformations that are run asynchronously, with backpressure handled automatically.
In a previous post, I talked about SBT-OpenCV, a plugin for SBT that makes it easy to get started with OpenCV in any SBT-defined JVM app using just one line in
project/plugins.sbt. Having handled the issue of getting the proper dependencies into a project, we can turn our attention to actually using the libraries to do something cool.
This post is the beginning of a series, where the end goal is to build a smile detector. Akka and OpenCV will be used, with Spark joining later on to complete the buzzwords treble.
A well-rounded and fun first step is to get a video feed from a webcam showing on our screen. To do this, we will cover a variety of things, including how to define a custom Akka
Source, how to use JavaCV, and some basic OpenCV image manipulation utilities.
OpenCV is arguably the defacto free, open-source computer vision library, but setting it up for usage in a JVM project can be hard because OpenCV itself is written in C++, so there are a bunch of system-dependent things that you need to download/compile/install before you can use it.
JavaCV, written by Bytedeco is a library that makes it more bearable to use OpenCV from JVM projects by providing a bunch of wrapper classes and logic around OpenCV (there’s a lot more to it, see their page for details).
Still, because JavaCV depends on JavaCPP for common and OpenCV C++ wrappers, and JavaCPP requires you to set your target platform (what platform you want to run on), I thought getting started could be easier still.
Play is one of two officially-supported web frameworks from Typesafe, the company behind Scala (the other is Spray). It runs on its own webserver, is non-blocking, and encourages the use of idiomatic Scala. It is often compared with Rails because of its emphasis on convention over configuration and because it’s a full-on framework that comes with most of the bells and whistles needed to build a full-featured webapp. Spray is considered by many to be the defacto API-centric alternative to Play, offering a Sinatra-esque DSL for routing and being slimmer to boot (from a files + LOC perspective).
After looking around I began suspecting that Play comes with the ability to be slimmed down. By combining the String Interpolating Routing DSL and Compile-time dependency injection of Play 2.4, I was able to build a Scala app that would give Sinatra a run for its money in terms of the whole brevity thing.
If you’ve been working with Scala for a while, you might have come across a few “problems” with the built in
Enumeration that’s provided out-of-the-box. This is especially true if you have colleagues who come from a Java background and yearn for the Java-style
Enum that gave them lots of power and flexibility.
A quick search on the internet for “Scala enumeration alternative” will yield a lot of results (perhaps on StackOverflow) where people have cooked up their own implementation of enumerations, usually built on
sealed traits. Personally, I found most of them to be either too inconvenient to use, too over-powered, or too complicated, and I really didn’t want to have to copy-paste enum-related code into all my projects.
Thus Enumeratum was born.
Last week, I decided to take a stab at learning Scala macros. I had played around with macros when I wrote Scheme for a living (yes, believe it or not, these places exist…and existed long before Clojure made Lisp hip again), but the complexity of Scala’s macros always put me off (if you don’t believe me, check out the example given in the offical docs for a simple print macro).
In Scala, things are not so simple, but with the introduction of quasiquotes and some refinements brought by Scala 2.11, things are smoother. Still, for a guy like me, the documentation was both sparse and DRY. Since I learn best when I’m actively engaged in building something, I decided to try writing the run-of-the-mill unless-when macros in Scala.
This post aims to summarise my journey towards implementing unless-when and hopefully along the way make Scala macros accessible, at least at an introductory level, for Most People. There are already a few Scala macro blog posts out there but another one can’t hurt.
A couple days ago, I released v0.1.3 of Schwatcher, which introduces the ability to monitor events on file paths using a composable Rx Observable interface. “What does that even mean and why should you care?” is what this blog post tries to answer.
The original version of Schwatcher allowed you to tell a
MonitorActor what callback you want to fire when a certain type of event happened on a file path. This is fine and there are people out there using it in production as is. The limitation to this approach is that (at least by default), the events are difficult to treat as data and thus difficult to compose.
With Rx, we turn file path events into an asynchronous stream/channel. Essentially, you tell a
RxMonitor object what path and event type you want to monitor and when an event happens, it will get pushed into its
observable (the stream). You can then choose to filter, map, or fold over this data stream, creating new data streams. If you wish to cause side-effects, you can add one or more
observers to these data streams.