Skip to content

List comprehensions

Agency supports Python-style list comprehensions:

ts
const doubled = [x * 2 for x in numbers]

Filtering

Add an if clause to keep only some items:

ts
const bigNames = [name for name in names if name.length > 5]

Running the items concurrently

Prefix with fork to run each item concurrently:

ts
const summaries = fork [llm("Summarize: ${doc}") for doc in docs]

Note that each branch will get isolated state for global variables. See the state isolation section for more details.

Example:

ts
// global variable
let count = 0

node main() {
  const xs = range(10)
  // count is still 0 afterwards - each branch changed its own copy
  const results = fork [count += x for x in xs]
}

Each branch got its own copy of count. The state wasn't shared, and was thrown away when the branch finished.

Shared state

If you want shared state, use forkShared:

ts
// global variable
let count = 0

node main() {
  const xs = range(10)
  // count is now 45
  const results = forkShared [count += x for x in xs]
}

See the concurrency and state isolation docs for more on shared state.

The if clause runs before the work fans out, so the filter itself is not concurrent.

race and raceShared

Put race in front to get the first result back, and cancel the rest:

ts
// whichever summary comes back first wins; the other branches are cancelled
const fastest = race [summarize(doc) for doc in docs]

Note that this returns a single result, not a list. race also gets isolated state. To share state, use raceShared.

Binders

List comprehension with an index variable:

ts
const labeled = ["${i}: ${name}" for name, i in names]
// ["0: Alice", "1: Bob"]

For an object, the list comprehension iterates over the key-value pairs:

ts
const config = { host: "localhost", port: "8080" }
const lines = ["${k}=${v}" for k, v in config]
// ["host=localhost", "port=8080"]

Filtering does not renumber indices:

ts
const xs = ["a", "b", "c", "d"]
const kept = ["${i}:${x}" for x, i in xs if x != "b"]
// ["0:a", "2:c", "3:d"] - note the missing 1

You can also destructure each item as you go:

ts
const greetings = ["Hi ${name}" for {name, age} in people]
const firsts = [a for [a, b] in pairs]

References