Arrays - Uiua Docs
Arrays - Uiua Docs
Arrays
Uiua is, first and foremost, an array language. The only composite data type
is the multidimensional array. Arrays have a lot of nice properties, and the
language's built-in functions are designed to make it easy to work with them.
If you've only ever programmed in non-array languages, then this will be a
completely foreign paradigm. In most array languages, most data structures
and control flow are replaced with operations on arrays.
Creating Arrays
Other than with functions, Uiua has two ways to create arrays. They are called
strand notation and stack notation.
1 1_2_3 � ↧ �
[1 2 3] Run
1 "Hello"_"World" � ↧ �
╭─ Run
╷ "Hello"
"World"
╯
Strand notation is good when you want to create short and/or simple arrays.
For longer or more complex arrays, you can use stack notation.
1 [1 2 3] � ↧ �
[1 2 3] Run
1 [¯5 37 42 π] � ↧ �
[¯5 37 42 π] Run
What's cool about stack notation is that it is not just a way to list elements.
The code between the brackets runs from right to left as it normally would.
When it is done, any items on the stack higher than when it started are put
into the array. This gives you some cool ways to create arrays.
1 [...5] � ↧ �
[5 5 5 5] Run
1 [×2.×2.×2.×2 .2] � ↧ �
[32 16 8 4 2] Run
1 [+1 2 +3 4] � ↧ �
[3 7] Run
Any functions inside the brackets will "pull in" their arguments from outside if
there are not enough inside.
1 [+] 1 9 � ↧ � 1/3
1 [...] 7 � ↧ � 1/2
1 [1_2_3 4_5_6] � ↧ �
╭─ Run
╷ 1 2 3
4 5 6
╯
1 [...[1 2 3]] � ↧ �
╭─ Run
╷ 1 2 3
1 2 3
1 2 3
1 2 3
╯
Unlike strand notation, stack notation may span multiple lines. The lines are
still executed right-to-left, but they are executed bottom-to-top so that the
arrays come out the same way they look in the code.
1 [1 2 3 � ↧ �
2 4 5 6
3 7 8 9]
[1 2 3 4 5 6 7 8 9] Run
1 [[1 2 3] � ↧ �
2 [4 5 6]
3 [7 8 9]]
╭─ Run
╷ 1 2 3
4 5 6
7 8 9
╯
More precisely, stack notation ⊟ couple s the first two stack items created
between the [] s and ⊂ join s the rest to that coupling. You may see this
refered to in error messages.
Other than their data, arrays also have a property called their shape. Shape is
a list of non-negative integers that describes the array's size along each of its
axes.
We can get the array's shape with the △ shape function. It's a triangle
because a triangle is a shape.
1 △[1 2 3] � ↧ � 1/2
1 △5 � ↧ � 1/2
While there are not common names for arrays with 3 or more dimensions,
Uiua supports arrays with an arbitrary number of axes.
The first element of the shape is the number of rows of the array. Rows does
not refer just to the rows of a matrix or table. It is the groups of elements
along the leading axis of the array. For lists, this is just the individual
elements. For matrices, it is the rows as you might traditionally think of them.
But arrays with a higher number of dimensions have rows as well. For
example, in an array with 3 dimensions, each row is a matrix.
From shape we can derive two closely-related properties called length and
rank.
⧻ length is the number of rows in the array. Length is always equal to the
first number in the shape (or 1 if the shape is empty).
The online editor and native interpreter both pretty-print any values that
remain on the stack when a program is finished. (This can be invoked
manually using the &s function.)
12 13 14 15
16 17 18 19
20 21 22 23
╯
This expands to any number of dimensions. The more dimensions, the more
space between the cells representing earlier axes.
20 21 22 23 24
25 26 27 28 29
30 31 32 33 34
35 36 37 38 39
40 41 42 43 44
45 46 47 48 49
50 51 52 53 54
55 56 57 58 59
╯
Pervasion
Most operations that apply to scalars are what is called pervasive when it
comes to arrays. This means that the operation automatically applies to every
item in the array.
1 +1 1_2_3 � ↧ � 1/3
When doing a pervasive operation on two arrays, the shape of one array
must be the prefix of the shape of the other.
1 +[1 2] [3 4 5] � ↧ � 1/3
Error: Shapes [2] and [3] are not Run < >
compatible
at 1:1
1 | +[1 2] [3 4 5]
─
Notice here that the shape of the first array is a prefix of the shape of the
second array.
1 △10_20 � ↧ � 1/7
2 △[3_4_5 6_7_8]
3 +10_20 [3_4_5 6_7_8]
[2] Run < >
[2 3]
╭─
╷ 13 14 15
26 27 28
╯
1 ⬚10+ [1 2] [3 4 5 6 7] � ↧ � 1/3
⬚ fill can be used in a lot of other cases. See its documentation for more.
You don't need to memorize all of these right now. This is just a brief
introduction to some of the array operations so that you won't be surprised
when you see them later.
If you ever see a glyph that you don't recognize in an example, you can hold
ctrl/⌘ and mouse over it in the editor to learn its name.
You can ctrl/⌘-click any glyph in the editor to see its documentation.
You can also click the names of functions in the site text to see their
documentation.
1 ⊟ 1_2_3 [4 5 6] � ↧ � 1/3
1 ⊢ [4 7 1] � ↧ � 1/2
1 ⊣ "hello" � ↧ � 1/2
1 ⇌ [4 7 1] � ↧ � 1/2
1 ↻2 [1 2 3 4 5] � ↧ � 1/3
1 ↙3 [1 2 3 4 5] � ↧ � 1/6
2 ↘3 [1 2 3 4 5]
[1 2 3] Run < >
[4 5]
⊡ pick indexes an array. Longer indices index deeper into the array.
Uiua is 0-indexed.
1 ⊡2 [3 8 4 1] � ↧ � 1/3
1 ⊏ [0 2 1 1 2] ↯3_3⇡9 � ↧ � 1/6
For curious array aficionados, Uiua uses an array model resembling J's Boxed
array model.
All arrays are flat and homogenous. Arrays always have a rectangular shape,
meaning that all rows along an axis always have the same length. Different
types of data, like numbers and characters, cannot be mixed in the same
array.
However, there is an escape hatch for when you really want jagged, nested, or
mixed-type arrays. In Uiua, an array of heterogeneous values can be
simulated with an array of boxes.
The array below cannot be constructed normally because its rows have
different △ shape s.
1 [1 2 [7 8 9]] � ↧ �
By using □ box , we can turn any value into a box that contains that value.
We can then put these boxes into an array together.
{1 2 [7 8 9]} Run
The {} s in the output hint at some syntax that will be introduced shortly.
1 □"banana" � ↧ � 1/2
Nested Arrays
Uiua has a special syntax for making arrays where every item is □ box ed.
1 {1 2 [7 8 9]} � ↧ �
{1 2 [7 8 9]} Run
Pervasive functions work through boxes and preserve the maximum □ box
depth of their arguments.
1 ¯ 1 � ↧ � 1/9
2 ¯ □1
3 ¯ □□1
¯1 Run < >
□¯1
□□¯1
1 +1 4 � ↧ � 1/18
2 +1 □4
3 +1 □□4
4 +□□1 □4
5 Run < >
□5
□□5
□□5
For more about working with box arrays, see □ box 's documentation.
Challenges
Challenge 1
1 � ↧ �
Run
Example: 1_2_5
[6 4 6]
Input: 3_1_7
[3 1 7]
Input: ↯2_4⇡8
╭─
╷ 0 1 2 3
4 5 6 7
╯
Input: 5
5
Challenge 2
Write a program that creates a matrix of 0's with as many rows as the first
argument and as many columns as the second argument.
1 � ↧ �
Run
Example: 3 4
╭─
╷ 0 0 0 0
0 0 0 0
0 0 0 0
╯
Input: 2 7
7
2
Input: 3 3
3
3
Input: 1 8
8
1
Challenge 3
1 � ↧ �
Run
Example: [1 2 3]
╭─
╷ 1 2 3
╯
Input: 1_3_1_5
[1 3 1 5]
Input: 5
5
Input: ↯2_3⇡6
╭─
╷ 0 1 2
3 4 5
╯
��
Challenge 4
Write a program that prepends the first row of the first argument to the
second argument.
1 � ↧ �
Run
Example: [1 2 3] 4_5_6
[1 4 5 6]
Input: 3_3 2_2
[2 2]
[3 3]
Input: [2 4 3] [9 9 9 9 9 1]
[9 9 9 9 9 1]
[2 4 3]
Challenge 5
Write a program that splits an array into its first row and the rest of its
rows.
1 � ↧ �
Run
Example: 1_2_3_4
[2 3 4]
1
Input: [27 9 3 1]
[27 9 3 1]
Input: ↯4_3⇡12
╭─
╷ 0 1 2
3 4 5
6 7 8
9 10 11
╯
��
Challenge 6
Write a program that boxes two strings and puts them in an array.
1 � ↧ �
Run
Example: "Hello" "World"
{"Hello" "World"}
��