umajho / dicexp

Dicexp 是一种表示掷骰的表达式。本仓库代码用于对该表达式求值,并作为该表达式的事实标准。
https://umajho.github.io/dicexp/
MIT License
2 stars 0 forks source link

特定情况下闭包调用会将结果固定下来 #22

Closed umajho closed 1 year ago

umajho commented 1 year ago

https://github.com/umajho/dicexp/commit/76823067c9c8459c2a3ccdec88ddbdade0837356 之前,像是 10#\(x -> x).(d10) 会将 d10 固定下来。在该 commit 中,是通过在解析时将 # 视作特殊的运算符,每次都重新解释一遍右侧的 Node 解决的。 但现在再想,即使是原先右侧作为 LazyValue 处理,每次也应该执行都有不同的结果。

像是 10#1 |> map \(x -> \(y -> y).(d10)) 这些没有问题,因为 map 每次调用外层闭包时,外层闭包也会重新解释其内部的内容。

这个 bug 目前潜藏在了深处。

umajho commented 1 year ago

复现:10d(\(x -> if(x==1, 1000, 1)).(d2))

要么是 10,要么特别大。

umajho commented 1 year ago

复现:10d(\(x -> if(x==1, 1000, 1)).(d2))

要么是 10,要么特别大。

这个行为其实没问题,两侧的值在传入函数后会固定住,所以右侧的结果固定住了。 若是存在 intersperse/2 函数,像是 intersperse([1, 2, 3], d10) 也同理,作为 d10 结果插入的值是相同的。

# 果然还是比较特殊,在于其右侧的结果不会被固定住,而是会反复被重新求值。

那就把 issue 关掉了。

umajho commented 1 year ago

但果然还是很怪,d 只会 concretize 右侧一次,而 # 当时每反复一次都会重新 concretize 一次。(见这里。)

还是继续开着这个 issue 吧。

umajho commented 1 year ago

经过大幅度重写,这里的问题应该已经无关紧要了。 在代码库里搜 “concretize” 这个词,结果只出现在一处过时的注释中。 还是关掉这个 issue 好了。