Partial application moves its arguments into the generated closure
維護者通常 1 天內回覆
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 25/100
- Issue 類型
- 缺陷
- 描述清晰度
- 描述清楚
- 活躍度
- 停滯
- 技術堆疊
- javascript
- 領域
- compilers
研究方向
Start in compiler/ml/translcore.ml at transl_apply's uncurried_partial_application branch, then compare its argument handling with build_apply's protect path. Check the compiler tests for partial application, including cases with await, side effects, and yield. Done means arguments are evaluated once at the partial application site and remain valid outside the generated closure.
由索引模型根據 Issue 內容生成。
描述
Partial application with ... puts the supplied arguments inside the closure it creates, instead of evaluating them first.
let add = (a, b, c) => a + b + c
let f = async p => {
let h = add(await p, ...)
h(1, 2) + h(3, 4)
}
compiles to
async function f(p) {
let h = (extra, extra$1) => add(await p, extra, extra$1);
return h(1, 2) + h(3, 4) | 0;
}
await inside a non-async arrow is a JavaScript syntax error, so the module fails to load.
The same placement also re-evaluates the argument on every call:
let g = () => {
let h = add(next(), ...)
h(1, 2) + h(1, 2)
}
function g() {
let h = (extra, extra$1) => add(next(), extra, extra$1);
return h(1, 2) + h(1, 2) | 0;
}
Here next() runs twice, once for each call of h.
When h is used only once, the optimizer inlines it and both problems disappear, which may be why this hasn't been noticed.
Expected: the arguments are evaluated once, where the partial application happens:
let arg = await p;
let h = (extra, extra$1) => add(arg, extra, extra$1);
Cause: in compiler/ml/translcore.ml, transl_apply's uncurried_partial_application branch puts the translated arguments directly into the body of the new function. The optional-argument path (build_apply) already let-binds non-trivial arguments outside the closure (protect); the ... path should do the same.
This also blocks generator functions, since a yield would be moved into the closure the same way.
Reproduced on master (8556f0ad72).
- 主要語言
- ReScript
- 星號
- 7.5k
- 分支
- 483
- 平均合併
- 1 天 2 小時
- 30 天內合併 PR
- 164
環境準備
在瀏覽器裡用你自己的 GitHub 帳號啟動這個專案的開發容器。
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
rescript-lang/rescript 的其他 Issue
-
難度 4/5 3-5 天 新手友好度 48/100
rescript-lang/rescript#8938 ·
維護者通常 1 天內回覆
-
discussion enhancement
難度 5/5 一週以上 新手友好度 35/100
rescript-lang/rescript#8934 · 1 個 reaction ·
維護者通常 1 天內回覆
-
難度 5/5 一週以上 新手友好度 25/100
rescript-lang/rescript#8910 ·
維護者通常 1 天內回覆
-
Nested JSX components under React Server Components: derive flat exports from the signature可能已有人在做 @cknitt 於 3 天前認領。 未關閉
難度 5/5 一週以上 新手友好度 25/100
rescript-lang/rescript#8901 ·
維護者通常 1 天內回覆
-
難度 5/5 一週以上 新手友好度 35/100
rescript-lang/rescript#8897 ·
維護者通常 1 天內回覆
查看 rescript-lang/rescript 的全部 Issue
相似的 Issue
-
bug priority: P2
難度 1/5 1 小時以內 新手友好度 78/100
維護者通常 1 天內回覆
-
confirmed generated by fuzzer llvm:optimizations miscompilation
難度 2/5 1-3 小時 新手友好度 78/100
llvm/llvm-project#234325 ·
維護者通常 1 天內回覆
-
grammar selfhost sev-3
難度 2/5 1-3 小時 新手友好度 78/100
-
難度 2/5 1-3 小時 新手友好度 62/100
-
難度 2/5 1-3 小時 新手友好度 78/100
gren-lang/compiler-common#41 ·