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
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会直接影响到编译器生成的代码。如果元数据与实际函数定义不精确匹配,就会破坏可变参数调用,甚至“丢弃”某些arity的调用。

我注意到,在Clojure和ClojureScript中,都过多地提供:arglists元数据,以提供帮助编辑器和REPL的提示。
在Clojure中,至少,为编辑器和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)
                                .CompilerServices: 类似这样
                                :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)))})
```
...