0% found this document useful (0 votes)
31 views18 pages

Arrays - Uiua Docs

Uploaded by

Pete
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views18 pages

Arrays - Uiua Docs

Uploaded by

Pete
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Uiua �� ⋅⋅⊙⋅⋅ ∘ Support Uiua's development Home

Back to Docs Home

〈 Previous: Math and Comparison Next: Types 〉

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.

Strand notation uses underscores to connect elements.

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.

Stack notation uses [] brackets to group elements.

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.

Remember that . duplicate duplicates the top item on the stack.

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

[10] Run < >

1 [...] 7 � ↧ � 1/2

[7 7 7 7] Run < >


1 [+×2] 20 2 � ↧ � 1/3

[42] Run < >

You can also use stack notation to make multidimensional arrays.

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.

△ shape and ⧻ length

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

[3] Run < >

1 △5 � ↧ � 1/2

[] Run < >

1 △[[1 2 3] [4 5 6]] � ↧ � 1/2

[2 3] Run < >

1 △[...[1 2 3]] � ↧ � 1/2

[4 3] Run < >

Arrays with 0 dimensions (an empty △ shape ) are called scalars.

Arrays with 1 dimension are often called lists or vectors.


Arrays with 2 dimensions are often called tables or matrices.

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).

Rank is the number of dimensions of the array. It is equivalent to the


⧻ length of the △ shape .

1 △[1_2_3 4_5_6 7_8_9] � ↧ � 1/7


2 ⧻[1_2_3 4_5_6 7_8_9]
3 ⧻△[1_2_3 4_5_6 7_8_9] # Rank
[3 3] Run < >
3
2

Pretty Array Output

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.)

To understand how the pretty-printed output corresponds to the actual array,


we can use ↯ reshape to create a multidimensional array. ↯ reshape
uses its first argument as a new shape for its second argument.
Here, we create a ⇡ range array of all the numbers up to 24 and turn it
into a 3-dimensional array with the shape [2 3 4] .

1 ↯2_3_4 ⇡24 � ↧ � 1/4

╭─ Run < >


╷ 0 1 2 3
╷ 4 5 6 7
8 9 10 11

12 13 14 15
16 17 18 19
20 21 22 23

Notice there are 2 big cells, each with 3 rows of 4 elements.

This expands to any number of dimensions. The more dimensions, the more
space between the cells representing earlier axes.

1 ↯2_3_2_5 ⇡60 � ↧ � 1/4

╭─ Run < >


╷ 0 1 2 3 4
╷ 5 6 7 8 9

10 11 12 13 14
15 16 17 18 19

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

[2 3 4] Run < >

1 √[4 9 16] � ↧ � 1/2

[2 3 4] Run < >

1 +1_2_3 4_5_6 � ↧ � 1/3

[5 7 9] Run < >

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

If you want to do some pervasive operation on arrays whose shapes do not


match, you can set a default value with ⬚ fill . Any places where the
shapes don't match will be filled in with that value.

1 ⬚10+ [1 2] [3 4 5 6 7] � ↧ � 1/3

[4 6 15 16 17] Run < >

⬚ fill can be used in a lot of other cases. See its documentation for more.

Pervasive operations are optimized in the interpreter to be very fast. You


should prefer to use them whenever possible.

Useful Array Operations

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.

⊟ couple turns two arrays into rows of a new array.

1 ⊟ 1_2_3 [4 5 6] � ↧ � 1/3

╭─ Run < >


╷ 1 2 3
4 5 6

⊢ first and ⊣ last get the first or last row of an array.

1 ⊢ [4 7 1] � ↧ � 1/2

4 Run < >

1 ⊢ [1_2 3_4 5_6] � ↧ � 1/2

[1 2] Run < >

1 ⊣ "hello" � ↧ � 1/2

@o Run < >

⇌ reverse reverses the rows of an array.

1 ⇌ [4 7 1] � ↧ � 1/2

[1 7 4] Run < >

1 ⇌ [1_2 3_4 5_6] � ↧ � 1/2

╭─ Run < >


╷ 5 6
3 4
1 2

↻ rotate rotates the rows of an array by some amount.

1 ↻2 [1 2 3 4 5] � ↧ � 1/3

[3 4 5 1 2] Run < >

♭ deshape flattens an array into a 1D array.

1 ♭ .[1_2 3_4 5_6] � ↧ � 1/3

╭─ Run < >


╷ 1 2
3 4
5 6

[1 2 3 4 5 6]
↙ take and ↘ drop isolate part of an array.

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

4 Run < >

1 ⊡1 [1_2_3 4_5_6] � ↧ � 1/6


2 ⊡1_1 [1_2_3 4_5_6]
[4 5 6] Run < >
5

⊏ select uses a list of indices to select rows of an array.

1 ⊏ [0 2 1 1 2] ↯3_3⇡9 � ↧ � 1/6

╭─ Run < >


╷ 0 1 2
6 7 8
3 4 5
3 4 5
6 7 8

1 ⊏[3 5 0 1 7 8 9 5 1 2 5 3 10] "their sinks"


� ↧ � 1/3
"i think he is" Run < >

The Array Model

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]] � ↧ �

Error: Cannot combine arrays with shapes [] Run


and [3]
at 1:1
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 [□1 □2 □[7 8 9]] � ↧ �

{1 2 [7 8 9]} Run

The {} s in the output hint at some syntax that will be introduced shortly.

° un □ box extracts a □ box ed value.


1 °□ .□[1 2 3] � ↧ � 1/4

⟦1 2 3⟧ Run < >


[1 2 3]

The ⟦⟧ s indicate that a list is □ box ed.

□ box ed strings also have special output delimiters, using ⌜⌟ s.

1 □"banana" � ↧ � 1/2

⌜banana⌟ Run < >

Having to write □ everywhere is annoying, and so...

Nested Arrays

Uiua has a special syntax for making arrays where every item is □ box ed.

Using {} s instead of [] s for stack array notation will automatically □ box


every item.

1 {1 2 [7 8 9]} � ↧ �

{1 2 [7 8 9]} Run

This is very useful for making lists of strings.

1 ["Uiua" "APL" "J" "BQN" "K" "Q"] # Fails


� ↧ �

Error: Cannot join arrays of shapes [3] and Run


[4]
at 1:1
1 | ["Uiua" "APL" "J" "BQN" "K" "Q"] # Fails
────────────────────────────────

1 {"Uiua" "APL" "J" "BQN" "K" "Q"} # Works!


� ↧ �

{"Uiua" "APL" "J" "BQN" "K" "Q"} Run


Functions that require their arguments to have matching types may require
□ box ing an argument.

For example, to check if a string is in a list of □ box ed strings with


∈ memberof , you would need to □ box the string first.

1 Langs ← {"Uiua" "APL" "J" "BQN" "K" "Q"}


� ↧ � 1/5
2 ∈ Langs □"APL"
1 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

1 ×10 {1_2_3 4_5 6} � ↧ � 1/3

{[10 20 30] [40 50] 60} Run < >

There is an exception for comparison functions, which compare


lexicographically.
1 = [1 2 3] [1 2 5] � ↧ � 1/28
2 = □[1 2 3] □[1 2 5]
3 > [1 2 3] [1 2 5]
4 > □[1 2 3] □[1 2 5]
5 > "banana" "orange"
6 > □"banana" □"orange"
7 > □"banana" "orange"
[1 1 0] Run < >
0
[0 0 1]
1
[1 1 0 1 0 1]
1
{[1 1 1 1 1 1] [1 1 1 1 1 1] [0 0 0 0 0 0] [1 1 0 1

Non-pervasive functions often require ° un □ box ing the arguments to


get at the value you want.

Consider this difference:

1 △ ⊢{1_2_3 5_6} � ↧ � 1/7


2 △ °□ ⊢{1_2_3 5_6}
[] Run < >
[3]

For more about working with box arrays, see □ box 's documentation.

Challenges

Challenge 1

Write a program that adds an array to its reverse.

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

Write a program that adds a 1-row leading axis to an array.

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: [1_2_3 4_5_6] +10↯3_3⇡9


╭─
╷ 10 11 12
13 14 15
16 17 18

╭─
╷ 1 2 3
4 5 6

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"}

Input: "ui" "ua"


"ua"
"ui"

Input: "dog" "cat"


"cat"
"dog"

��

〈 Previous: Math and Comparison Next: Types 〉

Back to Docs Home

You might also like