John A De Goes Profile picture
CEO @ZivergeTech, CEO @GolemCloud, OSS contributor @zioscala, speaker, writer. Accelerating human dominion.
Mar 27, 2023 20 tweets 4 min read
Can you do concurrency in direct-style Scala, without a functional effect system?

Sure, but you lose two things:

1. Compositional concurrency

2. Engineered interruption & state prop

In this thread, I will discuss each one, and then link to my recent talk at @FunScalaConf. COMPOSITIONAL CONCURRENCY

Compositional concurrency emerges from layering a well-designed functional API atop effects-as-values, and gives you the ability to precisely solve any problem in concurrency using a few simple, orthogonal operators.
Mar 16, 2023 21 tweets 5 min read
Programming language mascots, as designed by GPT-4 and Midjourney 4.

1/n
Scala Programming Language
Mar 10, 2023 6 tweets 2 min read
I have now tried both (1) and (2) for the Scala Center, and neither has worked, so I am officially giving up on effecting change, as my efforts are best spent elsewhere on creating technology.

This is the end of a process I started 4 years ago:

I wish others the best of luck in using whatever strategies they believe will be effective in achieving the change necessary for commercial adoption of Scala to grow and prosper.

I will be rooting for you to succeed, even while my efforts will be focused on creating technology.
Mar 9, 2023 8 tweets 2 min read
I have been personally attacked by several @scalarconf speakers.

I don't mean they questioned if my background was a good fit to design an effect system or to be CEO.

I mean smeared with the worst, most unprofessional ad hominem, with my every motivation impugned. I never called for nor expected @scalarconf to cancel these speakers just because they behaved unprofessionally toward me.

That would involve turning a community event into a weapon, to punish one subgroup and reward another.
Mar 9, 2023 10 tweets 4 min read
Scala Center has done useful work that helps industry adoption of Scala, and for this, we are all extremely grateful. 🙏

Yet, the report has a glaring omission: a retrospective to discuss how the org will learn from mistakes of the (recent) past:

degoes.net/articles/scala… As this very report shows, at a time when tooling, language stability, and platform support desperately need resources, the Scala Center is diverting scarce resources to fund items that, however noble, do not solve the problems of commercial Scala users.
Jan 29, 2023 14 tweets 3 min read
One developer suggested a backward-incompatible Scala 4 (?) wouldn't be the fatal asteroid that wipes the language out because 'migration tools' exist.

We heard that before, and it worked out exactly as well as I predicted it would:

Beyond the fact that migration tools will fail to automagically and atomically update code, macros, and third-party libraries, there is the glaringly obvious fact that each rewrite of the language resets much of our ecosystem to zero.
Jan 27, 2023 5 tweets 1 min read
A number of developers have asked me, "Why didn't your post look at Spark or Play?"

The reason is simple: Spark and Play contributed to the growth of Scala some time ago, but no longer.

Currently, they help stymie attrition due to sunk costs, but do not grow or shrink Scala. Play was a brilliant framework for its time and surely a compelling reason to adopt Scala. But the Java frameworks such as Micronaut and Quarkus are far ahead of Play, and it's unlikely Play can surpass them or inspire JVM shops to build new projects with Play.
Dec 11, 2022 29 tweets 5 min read
In functional programming, algebraic laws assert things like the following (for ZIO):

left.race(right) <-> right.race(left).map(flipTuple)

The dirty secret of effect systems is that such laws cannot be checked, even in theory. I am not referring to the obvious problem with law-checkers: they are built on generators, & therefore cannot prove, only disprove.

A law library can generate a few hundred lists and check that a ++ (b ++ c) is the same as (a ++ b) ++ c, but that's not proof, it's weak evidence.
Dec 10, 2022 6 tweets 2 min read
Public service announcement 1/4:

Type classes DESCRIBE structure, they don't BESTOW structure. The fact that List empty and concatenation form a monoid comes from the structure of List, not from the monoid type class or law libraries or unit tests. 🎓 2/4

Law libraries rely on generators, which means that it is IMPOSSIBLE for them to prove laws, only disprove them. At best, they provide some evidence of laws (by checking a few cases), in a fashion that's sometimes more concise (but not better) than unit tests. 🤔
Nov 15, 2022 5 tweets 2 min read
Loom with structured concurrency makes a concurrent race of two tasks sane (hurray!), but a simple JDK-powered race is not globally efficient, orthogonal, or leak-free.

Let's take a look at each issue in turn:

1/5 1. Globally Efficiency

In ZIO, racing always terminates the loser immediately & safely, but a JDK-powered race doesn't (currently) have this ability (the loser runs to completion, wasting resources!), nor is there a seamless backward-compatible way of adding this feature.

2/5
Oct 11, 2022 7 tweets 2 min read
In ZIO 2, the Ref data type lets you have a safe and convenient way to update shared state with atomicity, consistency, and isolation.

Any number of fibers can all safely update and query a ref concurrently:

ref.update(_ + 1)

ZIO 2 has much more than Ref, however! FiberRef gives you a Ref-like API but with fiber-local semantics, similar to a ThreadLocal: each fiber gets its own copy of the ref value. Moreover, when one fiber joins another fiber, its own fiber refs are merged with the child fiber refs in a principled, algebraic way.
Apr 5, 2022 25 tweets 4 min read
In Scala 3, context functions are ONLY useful for small DSLs. By "small DSLs", I mean single-purpose and non-extensible DSLs.

Examples include: HTML generation, database queries, etc.

This statement may surprise some, so I'll explain. A context-function is like a `using` method, but as a function value. It's the function version of `using`, and must exist so that functions have parity with methods.

(Scala 2.x has no such parity--for example, methods can be polymorphic, but functions cannot.)
Mar 14, 2022 25 tweets 5 min read
The big reveal at ZIO World 2022 is a HUGE simplification to resource management in ZIO 2.0 that brings new levels of simplicity, power, & performance.

In a nutshell: @adamfraser & I discovered ZIO Environment is now powerful enough to provide resource-safety by itself! In ZIO 1.x, we used a data type called Managed to provide resource safety. Although inspired by the Managed data type from Haskell, ZIO Managed innovated in a number of ways over both Haskell and Cats Effect Resource:
Feb 11, 2022 9 tweets 2 min read
Capture checking holds promise for two things:

1. Doing what we can already do in Scala, but in a different way, with a different set of trade-offs.

2. Scoped access, which is something we cannot really do in Scala and which we ordinarily have to use linear typing to achieve. Before elaborating, it's worth pointing out that, contrary to what some might think, capture checking has very little connection to pure functional programming, despite the similar terminology involved.
Feb 11, 2022 6 tweets 1 min read
Scala 3 union types work beautifully for composing fine-grained errors (ErrorA | ErrorB) without losing specifics, but they are NOT a valid replacement for a sum type such as Either (or EitherT, etc., if you are using an effect system). This is because sum types like Either have a well-defined success and error channel, which means it is possible to unambiguously and statically distinguish between success and failure for any possible choice of success and failure error types.
Sep 6, 2021 16 tweets 3 min read
In Scala, term inference allows the compiler to construct values from types, while type inference allows the compiler to construct types from values.

This distinction has profound ramifications for contextual abstractions in Scala 3. Term inference is useful when the construction of values is unambiguous and full of boilerplate.

Type inference is useful when the construction of types is unambiguous and full of boilerplate.

Importantly, the compiler can do *either* term inference or type inference, not both.
Mar 13, 2021 5 tweets 1 min read
Requirements for good 'checked exceptions':

1. Recognize that errors fall into two categories: recoverable and non-recoverable; and that this is a function of the *usage* and not the *error type*, so users must be free to shift errors between categories at will.

1/5
2. Have robust mechanisms for both error widening & narrowing.

There are two ways to widen: fail with a new error type, or mark a non-recoverable error as recoverable.

There are two ways to narrow: catch an error type, or mark a recoverable error as non-recoverable.

2/5
Mar 13, 2021 9 tweets 2 min read
Hot take: Checked exceptions in Java failed because they were extremely verbose and there was no machinery to abstract, not because they have no value.

Examples: Long exception lists:

void foo() throws A, B, ... Z

There was no way to define:

type All = A | B ... Z

to say:

void foo() throws All
Mar 12, 2021 29 tweets 8 min read
ZIO World 2021 Summary

ZIO downloads have tripled in the past year, almost reaching 1 million downloads / month, with 390 contributors, 800 forks, and almost 3k stars.

1/29 Numerous companies have shipped projects using ZIO, including recognizable names like Netflix, DHL, Adidas.

The list of commercial ZIO adopters is so long it doesn't fit on a single page (!), and captures just the companies who self-identified as using ZIO.

2/29