Functions
Define reusable logic with parameters, return values, recursion, and closures.
Theory
Functions are reusable blocks of logic that improve readability, reduce duplication, and make code easier to test. In PriyoScript, functions are declared with lisaaTask and optionally return values using priyoGiveBack. A function can accept parameters, perform calculations, call other functions, and return output to the caller. Functions are essential for structuring medium and large programs.
Why functions matter
If a logic block is repeated, move it into a function once and call it where needed.
Function Types Table
| Function type | Syntax pattern | Description |
|---|---|---|
| Basic function (no params) | lisaaTask name() { ... } | Runs reusable logic without input parameters. |
| Function with parameters | lisaaTask name(a, b) { ... } | Accepts input values from caller. |
| Function returning value | priyoGiveBack value | Sends computed result back to caller. |
| Void-style function | no priyoGiveBack | Performs side effects (for example output/logging). |
| Recursive function | name(...) inside same function | Calls itself until base condition is met. |
| Closure function | returns inner function | Inner function remembers outer variables. |
| Async function (stage-1) | prakritiWait lisaaTask ... | Enables prakritiPause inside the function body. |
| Generator-yield (stage-1) | prakritiGiveSome value | Produces step values consumable via next(). |
| Structured concurrency | prakritiConcurrency.group(...) | Runs async tasks with group wait/cancel semantics. |
| Bounded concurrency queue | prakritiConcurrency.queue(...) | Limits how many async tasks run at the same time. |
Syntax Quick Reference
monalisa {
lisaaTask add(a, b) {
priyoGiveBack a + b
}
priyoTell(add(2, 3))
}Async Functions and Await (Stage-1)
prakritiWait marks a function as async-capable. prakritiPause waits for an expression to resolve.
Example 1
monalisa {
prakritiWait lisaaTask addAsync(a, b) {
priyoGiveBack prakritiPause (a + b)
}
priyoTell(prakritiPause addAsync(20, 22))
}Output:
42Example 2
monalisa {
prakritiWait lisaaTask greetLater(name) {
priyoGiveBack "Hi " + prakritiPause name
}
priyoTell(prakritiPause greetLater("mona"))
}Output:
Hi monaPrakriti Concurrency
PriyoScript concurrency uses prakriti names for async work, lightweight task spawning,
channels, grouped task ownership, queues, cancellation, deadlines, combinators, and delayed task
scheduling.
Use prakritiGo when you want to start one cooperative task and keep its task handle. Use
prakritiChannel when tasks need to exchange values. Use prakritiConcurrency.group(...) or
.queue(...) when a parent scope should own, cancel, or inspect a set of tasks together.
Example 1: Spawn a task and receive from a channel
monalisa {
prakritiWait lisaaTask prepare(outbox, name) {
prakritiPause prakritiConcurrency.after(5, priyoEmpty)
prakritiPause outbox.send(name + " ready")
priyoGiveBack name
}
priyoKeep outbox = prakritiChannel()
priyoKeep task = prakritiGo prepare(outbox, "mona")
priyoTell(prakritiPause outbox.receive())
priyoTell(prakritiPause task.join())
}Output:
mona ready
monaExample 2: Run tasks in a group
monalisa {
prakritiWait lisaaTask fetchName(name) {
prakritiPause prakritiConcurrency.after(5, priyoEmpty)
priyoGiveBack name + " done"
}
priyoKeep group = prakritiConcurrency.group("names")
priyoKeep first = group.run(fetchName, "mona")
priyoKeep second = group.run(fetchName, "lisaa")
priyoTell(priyoArray.length(prakritiPause group.all()))
priyoTell(prakritiPause first.join())
}Output:
2
mona doneExample 3: Cooperative cancellation
monalisa {
prakritiWait lisaaTask worker(name, token) {
prakritiPause prakritiConcurrency.after(5, priyoEmpty)
token.throwIfCancelled()
priyoGiveBack name + " finished"
}
priyoKeep group = prakritiConcurrency.group("cancel")
priyoKeep token = group.token()
priyoKeep task = group.run(worker, "mona", token)
group.cancel("stop now")
prakritiTry {
priyoTell(prakritiPause task.join())
} prakritiCatch (err) {
priyoTell(err.code)
}
}Output:
PRUN-112Example 4: Delayed scheduling
monalisa {
prakritiWait lisaaTask greet(name) {
priyoGiveBack "Hello " + name
}
priyoKeep group = prakritiConcurrency.group("scheduled")
priyoKeep task = group.schedule(5, greet, "lisaa")
priyoTell(task.status())
priyoTell(prakritiPause task.join())
priyoTell(task.status())
}Output:
scheduled
Hello lisaa
fulfilledExample 5: Deadline-driven cancellation
monalisa {
prakritiWait lisaaTask worker(token) {
prakritiPause prakritiConcurrency.after(20, priyoEmpty)
token.throwIfCancelled()
priyoGiveBack "done"
}
priyoKeep group = prakritiConcurrency.group("deadline")
priyoKeep token = group.token()
group.deadline(5, "deadline reached")
priyoKeep task = group.run(worker, token)
prakritiTry {
priyoTell(prakritiPause task.join())
} prakritiCatch (err) {
priyoTell(err.code)
}
}Output:
PRUN-112Example 6: Race, any, and allSettled
monalisa {
prakritiWait lisaaTask delayedValue(name, delay) {
prakritiPause prakritiConcurrency.after(delay, priyoEmpty)
priyoGiveBack name
}
prakritiWait lisaaTask delayedBoom(delay) {
prakritiPause prakritiConcurrency.after(delay, priyoEmpty)
prakritiThrow "boom"
}
priyoKeep raceGroup = prakritiConcurrency.group("race")
raceGroup.run(delayedValue, "slow", 10)
raceGroup.run(delayedValue, "fast", 1)
priyoTell(prakritiPause raceGroup.race())
priyoKeep anyGroup = prakritiConcurrency.group("any")
anyGroup.run(delayedBoom, 1)
anyGroup.run(delayedValue, "winner", 5)
priyoTell(prakritiPause anyGroup.any())
}Output:
fast
winnerExample 7: Bounded task queues
monalisa {
prakritiWait lisaaTask worker(name, delay) {
prakritiPause prakritiConcurrency.after(delay, priyoEmpty)
priyoGiveBack name
}
priyoKeep queue = prakritiConcurrency.queue(1, "serial")
queue.run(worker, "first", 5)
queue.run(worker, "second", 5)
priyoTell(queue.limit())
priyoTell(queue.active())
priyoTell(queue.queued())
priyoTell(prakritiPause queue.all())
}Output:
1
1
1
[first, second]Concurrency API quick reference
| API | Purpose |
|---|---|
prakritiGo task(args...) | Start a cooperative task and return a handle. |
prakritiChannel(capacity?, label?) | Create a task communication channel. |
channel.send(value) / channel.receive() | Send and receive channel values asynchronously. |
prakritiConcurrency.group(label?) | Create a task group. |
prakritiConcurrency.queue(limit, label?) | Create a bounded task queue. |
prakritiConcurrency.after(ms, value?) | Resolve a value after a delay. |
group.run(...) / queue.run(...) | Start a task now. |
group.schedule(...) / queue.schedule(...) | Start or enqueue a task after a delay. |
group.all() / queue.all() | Wait for all started tasks. |
group.allSettled() / queue.allSettled() | Collect task outcomes without failing fast. |
group.race() / queue.race() | Settle on the first completed task. |
group.any() / queue.any() | Resolve with the first fulfilled task. |
group.deadline(ms, reason?) / queue.deadline(ms, reason?) | Auto-cancel after a timeout. |
group.pending() / queue.pending() | Count active pending tasks. |
queue.active() / queue.queued() / queue.limit() | Inspect queue capacity and backlog. |
task.join() / task.status() / task.error() | Inspect and await a specific task handle. |
token.cancel() / token.throwIfCancelled() | Cancel and cooperatively observe cancellation. |
1. Function Without Return Value
Runs logic without explicit returned result.
Example 1
monalisa {
lisaaTask greet() {
priyoTell("Hello from function")
}
greet()
}Output:
Hello from functionExample 2
monalisa {
lisaaTask banner() {
priyoTell("==== PriyoScript ====")
}
banner()
}Output:
==== PriyoScript ====2. Function With Return Value
Returns data so caller can reuse the computed value.
Example 1
monalisa {
lisaaTask add(a, b) {
priyoGiveBack a + b
}
priyoTell(add(10, 5))
}Output:
15Example 2
monalisa {
lisaaTask isAdult(age) {
priyoGiveBack age >= 18
}
priyoTell(isAdult(21))
}Output:
priyoTrue3. Recursive Function
A function that calls itself with a smaller problem until base condition.
Example 1
monalisa {
lisaaTask factorial(n) {
prakritiIf (n <= 1) {
priyoGiveBack 1
}
priyoGiveBack n * factorial(n - 1)
}
priyoTell(factorial(5))
}Output:
120Example 2
monalisa {
lisaaTask countdown(n) {
prakritiIf (n == 0) {
priyoGiveBack "done"
}
priyoTell(n)
priyoGiveBack countdown(n - 1)
}
priyoTell(countdown(3))
}Output:
3
2
1
done4. Closure Function
Function returns another function that keeps access to outer variables.
Example 1
monalisa {
lisaaTask makeCounter() {
priyoChange count = 0
lisaaTask next() {
count = count + 1
priyoGiveBack count
}
priyoGiveBack next
}
priyoKeep c = makeCounter()
priyoTell(c())
priyoTell(c())
}Output:
1
2Example 2
monalisa {
lisaaTask makeGreeter(prefix) {
lisaaTask greet(name) {
priyoGiveBack prefix + " " + name
}
priyoGiveBack greet
}
priyoKeep welcome = makeGreeter("Welcome")
priyoTell(welcome("mona"))
}Output:
Welcome mona5. Generator Yield (Stage-1)
prakritiGiveSome emits sequence values from a function. A yield function returns a generator-like
object with next(), hasNext(), and reset().
Example 1
monalisa {
lisaaTask series() {
prakritiGiveSome 1
prakritiGiveSome 2
}
priyoKeep g = series()
priyoTell(g.next().value)
priyoTell(g.next().value)
priyoTell(g.next().done)
}Output:
1
2
priyoTrueExample 2
monalisa {
lisaaTask names() {
prakritiGiveSome "mona"
prakritiGiveSome "lisaa"
}
priyoKeep g = names()
priyoTell(g.hasNext())
priyoTell(g.next().value)
g.reset()
priyoTell(g.next().value)
}Output:
priyoTrue
mona
monaPractice Questions
Concept Check
- When should you return a value instead of printing inside the function? 2. Why is a base condition mandatory in recursive functions? 3. What value does a closure preserve after the outer function finishes?
Related Docs
Last updated on