Last night I attended ScalaBridge London. I met one student who had recently studied computer science and decided to focus on Scala because of all of her classes she enjoyed functional programming the most. Another student works with SAS (Statistical Analysis Software) and wanted to learn a new language for her own professional development.

The group was in the middle of a six week series, which is a neat format that they are trying out for the first time. This gives students the chance to get to know each other and work together in a cohort, diving deeper into practicing the language over time.

I was there at the kind invitation of Noel Welsh, since I am visiting London and organizing a London Bridge event on May 28th to introduce all of the local groups to each other. I took the opportunity to learn a little Scala too.

The students had progressed to learning structural recursion and one student showed a colorful Sierpinski triangle and explained how she generated the colors. In the photo below, you can see Noel acting as a low-tech projector, holding up the laptop, so the new Scala engineer could talk about her work.

Man holding laptop with graphic of triangles and woman smiling

Learning a little Scala coding

At first I was a bit skeptical of using graphics to learn a language which was not designed for that purpose, but the experience won me over. The concrete visualization of code is helpful and I found it as delightful as I did when I first learned basic on an Apple II many years.

I learned that Scala is strongly typed functional programming language that is light on syntax, not requiring characters at the end of statements and whatnot. Using the SBT console I made a little drawing, defining my own color purple and creating a value to reuse some code for each eye:

val purple = Color.rgb(80.uByte, 0.uByte, 150.uByte)
val eye = circle(10) fillColor Color.black on circle(20) fillColor Color.cornflowerBlue

The Creative Scala curriculum uses the Doodle library which has easy-to-use layout methods beside, above, below, on, and under. So I could write eye beside eye the same way that I can write 1 + 2. Like Ruby, operators are methods, and I could have written eye.beside(eye) or 1.+(2).

I overlaid the two eyes on a blue head, and attempted to create a mouth below:

(circle(10) fillColor Color.pink below eye beside eye 
on circle(50) fillColor purple).draw

pink circle mouth below left eye

Oops! This was not intentional, and ended up as a sweet graphical illustration of operator precedence — easily fixed by adding parentheses:

(circle(10) fillColor Color.pink below (eye beside eye) 
on circle(50) fillColor purple).draw

pink circle centered below both eyes

I think my logic error may have been a happy accident, since I think the lop-sided face is more expressive. In any case, the graphics made debugging fun — thanks Noel!

Migration to Firebase from a Heroku-hosted Rails app appears to work seamlessly. I’ve only tested one user, but I could log in with the same password and Facebook account with no end-user intervention.

It took a little experimentation to come up with the correct format for export from heroku psql command line:

\COPY (select id, email, CASE WHEN confirmed_at IS NULL THEN 'false' ELSE 'true' END as Verified, regexp_replace(encode(encrypted_password::bytea, 'base64'), '\n', '') as hash, password_salt::text, screen_name, '' as photo, '' as google_id, '' as google_email, '' as google_name, '' as google_photo, uid as facebook_id, provider_email as facebook_email, '' as fname, '' as fphoto, '' as twitter_id, '' as twitter_mail, '' as twitter_name, '' as twitter_photo, '' as github_id, '' as github_mail, '' as github_name, '' as github_photo, EXTRACT(EPOCH FROM created_at)::bigint, EXTRACT(EPOCH FROM last_sign_in_at)::bigint, '' as phone FROM speakers ORDER BY id limit 160) TO '~/users.csv' WITH (FORMAT csv, DELIMITER ',');

Which I imported with the following command:

firebase auth:import ~/users.csv     \
    --hash-algo=BCRYPT               \
    --rounds=10                      \

Check your devise config file config/initializers/devise.rb — encryption options are configurable there.

Additional Notes

I found these samples helpful to get a test running very quickly.

Firebase auth import requires exactly 26 collumns (for csv import):

UID,Email,Email Verified,Password Hash,Password Salt,Name,Photo URL,Google ID,Google Email,Google Display Name,Google Photo URL,Facebook ID,Facebook Email,Facebook Display Name,Facebook Photo URL,Twitter ID,Twitter Email,Twitter Display Name,Twitter Photo URL,GitHub ID,GitHub Email,GitHub Display Name,GitHub Photo URL,User Creation Time,Last Sign-In Time,Phone Number

The model of declarative eventing allows for listening to very specific events and then triggering specific actions. This model simplifies the developer experience, as well as optimizing the system by reducing network traffic.

AWS S3 bucket trigger

In looking AWS to explain changes in S3 can trigger Lambda functions, I found that the AWS product docs focus on the GUI configuration experience. This probably makes it easy for new folks to write a specific Lambda function; however, it a little harder to see the system patterns before gaining a lot of hands-on experience.

The trigger-action association can be seen more clearly in a Terraform configuration. Under the hood, Teraform must be using AWS APIs for setting up the trigger). The configuration below specifies that whenever a json file is uploaded to a specific bucket with the path prefix “content-packages” then a specific Lambda function will be executed:

resource "aws_s3_bucket_notification" "bucket_terraform_notification" {
    bucket = "${aws_s3_bucket.terraform_bucket.id}"
    lambda_function {
        lambda_function_arn = "${aws_lambda_function.terraform_func.arn}"
        events = ["s3:ObjectCreated:*"]
        filter_prefix = "content-packages/"
        filter_suffix = ".json"
    }
}

— via justinsoliz’ github gist

Google Cloud events

To illustrate an alternate developer experience, the examples below are shown with Firebase JavaScript SDK for Google Cloud Functions, which is idiomatic for JavaScript developers using the Fluent API style, popularized by jQuery. The same functionality is available via command line options using gcloud, the Google Cloud CLI.

** Cloud Storage trigger**

Below is an example of specifying a trigger for a change to a Google Cloud Storage object in a specific bucket:

exports.generateThumbnail = functions.storage.bucket('my-bucket').object().onChange((event) => {
  // ...
});

Cloud Firestore trigger

This approach to filtering events at their source is very powerful when applied to database operations, where a developer can listen to a specific database path, such as with Cloud Firestore events:

exports.createProduct = functions.firestore
  .document('products/{productId}')
  .onCreate(event => {
    // Get an object representing the document
    // e.g. {'name': 'Wooden Doll', 'description': '...}
    var newValue = event.data.data();

    // access a particular field as you would any JS property
    var name = newValue.name;

    // perform desired operations ...
});