2024 Clojure 状态调查! 分享您的想法。

欢迎!请参阅 关于 页面以了解更多关于该功能的详细信息。

0
ClojureScript
{{js->clj}} 表示


  (cond

    [...]
                
    (coll? x)
    (into (empty x) (map thisfn x))


问题在于 {{(coll? x)}} 检查 ICollection,而 {{(empty x)}} 需要 IEmptyableCollection。当 x 通过第一次测试但未通过第二次测试时,{{js->clj}} 就会抛出 "错误:未为类型 : [object Object] 定义 IEmptyableCollection.-empty 协议方法。"

由于 {{js->clj}} 通常在包含 everything but the kitchen sink 的 JavaScript 对象上递归,这不可避免地是一项最佳努力,而不是高原则。一句话,这不是争论的地方。如果集合无法将空值,我期望 {{js->clj}} 尽力保留顺序但不保留类型:使用向量!

5 答案

0

评论者:rohitaggarwal

(链接: ~pbwolf) 你可以给出一个具体的失败案例吗?

0

评论者:jszakmeister

在这里很难给出具体的案例——它似乎只有在复杂的编译过程中才会出现。我有一个程序从服务器返回以下内容:{"Br": 0, "B": 100, "P": 1000} 作为 JSON。js->clj 就会在描述中提到的生成 "没有协议方法" 错误。我发现,如果我将下面的片段

`
(identical? (type x) js/Object)
(into {} (for [k (js-keys x)]

       [(keyfn k) (thisfn (unchecked-get x k))]))

`

放在这个片段之前

(coll? x) (into (empty x) (map thisfn x))

错误已消失——但我并不确定这是否是正确的做法。我怀疑密钥再次与已知的事情发生冲突,并且某个东西在不是集合的情况下却被当作集合处理。然后,当调用(empty x)时,我们失败了,因为我们未能实现所需协议的对象。

我认为这种问题以前在CLJS-1658和7e15b1f2b894d93ef94ff86d75226f1fd3919580中已被解决,但也许有一些我们正在遇到的其他事情,导致我们再次检出错误。

0

评论者:thheller

这很可能无法在不破坏别人js->clj语义的情况下修复。至少我无法想到一个简单的解决方案。

以下是这是一个简要的重现步骤

  • coll?检查ICollection,这是一个快速路径协议
  • 快速路径协议执行了一个位检查,而不是之前固定的哨兵检查
  • 位检查在名为{{cljs$lang$protocol_mask$partition0$}}的属性上执行,而Closure将其缩短为某些未知的东西。鉴于你的示例Object中的“短”键,由于Closure以a、b、c、...开始,因此这很可能冲突。

这个问题可以在Node REPL中重现

`
[6:1]~cljs.user=> (def obj #js {"cljs$lang$protocol_mask$partition0$" 8})

'cljs.user/obj

[6:1]~cljs.user=> (coll? obj)
true
[6:1]~cljs.user=> (empty obj)
eval错误 Error: 为类型object: [object Object] 未定义IEmptyableCollection.-empty协议方法
`

一个简单的修复方法是忘记js->clj并使用仅支持JSON值且不使用协议的东西。

我这里有一个可以使用的
https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/json.cljs#L4-L37

也许我们应该将json->clj添加到核心,并适当记录.js->clj的问题行为?

0

评论者:jszakmeister

{quote}
也许我们应该将json->clj添加到核心,并适当记录.js->clj的问题行为?
{quote}

我认为这是可取的。很久以前,我在项目中实现了自己的json->clj,以解决这个问题,但我想核心中的这个功能将非常有用。

顺便说一下,感谢提供重现步骤。遗憾的是,高级编译摘要缩短了它,可能导致潜在的冲突。

0
引用:https://clojure.atlassian.net/browse/CLJS-2062 (由alex+import报告)
...