On this page

Read a change, predict its effect

Use these exercises to review a small change before asking a compiler, a test suite or another agent to explain it. Each starts from the Customer showcase. Read the linked declaration, make a prediction, then compare it with the answer.

For intentionally invalid source and repairs, see diagnostics and repairs. Those cases distinguish missing intent and type/ownership errors from runtime failures.

require / validation: 1. Change a validation boundary

The validator uses Length(2, 100) for Name. Replace it with Length(3, 100). Predict the outcome for names “Al”, “Ana” and 101 copies of “A”, each paired with ana@example.com. Does the storage schema need to change? Does success activate the customer?

Answer: “Al” fails the minimum, “Ana” passes and the 101-character name fails the maximum. The name column still permits 100 characters, so this change needs no column expansion. Success still creates an inactive customer. Validation does not imply activation. The controller reports Name failures without storing input; the service validates too because non-HTTP callers can bypass the controller.

Add assertions for the property and valid/invalid category rather than a localized error sentence. The request-path checks explain what a direct controller test establishes.

self / arguments: 2. Review a suspicious rename

An agent adds this action inside Customer, which already has a writable Name property:

public action Rename(name as String)
    Name = name
end action

Is capitalization enough to select the property and parameter? Repair the action without changing the registration validation policy.

Answer: No. Bare references collide under case-insensitive binding. Select the member with self.Name and the parameter with arguments.name:

public action Rename(name as String)
    self.Name = arguments.name
end action

This is only a name-binding repair. It adds no trimming, validation, persistence or activation policy. Those would be separate application changes. Compare it with the guarded rename example in the C#/VB.NET bridge.

nothing / default: 3. Separate absence from defaults

Inside an action with the walkthrough's Customer visible:

let label as String = default
let customer as Customer = default
let readonly aliases = new Global.System.Collections.Generic.List <of String>()
aliases.Add("Ana")

Predict the first two values. Is Add legal? Would assigning aliases to a new List be legal? Does String default establish a rule that makes all missing references present?

Answer: Label is empty String. Customer is nothing because this ordinary class has no custom default. Add is legal because readonly protects the local binding, not the List's contents. Rebinding aliases is invalid. Default is type-specific; it neither creates arbitrary objects nor changes explicit nothing into an empty value everywhere. See values and defaults.

task_of / await: 4. Find the lost exception

Inside an action with a supplied path, an agent writes:

let pending = task_of(Global.System.IO.File.ReadAllTextAsync(path))
try
    Global.System.Console.WriteLine("Read started")
catch error as Global.System.Exception
    Global.System.Console.WriteLine(error.Message)
end try
let text = await pending

Will the handler catch a file-read failure observed at await? Would changing capture to a bare let pending = File.ReadAllTextAsync(path) solve it?

Answer: The await is outside try, so its failure escapes that handler. Move both capture and await inside try when invocation-time and asynchronous failures need that handler. A bare fresh awaitable call is a compile-time error; a Task-typed local would not remove the requirement to choose intent. Task_of does not delay invocation or schedule a thread. See operation observation.

concurrent all / first: 5. Predict dashboard timelines

The dashboard starts customer, orders and balance branches together. Suppose customer lookup completes first, orders next and balance last. Then suppose orders fails while balance is still running. Can the caller read a partly populated CustomerDashboard? Does task_of alone provide the same lifetime?

Answer: Concurrent all publishes the required results only after owned work and cleanup settle. The first timeline waits for balance; the second joins the remaining work before propagating failure, so the construction after the scope does not run. One genuine failure propagates as its original exception; several genuine failures aggregate in source order. Task_of alone retains an unowned operation without joining it. A branch can finish early, but its completed local work is not a published dashboard.

For first/any, a selected winner is also subject to joins and publication rules. The outcome reference explains why winner selection and returning to the caller are separate events.

using / dispose: 6. Inspect a worker's cleanup

The report system permits four complete worker bodies. Four jobs are running and a fifth is queued. The first renderer returns, but its DI scope's async cleanup is still waiting. Can the fifth job begin? What if cleanup then throws?

Answer: Not yet. Cleanup belongs to that worker body, so the fourth slot remains occupied until it settles. A cleanup failure makes that job Failed, with a generic public error and the original cause available to application logging. After recording the outcome, the worker continues to queued work. Returning from the renderer is not enough to publish success. The native reference check uses completion signals to exercise this exact delayed-cleanup boundary.

Cancellation: 7. Cancel a request and a job

A permitted caller submits a report and receives 202. Their HTTP connection then closes. Later they send DELETE for the report. Predict the difference between cancellation while Queued, cancellation while Running and cancellation after Succeeded. Can another authenticated subject inspect or cancel it?

Answer: After admission, the job's lifetime is independent of the submitting request. A queued cancellation prevents TryStart from claiming execution; the channel item can still occupy capacity until skipped. A running cancellation records the request and signals its token, without forcibly terminating computation. This application publishes Cancelled if cancellation wins before a successful result is published, even if the renderer ignored it. A genuine render/cleanup failure remains Failed. Cancelling a terminal job returns 409. Missing and other-subject job identifiers return 404.

The API must authorize customer access at admission and job ownership on lookup/cancel. It does not automatically recheck a later permission revocation at execution. Cooperative shutdown and process-local storage also provide no durable job guarantee. These are application policies, not new language rules.

Gate / snapshots: 8. Protect a database reader

An invoice source returns a list of references to the same live IDataRecord while advancing its reader. The renderer then processes that list concurrently. Is IReadOnlyList enough to make the rows independent? Would a Gate around each projection repair the snapshot?

Answer: No. A read-only list controls changes to the list through that view; it does not freeze the objects it refers to. A live reader's current-row view can change on the next read. Copy each row's required values into independent snapshots before retention or parallel processing, and release the reader at the acquisition boundary. Serializing later projections cannot restore earlier row values already overwritten. See reader contracts and snapshot processing.

Take / TryTake: 9. Locate a selection failure

These library calls assume DirectSharp.Collections is imported and no competing extension is equally applicable; otherwise qualify SequenceExtensions explicitly. Items contains integers 0 through 6. Compare the DirectSharp library calls items.Take(5, 10), items.TryTake(5, 10), and items.TryTake(20, 30). Which can fail after exposing a prefix? Which does work at the call? Does appending ?? throw change deferred failure timing?

Answer: Strict Take returns a deferred sequence. Full traversal yields 5 and 6, then throws ArgumentOutOfRangeException when it discovers the shortage. TryTake(5, 10) collects 5 and 6 at the call. TryTake(20, 30) returns actual nothing after determining that no values were selected. It makes no separate Count traversal; available collection metadata can optimize the same result.

Coalescing checks actual absence, not future enumeration failures. A present strict sequence is still present, so ?? throw does not force it, check its length or turn it into a snapshot. Ordinary source/cleanup failures propagate from both helper families. Revisit the sequence reference before substituting imported LINQ calls.

feature: 10. Review an optional adapter

The statement_rows feature filters, sorts and exports projected rows. An agent claims it makes export streaming, parallel and transactional because the source uses a feature block. Which claims follow from the declaration?

Answer: None of those follow. The feature binds ordinary Enumerable.Where, Enumerable.OrderBy and StatementRows.Write calls. Sorting buffers selected input; export enumerates it and can leave partial output on failure. CPU scheduling is explicit in the preceding application helper, not supplied by the feature. A temporary-output publication policy must be designed separately when partial output must stay invisible. The feature contributes local vocabulary, not different library semantics.

Review: explain the chosen language feature

For each change, identify the business rule, data ownership, failure boundary and observable result. Ask an agent to state those four things alongside its patch, then compare them with the actual code. Readability helps you check the explanation; integration tests still need to exercise real database, authentication and HTTP behavior.

Return to the guide, Customer showcase or developer bridge. Use the reference when your prediction depends on an exact edge case.