Osy#betaRun it on Osyrin: osyrin.com

Reference

Function

89 pages.

Crossing the network

An Osy# app runs in two places — the server, which holds the data, and the browser, which holds the screen — and the runtime moves between them in…

Functions (the unit of work)

A function is where your app's logic lives — a top-level unit of work, written like a C# method, that runs on the server. It is transactional by…

(int)x — casts

A C-style cast converts between the numeric types. It truncates toward zero, and it is checked — a value the target type cannot hold fails loudly…

++ / -- (increment / decrement)

Increment or decrement a numeric variable or property by one. In statement position (i++;) and as a for increment the pre- and post-forms are…

Array literals

An array literal [a, b, c] is a value: a list you can return, assign, pass as an argument, or supply as a UI prop. Its element type is inferred from…

Asymmetric signing — Crypto.SignRs256, VerifyRs256, SignEs256, VerifyEs256

Sign with a private key, verify with a public one. This is what a signed JWT is made of, and a signed JWT is how almost every service authenticates a…

Building and reading a TimeSpan

How to build a duration and read it back. Construct one with new TimeSpan(...) or a TimeSpan.FromX factory (including TimeSpan.FromMilliseconds)…

Compound assignment (+= -= *= /= %= ??=)

Update a variable or property in place: x op= y is shorthand for x = x op y. Arithmetic forms need a numeric lvalue; ??= assigns only when the left…

Constructing a DateTime, DateOnly, or TimeOnly

Build a temporal value from its components. DateTime.New takes a date, optionally with a time (defaulting to midnight); DateOnly.New takes a calendar…

Contains, StartsWith, EndsWith

Tests whether a string contains, begins with, or ends with another string. The match is case-sensitive and literal — like C#'s String.Contains, the…

Convert

Explicit conversion between types — number to text, text to number, a Guid to its text form. Osy# will not convert silently where information could…

Crypto.Encrypt and Crypto.Decrypt

Encrypt and decrypt values under your app's key, which the platform mints, protects, and rotates for you. There is no key parameter — you never…

Crypto.HmacSha256Hex and Crypto.FixedTimeEquals

HMAC-SHA-256 authenticates a message under a shared key — proving it came from a key holder and was not altered, which a plain hash cannot do. Always…

Crypto.Md5Hex

MD5 of a string's UTF-8 bytes rendered as 32-character lowercase hex — the canonical C# fingerprint form. Deterministic, so it pushes down into SQL…

Crypto.Sha256Hex

SHA-256 of a string's UTF-8 bytes as 64-character lowercase hex — the secure default hash. Deterministic, so it pushes down into SQL. Use it wherever…

Current time (DateTime.UtcNow, DurableClock.Now)

Read the current instant. `DateTime.UtcNow` (and the platform-idiomatic `DurableClock.Now`/…) return the current time from the platform's replay-safe…

Date arithmetic — AddDays, AddMonths, AddYears, AddHours, AddMinutes, AddSeconds, AddMilliseconds

Move a DateTime forward or back. AddDays/AddHours/AddMinutes/AddSeconds/AddMilliseconds take a fractional amount and are exact to the tick. AddMonths…

Do the same work for many items at once (Parallel, SemaphoreSlim)

Parallel.For, Parallel.ForEach and Parallel.ForEachAsync run one body per item, each as a task beside the others, and wait for all of them; failures…

Enum.Label, Enum.Description, Enum.Name

Read the human-facing words of an enum value in code: its Label (the [Label] text, or the member name when there is none), its Description (the…

Enumerable.Range

A sequence of consecutive integers, count of them, starting at start. It is how you iterate by index — including in a render block, which has foreach…

Guid.Empty and Guid.NewGuid

The C# Guid statics. `Guid.Empty` is the all-zero Guid constant, spelled without parens; `Guid.NewGuid()` mints a fresh unique Guid. Guid.Empty…

How deep can an object graph get?

A value built out of references to other values — a linked list, a tree, a chain of parents — may nest up to 500 levels. Past that, serializing it…

IEnumerable<T> with yield return — iterators

A function declared `IEnumerable<T>` whose body uses `yield return` is a C# iterator: each `yield return` adds one item to the sequence it hands…

Index from end and ranges

C#'s index from the end (^n) and ranges (a..b) inside an indexer. ^1 is the last element of a string, an array or a list; a range slices a string…

List OrderBy (in-memory)

Sort a local List<T> in memory by a key selector, returning a NEW sorted List<T> (the source is untouched). Ascending or descending, stable, exactly…

List Sort with a comparison

Order a local List<T> IN PLACE by a comparison you write: a lambda taking two elements and answering an int — negative when the first goes first, 0…

List Sort, Reverse and RemoveAt (in place)

Reorder or shorten a local List<T> IN PLACE, changing the list you are holding rather than answering a new one. Sort() orders by the elements…

List indexer

Positional get/set on a List<T> by integer index, exactly like C#'s List<T>.this[int]. The index must be an integer; the result is the element type…

Local functions — a function declared inside a body

A local function is a helper declared inside the body that uses it — `int Sq(int x) => x * x;`. It can be called before or after its declaration, can…

Math.Abs, Math.Sign, Math.Min, Math.Max, Math.Clamp, Math.Truncate, Math.Pow, Math.Sqrt, Math.Sin, Math.Cos, Math.Tan

The numeric helpers, each returning the type C# says it returns. Abs, Min, Max and Clamp answer in the WIDEST of their arguments, so a decimal stays…

Numeric types & literal suffixes

The platform numeric types are int, long, decimal, and double. Literals follow C# exactly, suffixes (L, m, d) included: a bare decimal-point literal…

Passing a function by name — method groups

A function's NAME, written where a function value is wanted, is that function — `Func<int, int> f = Double;`, `xs.Select(Double)`, `xs.Where(IsDue)`…

Patterns

A pattern asks a question about a value's SHAPE — is it 7, is it over 0 and under 10, does it have an X of 1, is it a list that starts with 1 — and…

Qr.Encode

A QR code for a piece of text, as rows of modules a page draws with ordinary boxes — level M, the smallest version that holds it, the mask the…

Raise(e) — say that something happened

`Raise(e)` says that the event `e` happened — an instance of a class marked `[Event]`. It is written in the same commit as the work around it, and…

Reading a date — Year, Month, Day, Hour, Minute, Second, DayOfWeek, DayOfYear, Date

Read a component off a DateTime — its year, month, day, hour, minute, second — or its day of the week (a DayOfWeek, as in C#), its day of the year (1…

Regex

Matching, replacing and splitting with regular expressions. A pattern means the same thing wherever your code runs — the platform makes the browser…

Signing with raw bytes — Crypto.HmacSha256, Sha256, ToHex, and Text.ToBytes

The byte-in, byte-out half of the crypto surface. Real request-signing schemes chain their HMACs — each step's raw output becomes the next step's key…

Stop a task (CancellationToken) and complete one by hand (TaskCompletionSource)

C#'s cancellation, with C#'s meaning. A CancellationTokenSource hands out a Token; cancel the source and every task that was handed the token stops —…

String interpolation & format specifiers

Build a string from literal text and embedded expressions with $"…{expr}…". A hole may carry a .NET format specifier after a colon ({amount:F2})…

Text.ByteSize

Formats a byte count as the words a person reads — "0 B", "1.5 KB", "2.7 MB". Binary units (1024) with the conventional KB/MB/GB labels. An ordinary…

Text.Capitalize, Text.Replace, Text.Repeat, Text.Left, Text.Right

Produce a new string from an old one: upper-case the first letter, replace every occurrence of a substring, repeat it, or take characters from one…

Text.Concat

Joins a list of values into one string with NOTHING between the elements. It is Text.Join with no separator, and the same operation as string.Concat…

Text.IndexOf

The C# string.IndexOf: the index of the FIRST ordinal occurrence of a substring, or -1 if absent. The 3-arg overload resumes the forward search at…

Text.Join

Joins a list of values into one string, placing the separator between each pair. It is the inverse of Text.Split, and the same operation as…

Text.LastIndexOf

The C# string.LastIndexOf: the index of the LAST ordinal occurrence of a substring, or -1 if absent. The 3-arg overload starts the backward search at…

Text.Length, Text.IsEmpty, Text.IsBlank, Text.Contains, Text.StartsWith, Text.EndsWith

Ask a string a question without changing it: its length, whether it is empty or blank, and whether it contains, starts with, or ends with a piece of…

Text.Like

Matches a string against a wildcard pattern, where % stands for any run of characters and _ for exactly one. It is the only wildcard search in the…

Text.Split

The C# string.Split: breaks a string on a separator and returns the substrings as a List<string> — iterable with foreach and queryable with .Count /…

Text.TitleCase

Capitalises the first letter of each word and lower-cases the rest, leaving a word that is already entirely upper-case untouched so acronyms survive…

Text.TrimStart, Text.TrimEnd, Text.PadStart, Text.PadEnd, PadLeft, PadRight

Trim whitespace from one end of a string, or pad it out to a width with a fill string. Trimming uses the full Unicode whitespace set. Padding never…

Text.Truncate

Shorten a string to at most maxLength characters — INCLUDING the ellipsis — cutting back to the last word boundary rather than mid-word. The bound…

The C# Osy# leaves out — and why

Osy# is C#-shaped, and leaves out three things on purpose: unsafe code (pointers, fixed, stackalloc, function pointers, native interop), float, and…

Totp.NewSecret, Totp.Uri, Totp.Verify, Totp.Code

Authenticator-app codes (RFC 6238 — the six-digit, thirty-second codes every authenticator app shows), which is what a second factor is built on…

Tuples and deconstruction

A function returns several values by declaring a tuple return type and returning a parenthesized list. The caller reads them by name (`t.ok`), or…

Typed locals

Locals can declare an explicit type instead of var; the declared type pins the binding, and every later assignment to the name is checked against it…

UnitOfWork

Every body accumulates its writes in a unit of work rather than sending them one at a time. UnitOfWork.Commit() makes everything accumulated so far…

UnitOfWork savepoints — Mark, Undo, Redo, RollbackTo

Marks form a stack on the unit of work. UnitOfWork.Mark(label) records everything staged so far and answers a UnitOfWorkMark; Undo() rolls back to…

Wait for several tasks (Task.WhenAll, Task.WhenAny)

Task.WhenAll waits for every task and answers their results in order; Task.WhenAny answers the first task to finish, and the others keep running, as…

Wait in place (Task.Delay)

Wait before carrying on — between checks on a job another system is still running, before trying a call again, or for a moment in a component. `await…

WebAuthn.* and Passkey.* — the two halves of a passkey

A passkey (W3C Web Authentication) has a server half and a browser half. `WebAuthn.*` runs on the server: it makes the options a browser is handed…

[Action] — what an app offers to be done, by name

Mark a function `[Action]` and the app offers it to be done BY NAME — by a rule, a macro, a tool — with everything a caller needs derived from the…

[CommitsAlone] — a function whose writes land by themselves

A function marked `[CommitsAlone]` runs in a unit of work of its own. What it writes is committed when it returns and stays committed whatever its…

[Event] — what happens to a record, declared once

An event is a class marked `[Event]`: something that happens to a record, declared once by the code that owns the record. It is raised where it…

[Interest] — the events a handler of every event cares about

`[Interest(nameof(Triggers))]` beside the `[On]` of a handler of EVERY event names a function that answers which event types it cares about now — the…

[OnStart] — work the app does when it is loaded

`[OnStart]` marks a function the platform runs, as the app, whenever the app version is loaded — on every node that serves it, after every compile…

[On] — hear an event, after the commit that raised it

`[On]` on a function makes it a HANDLER of the event its one parameter is. Every handler of an event — in the app and in every package that sees it —…

[OncePerDelivery] — a read made once for every event of a delivery

`[OncePerDelivery]` on a function that reads makes it answer once per delivery: the events one commit raised are delivered together, and a handler…

async / await and Task

C#'s async and await, with C#'s meaning. A call to a Task-returning method that you do not await where you make it starts a task that runs beside the…

break / continue

break leaves the enclosing loop; continue skips the rest of this pass. Inside a switch, break leaves the SWITCH, not the loop around it — the one…

const

A value fixed at compile time and folded into the places it is used. Declare one at the TOP LEVEL to share it across the whole app, on a component…

for

The C-style counting loop. Runs init once, then repeats the body while cond holds, running update after each pass. Any clause may be omitted; for…

foreach

Walks a collection — a query result, a list, or a parent's children. The normal way to iterate; reach for a for loop only when you need the index.

format specifiers

Formats a number to a string with a .NET format specifier — F2 for two decimal places, N0 for a grouped whole number, C for currency, P for a…

function

A function is a top-level unit of work, written like a C# method — a return type, a name, typed parameters, a body. It runs transactionally. Called…

function authorization ([Authorize] on a function)

`[Authorize(Policy)]` on a function runs it only for a caller who satisfies the named `policy` — checked when it is called from a page, an API or a…

if / else

Conditional branching, exactly as in C#. The condition must be a bool — there is no truthiness, so a null or a number is not a condition.

nameof

The C# compile-time name fold: validates the symbol and folds to its simple-name string literal — the last identifier of the chain. Invalid symbols…

reading a secret's value (Secret.Name)

`Secret.Name` in a function body evaluates to the declared secret's value — the key itself, as a string, read at the moment it is used…

switch

Branch on a value against constant case labels. Only the matched section runs (no fall-through); a default section handles the rest. break exits the…

switch expression

Choose a VALUE by matching a subject against patterns. Arms are tried in order and the first match wins. An arm is any C# pattern — a constant, a…

throw

Raises a fault. It ends the function immediately, and the rows the function wrote are discarded rather than half-written. An exception is a class:…

try / catch / finally

Handles a fault. C#'s syntax, including typed catches, catch filters and finally. The rows written inside a try block that throws are discarded — so…

using / IDisposable

C#'s `using`, exactly: `Dispose()` is called on every way out of the block — normal exit, return, break, continue, or an exception — last declared…

var

Declares a local whose type is inferred from its initializer, exactly as in C#. The local is still statically typed — var is about not repeating the…

verbatim strings (@"…")

`@"…"` is a string where a backslash is just a backslash. Nothing inside is an escape, `""` writes a single quote, and the text may run across lines…

while

Repeats while a bool condition holds. Reach for it when the number of iterations is not known up front — otherwise a foreach or a for loop says more.

x => … — lambdas, with or without parameter types

A lambda is an inline function: a parameter list, `=>`, and a body. Its parameter types come from where it is used, or you write them yourself —…

yield — a function that produces results over time

A `stream<T>` function produces its results one at a time instead of all at once, and a `live var` bound to one renders each item the moment it…