Content deleted Content added
Citation bot (talk | contribs) Alter: title, template type. Add: chapter. Removed parameters. | Use this bot. Report bugs. | Suggested by Headbomb | Linked from Wikipedia:WikiProject_Academic_Journals/Journals_cited_by_Wikipedia/Sandbox3 | #UCB_webform_linked 730/2306 |
The Death of UFCS: https://github.com/flix/flix/issues/1500 |
||
(8 intermediate revisions by 5 users not shown) | |||
Line 15:
| website = {{URL|https://flix.dev/}}
| influenced_by = [[F Sharp (programming language)|F#]], [[Go (programming language)|Go]], [[Haskell (programming language)|Haskell]], [[OCaml]], [[Scala (programming language)|Scala]]
| file_ext = {{Mono|.flix}}
}}
'''Flix''' is a [[functional programming|functional]], [[imperative programming|imperative]], and [[logic programming|logic]] [[programming language]] developed at [[Aarhus University]], with funding from the [[Danish Council for Independent Research|Independent Research Fund Denmark]],<ref>{{cite web |title=Forskningsprojekter |url=https://dff.dk/forskningsprojekter?SearchableText=functional+and+declarative+logic+programming&period%3Alist=all&instrument%3Alist=all&filed_method%3Alist=all |website=Danmarks Frie Forskningsfond |language=da}}</ref> and by a community of [[open source]] contributors.<ref>{{cite web |title=Flix Authors |url=https://github.com/flix/flix/blob/master/AUTHORS.md |website=GitHub |date=27 July 2022 |language=en}}</ref> The Flix language supports [[algebraic data types]], [[pattern matching]], [[parametric polymorphism]], [[currying]], [[higher-order function]]s, [[extensible records]],<ref>{{cite journal |last1=Leijen |first1=Daan |title=Extensible records with scoped labels |journal=Trends in Functional Programming}}</ref> [[Communicating sequential processes|channel and process-based concurrency]], and [[tail call elimination]]. Two notable features of Flix are its type and effect system<ref name="oopsla2020a">{{cite journal |last1=Madsen |first1=Magnus |last2=van de Pol |first2=Jaco |title=Polymorphic Types and Effects with Boolean Unification |journal=Proceedings of the ACM on Programming Languages |date=13 November 2020 |volume=4 |issue=OOPSLA |pages=1–29 |doi=10.1145/3428222|s2cid=227044242 |doi-access=free }}</ref> and its support for first-class Datalog constraints.<ref name="oopsla2020b">{{cite journal |last1=Madsen |first1=Magnus |last2=Lhoták |first2=Ondřej |title=Fixpoints for the Masses: Programming with First-class Datalog Constraints |journal=Proceedings of the ACM on Programming Languages |date=13 November 2020 |volume=4 |issue=OOPSLA |pages=125:1–125:28 |doi=10.1145/3428193|s2cid=227107960 |doi-access=free }}</ref>
Line 25:
== Overview ==
Flix is a [[programming language]] in the [[Standard ML|ML]]-family of languages. Its type and effect system is based on [[Hindley–Milner type system|Hindley-Milner]] with several extensions, including [[row polymorphism]] and [[Unification (computer science)#E-unification|Boolean unification]]. The syntax of Flix is inspired by [[Scala (programming language)|Scala]] and uses short [[Reserved word|keywords]] and [[curly braces]]
While many programming languages support a mixture of functional and imperative programming, the Flix type and effect system tracks the purity of every expression making it possible to write parts of a Flix program in a [[Purely functional programming|purely functional style]] with purity enforced by the effect system.
Line 33:
Monomorphization avoids [[Value type and reference type|boxing]] of primitive values at the cost of longer compilation times and larger executable binaries. Flix has some support for interoperability with programs written in [[Java programming language|Java]].<ref>{{cite web |title=Programming Flix - Interoperability |url=https://doc.flix.dev/interoperability/ |website=flix.dev}}</ref>
Flix supports [[tail call elimination]] which ensures that function calls in tail position never consume stack space and hence cannot cause the call stack to overflow.<ref>{{cite book |last1=Madsen |first1=Magnus |last2=Zarifi |first2=Ramin |last3=Lhoták |first3=Ondřej |title=Proceedings of the 27th International Conference on Compiler Construction |chapter=Tail call elimination and data representation for functional languages on the Java virtual machine |date=2018 |pages=139–150 |doi=10.1145/3178372.3179499|isbn=9781450356442 |s2cid=3432962 }}</ref> Since the [[Java bytecode instruction listings|JVM instruction set]] lacks explicit support for tail calls, such calls are emulated using a form of reusable stack frames.<ref>{{cite
The Flix compiler disallows most forms of unused or redundant code, including: unused local variables, unused functions, unused formal parameters, unused type parameters, and unused type declarations, such unused constructs are reported as compiler errors.<ref>{{cite web |title=Redundancies as Compile-Time Errors |url=https://flix.dev/blog/redundancies-as-compile-time-errors/ |website=flix.dev}}</ref> [[Variable shadowing]] is also disallowed. The stated rationale is that unused or redundant code is often correlated with erroneous code<ref>{{cite journal |last1=Engler |first1=D. |title=Using redundancies to find errors |journal=IEEE Transactions on Software Engineering |date=October 2003 |volume=29 |issue=10 |pages=915–928 |doi=10.1109/TSE.2003.1237172}}</ref>
Line 48:
<syntaxhighlight lang="flx">
def main(): Unit
</syntaxhighlight>
The type and effect signature of the <code>main</code> function specifies that it has no parameters, returns a value of type <code>Unit</code>, and that the function has the IO effect, i.e. is impure. The <code>main</code> function is impure because it invokes <code>printLine</code> which is impure.
=== Algebraic data types and pattern matching ===
Line 60:
<syntaxhighlight lang="flx">
enum Shape {
case Circle(
case Square(
case Rectangle(
}
</syntaxhighlight>
Line 71:
<syntaxhighlight lang="flx">
def area(s: Shape):
case Circle(r) => 3 * (r * r)
case Square(w) => w * w
Line 83:
<syntaxhighlight lang="flx">
def twice(f:
</syntaxhighlight>
Line 114:
<syntaxhighlight lang="flx">
def point2d(): {x:
</syntaxhighlight>
Line 120:
<syntaxhighlight lang="flx">
def sum(r: {x:
</syntaxhighlight>
Line 137:
The Flix type and effect system separates pure and impure expressions.<ref name="oopsla2020a"/><ref>{{cite web |title=Programming Flix - Effects |url=https://doc.flix.dev/effects/ |website=flix.dev}}</ref><ref>{{cite web|title=Rust Internals - Flix Polymorphic Effects|date=15 November 2020 |url=https://internals.rust-lang.org/t/flix-polymorphic-effects/13395}}</ref> A pure expression is guaranteed to be [[Referential transparency|referentially transparent]]. A pure function always returns the same value when given the same argument(s) and cannot have any (observable) side-effects.
For example, the following expression is of type <code>
<syntaxhighlight lang="flx">
1 + 2 :
</syntaxhighlight>
whereas the following expression
<syntaxhighlight lang="flx">
</syntaxhighlight>
Line 154:
<syntaxhighlight lang="flx">
// The syntax a -> Bool is short-hand for a -> Bool
def exists(f: a -> Bool, xs: Set[a]): Bool = ...
</syntaxhighlight>
Line 165:
<syntaxhighlight lang="flx">
</syntaxhighlight>
Line 174 ⟶ 173:
<syntaxhighlight lang="flx">
if (1 == 2)
</syntaxhighlight>
Line 182 ⟶ 181:
<syntaxhighlight lang="flx">
def map(f: a -> b
</syntaxhighlight>
Line 192 ⟶ 191:
<syntaxhighlight lang="flx">
def >>(f: a -> b
</syntaxhighlight>
The type and effect signature can be understood as follows: The <code>>></code> function takes two function arguments: <code>f</code> with effect <code>e1</code> and <code>g</code> with effect <code>e2</code>. The effect of <code>>></code> is effect polymorphic in the [[Logical conjunction|conjunction]] of <code>e1</code> and <code>e2</code>. If both are pure
The type and effect system allows arbitrary
For example, it is possible to express a higher-order function <code>h</code> that accepts two function arguments <code>f</code> and <code>g</code> where the effects of
<syntaxhighlight lang="flx">
def h(f: a -> b
</syntaxhighlight>
If <code>h</code> is called with a function argument <code>f</code> which
The type and effect system can be used to ensure that statement expressions are useful, i.e. that if an expression or function is evaluated and its result is discarded then it must have a side-effect. For example, compiling the program fragment below:
<syntaxhighlight lang="flx">
def main(): Unit
List.map(x -> 2 * x, 1 :: 2 :: Nil);
</syntaxhighlight>
Line 241 ⟶ 240:
The following Datalog rules compute the [[transitive closure]] of the edge relation:
<syntaxhighlight lang="
Path(x, y) :- Edge(x, y).
Path(x, z) :- Path(x, y), Edge(y, z).
Line 257 ⟶ 256:
<syntaxhighlight lang="flx">
def main(): #{Edge(
let f = #{
Edge(1, 2). Edge(2, 3). Edge(3, 4).
Line 273 ⟶ 272:
<syntaxhighlight lang="flx">
def edges(): #{Edge(
Edge(1, 2). Edge(2, 3). Edge(3, 4).
}
def closure(): #{Edge(
Path(x, y) :- Edge(x, y).
Path(x, z) :- Path(x, y), Edge(y, z).
}
def
</syntaxhighlight>
The un-directed closure of the graph can be computed by adding the rule:
<syntaxhighlight lang="
Path(x, y) :- Path(y, x).
</syntaxhighlight>
Line 294 ⟶ 293:
<syntaxhighlight lang="flx">
def closure(directed: Bool): #{Edge(
let p1 = #{
Path(x, y) :- Edge(x, y).
Line 317 ⟶ 316:
</syntaxhighlight>
because in <code>p1</code> the type of the <code>Edge</code> predicate is <code>Edge(
==== Stratified negation ====
Line 339 ⟶ 338:
<syntaxhighlight lang="flx">
def main(): #{A(
if (true)
A(x) :- A(x), not B(x).
|