feat(data): require explicit () for singleton variants; deprecate bare form - #80
Merged
Merged
Conversation
…e form Singleton variants were written as a bare identifier (`Quit`), which reinforced the false expectation that `Score.ZeroZero` is a *value*. It is not — it is the variant *type*; the value is `Score.ZeroZero()`. This tripped up users (#22) with confusing `convert`/dispatch MethodErrors. Julia has singleton *types* (an immutable no-field struct has one egal instance, `Base.issingletontype` == true), but the type and its instance are always distinct objects — there is no way to make a bare name be both a type and its value the way a Rust enum variant is. Moshi needs the variant name to stay a type (for dispatch/reflection/pattern matching), so the honest fix is to make the *syntax* explicit rather than to fake a value binding. Changes: - `@data` now accepts the explicit `Name()` singleton form (previously rejected with "missing fields") and treats it as the canonical spelling. - The bare `Name` form still parses to a Singleton but emits a `Base.depwarn(...; force=true)` at macro-expansion time. - Internal `Pattern` ADT (`Wildcard`) and all test/doc `@data` blocks migrated to the explicit `()` form so Moshi no longer uses its own deprecated syntax. - Docs updated to teach `Name()` and explain the type-vs-value point. - Added tests for the explicit form and the bare-form deprecation (guarded to skip under `--depwarn=error`, which escalates to a throw). Non-breaking (deprecation only): bumps 0.3.9 -> 0.3.10. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Benchmark Results (Julia v1)Time benchmarks
Memory benchmarks
|
This branch is based on main, which still points the benchmark page's RawCode components at the old `../benchmark/*.jl` paths. PR #78 moved those files into `../benchmark/comparison/`, so the docs build (and the Vercel preview) crashes with `ENOENT: ../benchmark/expronicon.jl`. Point all 7 paths at `../benchmark/comparison/`. `astro build` now completes (22 pages, 0 errors). Same fix as #79; both converge to identical content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repo uses release-please (release-type: julia), which bumps Project.toml + CHANGELOG.md from Conventional Commits on push to main. Manually bumping to 0.3.10 conflicts with the manifest (still 0.3.9), so revert to 0.3.9 and let the `feat:` commit drive the bump automatically. Also de-hardcode the version in the singleton deprecation note, since the exact release number is chosen by release-please. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on-syntax # Conflicts: # docs/src/content/docs/data/syntax.mdx
Records the lesson from this PR: manually bumping Project.toml in a feature PR fights release-please and, once that version is released, causes merge conflicts against main. Documents that release-please owns Project.toml/CHANGELOG.md/manifest and derives the bump from commit types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #80 +/- ##
==========================================
+ Coverage 91.41% 91.42% +0.01%
==========================================
Files 42 42
Lines 1607 1610 +3
==========================================
+ Hits 1469 1472 +3
Misses 138 138 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
github-actions Bot
referenced
this pull request
Jul 12, 2026
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This branch was successfully deployed
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.
Motivation
Follow-up to #22. The confusion in that issue comes from singleton variants being written as a bare identifier:
Score.ZeroZerois actually the variant type, not a value — you must callScore.ZeroZero()to get an instance ofScore.Type. The bare syntax reinforces the wrong mental model, producing bafflingconvert/dispatchMethodErrors (see #22).On "does Julia have singleton types?"
Yes — Julia has singleton types (an immutable no-field struct has exactly one instance;
Base.issingletontype(Empty) == true, and Moshi's ownScore.ZeroZero() === Score.ZeroZero()istrue). But the type and its instance are always distinct objects (Nothingvsnothing); there is no way to make one bare name be simultaneously a type and its sole value the way a Rustenumvariant is. Moshi needs the variant name to remain a type (for dispatch, reflection, and pattern matching), and aconstvalue binding is impossible for generic ADTs (Option.None{Float64}). So the honest fix is to make the syntax explicit rather than fake a value binding.Change
@datanow accepts the explicitName()singleton form (previously rejected with "missing fields") and treats it as the canonical spelling.Nameform still parses to aSingletonbut emits aBase.depwarn(...; force=true)at macro-expansion time pointing toName().release-type: julia); thefeat:commit drives a patch bump automatically.Scope
src/data/cons.jl— acceptName(), deprecate bareName.src/match/repr.jlWildcard→Wildcard()so Moshi doesn't warn on its own load; all test@datablocks migrated to().data/syntax.mdx,data/understand.mdx,start/*updated to teachName()and explain the type-vs-value point + deprecation.--depwarn=error, which escalates the warning to a throw).Verification
Pkg.test()green: data 285 (+5 new), match 103, derive 30, perf 5.@datasingleton warns at expansion, and the explicitName()form constructs correctly with no warning.JuliaFormatter(blue) reports all touched files unchanged.Notes
()to be a value (#22) #79 (the docs-clarification PR). Both touch the singleton docs, so a small merge conflict is expected depending on merge order — I can rebase whichever merges second.data/benchmarkRawCodepath issue (fixed separately in docs: clarify that singleton variants need()to be a value (#22) #79); it is unrelated to these changes and my MDX pages compile fine.Refs #22
🤖 Generated with Claude Code