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 投票

评论者:dnolen

补丁审查,我并不完全理解将 variadic-fn 的可变参数数量修改和添加此新标志的目的。难道不能直接将其逻辑放入 variadic-fn 中吗?

0 投票
_由 hlolli 提出的评论:

是的,我会为我的补丁找到更好的解决方案,只是第 3176 行中 let 绑定中的 `m` 符号。

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

合并了 arglists,但在此之后就没有办法知道 :arglists 是从提供的元数据来的,还是不是。不过我会重命名 let 符号,避免增加可变参数数量,我已经计划今天稍后做另一个补丁。

我还没有提交我的 Clojure 贡献者协议书,我现在正在填写...
0 投票
_由 hlolli 提出的评论:

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

代码
用于元数据的符号名 `m` 已经不是很好了,但我只是添加了逗号来区分 vararg-fn 情况和其他情况。

当我测试这个代码时,我发现多版本函数 arglist 元数据无论是否有特定地添加 arglists 都不起作用。如果是这样,我可以为这个话题再次打开一个 JIRA 票据。
0 投票
参考:https://clojure.atlassian.net/browse/CLJS-2351(由 hlolli 报告)
0 投票

这也适用于多版本函数。

(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-fnvariadic-arity-fn 的定义中检查元数据是否已经存在 `:arglists` 键来解决。

我希望看到这个问题的解决,如果你想要 multi-arity-fn 修正的补丁,请告诉我。

0 投票

这个工单缺少一个解释说明这个改变是必要或有用的吗?

对`:arglists`的修改将直接影响到编译器生成的代码。如果不匹配实际的函数定义,则会破坏变长调用,甚至在某些参数数量上“删除”调用。

我注意到`eduction`的定义在Clojure和ClojureScript中都覆盖了它的`:arglists`元数据。
在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"]}
正如我所说,有几个地方`:arglists`元数据可能会影响到生成的代码(例如 [CLJS-1871](https://clojure.atlassian.net/browse/CLJS-1871))。

用这个作文档说明应该应该是没有问题的,但从工单描述中并没有明确说明这一点。
对我来说,这完全是出于文档目的,虽然我不熟悉CLJS代码库,但提出的补丁让我有点担忧。与其覆盖内部的`arglists`变量,我更建议在组装元数据时覆盖它,这样就不会产生后续影响。
对我来说,这完全是出于文档目的。这对文档非常重要,否则编辑器的提示将显示gensyms而不是正确的名称。

我不熟悉CLJS代码库,但提出的补丁让我有点担心。与其覆盖内部的`arglists`变量,我怀疑是否仅仅在组装元数据时覆盖它,这样就不会产生后续的影响。

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