plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


6929b8b — Peter John 2026-10-26T12:14:31+05:30
docs(plans): queue T7 nullable sugar T? = Try[T, [Missing]]
docs/plans/2026-10-26-zig-generics-and-numbers.md CHANGED
@@ -149,3 +149,21 @@ LOC since b7a5ee8 (excluding generated parser files): 62 files changed, 2509 ins
149
149
  Known gaps:
150
150
  - A closure that calls an `fn`-typed parameter fails with `unknown function`; this was found while writing `sumWith`.
151
151
  - An enum field cannot have an `fn` type.
152
+
153
+ ## Added task T7: nullable sugar `T?` (user request, queued after the fn-field fix)
154
+
155
+ - `T?` in any type position is exactly `Try[T, [Missing]]`, desugared in the parser. `T??` is a parse error.
156
+ - Implicit wrapping applies only where the expected type is `T?`: a plain `T` value becomes `Ok(v)` and the bare tag `Missing` becomes `Err(Missing)`. Real error unions keep explicit Ok/Err.
157
+ - `?`, `??`, `?.`, match and exhaustiveness work unchanged, and `Missing` merges into wider unions via `?`.
158
+ - Representation: for ref-type T (class/enum/Str/List/Map/Try), the `Try[T,[Missing]]` instantiation lowers to `ref null T` (null = Missing) with no Ok allocation. Primitive and value-enum T keep the ordinary Try struct.
159
+
160
+ Tests:
161
+ - `nullable_sugar_desugars` (`Person?` unifies with `Try[Person, [Missing]]`);
162
+ - `implicit_ok_wrap` and `missing_literal`;
163
+ - `safe_nav_chain` (`u?.target?.name`);
164
+ - `elvis_default`;
165
+ - `question_merges_missing` into `[Missing, BadNumStr]`;
166
+ - `double_question_rejected`;
167
+ - `nullable_ref_no_alloc` (the wasm uses `ref.is_null`, with no struct.new for the Ok path).
168
+
169
+ Update the README's Error handling section and plum-examples/safe_navigation.plum to use `T?`.