u/NXDLang

Desingning async primitives for a security-focused language: Where should cancellation live?

I've been implementing typed async semantics in my language NXD.

Current primitives are:

SPAWN,

SEND,

RECV,

AWAIT,

PING

Types currently look roughly like:

`SPAWN -> ProcessHandle[T]`

`RECV -> ReceiveOperation[T]`

`AWAIT -> T`

`PING -> bool`

While implementing PING I realized there may be two classes of async operations:

Primary operations

SPAWN,

SEND,

RECV

These initiate work or communication.

Secondary operations:

AWAIT,

PING

These observe or resolve work created elsewhere.

My current thinking is that cancellation (currently considering ESC) should only apply to the primary operations and not observers.

For example:

ESC HANDLE

makes sense.

But:

ESC AWAIT TASK

ESC PING HANDLE

seems conceptually wrong because they are observing state rather than creating it.

For people who have designed async runtimes or languages:

Would you model cancellation as acting on the underlying task/process/channel, or would you allow cancellation of observer operations as first-class concepts as well?

reddit.com
u/NXDLang — 8 days ago

Designing async semantics for a new language. What would you do differently?

I've been spending the last few days implementing async support in NXD, a systems programming language I'm developing; that also has 3 transpilation targets.

Recent work completed:

• `Task[T]` semantic type

• `AWAIT Task[T] -> T`

• `ProcessHandle[T]`

• `AwaitGroup[T]`

• Completion-order result semantics

• Semantic validation and diagnostics for async operations

I'm currently working through the remaining messaging primitives (SEND is next).

One thing I've found interesting while implementing this is that many languages expose similar async syntax, but the underlying semantics differ significantly. After spending time studying other implementations, I found myself focusing less on the keyword await and more on the type relationships and execution model behind it.

For example, in my current design:

`Task[T]`

`AWAIT -> T`

`ProcessHandle[T]`

Represents a spawned process producing T

`AwaitGroup[T]`

Allows waiting on multiple processes

Results are returned in completion order

The completion-order behavior felt natural from an async perspective, but it also raised questions about predictability versus throughput, ordering guarantees, and how much of the runtime model should be exposed to the programmer.

For those who have designed or implemented async systems, compilers, runtimes, or schedulers:

Looking back, what async design decision caused the most trouble later?

Was it task representation, cancellation, ordering guarantees, await semantics, scheduler behavior, channels/messages, error propagation, or something else entirely?

reddit.com
u/NXDLang — 15 days ago

How do other complier projects handle source location propagation for semantic diagnostics?

​

Last night I finished wiring source locations through the NXD compiler pipeline so semantic diagnostics can point to the exact symbol instead of defaulting to line 1, column 1.

The flow is roughly:

AST -> IR -> JSON -> Rust semantic analyzer -> LSP -> VS Code

I'm curious how other language projects handle location tracking through lowering and semantic analysis. Do you carry spans everywhere, attach them only to selected nodes, or reconstruct locations later?

reddit.com
u/NXDLang — 22 days ago