Live data from Hacker News

Flix – A powerful effect-oriented programming language

flix.dev

51–60 of 197 posts

Re: Flix – A powerful effect-oriented programming language

#51

Earlier quoted context omitted.

Sorry to hijack, but since you are involved, can you explain why tail call optimization would incur a run time perf penalty, as the docs mention? I would expect tail call optimization to be a job for the compiler, not for the runtime.

We have to emulate tail calls using trampolines. This means that in some cases we have to represent stack frames as objects on the heap. Fortunately, in the common case where a recursive function simply calls itself in tail position, we can rewrite the call to a bytecode level loop and there is no overhead.

Thanks for explaining that term. That sounds really bad indeed. Maybe this is way too technical, but representing them as stack pointers was unfeasible?

Re: Flix – A powerful effect-oriented programming language

#52

Earlier quoted context omitted.

We have to emulate tail calls using trampolines. This means that in some cases we have to represent stack frames as objects on the heap. Fortunately, in the common case where a recursive function simply calls itself in tail position, we can rewrite the call to a bytecode level loop and there is no overhead.

Thanks for explaining that term. That sounds really bad indeed. Maybe this is way too technical, but representing them as stack pointers was unfeasible?

The JVM (and other VMs for that matter) do not grant direct access to the stack.

But the good news is that the common case incurs no overhead.

Re: Flix – A powerful effect-oriented programming language

#53
Probably Elixir spoiled me but when I see

  enum Shape {
    case Circle(Int32),
    case Square(Int32),
    case Rectangle(Int32, Int32)
  }
  def area(s: Shape): Int32 = match s {
    case Circle(r)       => 3 * (r * r)
    case Square(w)       => w * w
    case Rectangle(h, w) => h * w
  }
I wonder why not this syntax:

  def area(s: Shape.Circle(r)) = { 3 * (r * r) }
  def area(s: Share.Square(w)) = { w * w }
  def area(s: Shape.Rectangle(h, w)) = { h * w }

  area(Shape.Rectangle(2, 4))
The Int32 or Int32, Int32 types are in the definition of Shape, so we can be DRY and spare us the chances to mismatch the types. We can also do without match/case, reuse the syntax of function definition and enumerate the matches in there. I think that it's called structural pattern matching.

Re: Flix – A powerful effect-oriented programming language

#54

I am deeply impressed by the depth and breadth of this language. Algebraic data types, logic programming, mutability, all there from the get go. Another aspect that I love from their comparison table is that a single executable is both the package manager, LSP and the compiler. As I understand, the language server for Haskell has/had to do a lot of dances and re implement things from ghc as a dance between the partic…

>a single executable is both the package manager, LSP and the compiler oh my i just know you're going to love unison

Thanks for giving me homework. :-)

Re: Flix – A powerful effect-oriented programming language

#55

Earlier quoted context omitted.

TCO (tail call optimization) is often confused with TCE (tail call elimination), the latter is a runtime guarantee whereas the former is a compiler's best effort attempt to statically optimize tail calls.

Thanks! So you are implying that `TCO :: Maybe TCE`? I am trying to think of a situation where a functional language compiler does not have enough information at compile time, especially when effects are witnessed by types.

I'm not a compiler dev, but I know that many functional programming languages struggle with this in the same manner if the target platform does not support TCE itself, and therefore require trampolining.

Re: Flix – A powerful effect-oriented programming language

#56
post #35

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.
  }

Re: Flix – A powerful effect-oriented programming language

#57
post #35

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

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.

Re: Flix – A powerful effect-oriented programming language

#58
post #53

Probably Elixir spoiled me but when I see enum Shape { case Circle(Int32), case Square(Int32), case Rectangle(Int32, Int32) } def area(s: Shape): Int32 = match s { case Circle(r) => 3 * (r * r) case Square(w) => w * w case Rectangle(h, w) => h * w } I wonder why not this syntax: def area(s: Shape.Circle(r)) = { 3 * (r * r) } def area(s: Share.Square(w)) = { w * w } def area(s: Shape.Rectangle(h, w)) = { h * w } area(…

> can also do without match/case, reuse the syntax of function definition and enumerate the matches in there. I

I think that is multi-methods

Re: Flix – A powerful effect-oriented programming language

#59

// Computes the delivery date for each component. let r = query p select (c, d) from ReadyDate(c; d) facepalm . Select should always come last, not first, haven't we learned anything from the problems of SQL? LINQ got this right, so it should look like: query p from ReadyDate(c; d) select (c, d) Very cool language otherwise.

Yeah PRQL also got this right and it's sooo much nicer.

Re: Flix – A powerful effect-oriented programming language

#60

JVM is a no-starter. The language looks nice tho, shame they built it on JVM.

The JVM is a state-of-the-art virtual machine with multiple open source implementations, a large ecosystem, and a fast JIT compiler that runs on most platforms. It is hard to find another VM with the same feature set and robust tooling.

I think the problem is that it targets a VM instead of native machine architectures, not the quality of the VM. I also find the times I need to target a VM to be very limited as I'm generally writing code for a specific platform, not a cross platform application. Of course this will vary between developers.
Post reply on HN