Skip to content
Draft

Actions

In Draft, functions are called actions. They are the primary unit of code organization.

An action starts with action and ends with fin action.:

action greet()
write("Hello!")
fin action.

Parameters are defined in parentheses:

action greet(@name: String)
write("Hello, " + @name)
fin action.
@// Calling the action
@greet("World")
action add(@a: Int, @b: Int)
write(@a + @b)
fin action.
@add(3, 5) @// Output: 8
action greet(@name: String, @greeting: String = "Hello")
write(@greeting + ", " + @name)
fin action.
@greet("World") @// Output: Hello, World
@greet("World", "Hi") @// Output: Hi, World
action create_user(@name: String, @age: Int, @active: Boolean = true)
@// ...
fin action.
@create_user(name: "Alice", age: 30)
@create_user(name: "Bob", age: 25, active: false)

Use return to return a value:

action add(@a: Int, @b: Int) -> Int
return @a + @b
fin action.
@result = add(3, 5) @// result = 8

The last expression is automatically returned:

action add(@a: Int, @b: Int) -> Int
@a + @b
fin action.

Actions can be overloaded by parameter count or types:

action process(@value: Int)
write("Processing integer: " + string(@value))
fin action.
action process(@value: String)
write("Processing string: " + @value)
fin action.
@process(42) @// Calls Int overload
@process("hello") @// Calls String overload

Actions can be assigned to variables and passed as arguments:

@double = fn(@x: Int) -> Int => @x * 2
action apply(@value: Int, @fn: (Int) -> Int) -> Int
return @fn(@value)
fin action.
@result = apply(5, @double) @// result = 10

Actions can capture variables from their enclosing scope:

action make_counter(@start: Int) -> () -> Int
mut @count = @start
return fn() -> Int
@count = @count + 1
return @count
fin action.
fin action.
@counter = make_counter(10)
@counter() @// 11
@counter() @// 12
@counter() @// 13

Actions can call themselves:

action factorial(@n: Int) -> Int
if @n <= 1
return 1
fin if.
return @n * factorial(@n - 1)
fin action.
@factorial(5) @// 120

Draft optimizes tail-recursive calls:

action factorial_tail(@n: Int, @acc: Int = 1) -> Int
if @n <= 1
return @acc
fin if.
return factorial_tail(@n - 1, @acc * @n)
fin action.

Accept variable number of arguments:

action sum(@numbers: ...Int) -> Int
mut @total = 0
for @n in @numbers
@total = @total + @n
fin for.
return @total
fin action.
@sum(1, 2, 3, 4, 5) @// 15

Actions can be generic over types:

action first<T>(@items: Array<T>) -> T
return @items[0]
fin action.
@first([1, 2, 3]) @// Int
@first(["a", "b", "c"]) @// String

Inline actions defined with fn:

@square = fn(@x: Int) -> Int => @x * 2
@increment = fn(@x: Int) -> Int
return @x + 1
fin action.

Add actions to existing types:

extend String
action uppercase(@self: String) -> String
return @self#upper()
fin action.
fin extend.
@"hello"#upper() @// "HELLO"

Mark actions as pure (no side effects):

pure action add(@a: Int, @b: Int) -> Int
return @a + @b
fin action.

Control where actions can be accessed:

@// Public action (default)
action public_greet()
write("Hello")
fin action.
@// Private action (module-only)
priv action internal_helper()
@// ...
fin action.

Learn about Conditions and Loops for control flow.