code equivalences
This table showcases how to do various common tasks in a few different programming languages. Similar to Rosetta Code but may work better as a quick reference.
The currently covered languages are: Common Lisp, Guile (Scheme), Emacs Lisp, Pharo (Smalltalk), Factor, Raku, Python, SuperCollider, Lua, Bash, and Fish.
The following external pages are also useful references for these languages:
- Common Lisp Cheat Sheet
- Common Lisp vs. Scheme
- Pharo syntax in a nutshell
- Raku syntax
- Learning Raku from Python, in a nutshell
Show columns:
action | Common Lisp | Guile (Scheme) | Emacs Lisp | Pharo (Smalltalk) | Factor | Raku | Python | SuperCollider | Lua | Bash | Fish |
---|---|---|---|---|---|---|---|---|---|---|---|
Null | nil When differentiation between false and null is needed, some libraries use the symbol naming the type of the nil value ( null ). | #nil | nil | nil | f | Nil | None | nil | nil | (?) | (?) |
Booleans | t nil | #t #f | t nil | true false | t f | True False | True False | true false | true false | 0 1 | 0 1 |
Symbol | 'heyo | 'heyo | 'heyo | #heyo | heyo After defining a symbol with SYMBOL: , it subsequently is referred to with a bareword. | heyo | (unsupported) | \heyo | (unsupported) | (unsupported) | (unsupported) |
String | "Foo" | "Foo" | "Foo" | 'Foo' | "Foo" | "Foo" | "Foo" | "Foo" | "Foo" | "Foo" | "Foo" |
Character | #\F | #\F | ?F Emacs represents characters with Unicode codepoints, so this code results in 70 . | $F | CHAR: F | "F" Raku does not have a character type; this example is a single-character string. | "F" Python does not have a character type; this example is a single-character string. | $F | (unsupported) | (unsupported) | (unsupported) |
Unicode character (by codepoint) | (code-char 10084) | (integer->char 10084) | 10084 Emacs represents characters with Unicode codepoints. A list of codepoints can be converted to a string with concat . | Character codePoint: 10084 | 10084 Factor represents characters with their Unicode codepoints. An array of codepoints can be converted to a string with >string . | "\c[10084]" Raku does not have a character type; this example uses interpolation to produce a single-character string. | chr(10084) Python does not have a character type; chr returns a single-character string. | (?) | (unsupported) | (unsupported) | (unsupported) |
Unicode character (by name) | #\HEAVY_BLACK_HEART | (use-modules (ice-9 unicode))
(formal-name->char "HEAVY BLACK HEART") | ?\N{HEAVY BLACK HEART} Emacs represents characters as Unicode codepoints, so this code results in 10084 . | (UnicodeCharacterData named: 'HEAVY BLACK HEART') character This example requires the Unicode-Character-DataUnicode-Character-Data external library. Unicode characters can be looked up by their code point in stock Pharo using code like Character codePoint: 10084 . | CHAR: heavy-black-heart Factor represents characters as Unicode codepoints, so this code results in 10084 . | "\c[heavy black heart]" Raku does not have a character type; this example uses interpolation to produce a single-character string. | \N{HEAVY BLACK HEART} Python does not have a character type; this example uses interpolation to produce a single-character string. | (?) | (unsupported) | (unsupported) | (unsupported) |
Ratio | 4/3 | 4/3 | (unsupported) | 4/3 | 4/3 | 4/3 | import fractions
fractions.Fraction(4, 3) | 4/3 | (unsupported) | (unsupported) | (unsupported) |
List | '(1 2 3) | '(1 2 3) | '(1 2 3) | (?) | L{ 1 2 3 } Factor supports Lisp-style linked lists, but arrays are more idiomatic. | (1, 2, 3) | from collections import deque
deque([1, 2, 3]) | List.newUsing([1, 2, 3]) | (unsupported) | (unsupported) | (unsupported) |
Array | #(1 2 3) | #(1 2 3) | [1 2 3] | #(1 2 3) | { 1 2 3 } | [1, 2, 3] | [1, 2, 3] Python refers to its arrays as lists, however they are not traditional linked lists a la Lisp. | [1, 2, 3] | {1, 2, 3} Lua uses tables as both arrays and as hashtables. | (?) | 1 2 3 |
Comment | ; Do something. | ; Do something. | ; Do something. | "Do something." | ! Do something. | # Do something. | # Do something. | // Do something. | -- Do something. | # Do something. | # Do something. |
Multi-line comment | #| hello line 1
hello line 2 |# | #! hello line 1
hello line 2 !# | (unsupported) | "hello line 1
hello line 2" | USE: multiline
/* hello line 1
hello line 2 */ Factor supports a syntax that resembles multi-line comments, but single line comments (with !) are much more common. | #`( hello line 1
hello line 2 ) | """hello line 1
hello line 2""" | /* hello line 1
hello line 2 */ | --[[ hello line 1
hello line 2 ]] | (unsupported) | (unsupported) |
Math | (* (+ 1 3) 4) | (* (+ 1 3) 4) | (* (+ 1 3) 4) | 1 + 3 * 4. | 1 3 + 4 * | (1 + 3) * 4; | (1 + 3) * 4 | 1 + 3 * 4 | (1 + 3) * 4 | $(((1 + 3) * 4)) | math '(1 + 3) * 4' |
Define variable | (defvar foo) | (define foo) | (defvar foo) | | foo | | SYMBOL: foo | our $foo; | global foo | ~foo; | local foo | foo= | set foo |
Define variable with initial value | (defparameter foo 3) | (define foo 3) | (defvar foo 3) | | foo |
foo := 3. | SYMBOL: foo 3 foo set | our $foo = 3; | global foo
foo = 3 | ~foo = 3; | local foo = 3 | foo=3 | set foo 3 |
Define variable with initial value, not overwriting existing value | (defvar foo 3) | (?) | (defvar foo 3) | (unsupported) Pharo does not allow referencing undefined variables, and all defined variables default to nil . | SYMBOL: foo
foo [ 3 ] initialize | (unsupported) Raku has the //= operator, which sets a variable's value only if it is not already set, but this doesn't seem to work when combined with variable declarations with my or our. | (?) | ~foo = ~foo ? 3; Variables default to nil, and the ? operator returns the first non-nil value. | (?) | (?) | (?) |
Anonymous function (lambda) | (lambda (x y) (+ x y)) | (lambda (x y) (+ x y)) | (lambda (x y) (+ x y)) | [ :x :y | x + y ] | [ + ] | sub ($x, $y) { $x + $y } | lambda x, y: x + y | { | x y | x + y; } | function (x, y) x + y end | (unsupported) | (unsupported) |
Define function | (defun plus-3 (x) (+ x 3)) | (define (plus-3 x) (+ x 3)) | (defun plus-3 (x) (+ x 3)) | | plus_3 |
plus_3 := [ :x | x + 3 ] Typically, functions are defined as methods in a class rather than as blocks (anonymous functions) as shown here. | : plus-3 ( x -- y ) 3 + ; | sub plus-3($x) { return $x + 3; } | def plus_3(x): return x + 3 | ~plus_3 = { | x | x + 3; }; | function plus_3(x) x + 3 end | plus_3() { echo $(($1 + 3)); } | function plus_3; math $x + 3; end |
Call function with arguments | (funcall my-func 1 2) | (my-func 1 2) | (funcall my-func 1 2) | my_func value: 1 value: 2. | 1 2 my-func | my-func(1, 2) | my_func(1, 2) | my_func.value(1, 2); | my_func(1, 2) | my_func 1 2 | my_func 1 2 |
Print (no newline) | (princ "Hello.") | (display "Hello.") | (message "Hello.") | Transcript show: 'Hello.'. | "Hello." write | "Hello.".print; | print("Hello.", end="") | "Hello.".post; | (?) | echo -n "Hello." | echo -n "Hello." |
Print (with newline) | (format t "~A~%" "Hello.") | (display "Hello.")
(newline) | (?) | Transcript show: 'Hello.'; cr. | "Hello." print | "Hello.".say; | print("Hello.") | "Hello.".postln; | print("Hello.") | echo "Hello." | echo "Hello." |
If statement | (if some-test then-do-this else-this) | (if some-test then-do-this else-this) | (if some-test then-do-this else-this) | (?) | some-test [ then-do-this ] [ else-this ] if | if some-test { then-do-this } else { else-this } | if some_test:
then_do_this
else:
else_this | (?) | if some_test then then_do_this else else_this end | if some_test; then then_do_this; else else_this; fi | if some_test; then_do_this; else; else_this; end |
Get object's string representation | (format "~S" obj) | (?) | (format "%s" obj) | (?) | "%u" sprintf | $obj.raku | (?) | obj.cs; | (?) | (?) | (?) |
Print object's string representation | (print obj) | (?) | (message (format "%s" obj)) | Transcript show: obj. | obj . | $obj.raku.say | print(obj) | obj.postcs; | print(obj) Lua's print will not print the contents of tables or other compound objects; this functionality has to be implemented by the user. For tables, it can be done with for key, value in pairs(obj) do print(key, value) end | (?) | echo $obj |
Read a line of text | (read-line) | (use-modules (ice-9 rdelim))
(read-line) | (read-string "Enter some text: ") | SpRequestTextDialog new openModal. | readln | prompt() | input() | (?) | require('io'); io.read() | read var bash's read should be called with a variable name to specify where to write the text into. Without it, text is read, but discarded. | read |
Sequence length | (length my-sequence) | (length my-sequence) | (length my-sequence) | my_array size | my-array length | @my-array.elems | len(my_list) | my_list.size | #my_table | ${#my_list[@]} | count $my_list |
First sequence element | (first my-list) | (car my-list) | (car my-list) | my_array first | my-array first | @my-array.first | my_list[0] | my_list.first | my_table[1] | ${my_list[0]} | $my_list[1] |
Second list element | (second my-list) | (list-ref my-list 1) | (cadr my-list) | my_array second | my-array second | @my-array[1] | my_list[1] | my_list[1] | my_table[2] | ${my_list[2]} | $my_list[2] |
Last list element | (car (last my-list)) | (car (last-pair my-list)) | (car (last my-list)) | my_array last | my-array last | @my-array.tail | my_list[-1] | my_list.last | my_table[#my_table] | ${my_list[-1]} | $my_list[-1] |
List element at index N | (nth n my-list) | (list-ref my-list n) | (nth n my-list) | my_array at: n | n my-array nth | @my-array[n] | my_list[n] | my_list[n] | my_table[n] Note that Lua tables start from index 1. | ${my_list[n]} | $my_list[n] Note that Fish lists start from index 1. |
List of first N elements | (subseq my-list 0 n) | (list-head my-list n) | (subseq my-list 0 n) | (?) | my-array n head | @my-array.head(n) | my_list[:n] | my_list.keep(n) | (?) | (?) | $my_list[..$n] |
List without first N elements | (subseq my-list n) | (list-tail my-list n) | (subseq my-list n) | (?) | my-array n tail | @my-array[n..*] | my_list[n:] | my_list[n..] | (?) | (?) | $my_list[(math $n + 1)..] |
List of last N elements | (last my-list n) | (?) | (?) | (?) | my-array n tail* | @my-array.tail(n) | my_list[-n:] | my_list.keep(-n) | (?) | (?) | $my_list[(math - $n)..] |
List without last N elements | (butlast my-list n) | (?) | (butlast my-list n) | (?) | my-array n head* | (?) | my_list[:-n] | my_list.drop(-n) | (?) | (?) | $my_list[..(math "-1 * $n - 1")] |
List subsequence | (subseq my-list start end) | (?) | (subseq my-list start end) | (?) | start end my-array subseq | (?) | my_list[start:end] | my_list[start..end-1] | (?) | (?) | (?) |
Filter list to items true of predicate | (remove-if-not pred my-list) | (filter pred my-list) | (?) | (?) | my-array pred filter | @my-array.grep(pred) | [i for i in my_list if pred(i)] | my_list.select(pred) | (?) | (?) | (?) |
Filter list to items false of predicate | (remove-if pred my-list) | (filter pred my-list) | (cl-remove-if pred my-list) | (?) | my-array pred reject | (?) | [i for i in my_list if not pred(i)] | my_list.reject(pred) | (?) | (?) | (?) |
Test for item in list | (find item my-list) | (member item my-list) | (member item my-list) | (?) | item my-array member? | @my-array.first(pred) | (?) | my_array.includes(item) | (?) | (?) | contains item $my_list |
Get index of item in list | (position item my-list) | (?) | (cl-position item my-list) | (?) | item my-array index | (?) | (?) | my_array.indexOf(item) | (?) | (?) | contains --index item $my_list |
Get first item in list matching predicate | (find-if pred my-list) | (?) | (?) | (?) | my-array pred find find returns both the matching item and its index; nip can be used to discard the index. | @my-array.first(pred) | (?) | my_array.detect(pred) | (?) | (?) | (?) |
Test if all items in list match predicate | (every pred my-list) | (?) | (cl-every pred my-list) | (?) | (?) | (?) | (?) | (?) | (?) | (?) | (?) |
Get index of first element matching predicate | (position-if pred my-list) | (list-index pred my-list) | (?) | (?) | my-array pred find find returns both the matching item and its index; drop can be used to discard the item. | (?) | (?) | my_array.detectIndex(pred) | (?) | (?) | (?) |
Apply function to each list element and collect each result into a list (map) | (mapcar func my-list) | (?) | (mapcar func my-list) | (?) | my-array func map | @my-array.map(func) | (?) | my_array.collect(func) | (?) | (?) | (?) |
Combine elements of a sequence with a function (fold/reduce) | (reduce func my-list) | (reduce func identity my-list) | (?) | (?) | my-sequence identity func reduce | reduce &func, @my-array | (?) | my_array.reduce(func) | (?) | (?) | (?) |
Elements common to two lists (set intersection) | (intersection list-1 list-2) | (?) | (intersection list-1 list-2) | (?) | array-1 array-2 intersect | (?) | (?) | (?) | (?) | (?) | (?) |
Elements only in the first of two sequences (set difference) | (set-difference list-1 list-2) | (?) | (set-difference list-1 list-2) | (?) | sequence-1 sequence-2 diff | (?) | (?) | (?) | (?) | (?) | (?) |
Combine two sequences without duplicates (set union) | (remove-duplicates (append list-1 list-2)) | (?) | (union list-1 list-2) | (?) | sequence-1 sequence-2 union | (?) | (?) | (?) | (?) | (?) | (?) |
Unicode string length | (length "🤦🏼♂️") ; 5 | (string-length "🤦🏼♂️") ; 5 | (length "🤦🏼♂️") ; 5 | '🤦🏼♂️' size. "5" | "🤦🏼♂️" length ! 5 | "🤦🏼♂️".elems # 1 | len("🤦🏼♂️") # 5 | "🤦🏼♂️".size // 17 | (?) | (?) | (?) |
String subsequence | (subseq "foo bar" 0 3) | (substring "foo bar" 0 3) | (substring "foo bar" 0 3) | (?) | (?) | (?) | "foo bar"[0:3] | (?) | (?) | (?) | (?) |
Hash table | (make-hash-table) | (?) | (make-hash-table) | (?) | 8 <hashtable> <hashtable> requires an initial size. | Hash() | (?) | Dictionary() | (?) | declare -A my_hash bash requires a name for the variable when declaring it a hash. | (unsupported) |
Hash table literal | (unsupported) | (?) | #s(hash-table data (foo 1 bar 2)) | (?) | H{ { "foo" 1 } { "bar" 2 } } | {foo => 1, bar => 2} | (?) | (?) | (?) | declare -A my_hash=( [foo]=1 [bar]=2 ) | (unsupported) |
Get the value of key in hash table | (gethash "key" hash) | (?) | (gethash "key" hash) | (?) | hash "key" at | %hash{"key"} | (?) | hash.at(key) | (?) | ${hash[key]} | (unsupported) |
Set the value of key in hash table | (setf (gethash "key" hash) 9) | (?) | (puthash "key" 9 hash) | (?) | 9 "key" hash set-at | %hash{"key"} = 9; | (?) | hash.put(key, 9) | (?) | hash[key]=9 | (unsupported) |
Get list of keys in hash table | (loop for key being the hash-keys of hash collect key) | (?) | (hash-table-keys hash) | (?) | hash keys | %hash.keys; | (?) | hash.keys | (?) | ${!hash[@]} | (unsupported) |
Define a namespace | (defpackage #:my-package ...) | (?) | (unsupported) | (?) | "my-vocab" create-vocab Typically new vocabularies (namespaces) are defined with IN:, which also sets the current active vocabulary, simply switching to it if it already exists. | (?) | (?) | (?) | (?) | (unsupported) | (unsupported) |
Get the current namespace | *package* | (?) | (unsupported) | (?) | current-vocab | (?) | (?) | (?) | (?) | (unsupported) | (unsupported) |
Set the current namespace | (in-package #:my-package) | (?) | (unsupported) | (?) | IN: my-vocab IN: will also create the vocabulary if it doesn't already exist. | (?) | (?) | (?) | (?) | (unsupported) | (unsupported) |
Use a namespace | (use-package #:other-package) | (?) | (unsupported) | (?) | USE: other-vocab | (?) | (?) | (?) | (?) | (unsupported) | (unsupported) |