Comment by mcdow

3 days ago

Anyone have a good primer on what effect-oriented programming looks like and how it’s used? Feel free to shill your own blog!

Effect system allows programmers to annotate expressions that can have certain effects, just like the type system annotating type information on them, so compilers can enforce effect rules just like enforcing type rules.

For example for a type system,

  let a: Int      // this says 'a' has the type Int
  a = 5           // compiler allows, as both 'a' and 5 are of Int.
  a = 5.1         // disallowed, as 'a' and 5.1 are of different types.

Similarly for example for an effect system,

  let a: Int
  let b: Int!Div0 // 'b' is of type Int and the Div0 effect.
  let c: Int
  ...
  a = 1 / c       // disallowed, as '/' causes the Div0 effect which 'a' not supported
  b = 1 / c       // allowed, as both '/' and 'b' support the Div0 effect.

The effect annotations can be applied to a function just like the type annotations. Callers of the function need to anticipate (or handle) the effect. E.g. let's say the above code is wrapped in a function 'compute1(..) Int!Div0', a caller calling it can do.

  compute1(..) on effect(Div0) {
     // handle the Div0 effect.
  }

Shilling my book "Effect Oriented Programming" https://effectorientedprogramming.com/

The book uses Scala & ZIO but intends to be more about the concepts of Effects than the actual implementation. I'd love to do a Flix version of the book at some point. But first we are working on the TypeScript Effect version.

It looks like "effect" as in impure functions in a functional language? I.e. a new way of dealing with effects (global/hidden state mutations) in a language that makes the pure-impure distinction. I'm not entirely sure.

I thought it was going to be something like contracts or dependent types or something.

  • No. It is essentially resumable exceptions. You throw an exception saying “I need a MyAlgebraicType” and the effect handler catches the exception, generates the value, and returns execution to the place the exception was called from.

    • But entirely definable in user code, so an effect is essentially a set of possibly impure operations you can perform (like I/O or exception throwing), and a function that exhibits that effect has access to those operations. Of course the call sites then also exhibit that effect, unless they provide implementations of the effect operations.