Functions & Tasks
NEKOVA calls functions "tasks" — with default values, varargs, keyword arguments, and type hints all supported.
Basic tasks
task add(a, b):
return a + b
show add(2, 3)
Default parameter values
task greet(name, greeting="Hello"):
return greeting + ", " + name
show greet("Ada") # "Hello, Ada"
show greet("Ada", "Hey") # "Hey, Ada"
Keyword arguments
task greet(name, greeting="Hello"):
return greeting + ", " + name
show greet(name="Ada", greeting="Hey")
show greet("Ada", greeting="Yo") # positional + keyword mixed
Keyword arguments can fill in a later parameter while leaving an earlier one at its default:
task greet(name="World", greeting="Hello"):
return greeting + ", " + name
show greet(greeting="Hey") # "Hey, World"
Passing an unknown keyword, or the same parameter both positionally and by keyword, raises a clear error rather than guessing what you meant.
Variadic arguments
task total(*nums):
let sum = 0
for n in nums:
sum = sum + n
return sum
show total(1, 2, 3, 4)
Type hints and typed tasks
task add(a: int, b: int) -> int:
return a + b
Type hints on parameters and return values are checked at call time for int, float, str, bool, list, and dict.
Docstrings
A leading string in a task body is captured as documentation rather than treated as a statement:
task greet(name):
"""Says hello to someone."""
show "Hello " + name
show doc(greet) # "Says hello to someone."
Recursion
task factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
NEKOVA tracks its own call depth (500 by default) independently of Python's stack, so an unbounded recursive call reports the exact depth reached rather than a vague "infinite recursion" guess.
Closures
Tasks capture variables from their enclosing scope by reading them, the same as any nested scope:
task make_adder(x):
task add(y):
return x + y
return add
let add5 = make_adder(5)
show add5(3) # 8
show add5(10) # 15
Each call to make_adder creates a fresh x, so add5 and a second make_adder(100) don't interfere with each other.