100 Languages Speedrun: Episode 91: Arturo

Arturo is an another attempt at creating a minimal programming language.

I don't think it saw any use other than by its author yet, but it has a homebrew package (brew install arturo) and even VSCode extension, so let's give it a try!

Hello, World!

We can start with the very obvious Hello, World! program.

This identical program works in so many languages, they mostly differ in newline being included or not, and if you need parentheses or if they're optional.

#!/usr/bin/env arturo

print "Hello, World!"
$ ./hello.art
Hello, World!

Obnoxiously, Arturo prints Windows \r\n newlines even on OSX.

Arturo also has REPL with arturo. It annoyingly erases the whole screen and prints massive banner, and also only quits on Ctrl-C instead of Ctrl-D. These might sound like minor issues, but they're highly disruptive if you want to get into and out of repl. REPL should not mess the screen, it should only show prompt (maybe one line for version etc., but I'd recommend against it) and quit on Ctrl-D. Not following these basic rules is wrong.

Operator Precedence

Like many other minimalist languages, Arturo makes the same mistake of not having operator precedence. However unlike every single one of them which then evaluates left to right, Arturo evaluates right to left, possibly the world's only such language.

Of course I'd strongly advise even "minimalistic" languages to get their shit together and implement proper operator precedence. A lot of languages like Smalltalk's progeny had to undo this madness, and this is always more painful than getting it right in the first place.

#!/usr/bin/env arturo

print 2 * 3 + 4

It prints an answer that's not 10:

$ ./math.art
14

In practice this system just means parentheses everywhere, as it's not possible to overcome decades of math education like that for no reason, and without parnetheses everywhere you'll constantly be reading everything incorrectly.

Variables

Arturo variables are wild:

#!/usr/bin/env arturo

a: 1
b: 1
c: new 1

inc 'a

print a
print b
print c

What do you think this prints?

$ ./variables.art
2
2
1

WTF just happened? It goes beyond "modifying string literals" problem, we're modifying integer literals, and it wasn't even the same literal.

We can fix it by new, but I'm completely baffled by why anyone even thought to make them work like this.

FizzBuzz

We can do it with if? condition [then-block] else [else-block]:

#!/usr/bin/env arturo

loop 1..100 'n [
  print [
    if? 0 = n % 3 [
      if? 0 = n % 5 ["FizzBuzz"] else ["Fizz"]
    ] else [
      if? 0 = n % 5 ["Buzz"] else [n]]
    ]
  ]
]

Fibonacci

Arturo has string interpolation, with yet another syntax. If someone was interested in collecting all the variants, maybe there's a 100 string interpolation syntaxes by now.

It's also really damn slow, even this fib 1-20 takes 2s, fib 1-30 takes 4 minutes. By comparison Python does 1-30 fib in less than a second. So we're talking about 300x slower than Python.

#!/usr/bin/env arturo

fib: function [n] [
  if? n =< 2 [1] else [(fib (n - 1)) + (fib (n - 2))]
]

loop 1..20 'n [
  print ~"fib(|n|) = |fib n|"
]
$ ./fib.art
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8
fib(7) = 13
fib(8) = 21
fib(9) = 34
fib(10) = 55
fib(11) = 89
fib(12) = 144
fib(13) = 233
fib(14) = 377
fib(15) = 610
fib(16) = 987
fib(17) = 1597
fib(18) = 2584
fib(19) = 4181
fib(20) = 6765

Unicode

Arturo correctly handles Unicode:

#!/usr/bin/env arturo

print upper "Żółw"
print lower "Żółw"
print size "Żółw"
print size "🍰"
$ ./unicode.art
ŻÓŁW
żółw
4
1

Maybe

Blocks are passed as variables, and we can just execute them with do. In this example passing f instead of [do f] would also have worked.

#!/usr/bin/env arturo

maybe: function [f] [
  if 0 = random 0 1 [do f]
]

loop 1..20 'n [
  maybe [print n]
]
$ ./maybe.art
1
2
4
6
8
9
12
16

Wordle

Wordle is becoming the FizzBuzz of this series, so let's do one for Arturo as well.

By the way if you want to do a similar series, I think Wordle is a great toy problem, as it does file reading, string manipulation, user input, looping, Unicode, randomness, and all in very small amount of code.

Wordle in Arturo is quite decent:

#!/usr/bin/env arturo

words: split.words read "wordle-answers-alphabetical.txt"
word: words\[random 0 ((size words) - 1)]

guess: ""
while [guess <> word] [
  guess: input "Guess: "
  if? 5 <> size guess
    [print "Guess must be 5 letters long."]
  else [
    loop 0..4 'n [
      case []
        when? [guess\[n] = word\[n]] [prints "🟩"]
        when? [contains? word guess\[n]] [prints "🟨"]
        else [prints "🟥"]
    ]
    prints "\n"
  ]
]
$ ./wordle.art
Guess: arise
🟥🟥🟩🟩🟩
Guess: noise
🟥🟥🟩🟩🟩
Guess: guise
🟩🟩🟩🟩🟩

prints is the non-newline version of print and case is what Arturo has instead of if/elsif/else chains.

Should you use Arturo?

I don't recommend it.

If you try Arturo, operator precedence is likely going to be a huge pain, Arturo makes so many baffling design cohices, and it doesn't provide good feedback if you make mistakes.

If you want a minimalistic language to play with, I'd recommend starting with Ioke or Brat. If you tried them already, and want to try something else, then I guess Arturo is an option for another weekend.

Code

All code examples for the series will be in this repository.

Code for the Arturo episode is available here.