The website is infrequently updated, so let me provide some information about what we are currently working on:
- We are trying to make the entire compiler resilient (error-tolerant), incremental, and parallel. We have managed to make every single compiler phase (of which there are 28) parallel. This has already led to significant speed-ups. We are now trying to increase the degree of parallelism within each phase. We are also working on error resilience to provide LSP support no matter what errors a program contains (syntax, naming, type). For example, it should be possible to rename a variable even if the program currently has multiple errors.
- We are adding support for algebraic effects and handlers. This will allow users to define and handle their own effects.
- We are also exploring a novel way to combine type classes ("traits") and effects.
- We have recently added support for package management and integration with Maven.
In summary, we are already in a great spot, and useful programs can be written in Flix today. I encourage you to check out the documentation: https://doc.flix.dev/ and to try Flix!
> Flix supports region-based local mutation, which makes it possible to implement pure functions that internally uses mutable state and destructive operations, as long as these operations are confined to the region.
> We can use local mutation when it is more natural to write a function using mutable data and in a familiar imperative-style while still remaining pure to the outside world.
> We can also use local mutation when it is more efficient to use mutable data structures, e.g. when implementing a sorting algorithm.
Another language with a feature like this is F* (or FStar), but I think it uses a different kind of compile-time analysis.
Haskell actually kind of lets you do it through the ST monad (there's a function called runST that turns mutable code inside the ST monad into pure code). But F* (and Flix) can do it implicitly
I absolutely love the idea of embedding Prolog-esque rules inside a full traditional programming language for solving specific problems. The region-based local mutation is also an incredible idea that would really solve one of my core pain points with immutable languages like Haskell and Elixir.
Also this part made me let out an audible "wow":
> We can exploit purity reflection to selectively use lazy or parallel evaluation inside a library without changing the semantics from the point-of-view of the clients.
Will definitely keep an eye on this language! The syntax seems a little odd (inferring type parameters for functions?) but I'm sure I could get used to it.
In the year since I wrote this post, Pony added partial division. I still don’t know anything about the language but they’ve been getting grief over this post so I wanted to clear that up.
I think Hillel's post was just saying that 1/0 == 0 doesn't lead to any mathematical contradictions.
Another way to think about it is that I believe 1/0 == 42 and 1/0 == 43 are just as valid. They don't lead to contradictions.
[In ZF set theory] Since 0 is not in the domain of recip, we know nothing about the value of 1 / 0; it might equal √2, it might equal R, or it might equal anything else.
But I don't think you want to use a language where 1/0 == 42, and likewise for 0.
Datalog is highly undervalued IMHO. You can describe quite complex relationships in your data, without telling the computer _how_ to realise them (as in imperatively). In fact, there are different strategies (forward vs backward chaining) where you may never realise the data at all.
Woah, the effect system looks really neat at first glance. Also, “region-based local mutation” so your pure functions can use mutation under the hood for performance? Sweet!
I'd like to see an experimental language that leans hard into the concept of controlled mutation.
I always say that purely in terms of design my ideal language is high-level Haskell, low-level C. Conceptually, purely functional design is how programming "should" (note the quotes) be, but doing so down to the level of functions is both not very practical (some algorithms are just easier to express in terms pointers moving around rather than folds, reduces and the like), and makes it hard to reason about performance (especially memory, and most especially if you throw laziness in the mix).
But then again, I write my own stuff in python because I'm a lazy fuck, so probably it's not meant to be :(
Functional Programming was, for a long time, talked about as yet-another-solution to solve the issue of complexity in larger codebases, primarily the complexity of controlling state getting out o hand.
Similar to OOP, which promised to do this by encapsulating state, FP promised to do this via purity, aka. getting rid of as much state as possible, and only allowing stateful transition at certain well defined sections of the program.
The "market advantage" of OOP was that, via Java, it was already so well established, and so many coders had been trained in OOP languages, that it remained alive. FP on the other hand, coming out of academia and requiring all these industry people to suddenly do things in syntactically and conceptually different ways, never really gained traction. OOP simply came first, it is as simple as that.
Whether FP would have actually solved the problem is anyones guess, since it never gained the traction of OOP and Procedural languages. My best guess is that it wouldn't, because I don't believe in silver bullets.
It should be noted that both approaches contributed valueable things to contemporary languages. E.g. first order functions being the norm comes from FP.
Functional programming “won” in terms of getting many of their features implemented into mainstream programming languages. This is a paradigm, it doesn’t require 100% pure usage. It allows for additional safety in parallel contexts.
Unpopular opinion, functional programming style got a big push because the inability of languages and compilers to deal with state especially mutable state, so they bring out the purity big gun and ban all mutable states. However, state and mutable state are natural and useful for programmers to work with, thus functional programming never gains mainstream.
With the advance of lifetime analysis, mutable value semantics, and local mutability, there’s no need to ban mutable state outright. The push for functional programming will be waning in regarding to purity.
I think for me the appeal is that just that all the big brain programming language research seems to happen in weird new functional languages. I assume they're just a better petri dish for experimenting with weird shit, or maybe they come up with all the weird shit to be able to get things done in the Haskell-du-jour, or maybe weird shit just gets branded as functional programming by default. (These days the fp people always talk about linear types, or effects, or other things that don't seem to involve functions at all, idk what's up with that...)
I assume that all of this gets funding because ten years later it makes C# programmers more productive, not because of mass appeal.
Datalog! I especially like that in the smorgasbord of features. I'm still not convinced having a sentient AI encoded in the type system is what the doctor ordered for industry at large.
That's just what I was thinking too haha. Honestly I really like the rest of the syntax though. (And of course, the type system features look neat but it's easier to have an opinion on syntax.)
Just a friendly UBC piggyback on Waterloo’s programming language ;)
Over summer, I built my own little functional language, Crumb (https://github.com/liam-ilan/crumb). Unlike Flix, the scope is tiny, but some pretty awesome stuff has been done with it. (Checkout this pixel art editor in your terminal, 100% Crumb: https://github.com/ronilan/crumbicon).
> Unused definitions, type declarations, etc. are compile-time errors.
This is disappointing. One my main grievances with Go is that it's very difficult to prototype code because it won't compile with unused variables. It massively slows down development. It annoyed me so much that I eventually forked the Go compiler and made a version where unused variables are only a warning.
Playing around with ML and being forced to use python, I find having no block termination character and selecting which context a line of code is in by how much you un-indent it, is the worst.
Give me braces and rip a formatter across the whole codebase and be done with it.
Furthermore, I think that the trend of compilers/interpreters caring about whitespace formatting rules should really end. You can't ever force everyone in the world to write aesthetically pleasing code in your language and someone out there will always be able to write a complete trainwreck, and everyone disagrees on what is or is not aesthetically pleasing. Leave the problem up to configurable code linters where it belongs. Let people make "mistakes" (in your eyes) if they want to.
Flix seems to be implemented in Scala 2.13. Should we expect Flix to work anywhere Scala 2.13 works? ie: if Scala 2.13 supports JDK 8, should we expect that Flix will not take advantage of later JVM features?
The implementation language does not affect the target "machine". Also Flix is implemented in both Scala and Flix (but GitHub does not yet recognize Flix code). Flix targets Java 11, but is moving to target Java 21, and will take advantage of all features available there, including Project Loom. We are just waiting for Java 21 to become a bit more widespread.
[+] [-] jorkadeen|2 years ago|reply
- We are trying to make the entire compiler resilient (error-tolerant), incremental, and parallel. We have managed to make every single compiler phase (of which there are 28) parallel. This has already led to significant speed-ups. We are now trying to increase the degree of parallelism within each phase. We are also working on error resilience to provide LSP support no matter what errors a program contains (syntax, naming, type). For example, it should be possible to rename a variable even if the program currently has multiple errors.
- We are adding support for algebraic effects and handlers. This will allow users to define and handle their own effects.
- We are also exploring a novel way to combine type classes ("traits") and effects.
- We have recently added support for package management and integration with Maven.
In summary, we are already in a great spot, and useful programs can be written in Flix today. I encourage you to check out the documentation: https://doc.flix.dev/ and to try Flix!
(I am one of the developers of Flix).
[+] [-] mlinksva|2 years ago|reply
Are there any [plans for] supply chain attack mitigations?
Naively searching, I find https://github.com/flix/flix/issues/4380#issuecomment-123641... (Proposed Principle: A package can be declared as "safe") and https://github.com/flix/flix/issues/2837 (Add capability-safety to polymorphic effects?) the latter closed with working on something related to this https://github.com/flix/flix/issues/3000 (The Road to Algebraic Effects).
[+] [-] amelius|2 years ago|reply
[+] [-] a-dub|2 years ago|reply
[+] [-] unknown|2 years ago|reply
[deleted]
[+] [-] nextaccountic|2 years ago|reply
> Flix supports region-based local mutation, which makes it possible to implement pure functions that internally uses mutable state and destructive operations, as long as these operations are confined to the region.
> We can use local mutation when it is more natural to write a function using mutable data and in a familiar imperative-style while still remaining pure to the outside world.
> We can also use local mutation when it is more efficient to use mutable data structures, e.g. when implementing a sorting algorithm.
Another language with a feature like this is F* (or FStar), but I think it uses a different kind of compile-time analysis.
Haskell actually kind of lets you do it through the ST monad (there's a function called runST that turns mutable code inside the ST monad into pure code). But F* (and Flix) can do it implicitly
[+] [-] mikhailfranco|2 years ago|reply
An Erlang/Elixir process is single-threaded by definition, so there is no contention and in-place mutation could be allowed.
[+] [-] dang|2 years ago|reply
Flix – Safe, reliable, concise, and functional-first programming language - https://news.ycombinator.com/item?id=31448889 - May 2022 (42 comments)
Flix – Next-generation reliable, concise, functional-first programming language - https://news.ycombinator.com/item?id=25513397 - Dec 2020 (84 comments)
The Flix Programming Language - https://news.ycombinator.com/item?id=19928153 - May 2019 (2 comments)
[+] [-] 3PS|2 years ago|reply
Also this part made me let out an audible "wow":
> We can exploit purity reflection to selectively use lazy or parallel evaluation inside a library without changing the semantics from the point-of-view of the clients.
Will definitely keep an eye on this language! The syntax seems a little odd (inferring type parameters for functions?) but I'm sure I could get used to it.
[+] [-] archargelod|2 years ago|reply
> Dividing by zero yields zero. https://www.hillelwayne.com/post/divide-by-zero/
That's one interesting point I would love to read any opinions on.
Edit: Here's a HN discussion about the `divide by zero` article - https://news.ycombinator.com/item?id=17736046
[+] [-] karmakaze|2 years ago|reply
[0] https://tutorial.ponylang.io/gotchas/divide-by-zero.html
[+] [-] lamontcg|2 years ago|reply
[+] [-] chubot|2 years ago|reply
In the year since I wrote this post, Pony added partial division. I still don’t know anything about the language but they’ve been getting grief over this post so I wanted to clear that up.
https://tutorial.ponylang.io/expressions/arithmetic.html#par...
I think Hillel's post was just saying that 1/0 == 0 doesn't lead to any mathematical contradictions.
Another way to think about it is that I believe 1/0 == 42 and 1/0 == 43 are just as valid. They don't lead to contradictions.
[In ZF set theory] Since 0 is not in the domain of recip, we know nothing about the value of 1 / 0; it might equal √2, it might equal R, or it might equal anything else.
But I don't think you want to use a language where 1/0 == 42, and likewise for 0.
[+] [-] ReleaseCandidat|2 years ago|reply
Example see: https://github.com/Release-Candidate/flix-test
[+] [-] IshKebab|2 years ago|reply
* Example at the top
* Link to playground
* Explanation of all the features, with examples!
* Says which features are unique
The only thing I was found wondering was "why datalog"?
Language looks pretty good.
[+] [-] alexchamberlain|2 years ago|reply
[+] [-] ashton314|2 years ago|reply
[+] [-] qsort|2 years ago|reply
I always say that purely in terms of design my ideal language is high-level Haskell, low-level C. Conceptually, purely functional design is how programming "should" (note the quotes) be, but doing so down to the level of functions is both not very practical (some algorithms are just easier to express in terms pointers moving around rather than folds, reduces and the like), and makes it hard to reason about performance (especially memory, and most especially if you throw laziness in the mix).
But then again, I write my own stuff in python because I'm a lazy fuck, so probably it's not meant to be :(
[+] [-] globalnode|2 years ago|reply
[+] [-] usrbinbash|2 years ago|reply
Similar to OOP, which promised to do this by encapsulating state, FP promised to do this via purity, aka. getting rid of as much state as possible, and only allowing stateful transition at certain well defined sections of the program.
The "market advantage" of OOP was that, via Java, it was already so well established, and so many coders had been trained in OOP languages, that it remained alive. FP on the other hand, coming out of academia and requiring all these industry people to suddenly do things in syntactically and conceptually different ways, never really gained traction. OOP simply came first, it is as simple as that.
Whether FP would have actually solved the problem is anyones guess, since it never gained the traction of OOP and Procedural languages. My best guess is that it wouldn't, because I don't believe in silver bullets.
It should be noted that both approaches contributed valueable things to contemporary languages. E.g. first order functions being the norm comes from FP.
[+] [-] kaba0|2 years ago|reply
[+] [-] troupo|2 years ago|reply
Many functional zealots aim for a purity beyond all reason and comprehension. When what you really want is something like Erlang/Elixir or even C#.
[+] [-] ww520|2 years ago|reply
With the advance of lifetime analysis, mutable value semantics, and local mutability, there’s no need to ban mutable state outright. The push for functional programming will be waning in regarding to purity.
[+] [-] michaelsbradley|2 years ago|reply
Why / why not?
[+] [-] ben0x539|2 years ago|reply
I assume that all of this gets funding because ten years later it makes C# programmers more productive, not because of mass appeal.
[+] [-] Yoric|2 years ago|reply
I've been looking for such a feature for some time. Do I understand correctly that the facts can be established dynamically from, say, IO functions?
Also, are you going to present at FOSDEM?
[+] [-] preordained|2 years ago|reply
[+] [-] linter|2 years ago|reply
[+] [-] subarctic|2 years ago|reply
[+] [-] imoverclocked|2 years ago|reply
Also, I agree but I'm not sure what I would propose as a better token. Maybe another colon?
def printAndInc(x: Int32): Int32 \ IO =
becomes:
def printAndInc(x: Int32): Int32 : IO =
Or maybe, since functions need something after the \, even for pure functions, we just drop the \ and use the last argument?
def printAndInc(x: Int32): Int32 IO =
[+] [-] nikolay|2 years ago|reply
[+] [-] ww520|2 years ago|reply
One thing not clear is what's the reference vs value model, lifetime, and mutable vs immutable model.
[+] [-] liamilan|2 years ago|reply
Over summer, I built my own little functional language, Crumb (https://github.com/liam-ilan/crumb). Unlike Flix, the scope is tiny, but some pretty awesome stuff has been done with it. (Checkout this pixel art editor in your terminal, 100% Crumb: https://github.com/ronilan/crumbicon).
There’s a template (https://github.com/liam-ilan/crumb-template) and vscode highlighter (https://github.com/liam-ilan/crumb-vscode) for anyone who wants to mess around with it. Any feedback super appreciated :D
[+] [-] unknown|2 years ago|reply
[deleted]
[+] [-] Asraelite|2 years ago|reply
This is disappointing. One my main grievances with Go is that it's very difficult to prototype code because it won't compile with unused variables. It massively slows down development. It annoyed me so much that I eventually forked the Go compiler and made a version where unused variables are only a warning.
[+] [-] pimbrouwers|2 years ago|reply
[+] [-] owenbrown|2 years ago|reply
You’re able to fit more code on a screen, and it’s less visual noise. It’s like Pareto better. I really don’t get why others don’t copy it.
[+] [-] lamontcg|2 years ago|reply
Give me braces and rip a formatter across the whole codebase and be done with it.
Furthermore, I think that the trend of compilers/interpreters caring about whitespace formatting rules should really end. You can't ever force everyone in the world to write aesthetically pleasing code in your language and someone out there will always be able to write a complete trainwreck, and everyone disagrees on what is or is not aesthetically pleasing. Leave the problem up to configurable code linters where it belongs. Let people make "mistakes" (in your eyes) if they want to.
[+] [-] imoverclocked|2 years ago|reply
[+] [-] jorkadeen|2 years ago|reply
(I am one of the developers of Flix).
[+] [-] airstrike|2 years ago|reply
[+] [-] paolosimone|2 years ago|reply
Rough edges, but I'm really liking it so far. Let's see how it will handle the upcoming Advent of Code.