Cogs and Levers A blog full of technical stuff

Creating a Scala SBT project structure

Today’s post is going to be a tip on creating a project structure for your Scala projects that is SBT ready. There’s no real magic to it, just a specific structure that you can easily bundle up into a console application.

The shell script

To kick start your project, you can simple use the following shell script:

#!/bin/zsh
mkdir $1
cd $1

mkdir -p src/{main,test}/{java,resources,scala}
mkdir lib project target

echo 'name := "$1"
version := "1.0"
scalaVersion := "2.10.0"' > build.sbt

cd ..

This will give you everything that you need to get up an running. You’ll now have a structure like the following to work with:

.
├── build.sbt
├── lib
├── project
├── src
│   ├── main
│   │   ├── java
│   │   ├── resources
│   │   └── scala
│   └── test
│       ├── java
│       ├── resources
│       └── scala
└── target

Spellcheck for Sublime

Today’s post is a very quick tutorial on turning on spell check, for Sublime Text.

Looking at the documentation you can add the following:

"spell_check": true,
"dictionary": "Packages/Language - English/en_US.dic"

Easy.

Managing multiple SSH identities

Sometimes, it makes sense to have multiple SSH identites. This can certainly be the case if you’re doing work with your own personal accounts, vs. doing work for your job. You’re not going to want to use your work account for your personal stuff.

In today’s post, I’m going to run through the few steps that you need to take in order to manage multiple SSH identities.

Different identities

First up, we generate two different identities:

ssh-keygen -t rsa -C "user@work.com"

When asked, make sure you give the file a unique name:

Enter file in which to save the key (/home/michael/.ssh/id_rsa): ~/.ssh/id_rsa_work

Now, we create the identity for home.

ssh-keygen -t rsa -C "user@home.com"

Again, set the file name so they don’t collide:

Enter file in which to save the key (/home/michael/.ssh/id_rsa): ~/.ssh/id_rsa_home

Now, we should have the following:

id_rsa_home
id_rsa_home.pub
id_rsa_work
id_rsa_work.pub

Configuration

Now we create a configuration file that ties all of the identities up. Start editing ~/.ssh/config:

# Home account
Host home-server.com
  HostName home-server.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_rsa_home

# Company account
Host work-server.com
  HostName work-server.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_rsa_work

Delete all of the cached keys:

ssh-add -D

If you see the error message Could not open a connection to your authentication agent. you’ll need to run the following:

ssh-agent -s

Add your keys

You can now list your keys with:

ssh-add -l

You can add your keys back in with the following:

ssh-add ~/.ssh/id_rsa_work
ssh-add ~/.ssh/id_rsa_home

That’s it!

Futures and Promises in Scala

The wikipedia article for Futures and promises opens up with this paragraph, which I thought is the perfect definition:

In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is initially unknown, usually because the computation of its value is yet incomplete.

In today’s article, I’ll walk you through the creation and management of the future and promise construct in the Scala language.

Execution context

Before continuing with the article, we need to make a special note about the ExecutionContext. Futures and promises both use the execution context to perform the execution of their computations.

Any of the operations that you’ll write out to start a computation requires an ExecutionContext as a parameter. These can be passed implicitly, so it’ll be a regular occurrence where you’ll see the following definition:

// define the implicit yourself
implicit val ec: ExecutionContext = ExecutionContext.global

// or - import one already defined
import ExecutionContext.Implicits.global

ExecutionContext.global is an ExecutionContext that is backed by a ForkJoinPool.

Futures

We create a Future in the following ways:

/* Create a future that relies on some work being done
   and that emits its value */
val getName = Future {
  // simulate some work here
  Thread.sleep(100)
  "John"
}

/* Create an already resolved future; no need to wait
   on the result of this one */
val alreadyGotName = Future.successful("James")

/* Create an already rejected future */
val badNews = Future.failed(new Exception("Something went wrong"))

With a future, you set some code in place to handle both the success and fail cases. You use the onComplete function to accomplish this:

getName onComplete {
  case Success(name) => println(s"Successfully got $name")
  case Failure(e) => e.printStackTrace()
}

Using a for-comprehension or map/flatMap, you can perform functional composition on your Future so that adds something extra through the pipeline. In this case, we’re going to prefix the name with a message should it start with the letter “J”:

val greeting = for {
  name <- getName
  if name.startsWith("J")
} yield s"Hello there, $name!"

Blocking

If you really need to, you can make your future block.

val blockedForThisName = Future {
  blocking {
    "Simon"
  }
}

Promises

The different between a Future and a Promise is that a future can be thought of as a read-only container. A promise is a single-assignment container that is used to complete a future.

Here’s an example.

val getNameFuture = Future { "Tom" }
val getNamePromise = Promise[String]()

getNamePromise completeWith getNameFuture

getNamePromise.future.onComplete {
  case Success(name) => println(s"Got the name: $name")
  case Failure(e) => e.printStackTrace()
}

getNamePromise has a future that we access through the future member. We treat it as usual with onComplete. It knows that it needs to resolve because of the completeWith call, were we’re telling getNamePromise to finish the getNameFuture future.

Getting functional with Java 8

Java 8 provides developers with functional programming facilities that are very new to the language itself.

In today’s post, I’ll go through a primer of the different facilities that you can use.

Functional Interfaces

Single abstract method interfaces have been taken a step further in Java 8, where the programmer is able to decorate their interface using a @FunctionalInterface annotation. These can then be represented as lambda expressions and method references. These are building blocks for functional programming.

Consumer<T>

Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.

Uses are passing to the forEach function.

Supplier<T>

This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

Used in the creation of streams.

Predicate<T>

This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

Used with filter

Function<T, R>

This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

Used to pass to map

Functional Syntax

Defining a Functional Interface

@FunctionalInterface
public interface TailCall<T> {
  
  TailCall<T> apply();

  default boolean isComplete() { return false; }

}

A functional interface must:

  • Have one abstract, unimplemented method
  • May have zero or more default or implemented methods
  • May have static methods

Lambda expressions

// no parameters
() -> func(1)

// explicit definition of parameter types
(final String colour) -> System.out.println(colour)

// implicit parameter definition
(colour) -> System.out.println(colour)
colour -> System.out.println(colour)

// multiples
(x, y) -> x * y

// multi-line lambda
(x) -> {
  func1(x);
  func2(x);
}

Composition, method references

products.stream()
        .filter(Pricing::hasDiscount)
        .mapToDouble(Product::getUnitPrice)
        .average()
        .getAsDouble();