7fe08139fb
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.
510 lines
8.2 KiB
Markdown
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 |