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 patch 系统,不过,这个补丁将使编译器尊重用户提供的 :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
"Rich Hickey 和 Hlöðver Sigurðsson 之间的 Clojure CA 已签署和存档!"

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

当我测试这个时,我发现多参数函数的 arglist 元数据无法在没有添加 arglist 的情况下使用。如果是这样,我可以为此开启另一个 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 键来解决此问题。

我非常希望看到这个问题的修复,如果您要为多参数函数的修复提供一个补丁,请告知。

0

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

修改 :arglists 会直接影响到编译器生成的代码。如果元数据与实际函数定义不完全匹配,它将破坏变长函数调用甚至取消对某些形参数的调用。

我注意到在 Clojure 和 ClojureScript 中,`eduction` 的定义覆盖了其 :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](.

用这个来做文档说明是没问题的,但这一点在工单描述中并不清楚。
作者:
在我的情况下,这纯粹是用于文档目的,虽然我对 CLJS 代码库不是很熟悉,但提出的补丁让我有些担忧。与其覆盖内部的 `arglists` 变量,我更愿意覆盖它在组装元数据时,这样就不会产生后续影响。
作者:
在我的情况下,这纯粹是用于文档目的。而且这非常重要,否则编辑的提示会显示 gensyms 而不是合适的名称。

 我对 CLJS 代码库不是很熟悉,但提出的补丁让我有些担忧。与其覆盖内部的 `arglists` 变量,我想知道是否只在组装元数据时覆盖它,这样就不会产生后续影响。

```
meta     (assoc meta
                               :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)))})
```
...