Summary
A function whose body is integer arithmetic produces Result<int, MathError>. Annotating the return type -> int makes codegen auto-unwrap that Result to a plain int. Without the annotation the function returns the wrapped Result, so a downstream toString prints Success(42) instead of 42. The annotation looks redundant (HM infers a type) but is semantically load-bearing, and there is no diagnostic when it is removed — the output silently changes.
Repro (Default flavor; ML f x y = x + y vs f : int -> int -> int behaves identically)
fn add(x, y) = x + y // no return type
let base = add(40, 2)
print("${toString(base)}") // prints: Success(42)
fn add(x, y) -> int = x + y // load-bearing return type
let base = add(40, 2)
print("${toString(base)}") // prints: 42
Impact
The planned [ANALYZER-REDUNDANT-SYMBOL] autofix (#159) classifies inferable return types as redundant and deletes them. Applied here it would silently change program output from 42 to Success(42) — a correctness regression with no error. This bit the in-progress "strip redundant types" sweep on the example twins (examples/tested/ml/*), where stripping the arithmetic returns turned golden outputs into Success(...).
Suggested fix (either)
- Drive Result auto-unwrap from the use site (arithmetic /
toString / print context) so it does not depend on an explicit annotation; OR
- Treat an auto-unwrap-enabling return type as load-bearing in
[ANALYZER-REDUNDANT-SYMBOL] so it is never stripped, and document it as such.
Found while form-aligning + de-mainning the examples/tested/ml/ twins for the curry-by-default work.
Summary
A function whose body is integer arithmetic produces
Result<int, MathError>. Annotating the return type-> intmakes codegen auto-unwrap that Result to a plainint. Without the annotation the function returns the wrappedResult, so a downstreamtoStringprintsSuccess(42)instead of42. The annotation looks redundant (HM infers a type) but is semantically load-bearing, and there is no diagnostic when it is removed — the output silently changes.Repro (Default flavor; ML
f x y = x + yvsf : int -> int -> intbehaves identically)Impact
The planned
[ANALYZER-REDUNDANT-SYMBOL]autofix (#159) classifies inferable return types as redundant and deletes them. Applied here it would silently change program output from42toSuccess(42)— a correctness regression with no error. This bit the in-progress "strip redundant types" sweep on the example twins (examples/tested/ml/*), where stripping the arithmetic returns turned golden outputs intoSuccess(...).Suggested fix (either)
toString/printcontext) so it does not depend on an explicit annotation; OR[ANALYZER-REDUNDANT-SYMBOL]so it is never stripped, and document it as such.Found while form-aligning + de-mainning the
examples/tested/ml/twins for the curry-by-default work.