又一个基于JVM的编程语言:Flix

21-12-10 banq

Flix 是一种有原则的函数式、命令式和逻辑编程语言,由奥胡斯大学、滑铁卢大学和开源贡献者社区开发。

Flix 的灵感来自 OCaml 和 Haskell,以及来自 Rust 和 Scala 的想法。Flix 看起来像 Scala,但它的类型系统基于 Hindley-Milner。Flix 的两个独特功能是其多态效果系统和对一流 Datalog 约束的支持。

Flix 编译为 JVM 字节码,运行在 Java 虚拟机上,支持全尾调用消除。Flix 的 VSCode 插件可用。

详击标题

 

Flix 旨在提供其他编程语言无法提供的独特函数组合,包括:

  • 代数数据类型和模式匹配(如 Haskell、OCaml)、
  • 可扩展记录(如 Elm)、
  • 类型类(如 Haskell、Rust)、
  • 高级别的类型(如 Haskell)、
  • 类型推断(如 Haskell、OCaml)、
  • 基于通道和进程的并发(如 Go)、
  • 多态效应系统(一个独特的特性)、
  • 纯多态函数(一个独特的特性)、
  • 一流的 Datalog 约束(一个独特的函数)
  • 并编译为 JVM 字节码(如 Scala)。 

Flix 从许多其他优秀语言中汲取灵感,包括 Elm、F#、OCaml、Haskell、Rust 和 Scala。Flix 在视觉上类似于 Scala,强调简洁和关键字的使用。 

def main(_args: Array[String]): Int32 & Impure = 
    println("Hello World!");

 

代数数据类型和模式匹配

代数数据类型和模式匹配是函数式编程的基本要素,Flix 以最小的代价支持。

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
}

  

类型类

Flix 使用类型类来抽象支持一组通用操作的类型。

class Eq[a] {
    def eq(x: a, y: a): Bool
    def neq(x: a, y: a): Bool = not Eq.eq(x, y)
}

instance Eq[(a1, a2)] with Eq[a1], Eq[a2] {
    def eq(t1: (a1, a2), t2: (a1, a2)): Bool =
        let (x1, x2) = t1;
        let (y1, y2) = t2;
        x1 == y1 and x2 == y2
}

 

并发

Flix 的并发模型受到 Go 的启发。在 Flix 中,进程通过通道上的不可变消息传递进行通信。

以下程序生成一个新进程来执行(琐碎)计算,然后使用通道将结果发送到主进程。

/// Computes the sum of `x` and `y` and sends the result on the channel `c`.
def sum(x: Int, y: Int, c: Channel[Int]): Unit & Impure =
    c <- (x + y); ()

/// Computes the sum of 21 and 42 using a fresh process.
def main(_args: Array[String]): Int32 & Impure =
    let c = chan Int 1;     // construct a new empty channel for the result.
    spawn sum(21, 42, c);   // spawn sum to run in a separate process.
    <- c                    // wait for the result to arrive on the channel.

 

多态效应:分离纯代码和不纯代码

Flix 的一个独特之处在于它的多态效果系统。Flix 类型和效果系统干净地分离纯代码和不纯代码。如果表达式是纯表达式,那么它的计算结果总是相同的,并且不会产生副作用。如果一个函数是纯函数,那么当给定相同的参数时,它总是计算为相同的值。

/// A pure function
def sum(x: Int32, y: Int32): Int32 = x + y
/// An impure function
def sayHello(): Unit & Impure = Console.printLine("Hello World")

 

Datalog 约束逻辑编程

Flix 的另一个独特功能是它支持具有一流 Datalog 约束的逻辑编程。Datalog 是一种简单但功能强大的声明式逻辑编程语言,特别适合对图进行递归查询。

 

1
猜你喜欢