Topaz Docs

Data Types in Topaz

This section provides a comprehensive overview of the built-in data types available in the Topaz language. Topaz is a statically-typed language with strong type inference, meaning that while types are checked at compile-time for safety and efficiency, you often don't need to explicitly write them everywhere.

Core Data Types

These are the fundamental data types in Topaz, forming the building blocks for all data structures.

Numbers (Integer and Float)

Topaz handles both whole numbers (Integers) and numbers with decimal points (Floating-Point numbers). The specific internal representation (e.g., int32, float64) is managed by the compiler for efficiency, but you typically work with them as general numbers, and their type is inferred.

;; Numbers are inferred based on their notation
($ age 30)          ;; Inferred as an Integer
($ count -100)       ;; Inferred as an Integer
($ price 19.99)      ;; Inferred as a Float
($ pi 3.1415926535)  ;; Inferred as a Float

;; For specific scenarios where precision or size matters,
;; future extensions may allow explicit type hints or suffixes,
;; but type inference is preferred for general use.

Booleans (Boolean)

Represents truth values using dedicated boolean literals #true and #false. These provide type safety and clarity compared to numeric representations.

;; Boolean literals
($ is-active #true)       ;; Boolean true
($ has-permission #false) ;; Boolean false

;; Using booleans in conditional expressions
(IF is-active
  (io:print "System is active")
  (io:print "System is inactive")
)

;; Boolean operations
($ both-true (AND #true #true))    ;; Evaluates to #true
($ either-true (OR #false #true))  ;; Evaluates to #true
($ negated (NOT #true))            ;; Evaluates to #false

Strings (String)

Represents sequences of characters, typically UTF-8 encoded. Strings are enclosed in double quotes.

($ name "Topaz Language")
($ message "Hello, Topaz! 👋")
($ empty-string "")
($ greeting (string:concat "Hello, " name))

Symbols (Symbol)

Symbols are unique identifiers, often used as keys in maps, for enumerated values, or as uninterpreted programmatic tokens. They are typically prefixed with a colon (:) or a single quote (') depending on the context and desired evaluation semantics (details in Language Reference).

($ mode :edit)          ;; A keyword-like symbol
($ status 'pending)       ;; Another style of symbol
($ first-name 'firstName) ;; Symbol used as an identifier

Vectors (Vector)

Vectors are ordered, typically homogeneous collections of items, similar to arrays or lists in other languages. They are defined using square brackets [].

($ empty-vector [])
($ numbers [1 2 3 4 5])      ;; A vector of integers
($ strings ["hello" "world" "topaz"]) ;; A vector of strings
($ nested-vector [1 [2 3] 4])

;; Vector operations using the vector module
($ doubled (vector:map (λ (x) (* x 2)) numbers))
($ first-item (vector:first numbers))  ;; Gets 1
($ rest-items (vector:rest numbers))   ;; Gets [2 3 4 5]

Maps (Map)

Maps are collections of key-value pairs, similar to dictionaries, hash maps, or objects in other languages. They are defined using a hash symbol followed by parentheses (# ...) with alternating keys and values. Symbols are commonly used as keys.

($ empty-map (#))
($ user-profile 
  (# 
    :name "Jamie Yoon" 
    :role "CTO" 
    :active #true 
    :projects ["Topaz" "Studio Haze"]
  )
)
($ config (# "version" "1.0.2" "debug-mode" #false)) ;; String keys with boolean values

;; Map operations using the map module
($ user-name (map:get user-profile :name))  ;; Gets "Jamie Yoon"
($ updated-profile (map:assoc user-profile :active #false))  ;; Returns new map with updated value

Processes (Process)

Processes (akin to functions or lambdas) are first-class citizens in Topaz. They can be assigned to variables, passed as arguments, and returned from other processes. They are defined using (λ ...). While not a data structure in the traditional sense, they are a fundamental "type" of value you'll work with.

($ add 
  (λ (a b) 
    (+ a b)
  )
)
($ my-adder add) ;; Assigning a process to another variable
(io:print (core:to-string (my-adder 10 20))) ;; Prints 30

NULL_SIG (The Null Signal)

NULL_SIG is a special, unique value in Topaz representing the absence of a meaningful value, a void result, or a 'nothingness' signal. It's distinct from zero or an empty string. Processes that don't explicitly return a value might implicitly yield NULL_SIG.

($ no-value NULL_SIG)

($ do-something-that-returns-nothing
  (λ () 
    (io:print "Performing an action...")
    ;; No explicit return, yields NULL_SIG
  )
)
($ result (do-something-that-returns-nothing))
;; Here, 'result' would hold NULL_SIG

User-Defined Types

Topaz v1.0 supports robust mechanisms for creating custom data types, providing type safety and clear data modeling capabilities.

Structured Types (DEFINE-TYPE)

Use DEFINE-TYPE to create structured data types (similar to structs or records) with named fields and their corresponding types.

Syntax: (DEFINE-TYPE TypeName (# :fieldName1 FieldType1 :fieldName2 FieldType2 ...))

;; Define a Point type with floating-point coordinates
(DEFINE-TYPE Point (# :x Float :y Float))

;; Define a Person type with multiple field types
(DEFINE-TYPE Person (# :name String :age Integer :active Boolean))

;; Define a nested type using other user-defined types
(DEFINE-TYPE Rectangle (# :top-left Point :bottom-right Point))

;; Create instances using map literals that match the type structure
($ origin (# :x 0.0 :y 0.0))  ;; Type: Point
($ user (# :name "Alice" :age 30 :active #true))  ;; Type: Person
($ rect (# :top-left origin :bottom-right (# :x 10.0 :y 10.0)))  ;; Type: Rectangle

Enumerated Types (DEFINE-ENUM)

Use DEFINE-ENUM to create types with a fixed set of possible values, useful for state machines, configuration options, and domain modeling.

Syntax: (DEFINE-ENUM EnumName :Value1 :Value2 :Value3 ...)

;; Define basic enumerations
(DEFINE-ENUM Color :RED :GREEN :BLUE :YELLOW)
(DEFINE-ENUM Status :PENDING :IN_PROGRESS :COMPLETED :FAILED :CANCELLED)
(DEFINE-ENUM Direction :NORTH :SOUTH :EAST :WEST)

;; Use enumeration values
($ current-color :RED)
($ task-status :IN_PROGRESS)
($ facing :NORTH)

;; Enums work well with conditional logic
(IF (= current-color :RED)
  (io:print "Stop!")
  (io:print "Proceed")
)

Generic Types

Topaz supports parametric polymorphism through generic type parameters, allowing you to write reusable code that works with multiple types.

;; Generic function that works with any type T
($ identity
  (λ [T] (value: T)
    value
  )
)

;; Generic function for vectors of any element type E
($ vector-length
  (λ [E] (vec: (Vector E))
    (vector:length vec)
  )
)

;; Generic data structures can be defined using type parameters
;; Note: The exact syntax for generic type definitions is part of future language extensions
;; (DEFINE-TYPE Maybe [T] (# :some T | :none NULL_SIG))  ;; Future syntax example

Working with User-Defined Types

;; Pattern matching and field access (using map operations)
($ get-person-info
  (λ (person: Person)
    ($ name (map:get person :name))
    ($ age (map:get person :age))
    (string:concat name " is " (core:to-string age) " years old")
  )
)

;; Type-safe operations
($ calculate-distance
  (λ (p1: Point p2: Point)
    ($ dx (- (map:get p2 :x) (map:get p1 :x)))
    ($ dy (- (map:get p2 :y) (map:get p1 :y)))
    (math:sqrt (+ (* dx dx) (* dy dy)))
  )
)

;; Using the functions
($ alice (# :name "Alice" :age 30 :active #true))
($ point1 (# :x 0.0 :y 0.0))
($ point2 (# :x 3.0 :y 4.0))

(io:print (get-person-info alice))  ;; "Alice is 30 years old"
(io:print (core:to-string (calculate-distance point1 point2)))  ;; "5.0"

Further Information

For more context on how these types are used within the language's grammar and operations, please refer to the main Syntax Reference. More advanced topics like type inference details, generics (parametric polymorphism), and the specifics of defining custom types will be covered in dedicated guides as the language evolves.