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.

1def quine(): Unit\
2 IO = {
3 let xs:List[String] = List#{
4 "def quine(): Unit",
5 " IO = {",
6 " let xs:List[String] = List#{",
7 " };",
8 " let join = String.flatten;",
9 " let get = List.slice;",
10 " let len = List.length;",
11 " let cp2v = c ->",
12 " match CodePoint.toChars(c) {",
13 " case Some(v) => v",
14 " case None => Vector#{}};",
15 " let st = x ->",
16 " cp2v(x) |> Vector.get(0) |> Char.toString;",
17 " let (qte, comma, bslash, space) =",
18 " (st(0x0022), st(0x002C), st(0x005C), st(0x0020));",
19 " let pad = join(space::space::space::space::Nil);",
20 " let quote = x ->",
21 " join(pad::pad::qte::x::qte::Nil);",
22 " let quoteComma =",
23 " x -> join(pad::pad::qte::x::qte::comma::Nil);",
24 " let firstLine =",
25 " join(get({start=0}, {end=1}, xs) ::: bslash::Nil);",
26 " firstLine |> println;",
27 " foreach(",
28 " line <- get({start=1}, {end=3}, xs))",
29 " line |> println;",
30 " foreach(",
31 " line <- get({start=0},{end=len(xs)-1}, xs))",
32 " quoteComma(line) |> println;",
33 " foreach(",
34 " line <- get({start=len(xs)-1},{end=len(xs)}, xs))",
35 " quote(line) |> println;",
36 " foreach(",
37 " line <- get({start=3}, {end=len(xs)}, xs))",
38 " line |> println",
39 "}"
40 };
41 let join = String.flatten;
42 let get = List.slice;
43 let len = List.length;
44 let cp2v = c ->
45 match CodePoint.toChars(c) {
46 case Some(v) => v
47 case None => Vector#{}};
48 let st = x ->
49 cp2v(x) |> Vector.get(0) |> Char.toString;
50 let (qte, comma, bslash, space) =
51 (st(0x0022), st(0x002C), st(0x005C), st(0x0020));
52 let pad = join(space::space::space::space::Nil);
53 let quote = x ->
54 join(pad::pad::qte::x::qte::Nil);
55 let quoteComma =
56 x -> join(pad::pad::qte::x::qte::comma::Nil);
57 let firstLine =
58 join(get({start=0}, {end=1}, xs) ::: bslash::Nil);
59 firstLine |> println;
60 foreach(
61 line <- get({start=1}, {end=3}, xs))
62 line |> println;
63 foreach(
64 line <- get({start=0},{end=len(xs)-1}, xs))
65 quoteComma(line) |> println;
66 foreach(
67 line <- get({start=len(xs)-1},{end=len(xs)}, xs))
68 quote(line) |> println;
69 foreach(
70 line <- get({start=3}, {end=len(xs)}, xs))
71 line |> println
72}

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: