logo Dorpn v0.4.1 GitHub
Language Guide

Variables & Scope

A comprehensive guide to variable declaration, constants, and scope management in Dorpn's statically-typed environment.

Variable Declaration with tag

The tag keyword introduces mutable variables into the current scope. Variables declared with tag can be reassigned new values, provided the new value matches the variable's inferred or explicitly declared type.

  • Mutability — values can be modified after initialization
  • Type binding — each variable is permanently bound to a specific type (Int, Float, String, or Bool)
  • Scope awareness — variables exist from their point of declaration forward
  • Case sensitivity — variable names follow standard identifier rules

Variables can be declared with explicit type annotations or rely on automatic type inference from the assigned value. The type, once established, remains fixed for the variable's lifetime.

dorpn
tag name = "Dorpn"      # String
tag count = 42          # Integer
tag price = 19.99       # Float
tag active = true       # Boolean

Constants with Const

The Const keyword creates immutable named values that cannot be modified after initialization. Constants provide compile-time guarantees about value stability and enable performance optimizations.

  • Immutable by design — attempting to reassign a constant triggers a compile-time error
  • Compile-time verification — constants are validated during compilation
  • Naming convention — typically UPPER_SNAKE_CASE for clarity
  • Scope hierarchy — constants follow standard lexical scoping rules

Constants are ideal for configuration values, mathematical constants, application metadata, and any value that should remain invariant throughout program execution.

dorpn
Const PI = 3.14159
Const APP_NAME = "Dorpn"
Const MAX_RETRIES = 3
dorpn
Const PI = 3.14159
PI = 3.14  # ERROR: Cannot assign to constant!

Scope Rules & Visibility

Dorpn employs static (lexical) scoping where variable visibility is determined by the program's textual structure. Scopes are created by code blocks, function definitions, and control structures.

Scope Description
Global scope Variables declared outside any function or block
Function scope Variables declared within a function (local to that function)
Block scope Variables declared within control structures (if, loop, keep blocks)
Nested scopes Inner scopes can access outer scope variables, but not vice versa

Variables are available from their point of declaration:

dorpn
tag global = "I'm available everywhere below"

if true:
    tag local = "I'm only in this block"
    print(global)  # Works
    print(local)   # Works

print(global)  # Works
# print(local)  # ERROR: Not defined here

Shadowing behavior

A variable in an inner scope can "shadow" (temporarily hide) a variable with the same name from an outer scope. The original variable becomes inaccessible within the inner scope but regains visibility once the inner scope exits.

Lifetime management

  • Variables exist from their point of declaration until the end of their containing scope
  • Memory for variables is managed automatically via the generated C code
  • No garbage collector overhead — memory is freed deterministically

Best Practices & Guidelines

Variable naming

  • Use descriptive names that indicate purpose and content type
  • Prefer camelCase for variables, UPPER_SNAKE_CASE for constants
  • Avoid single-letter names except for loop counters or mathematical variables
  • Consider type hints in names when beneficial (e.g. userCount, priceFloat)

Declaration placement

  • Declare variables as close as possible to their first use
  • Group related variables with blank lines for visual separation
  • Initialize variables at declaration when practical
  • Place constants at the top of files or logical sections

Scope management

  • Minimize variable scope to reduce cognitive load
  • Avoid global variables when local alternatives exist
  • Use constants for values that shouldn't change
  • Consider function parameters over shared global state
Aspect tag Variables Const Constants
Mutability Mutable (can be reassigned) Immutable (fixed value)
Type flexibility Fixed type after first assignment Fixed type and value
Memory May change memory allocation Fixed allocation
Use case Changing values, accumulators Configuration, invariants
Naming convention camelCase UPPER_SNAKE_CASE

Common Pitfalls & Solutions

Reassignment errors
Attempting to change a variable's type after declaration results in a compile-time type mismatch error. Use separate variables for different types instead.
Constant modification
Constants cannot be reassigned. Any attempt triggers a compile-time error. Use tag instead if the value needs to change.
Scope confusion
Variables declared in inner scopes are not accessible in outer scopes. Declare variables at the appropriate scope level, or return values from inner scopes when needed externally.
Shadowing issues
Accidental shadowing can make outer variables inaccessible. Use distinct names across nested scopes, or be intentional about when shadowing is used for clarity.

Design Principles Behind Dorpn's Variable System

  • Predictability over convenience — variables have fixed types to eliminate runtime type errors and enable better compiler optimizations
  • Explicit over implicit — type inference is supported, but the system encourages clarity through appropriate naming and optional annotations
  • Safety through immutability — constants provide compile-time guarantees about value stability, reducing bug surfaces
  • Local reasoning — lexical scoping helps you understand variable visibility by examining local code structure
  • Gradual disclosure — simple variable usage is straightforward; advanced patterns are available but not required for basic programs
Summary
Dorpn's variable system balances flexibility with safety, enabling both rapid prototyping and robust production code through its clear semantics and compile-time guarantees.