请在2024 年 Clojure 状态调查中分享您的看法!

欢迎!请参阅关于页面获取更多关于此网站如何工作的信息。

+1
ClojureScript
考虑没有参数的函数


(defn aarg {:arglists '([fake])} [])
=> {:ns cljs.user,
 :name aarg,
 :file nil,
 :end-column 11,
 :column 1,
 :line 1,
 :end-line 1,
 :arglists ([fake]),
 :doc nil,
 :test nil}


所有工作都按预期进行,但是当引入可变参数后


(defn aarg {:arglists '([fake])} [& env])
(meta #'aarg)
=> {:ns cljs.user,
 :name aarg,
 :file nil,
 :end-column 11,
 :top-fn {:variadic true,
          :max-fixed-arity 0,
          :method-params [(env)],
          :arglists ([& env]),
          :arglists-meta (nil)},
 :column 1,
 :line 1,
 :end-line 1,
 :arglists ([& env]),
 :doc nil,
 :test nil}


:arglists不受影响。

8 个答案

0

评论由:hlolli

我刚刚提交了一个补丁,之前从未使用过jira补丁系统,除此之外,这个补丁将使编译器当我们提供时尊重`:arglists`元数据。希望得到反馈并合并:)

0

评论由:dnolen

感谢,您提交了Clojure CA吗?

0
by

评论由:dnolen

补丁审查,我不是很理解改变可变参数函数的参数个数和添加这个新标识符的目的。难道直接将逻辑放到可变参数函数中不行吗?

0
by
_由 hlolli 发布的评论

是的,我将找到更好的解决方案来修正我的补丁,只是第三行 let 绑定的 `m` 符号:

m (conj {:arglists (core/list 'quote (sigs fdecl))} m)

合并了参数列表,并且在此之后无法知道 :arglists 是否来自提供的元数据。但我将重命名 let 符号,并很容易避开添加参数个数,我将稍后今天再次提交补丁。

我还没有提交我的 Clojure 贡献者协议,我现在正在填写...
0
by
_由 hlolli 发布的评论

昨天我签署了 Clojure CA
"Rich Hickey 和 Hlöðver Sigurðsson 之间的 Clojure CA 已签署并归档!"

代码
用于元数据的符号名 m 已经不是很好了,但我只是添加了一个逗号来区分可变参数函数情况和其他情况。

我在测试中发现多参数函数的参数列表元数据无论是在是否专门添加参数列表的情况下都不工作。如果是这样,我可以为该问题打开另一个 jira 报告。
0
by
参考:https://clojure.atlassian.net/browse/CLJS-2351(由 hlolli 报告)
0
by

这同样适用于多重参数函数

(defn bar {:arglists '([foo bar])}
  ([x] 1)
  ([x y] 2))

(meta #'bar)
;;=> {:ns cljs.user,
 :name bar,
 :file nil,
 :end-column 10,
 :top-fn
 {:variadic? false,
  :fixed-arity 2,
  :max-fixed-arity 2,
  :method-params ([x] [x y]),
  :arglists ([x] [x y]),
  :arglists-meta (nil nil)},
 :column 1,
 :line 1, 
 :end-line 1, 
 :arglists ([x] [x y]), 
 :doc nil, 
 :test nil}

而单参数函数则工作正常

(defn foo {:arglists '([foo])} [x] 1)
(meta #'foo)
;; => {:ns cljs.user,
 :name foo,
 :file nil,
 :end-column 10,
 :column 1,
 :line 1, 
 :end-line 1, 
 :arglists ([foo]), 
 :doc nil, 
 :test nil}

我认为这可以通过在 multi-arity-fn 定义和 variadic-arity-fn 中检查元数据中是否已经存在一个 :arglists 键来解决。

我非常希望看到这个问题的解决,如果你需要针对多参数函数修复的补丁,请告诉我。

0

这个工单缺少解释为什么这个改动是必要的/有用的?

修改`:arglists`将直接影响编译器生成的代码。如果元数据与实际函数定义不完全匹配,则将破坏可变参数调用或甚至“丢弃”某些变体数的调用。

by
我注意到在Clojure和ClojureScript中,`eduction`的定义覆盖了其`:arglists`元数据。
by
在Clojure中,至少,提供`:arglists`元数据以向编辑器和REPL提供有用的提示是很常见的,而且`:arglists`元数据根本不影响语义:它只是为了提供可读性强的提示。

以下在Clojure中有效

dev=> (defn foo {:arglists '([foo bar])} ([x]) ([x y]))

#'dev/foo

dev=> (meta #'foo)

{:arglists ([foo bar]), :line 1, :column 1, :file "/home/seanc/.clojure/dev.clj", :name foo, :ns #object[clojure.lang.Namespace 0x34e700f4 "dev"]}
by
就像我说的,有几个地方`:arglists`元数据可能会影响生成的代码(例如[CLJS-1871]()。

如果要用于文档目的,这应该是没有问题的,但这个工单描述中没有明确指出。
在我的情况下,这纯粹是为了文档目的,虽然我对CLJS代码库不太熟悉,但建议的补丁让我有点担忧。与其覆盖内部的`arglists`变量,我宁愿在组装元数据时覆盖它,这样就不会产生下游影响。
在我的情况中,这纯粹是为了文档目的。这非常重要,否则编辑器提示会显示gensym而不是正确的名称。

 我不熟悉CLJS代码库,但建议的补丁让我有点担忧。与其覆盖内部的`arglists`变量,我不禁想,如果在组装元数据时覆盖它是否会有帮助,这样就不会产生下游影响。

```
元数据                                (关联元数据
                               :top-fn
                               {:variadic? variadic?
                                :fixed-arity mfa
                                :max-fixed-arity mfa
                                :method-params (core/cond-> sigs macro? elide-implicit-macro-args)
                                ;; FIX: 有点像这样
                                :arglists (or (:arglists meta)
                                                       (core/cond-> arglists macro? elide-implicit-macro-args))
                                :arglists-meta (if (:arglists meta)
                                                 (doall (map meta (:arglists meta)))
                                                 (doall (map meta arglists)))})
```
...