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, Fish, and JavaScript.

The following external pages are also useful references for these languages:

Show columns:

taskCommon LispGuile (Scheme)Emacs LispPharo (Smalltalk)FactorRakuPythonSuperColliderLuaBashFishJavaScript
Fundamental Types

When differentiation between false and null is needed, some libraries use the symbol naming the type of the nil value (null).
Booleanst nil#t #ft niltrue falset fTrue FalseTrue Falsetrue falsetrue false0 10 1true false
Special atoms #<unspecified> #<eof> (?) (?)(?)(?)(?) undefined

After defining a symbol with SYMBOL:, it subsequently is referred to with a bareword.

Emacs represents characters with Unicode codepoints, so this code results in 70.

Factor represents characters with Unicode codepoints, so this code results in 70.
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: 1008410084

Factor represents characters with their Unicode codepoints. An array of codepoints can be converted to a string with >string.

Raku does not have a character type; this example uses interpolation to produce a single-character string.

Python does not have a character type; chr returns a single-character string.

SuperCollider only supports ASCII, not Unicode.

JavaScript does not have a character type; this example uses the Unicode character escape sequence to create a single-character string from the codepoint at hex 0x2764 (dec 10084).
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.

Python does not have a character type; this example uses interpolation to produce a single-character string.
Ratio4/34/3(unsupported)4/34/34/3import fractions fractions.Fraction(4, 3)4/3(unsupported)(unsupported)(unsupported)(unsupported)
Sequence (idiomatic)'(1 2 3)'(1 2 3)'(1 2 3)#(1 2 3){ 1 2 3 }[1, 2, 3][1, 2, 3][1, 2, 3]{1, 2, 3}(1 2 3)1 2 3(?)
Linked list'(1 2 3)'(1 2 3)'(1 2 3)| linkedList | linkedList := LinkedList new. linkedList add: 1. linkedList add: 2. linkedList add: 3.

Pharo supports linked lists, but arrays are more idiomatic.
L{ 1 2 3 }

Factor supports 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)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)(?)
Define variable(defvar foo)(define foo)(defvar foo)| foo |SYMBOL: fooour $foo;global foo~foo;local foofoo=set foo(?)
Define variable with initial value(defparameter foo 3)(define foo 3)(defvar foo 3)| foo | foo := 3.SYMBOL: foo 3 foo setour $foo = 3;global foo foo = 3~foo = 3;local foo = 3foo=3set foo 3(?)
Define variable with initial value, not overwriting existing value(defvar foo 3)(define 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 such as 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 endplus_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-funcmy-func(1, 2)my_func(1, 2)my_func.value(1, 2);my_func(1, 2)my_func 1 2my_func 1 2(?)
Print (no newline)(princ "Hello.")(display "Hello.")(message "Hello.")Transcript show: 'Hello.'."Hello." write"Hello.".print;print("Hello.", end="")"Hello.".post;io.write("Hello.")echo -n "Hello."echo -n "Hello."(?)
Print (with newline)(format t "~A~%" "Hello.")(display "Hello.") (newline)(message "%s\n" "Hello.")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)someTest ifTrue: [ thenDoThis ]; ifFalse: [ elseThis ].some-test [ then-do-this ] [ else-this ] ifif some-test { then-do-this } else { else-this }if some_test: then_do_this else: else_thisif(some_test, { then_do_this }, { else_this })if some_test then then_do_this else else_this endif some_test; then then_do_this; else else_this; fiif some_test; then_do_this; else; else_this; end(?)
Get type of datum(type-of datum)(use-modules (oop goops)) (class-of datum)(type-of datum)datum class.datum class-ofdatum.WHATtype(datum)datum.classtype(datum)(unsupported)(unsupported)typeof(datum)
Get object's string representation(format "~S" obj)(format #f "~S" obj)(format "%s" obj)obj storeString."%u" sprintf$obj.rakurepr(obj)obj.cs;tostring(obj)

Lua does not have a built-in way to get a string representation of a table.
Print object's string representation(print obj)(write obj)(message (format "%s" obj))Transcript show: obj.obj .$obj.raku.sayprint(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 $objecho $objconsole.log(obj)
Read a line of text(read-line)(use-modules (ice-9 rdelim)) (read-line)(read-string "Enter some text: ")SpRequestTextDialog new openModal.readlnprompt()input()EZText(action:{ | widget | f = widget.value; widget.window.close; });

SuperCollider's EZText is a graphical text field widget. Its callback action must be set to a function which binds the field's text to a variable (f in this case). 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.
Random integer from 0 below N(random n)(random n)(random n)n atRandom - 1n randomn.rand.Intfrom random import randint randint(0, n - 1)n.randrequire("math") math.random(0, n - 1)$(($RANDOM % $n))random 0 (math $n - 1)Math.floor(Math.random() * n)
Sequence length(length my-sequence)(length my-sequence)(length my-sequence)my_array sizemy-array length@my-array.elemslen(my_list)my_array.size#my_table${#my_list[@]}count $my_listmy_array.length
First sequence element(first my-list)(car my-list)(car my-list)my_array firstmy-array first@my-array.firstmy_list[0]my_array.firstmy_table[1]${my_list[0]}$my_list[1]my_array[0]
Second sequence element(second my-list)(list-ref my-list 1)(cadr my-list)my_array secondmy-array second@my-array[1]my_list[1]my_array[1]my_table[2]${my_list[2]}$my_list[2]my_array[1]
Last sequence element(car (last my-list))(car (last-pair my-list))(car (last my-list))my_array lastmy-array last@my-array.tailmy_list[-1]my_array.lastmy_table[#my_table]${my_list[-1]}$my_list[-1]my_array[my_array.length-1]
Sequence element at index N(nth n my-list)(list-ref my-list n)(nth n my-list)my_array at: nn my-array nth@my-array[n]my_list[n]my_array[n]my_table[n]

Note that Lua tables start from index 1.

Note that Fish lists start from index 1.
First N elements of sequence(subseq my-list 0 n)(list-head my-list n)(subseq my-list 0 n)myList first: n head@my-array.head(n)my_list[:n]my_array.keep(n)table.unpack(my_table, 1, n)"${my_array[@]:0:$n}"$my_list[..$n](?)
Sequence without first N elements(subseq my-list n)(list-tail my-list n)(subseq my-list n)myList allButFirst: nmy-array n tail@my-array[n..*]my_list[n:]my_array[n..]table.unpack(my_table, n+1)(?)$my_list[(math $n + 1)..](?)
Sequence of last N elements(last my-list n)(list-tail my-list (- (length my-list) n))(last my-list n)myList last: nmy-array n tail*@my-array.tail(n)my_list[-n:]my_array.keep(-n)table.unpack(my_table, #my_table-(n-1))(?)$my_list[(math - $n)..](?)
Sequence without last N elements(butlast my-list n)(?)(butlast my-list n)myList allButLast: nmy-array n head*(?)my_list[:-n]my_array.drop(-n)table.unpack(my_table, 1, #my_table-n)(?)$my_list[..(math "-1 * $n - 1")](?)
Sequence subsequence(subseq my-list start end)(?)(subseq my-list start end)myList copyFrom: start to: endstart end my-array subseq@my-array[start..end-1]my_list[start:end]my_array[start..end-1]table.unpack(my_table, start, end)(?)$my_list[start..end](?)
Filter sequence to items true of predicate(remove-if-not pred my-list)(filter pred my-list)(cl-remove-if-not pred my-list)myList select: [ :x | x pred. ].my-array pred filter@my-array.grep(pred)[i for i in my_list if pred(i)]
Filter sequence to items false of predicate(remove-if pred my-list)(filter (lambda (x) (not (pred x))) my-list)(cl-remove-if pred my-list)myList reject: [ :x | x pred. ].my-array pred reject(?)[i for i in my_list if not pred(i)]my_array.reject(pred)(?)(?)(?)(?)
Remove instances of item from sequence(remove item my-list)(?)(cl-remove item my-list)(?)item my-sequence remove(?)[i for i in my_list if i != item]my_array.removeEvery([item])(?)(?)(?)(?)
Test for item in sequence(find item my-list)(member item my-list)(member item my-list)myList includes: item.item my-array member?@my-array.first(pred)item in my_listmy_array.includes(item)(?)(?)contains item $my_list(?)
Get index of item in sequence(position item my-list)(list-index my-list item)(cl-position item my-list)myList indexOf: item.item my-array index(?)my_list.index(item)my_array.indexOf(item)(?)(?)contains --index item $my_list(?)
Get first item in sequence matching predicate(find-if pred my-list)(?)(cl-find-if pred my-list)myList detect: [ :x | x pred. ].my-array pred find

find returns both the matching item and its index; nip can be used to discard the index.
Get index of first element matching predicate(position-if pred my-list)(list-index pred my-list)(cl-find-if pred my-list)(?)my-array pred find

find returns both the matching item and its index; drop can be used to discard the item.
Test if all items in sequence match predicate(every pred my-list)(?)(cl-every pred my-list)(?)my-sequence pred all?(?)(?)my_array.every(pred)(?)(?)(?)(?)
Count occurrences of item in sequence(count item my-list)(?)(cl-count item my-list)myList occurrencesOf: itemmy-sequence [ item = ] count(?)my_list.count(item)my_array.occurrencesOf(item)(?)(?)(?)(?)
Count items in sequence matching predicate(count-if pred my-list)(?)(cl-count-if pred my-list)myList count: predmy-sequence pred count(?)len(list(filter(pred, my_list)))my_array.count(pred)(?)(?)(?)(?)
Apply function to each element, collecting results (map)(mapcar func my-list)(map func my-list)(mapcar func my-list)myList collect: [ :x | func ].my-array func
Combine elements of a sequence with a function (fold/reduce)(reduce func my-list)(reduce func identity my-list)(seq-reduce func my-list identity)myList inject: identity into: funcmy-sequence identity func reducereduce &func, @my-array(?)my_array.reduce(func)(?)(?)(?)(?)
Elements common to two sequences (set intersection)(intersection list-1 list-2)(?)(intersection list-1 list-2)(?)array-1 array-2 intersect(?)(?)array1.sect(array2)(?)(?)(?)(?)
Elements only in the first of two sequences (set difference)(set-difference list-1 list-2)(?)(set-difference list-1 list-2)list1 difference: list2sequence-1 sequence-2 diff(?)(?)array1.difference(array2)(?)(?)(?)(?)
Combine two sequences without duplicates (set union)(union list-1 list-2)(?)(union list-1 list-2)list1 union: list2sequence-1 sequence-2 union(?)(?)array1.union(array2)(?)(?)(?)(?)
Remove duplicates in sequence(remove-duplicates my-list)(?)(cl-remove-duplicates my-list)(?)my-seq members(?)(?)my_array.asSet.asArray

Converting to a set will not preserve the order of elements in the array.
Remove duplicates in sequence, comparing with predicate(remove-duplicates my-list :test pred)(?)(cl-remove-duplicates my-list :test pred)(?)(?)(?)(?)(?)(?)(?)(?)(?)
Reverse sequence(reverse my-list)

Common Lisp also has an nreverse function which reverses in place.
(reverse my-list)(reverse my-list)myArray reversemy-sequence reverse@my-array.reversemy_list.reverse() my_list

Python's list.reverse method reverses in place.

JavaScript also has a .reverse() method which reverses in place.
Sort sequence in natural order(sort my-list #'<)(?)(sort my-list #'<)myList sortedmy-sequence sort(?)(?)my_array.sort(?)(?)(?)my_array.toSorted(pred)
Sort sequence by predicate(sort my-list pred)(?)(sort my-list pred)myList sorted: predmy-sequence pred sort-by(?)(?)my_array.sort(pred)(?)(?)(?)my_array.toSorted(pred)
Unicode string length(length "🤦🏼‍♂️") ; 5(string-length "🤦🏼‍♂️") ; 5(length "🤦🏼‍♂️") ; 5'🤦🏼‍♂️' size. "5""🤦🏼‍♂️" length ! 5"🤦🏼‍♂️".elems # 1len("🤦🏼‍♂️") # 5"🤦🏼‍♂️".size // 17(?)foo='🤦🏼‍♂️'; echo ${#foo} # 5string length "🤦🏼‍♂️" # 5(?)
String concatenation(concatenate 'string "foo" "bar")(string-append "foo" "bar")(concat "foo" "bar")'foo', 'bar'"foo" "bar" append"foo" ~ "bar""foo" + "bar""foo" ++ "bar"(?)"foo""bar""foo""bar"(?)
String subsequence(subseq "foo bar" 0 3)(substring "foo bar" 0 3)(substring "foo bar" 0 3)'foo bar' copyFrom: 1 to: 3.0 3 "foo bar" subseqsubstr("foo bar", 0, 3)"foo bar"[0:3]"foo bar"[0..2](?)(?)string sub -s 1 -e 4 "foo bar"(?)
Hash table(make-hash-table)(make-hash-table)(make-hash-table)Dictionary new8 <hashtable>

<hashtable> requires an initial size.
Hash()(?)Dictionary()(?)declare -A my_hash

bash requires a name for the variable when declaring it a hash.
Hash table literal(unsupported)(?)#s(hash-table data (foo 1 bar 2))(unsupported)H{ { "foo" 1 } { "bar" 2 } }{foo => 1, bar => 2}(?)(foo: 1, bar: 2)

SuperCollider's events (used for this example) do not support looking up keys by strings, so symbols are used.
(?)declare -A my_hash=( [foo]=1 [bar]=2 )(unsupported)(?)
Get the value of key in hash table(gethash "key" hash)(?)(gethash "key" hash)myDict at: keyhash "key" at%hash{"key"}(?)${hash[key]}(unsupported)(?)
Set the value of key in hash table(setf (gethash "key" hash) 9)(?)(puthash "key" 9 hash)myDict at: 'key' put: 99 "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)myDict keyshash keys%hash.keys;(?)hash.keys(?)${!hash[@]}(unsupported)(?)
Define a namespace(defpackage #:my-package ...)(define-module (my-module) ...)(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.
Get the current namespace*package*(current-module)(unsupported)(?)current-vocab(?)(?)currentEnvironment(?)(unsupported)(unsupported)(?)
Set the current namespace(in-package #:my-package)(set-current-module (resolve-module '(my-module)))(unsupported)(?)IN: my-vocab

IN: will also create the vocabulary if it doesn't already exist.
Use a namespace(use-package #:other-package)(use-modules (my-module) ...)(unsupported)(?)USE: other-vocabuse MyModule;(?)env.use(func)

In this example, env is the environment (namespace) being used, and func is the function being evaluated in that environment.