请在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 发布

补丁审查,我并不真正理解改变变长参数函数的参数数及添加新标志的目的。不直接将逻辑放入变长参数函数中可以吗?

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 元数据无论是否有特定添加 arglists 都不起作用。如果是这样,我可以为该问题打开另一个 jira 工单。
0
参考:[https://clojure.atlassian.net/browse/CLJS-2351](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-fn 定义和 variadic-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](https://clojure.atlassian.net/browse/CLJS-1871)。

为了文档用途使用这是可以的,但这一点在票据描述中并不清楚。
对于我的情况,这纯粹是为了文档目的,虽然我对CLJS代码库不熟悉,但提议的补丁让我有些顾虑。我更愿意在组装元数据时覆盖`arglists`变量,这样就不会产生下游的影响。
对于我的情况,这纯粹是为了文档目的。并且这对文档非常重要,否则编辑器提示会显示gensyms而不是正确的名称。

 我对CLJS代码库不熟悉,但提议的补丁让我有些顾虑。我怀疑是否只在组装元数据时覆盖`arglists`变量会有所帮助,因为这样就不会产生下游的影响。

```
元数据     (assoc meta
                               :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 (если (:arglists meta)
                                                 (доал (мап(meta) (:arglists meta)))
                                                 (доал (мап(meta) arglists))))})
```
...