Types

Smart Placement has built-in types to handle different kinds of data. Each type serves a specific purpose and includes its own validation rules and UI representation.

Collections

There are two collection types for grouping data:

// Lists - When order matters
claim_dates: [Date];  // Ordered sequence of dates

// Sets - When order doesn't matter
risk_codes: #{Text};  // Unique collection of codes

List comprehension

List comprehension lets you transform collections of data. The basic syntax is:

[new_value | item <- collection]

For example:

// Convert names to uppercase
names: [Text] = ["John", "Jane"];
uppercase = [to_upper(name) | name <- names];

// Create structured data from codes
risk_codes: #{Text} = #{"PB", "PR"};
details = [{
    code: code,
    description: lookup(risk_codes_table, code)
} | code <- risk_codes];
List comprehension: Essential when working with parameterised data points and tables, where you need to transform IDs into structured data.

Parameterised data points

In Smart Placement, you can parameterise data points using unique identifiers (UUIDs). This is particularly useful when you need to:

  1. Create dynamic collections of data

  2. Reference specific instances of data

  3. Create relationships between different parts of your data model

The following is a basic example using sections in a policy:

// Define a collection of section IDs
type SectionId = Uuid<"section">;
sections.sections: #{SectionId};

// Define parameterized data points for each section
section.coverage(section_id: SectionId): Text;
section.limit(section_id: SectionId): Number<policy.currency>;
section.premium(section_id: SectionId): Number<policy.currency>;

// Group the section data together using list comprehension
// For each section_id in sections.sections, create a record with coverage, limit, and premium
sections = {
    sections.sections: [{
        coverage: section.coverage(section_id),
        limit: section.limit(section_id),
        premium: section.premium(section_id)
    } | section_id <- sections.sections]  // Transform each ID into a structured record
};

This example shows how list comprehension helps transform a collection of IDs (sections.sections) into a collection of structured records, each containing the section’s coverage, limit, and premium data.

UUID (Universally Unique Identifier) is a 128-bit identifier that is unique across space and time. In Brossa:

- UUIDs are used to uniquely identify rows in tables, sections, layers, or any other collection of items
- They can be typed (e.g., Uuid<"section">) to ensure type safety when referencing specific kinds of items
- They are automatically generated and managed by the system, so you rarely need to create them manually

Scalar types

// Text - For storing any text value
insured.name: Text;

// CaselessText - For case-insensitive text
occupation: CaselessText;  // Matches "Accountant" and "accountant"

// Number - For decimal values
risk.limit: Number;

// Int - For whole numbers
number_of_locations: Int;

// Date - For calendar dates (YYYY-MM-DD)
inception_date: Date;  // 2024-03-21

// Percent - For percentage values
broker.commission: Percent;  // 10%

// Umr - For Lloyd's Unique Market References
broker.umr: Umr;  // B1234ABC123456
UMR format:

The Umr type enforces Lloyd’s market standards for Unique Market References:

. Broker ID (chars 2-5): A 4-digit identifier used by the broker_code() function
. Extra Data (chars 6-17): Up to 12 alphanumeric characters for the reference

Format: B + 4 digits + 0-12 alphanumeric characters
Example: B0702SC300570p

- B: Required prefix
- 0702: Broker code
- SC300570p: Reference data
// YesNo - For yes/no choices (Bool)
has_claims: YesNo;  // yes or no

// Promise<T> - For asynchronous operations
place_details_promise: Promise<Place>;
The Promise<T> type is typically used in service definitions and API calls rather than direct data point declarations.

Units and qualified types

You can qualify number types with units to ensure type-safety in calculations. The following are common patterns:

// Currency qualification
premium: Number<"USD">;  // Fixed currency
section.premium: Number<policy.currency>;  // Dynamic currency

// System currency for internal calculations
max_line: Number<policy.currency_system> = 20_000_000<policy.currency_system>;
Working with qualified types:

- Values must share the same units for arithmetic operations
- The result inherits the unit from its operands
- Use exchange rates to convert between different currencies