Files
AILang/experiments/2026-05-12-cross-model-authoring/qwen-mexpr.md
T
Brummel 7fe08139fb experiment(cma): M-expressions tested — middle of the pack; sharpens the finding (refs #68)
Tested McCarthy's head[a; b] notation (user request). Explicit structure
(brackets + semicolons) in the function-call shape LLMs know cold. Result
4-5/8 (model variance over two runs): below plain parens, above bracket-free.

Two watch-out catches kept it honest: (1) a trailing ';' before ']' — a normal
trailing separator Qwen wrote — was rejected by my too-strict parser; fixed to
tolerate it, round-trip preserved (without this M-expr looked unfairly bad).
(2) L4 then failed with 43 '[' vs 42 ']', a genuine Qwen bracket imbalance (not
truncation), the same depth-tracking failure as plain parens.

Why worse than plain parens despite being explicit: swapping () for [] does
nothing for the balance burden, and the semicolons ADD a second consistency
requirement Qwen does not reliably meet.

This sharpens the overall finding across five formats (annotated-parens 7/8 >
plain parens 6/8 > M-expr 4-5/8 > indent 3/8 > YAML 2/8): the discriminator is
not "explicit vs implicit" but REDUNDANT CUE vs EXTRA BURDEN. Depth-annotated
parens carry nesting redundantly so the model can't lose its place (best);
indentation moves tracking to an implicit channel (worst); M-expr semicolons
add bookkeeping on top of bracket balance (middle). Lever for an LLM-authored
language: redundant self-checking structure, not a lighter or more familiar
surface that carries extra bookkeeping. Synthesis in format-findings.md.
2026-06-02 19:11:18 +02:00

510 lines
8.2 KiB
Markdown

# Qwen format probe — M-expressions `head[a; b]`
**Model:** Qwen/Qwen3-Coder-Next; single-shot; own literal parser (atoms verbatim).
---
## L0_const — ✅ green
tokens: prompt=616 completion=56
model output:
```
module[
m;
fn[
answer;
type[
fn-type[
params[];
ret[
own[
con[Int]
]
]
]
];
params[];
body[
42
]
]
]
```
converted Form-A:
```
(module m (fn answer (type (fn-type (params) (ret (own (con Int))))) (params) (body 42)))
```
## L1_arith — ✅ green
tokens: prompt=618 completion=72
model output:
```
module[
m;
fn[
triple;
type[
fn-type[
params[
own[
con[Int]
]
];
ret[
own[
con[Int]
]
]
]
];
params[x];
body[
app[*; x; 3]
]
]
]
```
converted Form-A:
```
(module m (fn triple (type (fn-type (params (own (con Int))) (ret (own (con Int))))) (params x) (body (app * x 3))))
```
## L2_print — ✅ green
tokens: prompt=613 completion=79
model output:
```
module[
m;
fn[
main;
type[
fn-type[
params[];
ret[
own[
con[Unit]
]
];
effects[IO]
]
];
params[];
body[
seq[
app[print; 7];
do[io/print_str; "\n"]
]
]
]
]
```
converted Form-A:
```
(module m (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (seq (app print 7) (do io/print_str "\n")))))
```
## L3_adt — ✅ green
tokens: prompt=632 completion=122
model output:
```
module[
m;
data[
Light;
ctor[Red];
ctor[Green]
];
fn[
code;
type[
fn-type[
params[
own[
con[Light]
]
];
ret[
own[
con[Int]
]
]
]
];
params[x];
body[
match[
x;
case[
pat-ctor[Red];
0
];
case[
pat-ctor[Green];
1
]
]
]
]
]
```
converted Form-A:
```
(module m (data Light (ctor Red) (ctor Green)) (fn code (type (fn-type (params (own (con Light))) (ret (own (con Int))))) (params x) (body (match x (case (pat-ctor Red) 0) (case (pat-ctor Green) 1)))))
```
## L4_rec — ❌ convert
tokens: prompt=644 completion=301
model output:
```
module[
m;
data[
IntList;
ctor[Nil];
ctor[
Cons;
con[Int];
con[IntList]
]
];
fn[
length;
type[
fn-type[
params[
own[
con[IntList]
]
];
ret[
own[
con[Int]
]
]
]
];
params[xs];
body[
match[
xs;
case[
pat-ctor[Nil];
0
];
case[
pat-ctor[Cons; h; t];
app[
+;
1;
app[length; t]
]
]
]
]
];
fn[
main;
type[
fn-type[
params[];
ret[
own[
con[Unit]
]
];
effects[IO]
]
];
params[];
body[
let[
xs;
term-ctor[
IntList;
Cons;
1;
term-ctor[
IntList;
Cons;
2;
term-ctor[
IntList;
Cons;
3;
term-ctor[IntList; Nil]
]
];
seq[
app[
print;
app[length; xs]
];
do[io/print_str; "\n"]
]
]
]
]
]
```
**convert:**
```
own parser rejected output: unterminated [
```
## L5_series_len — ❌ check
tokens: prompt=875 completion=182
model output:
```
module[
demo_m;
fn[
main;
type[
fn-type[
params[];
ret[
own[
con[Unit]
]
];
effects[IO]
]
];
params[];
body[
let[
s;
new[
Series;
con[Float];
3
];
];
let[
s1;
app[Series.push; s; 1.0];
];
let[
s2;
app[Series.push; s1; 2.0];
];
let[
s3;
app[Series.push; s2; 3.0];
];
seq[
app[
print;
app[Series.len; s3]
];
do[io/print_str; "\n"]
]
]
]
]
```
converted Form-A:
```
(module demo_m (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (let s (new Series (con Float) 3)) (let s1 (app Series.push s 1.0)) (let s2 (app Series.push s1 2.0)) (let s3 (app Series.push s2 3.0)) (seq (app print (app Series.len s3)) (do io/print_str "\n")))))
```
**check:**
```
error: [surface-parse-error] parse error: expected term, got `)` at byte 134
```
## L6_series_at — ❌ check
tokens: prompt=883 completion=190
model output:
```
module[
demo_m;
fn[
main;
type[
fn-type[
params[];
ret[
own[
con[Unit]
]
];
effects[IO]
]
];
params[];
body[
let[
s;
new[
Series;
con[Float];
3
];
];
let[
s1;
app[Series.push; s; 1.0];
];
let[
s2;
app[Series.push; s1; 2.0];
];
let[
s3;
app[Series.push; s2; 3.0];
];
seq[
app[
print;
app[
Series.at;
s3;
0
]
];
do[io/print_str; "\n"]
]
]
]
]
```
converted Form-A:
```
(module demo_m (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (let s (new Series (con Float) 3)) (let s1 (app Series.push s 1.0)) (let s2 (app Series.push s1 2.0)) (let s3 (app Series.push s2 3.0)) (seq (app print (app Series.at s3 0)) (do io/print_str "\n")))))
```
**check:**
```
error: [surface-parse-error] parse error: expected term, got `)` at byte 134
```
## L7_sma — ❌ check
tokens: prompt=966 completion=327
model output:
```
module[
demo_m;
fn[
main;
type[
fn-type[
params[];
ret[
own[
con[Unit]
]
];
effects[IO]
]
];
params[];
body[
let[
s;
new[
Series;
con[Float];
3
];
let[
s1;
app[Series.push; s; 1.0];
];
let[
s2;
app[Series.push; s1; 5.0];
];
let[
s3;
app[Series.push; s2; 3.0];
];
seq[
app[
print;
app[
/;
app[Series.sum; s3];
3.0
]
];
let[
s4;
app[Series.push; s3; 8.0];
seq[
app[
print;
app[
/;
app[Series.sum; s4];
3.0
]
];
let[
s5;
app[Series.push; s4; 6.0];
seq[
app[
print;
app[
/;
app[Series.sum; s5];
3.0
]
];
let[
s6;
app[Series.push; s5; 2.0];
]
```
converted Form-A:
```
(module demo_m (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (let s (new Series (con Float) 3) (let s1 (app Series.push s 1.0)) (let s2 (app Series.push s1 5.0)) (let s3 (app Series.push s2 3.0)) (seq (app print (app / (app Series.sum s3) 3.0)) (let s4 (app Series.push s3 8.0) (seq (app print (app / (app Series.sum s4) 3.0)) (let s5 (app Series.push s4 6.0) (seq (app print (app / (app Series.sum s5) 3.0)) (let s6 (app Series.push s5 2.0)))))))))))
```
**check:**
```
error: [surface-parse-error] parse error: expected term, got `)` at byte 166
```
---
## Ladder
- L0_const: ✅ green
- L1_arith: ✅ green
- L2_print: ✅ green
- L3_adt: ✅ green
- L4_rec: ❌ convert
- L5_series_len: ❌ check
- L6_series_at: ❌ check
- L7_sma: ❌ check