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.
Flix – A powerful effect-oriented programming language
51–60 of 197 posts
Re: Flix – A powerful effect-oriented programming language
#52Earlier 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?
But the good news is that the common case incurs no overhead.
Re: Flix – A powerful effect-oriented programming language
#53 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
#54I 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
Re: Flix – A powerful effect-oriented programming language
#55Earlier 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.
Re: Flix – A powerful effect-oriented programming language
#56Anyone have a good primer on what effect-oriented programming looks like and how it’s used? Feel free to shill your own blog!
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
#57Anyone have a good primer on what effect-oriented programming looks like and how it’s used? Feel free to shill your own blog!
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
#58Probably 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(…
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.
Re: Flix – A powerful effect-oriented programming language
#60JVM 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.