Posts in the “scala” category

Functional programming: Math functions, not programming functions

“There’s only ONE rule, but it’s an important one: all of your values must be functions. Not programming functions, but math functions.”

I think I read that quote in an earlier version of this article. The quote is about functional programming, and it influenced something I wrote in my book, Functional Programming, Simplified: Functional programmers think about themselves as being mathematicians, and think of their code as being a combination of algebraic equations, where each function is a pure function that you can think of in mathematical terms.

Notes from “Thinking Functionally with Haskell”

I’m always curious about how people think, and these days I’m most interested in how functional programmers think about programming problems. Along those lines I found a good blog post (tutorial) titled, “Thinking Functionally with Haskell”, and these are my notes from that post:

Notes from Functional and Reactive Domain Modeling

I’m a big fan of the book, Functional and Reactive Domain Modeling, and these are some of my notes (“CliffsNotes”) from the book, most of them coming from the first chapter.

Chapter 1. Functional domain modeling

  • domain model
    • the representation of how the business works
    • blueprint of the relationships between the entities
    • objects that belong to the domain
    • behaviors those objects have
    • the language/vocabulary of the business
    • the context within which the model operates
  • essential complexities - complexities inherent to the business
  • incidental complexities - complexities introduced by the solution itself

Domain-driven design

  • bounded context - smaller model within the whole; a complete area of functionality within the larger system
  • the complete domain model is made up from a collection of bounded contexts
  • bounded contexts communicate via services/interfaces/APIs (me: think of them as web services)
  • ubiquitous language = domain vocabulary

Entities and value objects:

  • entities have an id (like a database id), and they are mutable; usually has a definite lifecycle
  • value objects (like an address) don’t have an id; they are identified by the values that are contained, and are therefore immutable
  • entity has an id that can’t change, and value object has a value that can’t change

Services:

  • services = behaviors = functions
  • usually models a use case of the business

Object lifecycles:

  • creation
  • participation in behaviors
  • persistence to a data store
  • factories (p.9)
    • centralize code to create entities
  • aggregates - a transaction boundary in the model
  • aggregate root - guardian of the graph and single point of interaction of the aggregate with its clients
  • Effective Aggregate Design by Vaughn Vernon

Scala:

  • Use case classes to model aggregates (ADTs)
  • Traits let you define modules which can be composed using mixin composition

Repositories:

  • the interface (trait) has no knowledge of the underlying data store

Thinking functionally

  • functions are the main abstraction to model domain behaviors (standalone functions in modules (traits), like Haskell)
  • mutable state is an anti-pattern when it comes to reasoning about your code
  • pure functions ...
  • general principles:
    • model immutable state as ADTs with case classes
    • model behaviors as functions in modules
    • behaviors in modules operate on their corresponding ADTs
  • more:
    • ADTs have no behaviors
    • services are defined in modules, which are implemented as Scala traits
    • when you need a concrete instance of a trait, create it with the object keyword

1.3.2 Pure functions compose (p.22)

  • good examples
  • composition = Unix pipeline (me)
  • HOFs like map are known as combinators
  • andThen and compose examples
  • takeaway: “appreciate how function composition through combinators can lead to enrichment of domain behaviors”

1.4 Managing side effects

  • stuff like I/O
  • decouple side effects as far as possible from pure domain logic

1.5 Virtues of pure model elements

  • equational reasoning
  • substitution model of evaluation
  • substitution model only works if functions are pure
  • referentially transparent expressions
  • three pillars of functional programming
    • referentially transparency
    • substitution model
    • equational reasoning

Other good quotes/notes

“Abstractions compose when types align; otherwise you’re left with islands of artifacts you can’t reuse and compose.”

About monads and effects in functional programming:

  • Future models latency as an effect
  • Try abstracts the effect of failures (manages exceptions as effects)
  • Option models the effect of optionality

Functional and Reactive Domain Modeling

If you haven’t read it yet, I highly recommend the book  Functional and Reactive Domain Modeling, with one caveat: it tends to assume that you already know a lot about functional programming. For example, if you already know what functors and monads are, it can help you understand how to use them in Scala. If you don’t already know what those things are, I’ll point you to my own book, Functional Programming, Simplified, about 40% of which you can read for free.

A Scala “functional programming style” To-Do List application written with Cats

NOTE: If you read my previous article (a Scala functional programming style To-Do List application), the new content in this article starts down at The Scala/FP Code section.

Back when I was writing Functional Programming, Simplified I started to write a little Scala/FP “To-Do List” application that you can run from the command line, based on a similar application in the Learn You A Haskell For Great Good book. For reasons I don’t remember, I decided not to include it in the book, and forgot about it until I started using GraalVM (“Graal”) recently.

In functional programming, side effects are kind of a big deal

50% off discount code for “Functional Programming, Simplified”

If you’ve been waiting for a coupon or discount to learn functional programming, today may be your lucky day. I just created a 50% off discount code for the PDF version of “Functional Programming, Simplified” (a best-selling, highly-rated book about functional programming in Scala). But hurry, because the discount is limited to the first 100 buyers.

As I have written before, you can read all those books on the right, or just read the one book on the left, which is based on the best of those books.

Wikipedia Reader

Summary: My “Wikipedia Reader” application reads Wikipedia pages to you. The current release is a very rough Version 0.1 (alpha) release. What’s new: 1) It works. 2) It’s packaged as a Mac OS X application. 3) It supports the use of multiple reading voices.

Update: I’ll get a new build out this weekend that eliminates the bugs shown in the video.

In my spare time I’ve been working on an application I call a “Wikipedia Reader” (or Wikipedia Page Reader). As its name implies, it reads Wikipedia pages and speaks the page content to you. The functionality is shown in this 112-second video:

An example of Scala’s `f` string interpolator

With Scala it’s common to embed variables in strings like this with the s string interpolator:

val name = "Fred"
println(s"My name is $name.")

That’s cool, but when you need to format your string, Scala gives you an even more powerful tool: the f string interpolator. Here’s an example of how I just did this in my LittleLogger logging library:

The Scala 3 'for' loop (for/yield) syntax and examples

As a brief note today, here are some examples of the Scala 3 for loop syntax, including the for/do and for/yield expressions that are new to Scala 3.

Scala 3 'for' loop syntax (for/do)

// single line
for i <- ints do println(i)
for (i <- ints) println(i)

// multiline
for
    i <- ints
    if i > 2
do
    println(i)

Using 'end for' with for/do

You can also add end for to the end of a Scala 3 for loop, so the previous multiline example can also look like this:

for
    i <- ints
    if i > 2
do
    println(i)
end for

When your for loops get longer, I find that adding end for to the end of them makes them easier to read.

Scala 3 'for' loop as the body of a method

These examples show how to use a for loop as the body of a Scala method:

import io.Source

def printLines1(source: Source): Unit =
    for line <- source.getLines do println(line)

def printLines2(source: Source): Unit =
    for line <- source.getLines
    do println(line)
    
def printLines3(source: Source): Unit =
    for line <- source.getLines
    do
        println(line)
        
def printLines4(source: Source): Unit =
    for
        line <- source.getLines
    do
        println(line)
        
def printLines5(source: Source): Unit =
    for
        line <- source.getLines
        if line.trim != ""
    do
        // a multiline `do` block
        println("in `do` block of `for`")
        println(line)

Scala 3 for/yield expressions

Here are some single-line for/yield expressions:

Futureboard, a Flipboard-like Scala Futures demo

I’ll write more about this shortly, but yesterday I created a little video of a demo application I call Futureboard. It’s a Scala/Swing application, but it works like Flipboard in that it updates a number of panels — in this case Java JInternalFrames — simultaneously every time you ask it to update.

The “update” process works by creating Scala futures, one for each internal frame. When you select File > Update, a Future is created for each news source, and then simultaneous calls are made to each news source, and their frames are updated when the data returns. (Remember that Futures are good for one-shot, “handle this relatively slow and potentially long-running computation, and call me back with a result when you’re done” uses.)

Here’s the two-minute demo video:

Scala best practices: null values, Option, Some, and None

In his book, Beginning Scala, David Pollak provides a series of statements that can be considered as a recipe for avoiding the use of null values in your Scala code. I've organized his statements here in the following three sections.

1) General rules about null and Option

We begin with the following general rules regarding the use of null values in Scala code: