Defining terms

In Unison, we can give a value a name, for example:

favoritePie : Text
favoritePie = "Apple pie"

We call these definitions "term declarations", and they typically have two parts. The first,favoritePie : Textis the type signature, and it tells Unison and other programmers what type your term is. You might read this in human language asfavoritePiehas the typeText.Unison is able to infer the type of a given term so you might see this first part omitted for simple definitions.

The second linefavoritePie = "Apple pie"supplies the implementation for your term.

๐ŸŽจ
By convention, types are capitalized in Unison, whereas term names are "camelCase."

The value assigned to a Unison term doesn't vary while a program is running, so if you try to reassign it like this:

favoritePie = "Apple pie"
favoritePie = "Peach pie"

TheUCMwill fail to typecheck:

I found 1 name with multiple definitions:

favoritePie

Tuples

Tuples are a way to join together values of different types into one value.

dessertOrder : (Text, Text, Nat)
dessertOrder = ("Alice", "Blueberry pie", 5)

A tuple is specific to the length of values joined together and the types of each of those values, so they're useful for structured data. There is no upper limit to the number of things you can put in a tuple in Unison.

If you try to add values to your tuple without changing the corresponding type, or supply a value of the wrong type, the UCM will fail to typecheck.

dessertOrder : (Text, Text, Nat)
dessertOrder = ("Alice", "Blueberry pie", "Chocolate cake", 2 )
I found a value  of type:  Text where I expected to find:  Nat

  38 | dessertOrder : (Text, Text, Nat)
  39 | dessertOrder = ("Alice", "Blueberry pie", "Chocolate cake", 2 )

  from right here:

  39 | dessertOrder = ("Alice", "Blueberry pie", "Chocolate cake", 2 )

When we want to un-tuple one of these values, we can use extraction functions which start withat1.

dessertOrder = ("Alice", "Blueberry pie", 5) at2 dessertOrder
โงจ
"Blueberry pie"

Tuple pattern decomposition

Let's say you're working with data that's modeled by a tuple composed of aText,aBytes,and aText.Later when writing a function which uses this tuple you might need to access the values at each position in the tuple and bind them to a variable name. You could do this with theat1,at2,andat3functions defined onTuple

getByteSize : (Text, Bytes, Text) -> Nat getByteSize tuple3 = use Bytes ++ use Text toUtf8 first = at1 tuple3 bytes = at2 tuple3 last = at3 tuple3 Bytes.size (toUtf8 first ++ bytes ++ toUtf8 last) getByteSize ("Shepherds", 0xsdeadbeef, "Pie")
โงจ
16

But you can also rewrite the function to decompose the tuple into the desired variable names in one line. Just make sure the number of variables you're defining matches the tuple structure.

getByteSize : (Text, Bytes, Text) -> Nat
getByteSize tuple3 =
  _ = "tuple decomposition ๐Ÿ‘‡"
  let
    (first, bytes, last) = tuple3
    size (toUtf8 first ++ bytes ++ toUtf8 last)
โœจ
You can't decompose a tuple into terms at thetop levelof a Unison program. So(first, bytes, last) = ("Shepherds", 0xsdeadbeef, "Pie")outside of the body of another Unison function would fail to typecheck.

A few more types

We've seen a couple of basic types already, but here's a rudimentary vocabulary of Unison types to get you started writing Unison programs.

NamePurposeExample
Texttextual data"textBlob"or"""multi-line text"""
Charsingle character?a
Bytesbyte literal0xsdeadbeef0d0a
Nat64 bit positive whole numbers. 0 to 2^64 - 15 Nat.+ 5
Int64 bit signed positive or negative whole numbers. -2^64/2 to 2^64/2 - 1+4 Int.- +9
Float64 bit floating point numbers3.14159
Booleantrue or false values for logictrue || false