Skip to content

Commit af07a10

Browse files
committed
MeTTa TS 1.3.1
1 parent 93c4bc7 commit af07a10

15 files changed

Lines changed: 87 additions & 13 deletions

File tree

RELEASE_NOTES.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
# MeTTa TS 1.3.1
2+
3+
MeTTa TS 1.3.1 fixes the type checker's arity check for overloaded operations. An
4+
operation declared with several signatures is now accepted whenever a call matches
5+
any of them, not only the last-declared one.
6+
7+
## Fix
8+
9+
`check-types` reported `IncorrectNumberOfArguments` for a call whose argument count
10+
did not match an operation's last-declared signature, even when another overload
11+
accepted it. The documentation operation `@return`, for example, is declared both
12+
`(-> String DocReturnInformal)` and `(-> DocType DocDescription DocReturn)`, so the
13+
one-string form `(@return "…")` used throughout the standard library and the `das`
14+
module was wrongly flagged. The applicability check now consults every declared
15+
signature and, following Hyperon, accepts the call when any overload matches the
16+
argument count and its argument types. Genuinely wrong arities still error, and
17+
singly-typed operations are unchanged. This removes a false-positive warning the
18+
MeTTa LSP surfaced on valid documentation.
19+
20+
## Verification
21+
22+
- The conformance oracle passes all 23 corpus files, byte-identical to 1.3.0.
23+
- `pnpm test` passes, with a new regression test for overloaded-operation arity.
24+
- No performance change: the overload lookup runs only when the primary signature's
25+
arity does not match, so the common path is untouched (measured within noise).
26+
27+
## Packages
28+
29+
All public packages use version `1.3.1`:
30+
31+
```bash
32+
npm install @metta-ts/core@1.3.1
33+
npm install -g @metta-ts/node@1.3.1
34+
```
35+
136
# MeTTa TS 1.3.0
237

338
MeTTa TS 1.3.0 moves the standard libraries and the debugger engine out of the

packages/browser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/browser",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/core",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/core/src/eval.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,18 @@ describe("evaluator (smoke)", () => {
111111
!(g a)`;
112112
expect(first(run(tooFew))).toEqual(["(Error (g a) IncorrectNumberOfArguments)"]);
113113
});
114+
115+
it("accepts a call matching any overload of a multiply-typed op", () => {
116+
// A multiply-declared op accepts either arity; a count matching a non-last signature must not be flagged
117+
// IncorrectNumberOfArguments. This is the mechanism behind the LSP false positive on `@return`'s valid
118+
// one-string doc form, which core declares both `(-> String DocReturnInformal)` and `(-> DocType …)`.
119+
const decls = `
120+
(: r (-> String Done))
121+
(: r (-> Number Number Done))`;
122+
expect(first(run(`${decls}\n!(check-types (r "one"))`))).toEqual(["()"]);
123+
expect(first(run(`${decls}\n!(check-types (r 1 2))`))).toEqual(["()"]);
124+
expect(first(run(`${decls}\n!(check-types (r))`))).toEqual([
125+
"(Error (r) IncorrectNumberOfArguments)",
126+
]);
127+
});
114128
});

packages/core/src/eval.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2190,7 +2190,32 @@ export function checkApplication(
21902190
// precomputed `opSig` it then reuses for partial application, so the signature is looked up once per
21912191
// application.
21922192
if (opSig !== undefined && opSig.length >= 1 && args.length !== opSig.length - 1) {
2193-
const hasTupleType = (env.types.get(op) ?? []).some((t) => opOf(t) !== "->");
2193+
const allTypes = env.types.get(op) ?? [];
2194+
const hasTupleType = allTypes.some((t) => opOf(t) !== "->");
2195+
// `env.sigs` keeps only the last declaration, but a multiply-typed op has more. `@return`, for example,
2196+
// is declared both `(-> String DocReturnInformal)` and `(-> DocType DocDescription DocReturn)`, so the
2197+
// one-string doc form `(@return "…")` is valid even though it does not match the last signature. Hyperon
2198+
// `check_if_function_type_is_applicable` accepts a call when ANY function type applies, so gather the
2199+
// overloads that accept this argument count: if one type-checks, the call is applicable.
2200+
const arityMatches: Atom[][] = [];
2201+
for (const t of allTypes)
2202+
if (t.kind === "expr" && opOf(t) === "->" && args.length === t.items.length - 2)
2203+
arityMatches.push(t.items.slice(1));
2204+
if (arityMatches.length > 0) {
2205+
let firstMismatch: [number, Atom, Atom] | undefined;
2206+
for (const overloadSig of arityMatches) {
2207+
const overloadMm = typeMismatch(env, w, op, args, overloadSig);
2208+
if (overloadMm === undefined) return null;
2209+
firstMismatch ??= overloadMm;
2210+
}
2211+
if (hasTupleType || firstMismatch === undefined) return null;
2212+
const [pos, expected, actual] = firstMismatch;
2213+
return expr([
2214+
sym("Error"),
2215+
expr([sym(op), ...args]),
2216+
expr([sym("BadArgType"), gint(pos), expected, actual]),
2217+
]);
2218+
}
21942219
// PeTTa-style partial application is allowed for grounded ops. User-declared typed functions keep
21952220
// Hyperon's strict arity errors.
21962221
const underAppliedPartial =

packages/das-client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/das-client",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/das-gateway/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/das-gateway",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/debug/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/debug",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.js",

packages/edsl/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/edsl",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"author": "MesTTo",
55
"license": "MIT",
66
"description": "Ergonomic, typed TypeScript eDSL for MeTTa: term builders, tagged templates, host-interop builders, and auto-grounding of TypeScript values.",

packages/grapher/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@metta-ts/grapher",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"author": "MesTTo",
55
"license": "MIT",
66
"description": "MeTTa visual editor and reduction renderer for browser and Node.js, with node-graph and nested-block views.",

0 commit comments

Comments
 (0)