Summary
int(x) correctly returns Result<Int, String> now, but common app code needs an ergonomic “parse with fallback” helper so developers do not have to write the same small wrapper in every app.
Suggestion: add a standard helper such as:
int_or(value, fallback) -> Int
or possibly an overloaded/convenience form:
int(value, fallback) -> Int
Motivation
Issue #51 made int() return Result instead of throwing on invalid input. That was the right semantic move: parsing can fail, and app code should not silently pretend bad external data is valid.
The practical friction showed up while upgrading the Avant Garde app to ntnt 0.4.10. Existing code had patterns like:
let status = int(data["status"] ?? 0)
if status >= 300 {
...
}
Under the current semantics, status is a Result, so this correctly fails as:
Type error: Cannot apply '>=' to Result and Int
The fix was to add local wrappers like:
fn safe_int(value: Any, fallback: Int) -> Int {
let parsed = int(value) otherwise {
return fallback
}
return parsed
}
and then use:
let status = safe_int(data["status"] ?? 0, 0)
That is correct, but it is also boilerplate for a very common boundary case: query params, env vars, API payloads, JSON feeds, dates/times, HTTP status fields, cache metadata, etc.
Proposed API
Preferred shape:
int_or(value: Any, fallback: Int) -> Int
Behavior:
- If
int(value) succeeds, return the parsed integer.
- If
int(value) returns Err(...), return fallback.
- Should work for the same accepted inputs as
int: Int, Float, String, Bool.
- Should not throw for ordinary parse/conversion failure.
Examples:
int_or("42", 0) // 42
int_or("", 0) // 0
int_or("nope", -1) // -1
int_or(None, 0) // 0
Alternatives
Keep requiring otherwise
let n = int(value) otherwise { return 0 }
This is semantically fine, but noisy when the desired behavior is local fallback, not route/function early return. It also encourages each app to create its own safe_int helper.
Overload int(value, fallback)
This may be more discoverable, but it changes the arity/meaning of int and could blur the clean “int() returns Result” rule. I mildly prefer int_or because it keeps the failure-handling choice explicit.
Add a generic unwrap_or(result, fallback)
Useful more broadly, but still leaves parse-with-fallback less obvious for the highest-frequency case. This may be complementary rather than a replacement.
Why this is still compatible with #51
This does not argue for reverting int() to throwing or returning a bare integer. int() returning Result<Int, String> is good. The request is for a companion convenience helper for the common, deliberate fallback path.
Current model is semantically honest; this would make the safe path ergonomic enough that app code does not grow little safe_int mushrooms everywhere. Which is very on-brand for web apps, but not ideal.
Summary
int(x)correctly returnsResult<Int, String>now, but common app code needs an ergonomic “parse with fallback” helper so developers do not have to write the same small wrapper in every app.Suggestion: add a standard helper such as:
or possibly an overloaded/convenience form:
Motivation
Issue #51 made
int()returnResultinstead of throwing on invalid input. That was the right semantic move: parsing can fail, and app code should not silently pretend bad external data is valid.The practical friction showed up while upgrading the Avant Garde app to ntnt
0.4.10. Existing code had patterns like:Under the current semantics,
statusis aResult, so this correctly fails as:The fix was to add local wrappers like:
and then use:
That is correct, but it is also boilerplate for a very common boundary case: query params, env vars, API payloads, JSON feeds, dates/times, HTTP status fields, cache metadata, etc.
Proposed API
Preferred shape:
Behavior:
int(value)succeeds, return the parsed integer.int(value)returnsErr(...), returnfallback.int:Int,Float,String,Bool.Examples:
Alternatives
Keep requiring
otherwiseThis is semantically fine, but noisy when the desired behavior is local fallback, not route/function early return. It also encourages each app to create its own
safe_inthelper.Overload
int(value, fallback)This may be more discoverable, but it changes the arity/meaning of
intand could blur the clean “int()returns Result” rule. I mildly preferint_orbecause it keeps the failure-handling choice explicit.Add a generic
unwrap_or(result, fallback)Useful more broadly, but still leaves parse-with-fallback less obvious for the highest-frequency case. This may be complementary rather than a replacement.
Why this is still compatible with #51
This does not argue for reverting
int()to throwing or returning a bare integer.int()returningResult<Int, String>is good. The request is for a companion convenience helper for the common, deliberate fallback path.Current model is semantically honest; this would make the safe path ergonomic enough that app code does not grow little
safe_intmushrooms everywhere. Which is very on-brand for web apps, but not ideal.