Add try(value, default) special form#17
Merged
Merged
Conversation
What: - New higher-order special form `try(value, default)` registered in the same dispatch table as map/filter/etc. Evaluates `value`; if evaluation returns an ErrEvaluate, evaluates and returns `default` instead. The default is lazy and only runs when the primary fails. - Trapped: anything wrapping ErrEvaluate (missing keys, nil selectors, out-of-range indices, type-coercion failures from int/float/etc.). - Not trapped: raw context.Canceled / context.DeadlineExceeded so cancellation stays observable, and anything wrapping ErrCompile. - Spec, llms.txt, and suggester (via higherOrderNames) updated. - Tightened TestSuggest_UndefinedIdentAvailableList so it does not rely on the exact higher-order form count. Why: - Strict missing-key access stays the default; typos must fail loudly. try is the explicit opt-in for "I know this might miss; here is a fallback." Combined with operand-returning || it covers the common optional-field case without adding a `default(x, y)` builtin or `??` operator. See docs/design/language-evolution.md (step 2).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
try(value, default)special form so callers can opt in to graceful failure on a per-expression basis without weakening the strict-missing-key default.What it traps
ErrEvaluate: missing fields/keys, nil selectors, out-of-range indices, type-coercion failures fromint/float/ etc.What it does not trap
context.Canceledandcontext.DeadlineExceeded— cancellation must remain observable.ErrCompile— defensive; expr should not surface these at Run time, but if it does, that signals a programmer mistaketryis not the right place to swallow.The
defaultexpression is lazy: it only evaluates when the primary failed. That means callers can supply expensive or side-effecting fallbacks without paying for them on the success path.Implementation
higherOrderFormsandhigherOrderNamesso dispatch and the did-you-mean suggester pick it up automatically.WithFunctions) wins over the form, matching every other special form.Tests and docs
higher_order_test.go: 12 new tests covering success path, default-on-eval-error, default-on-type-error, lazy default (panicking if invoked), default error propagation, arity, ctx cancellation passthrough, env / func shadowing, nested composition, andtry(...) || fallbackinterop.suggest_test.go: tightened to avoid relying on the exact higher-order form count.docs/reference/spec.mdandllms.txt: new entry plus a paragraph spelling out the trap/no-trap semantics.Test plan
go test ./...go test -race ./...FuzzCompile20sFuzzEval20s