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.