drcabana.org
Computational divertissements


A quine in Flix

Posted on

One of my standard exercises when learning a new programming language is to write a quine. Here is a Flix language quine.

def quine(): Unit\
    IO = {
    let xs:List[String] = List#{
        "def quine(): Unit",
        "    IO = {",
        "    let xs:List[String] = List#{",
        "    };",
        "    let join = String.flatten;",
        "    let get = List.slice;",
        "    let len = List.length;",
        "    let cp2v = c ->",
        "        match CodePoint.toChars(c) {",
        "            case Some(v) => v",
        "            case None => Vector#{}};",
        "    let st = x ->",
        "        cp2v(x) |> Vector.get(0) |> Char.toString;",
        "    let (qte, comma, bslash, space) =",
        "        (st(0x0022), st(0x002C), st(0x005C), st(0x0020));",
        "    let pad = join(space::space::space::space::Nil);",
        "    let quote = x ->",
        "        join(pad::pad::qte::x::qte::Nil);",
        "    let quoteComma =",
        "        x -> join(pad::pad::qte::x::qte::comma::Nil);",
        "    let firstLine =",
        "        join(get({start=0}, {end=1}, xs) ::: bslash::Nil);",
        "    firstLine |> println;",
        "    foreach(",
        "        line <- get({start=1}, {end=3}, xs))",
        "        line |> println;",
        "    foreach(",
        "        line <- get({start=0},{end=len(xs)-1}, xs))",
        "        quoteComma(line) |> println;",
        "    foreach(",
        "        line <- get({start=len(xs)-1},{end=len(xs)}, xs))",
        "        quote(line) |> println;",
        "    foreach(",
        "        line <- get({start=3}, {end=len(xs)}, xs))",
        "        line |> println",
        "}"
    };
    let join = String.flatten;
    let get = List.slice;
    let len = List.length;
    let cp2v = c ->
        match CodePoint.toChars(c) {
            case Some(v) => v
            case None => Vector#{}};
    let st = x ->
        cp2v(x) |> Vector.get(0) |> Char.toString;
    let (qte, comma, bslash, space) =
        (st(0x0022), st(0x002C), st(0x005C), st(0x0020));
    let pad = join(space::space::space::space::Nil);
    let quote = x ->
        join(pad::pad::qte::x::qte::Nil);
    let quoteComma =
        x -> join(pad::pad::qte::x::qte::comma::Nil);
    let firstLine =
        join(get({start=0}, {end=1}, xs) ::: bslash::Nil);
    firstLine |> println;
    foreach(
        line <- get({start=1}, {end=3}, xs))
        line |> println;
    foreach(
        line <- get({start=0},{end=len(xs)-1}, xs))
        quoteComma(line) |> println;
    foreach(
        line <- get({start=len(xs)-1},{end=len(xs)}, xs))
        quote(line) |> println;
    foreach(
        line <- get({start=3}, {end=len(xs)}, xs))
        line |> println
}

If you want to run this code you likely want to grab it as a gist.

The code follows the quine generation approach I describe here and here, adapted to the syntax of the Flix language.

I did not put any comments in the code itself, but some remarks are in order: