Skip to content

Types

Blossom employs a static, strong and explicit typing system with immutable variables.

Type consistency is asserted during compile time, meaning that any typing mismatch or violation will result in an error, preventing the program from being built.

Empty initializations are also disallowed.

Atoms & Molecules

Atoms

Atoms are self-defining values - their identity is their value. They're immutable, lightweight and perfect for representing unique constants.

Example

@Success @UserNotAuthorized

Molecules

Molecules are groups of related atoms, useful for creating sets of related constants.

Example

@(Red, Green, Blue) @(Admin, Operator, Viewer)

Molecules can also be accessed using the . operator.

Example

blossom
Color := @(Red, Green, Blue)

MyFavoriteColor: Color = Color.Blue
MySecondFavoriteColor: Color = @Green

Primitives

Primitives are the basic, fundamental data types built into Blossom. They represent the simplest possible values and serve as the building blocks for more complex data structures. Unlike composite types, primitives are atomic - meaning they cannot be broken down into smaller parts.

Bool

Boolean values are logical entities that can only have two states: True or False. They represent binary choices and are fundamental to computational logic.

Example

True False

Int

Integer values are whole numbers that can be positive, negative or zero. They represent quantities without any fractional or decimal components.

Example

1517 301 -127 0

Float

Floating-point values are numbers that contain decimal points. They can represent both very large and very small numbers through standard decimal or scientific notation.

Example

3.14 -1.67 1.24e-10

String

String values are sequences of characters that represent text. Each string is a series of Unicode characters enclosed in double quotes.

Example

"Blossom" "Hello" "123"

None

None is a special type that represents the absence of a value.

Example

None

Collections

Blossom provides several fundamental data structures for organizing and manipulating data.

As with all values in Blossom, collections are immutable. Consequently, operations on collections result in the creation of new collections, unlike the in-place modification common in other languages.

List

Lists are homogeneous collections of elements.

Example

blossom
Numbers: List<Int> = [1, 2, 3, 4, 5]

Set

Sets are homogeneous collections of unique elements.

Example

blossom
UniqueColors: Set<String> = {"Red", "Green", "Blue"}
ExtendedColors: Set<String> = Set.Add(UniqueColors, "Yellow")
HasRed: Bool = Set.Contains(UniqueColors, "Red")

Map

Maps are collections of key-value pairs where each key is unique.

Example

blossom
Scores: Map<String, Int> = [
    "Alice"   => 95,
    "Bob"     => 87,
    "Charlie" => 92
]

Tuple

Tuples are fixed-size, heterogeneous, ordered collections of values.

Example

blossom
Point := (Float, Float)
Origin: Point = (0.0, 0.0)

Record

Records are immutable data structures comprised of named fields, each associated with a value.

Example

blossom
Person := { Name: String, Age: Int }

alice: Person = { Name: "Alice", Age: 30 }
bob: Person = { Name: "Bob", Age: 42 }

Optional

Optional types explicitly handle the presence or absence of a value.

Example

blossom
FindUser :: (id: String) : Optional<User> -> {
    match Database.Query(id) -> {
        user: User => user
        _          => None
    }
}

Composition

Blossom provides a type composition mechanism, enabling the construction of new types from primitive and collection types. Types are defined using the := operator, a composite symbol representing both type annotation and value assignment.

Example

blossom
ListOfFloats := List<Float>

Subject := @(Calculus, History, Biology)
Student := { Name: String, Enrollments: List<Course> }
Teacher := { Name: String, Subject: Subject }
Course  := (Teacher, List<Student>)

WARNING

Composite types must be defined outside of function signatures.

This ensures code clarity and promotes type reuse. Type definitions cannot be created inline within function parameters.

Constraints

Blossom allows you to define runtime constraints on types using the &> operator. Constraints are expressions that must evaluate to a Bool value. Every time a value is assigned to a constrained type, its constraints are validated in order. If any constraint evaluates to False, a @ConstraintError is thrown.

Constraints are validated in the order they are defined.

The type name is used within each constraint block to reference the value being validated.

Example

Email
blossom
Email := String
    &> String.NotEmpty(Email)
    &> String.Length(Email) <= 255
    &> Regex.Validate(Email, EMAIL_REGEX)
Username
blossom
Username := String
    &> String.NotEmpty(Username)
    &> String.Length(Username) >= 3
    &> String.Length(Username) <= 20
    &> Regex.OnlyAllows(Username, ~"[a-zA-Z0-9_-]")
Password
blossom
Password := String
    &> String.Length(Password) >= 8
    &> String.HasUpperCase(Password)
    &> String.HasLowerCase(Password)
    &> String.HasNumber(Password)
    &> String.HasSpecialChar(Password)
Rectangle
blossom
Rectangle := { Width: Float, Height: Float }
    &> Rectangle.Width > 0
    &> Rectangle.Height > 0
    &> Rectangle.Width <= 1000
    &> Rectangle.Height <= 1000
NonEmptyList
blossom
NonEmptyList := List<T>
    &> List.Length(NonEmptyList) > 0
    &> List.Length(NonEmptyList) <= 1000