Instance call support: @ separator, void-returns-Any, hybrid field type system, and class method emission#664
Merged
joehendrix merged 2 commits intomainfrom Mar 27, 2026
Merged
Conversation
acca015 to
4c6b6b3
Compare
21fdd05 to
58208e4
Compare
9bf553e to
080c937
Compare
shigoel
previously approved these changes
Mar 27, 2026
joscoh
previously approved these changes
Mar 27, 2026
Contributor
joscoh
left a comment
There was a problem hiding this comment.
Not necessarily blocking, but the ... ++ "@" pattern appears 9 times throughout the code. If we ever want to change the naming convention, it would be better to have this in a separate function.
…pe system, and class method emission - Use @ as class-method separator (e.g., Storage@put_item) to avoid ambiguity with underscored names - Void PySpec procedures now return Any (via from_none), eliminating special-case void handling at call sites - Add translateFieldType: builtins become Any on Composite fields, class types stay Composite (hybrid two-kind system) - Self parameter typed as Composite in __init__/methods - Throw unsupportedConstruct for Composite→Any coercion attempts - Synthesize throwaway LHS variables in LaurelToCoreTranslator for statement-position calls to void-returns-Any procedures - Emit user-defined class method definitions as static procedures - Add positive and negative dispatch tests, regenerate expected files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
080c937 to
2b7a538
Compare
mkInstanceMethodCall now returns Hole for Any-typed receivers, consistent with how other unknown method calls on Any are handled. This fixes the type checking error for `with open(...) as f:` where the context manager type is Any. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
shigoel
approved these changes
Mar 27, 2026
joscoh
approved these changes
Mar 27, 2026
olivier-aws
pushed a commit
that referenced
this pull request
Mar 30, 2026
…pe system, and class method emission (#664) ## Summary Three interrelated changes to the Python→Laurel→Core pipeline that enable correct handling of instance methods, void procedures, and user-defined class fields: 1. **Unambiguous `@` separator for instance methods** — `Storage@put_item` instead of `Storage_put_item`, eliminating collisions with underscored names 2. **Void procedures return Any** — all PySpec procedures now have exactly one output (void returns `Any` via `from_none`), removing special-case void handling at call sites 3. **Hybrid two-kind field type system** — builtin types (int, str, bool, float) become `Any` on Composite fields; class types (PySpec services, user classes) stay `Composite`, matching parameter semantics at call boundaries 4. **User-defined class method emission** — class method definitions (`Counter@__init__`, `Counter@increment`) are now included in the Laurel program as static procedures ## PythonToLaurel changes - `@` separator applied across PythonToLaurel, PythonToCore, PySpecPipeline, and Specs/ToLaurel - New `translateFieldType` helper maps builtins→Any, composites→Composite for field declarations - `self` parameter typed as `Composite` (not `Any`) in `__init__` and user methods - Removed `wrapFieldInAny` for `self.field` reads in method bodies — builtin fields are already Any-typed - `unsupportedConstruct` error thrown when Composite→Any coercion is attempted (e.g., returning a Storage field as str) ## LaurelToCoreTranslator changes - Statement-position calls now synthesize throwaway `$unused_N` variables to match output count, fixing Core arity checks for void-returns-Any procedures - Single-target `Assign` with `StaticCall` also synthesizes extra LHS variables for multi-output procedures ## Testing - New dispatch tests for void assign/init, non-void discard, instance call result, user class construct, class field assign, and class method return - Two negative tests for Composite↔Any kind mismatches: `test_class_composite_as_any` (Composite field returned as Any) and `test_class_any_as_composite` (Any value assigned to Composite field). The latter requires explicit pyspec paths since `IdentifyOverloads` resolves modules from complete programs with `main`, not isolated class snippets. - 7 regenerated expected_laurel files reflecting the new field type system ## Known limitations - Composite→Any coercion (e.g., returning a `Storage` field as `str`) is explicitly rejected with a user-facing error. Coercion functions are being developed separately. - Procedure names used as type annotations (e.g., `Storage_put_item` as a type) silently fall through to `Any` instead of producing an error or warning. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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
Three interrelated changes to the Python→Laurel→Core pipeline that enable correct handling of instance methods, void procedures, and user-defined class fields:
@separator for instance methods —Storage@put_iteminstead ofStorage_put_item, eliminating collisions with underscored namesAnyviafrom_none), removing special-case void handling at call sitesAnyon Composite fields; class types (PySpec services, user classes) stayComposite, matching parameter semantics at call boundariesCounter@__init__,Counter@increment) are now included in the Laurel program as static proceduresPythonToLaurel changes
@separator applied across PythonToLaurel, PythonToCore, PySpecPipeline, and Specs/ToLaureltranslateFieldTypehelper maps builtins→Any, composites→Composite for field declarationsselfparameter typed asComposite(notAny) in__init__and user methodswrapFieldInAnyforself.fieldreads in method bodies — builtin fields are already Any-typedunsupportedConstructerror thrown when Composite→Any coercion is attempted (e.g., returning a Storage field as str)LaurelToCoreTranslator changes
$unused_Nvariables to match output count, fixing Core arity checks for void-returns-Any proceduresAssignwithStaticCallalso synthesizes extra LHS variables for multi-output proceduresTesting
test_class_composite_as_any(Composite field returned as Any) andtest_class_any_as_composite(Any value assigned to Composite field). The latter requires explicit pyspec paths sinceIdentifyOverloadsresolves modules from complete programs withmain, not isolated class snippets.Known limitations
Storagefield asstr) is explicitly rejected with a user-facing error. Coercion functions are being developed separately.Storage_put_itemas a type) silently fall through toAnyinstead of producing an error or warning.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.