duangsuse::Echo
唉,这位的文风也很清晰,而且他居然会为附加功能的缺失说 Sorry ! 看着看着就莫名觉得很感慨😳, ParserKt 所谓之「不制造问题」是有多深刻啊…… 几乎所有的,哪怕函数式解析器框架都支持 Backtracing, ParserKt 刻意只让 peek(1) ,即便现在也醒目地和新 peek(n) 划清界地(这也是 "Decide" 这个名称的由来,因为它只能判1字符😂),却可以让用户清晰地利用 Piped.concat 解决 Name|Name '('{Expr}[',']')' 的歧义消除(而不是先读个…
https://epsil.github.io/gll/#continuation-passing-style-section
#FP #scheme #parser 想了解 continuation-passing-style (没有 return 如何编程?)的大佬们可以看看这人的文章,我觉得相当好。实用性,王垠那几十行代码不就是 CPS 优化吗。
照例个人观点:
0. 上文定义了 success/failure 的 union ,以及 (successed val rest) failure ,还有添加回调的 (bind p f),基本是 (match (p s) [(success v rest) (+ v 1)] [failure failure]) 这么用的。
实现的解析器不支持流,支持 substring 。传递方式是 backtrace (比如 (string "abc") 在 (seq) 里成功则 (cons "abc" (cont "")) 失败就只是 failure 单值,所以要利用 memo 函数)
1. PKT 是不需要这种“优化”的(顶多比过程式慢 50倍的纯函数式框架要用),因为我们的 Seq 明白一解析器失败不考虑后面就 return notParsed ,不需要玩 p1(p2(p3 { })) 这种耗栈的游戏。Kotlin 不支持 CPS 优化,编程也不是智商测试。
2. CPS 也是有一定价值的,虽然它会损失一定性能,但能够拿到调用者的句柄(比如在有 Decide 的模式里,就可以后继操作遍历所有分支了,或者进行异步回调"thunk"函数)。和非 CPS 一样可作为 suspend fun 协程
3. 即便这篇文章相对易懂 #Lisp #Racket ,我不建议大家认真用 Racket ,原因是括号的表现力不够
比如文中
4. 从解决实际问题而言我觉得 ParserKt 更贴近,但这个文章所创建的解析组合子用更少的代码定义了更广义的实现方法,非常有意思(最后也用左递归和 regex 创建了计算器,缓存和穷举最长匹配问题如此有意思以至于我开始可惜PKT不用处理它了😳),而且也易懂的讲解了 CPS/trampoline 以及“穷举所有可能结果”的正统函数式思路 #Learn
#FP #scheme #parser 想了解 continuation-passing-style (没有 return 如何编程?)的大佬们可以看看这人的文章,我觉得相当好。实用性,王垠那几十行代码不就是 CPS 优化吗。
照例个人观点:
0. 上文定义了 success/failure 的 union ,以及 (successed val rest) failure ,还有添加回调的 (bind p f),基本是 (match (p s) [(success v rest) (+ v 1)] [failure failure]) 这么用的。
实现的解析器不支持流,支持 substring 。传递方式是 backtrace (比如 (string "abc") 在 (seq) 里成功则 (cons "abc" (cont "")) 失败就只是 failure 单值,所以要利用 memo 函数)
1. PKT 是不需要这种“优化”的(顶多比过程式慢 50倍的纯函数式框架要用),因为我们的 Seq 明白一解析器失败不考虑后面就 return notParsed ,不需要玩 p1(p2(p3 { })) 这种耗栈的游戏。Kotlin 不支持 CPS 优化,编程也不是智商测试。
2. CPS 也是有一定价值的,虽然它会损失一定性能,但能够拿到调用者的句柄(比如在有 Decide 的模式里,就可以后继操作遍历所有分支了,或者进行异步回调"thunk"函数)。和非 CPS 一样可作为 suspend fun 协程
3. 即便这篇文章相对易懂 #Lisp #Racket ,我不建议大家认真用 Racket ,原因是括号的表现力不够
比如文中
(let (result (apply op args)) (entry (mcons args result)) (set! alist (mcons entry alist)) (m=map)一大堆括号,有没有注意到 (let (a v) expr) 只是为可读性而加的,量定义可以内联…… 只是表达 alist = args to op(args) : alist 甚至 alist[args] = result 的意思呢(这例还是SICP里的呢,多余命名量本身就可能意味着语言性能缺失😢,比如『文言文』里甲乙丙丁一大堆OK么)…… 函数式那么多年修成正果了,开始从“无副作用”往“看起来像过程式”靠,草生(* ̄m ̄)4. 从解决实际问题而言我觉得 ParserKt 更贴近,但这个文章所创建的解析组合子用更少的代码定义了更广义的实现方法,非常有意思(最后也用左递归和 regex 创建了计算器,缓存和穷举最长匹配问题如此有意思以至于我开始可惜PKT不用处理它了😳),而且也易懂的讲解了 CPS/trampoline 以及“穷举所有可能结果”的正统函数式思路 #Learn
Vegard’s blog
General Parser Combinators in Racket
How to implement a general parser combinator framework which handles left-recursive and ambiguous grammars.
#linux #windows #wsl #sysadmin
一个 npm/vue 项目,试了 wsl(2),失败后虚拟机+ vbox(vmware) shared dir, IDEA source depoly, samba, nfs(失败) 四种方案,最终选择了 samba
为了在主机和虚拟间共享项目文件夹, VBox 的实现性能太低而且不支持软连接(npm install 要炸)、 IDEA 的代码部署可以全量上传下载,但是 sync 时也有点慢、 Samba 配置要禁用 unix extensions 并启用 follow symlinks, wide links 只是偶尔卡、NFS 在 Windows 下文件无法重命名,而 Linux 下则显示来自奇怪的用户,并且依然卡……
个人观点:没用过 Qt 以外的跨平台,不过我是从来只在本地测试的……
一个 npm/vue 项目,试了 wsl(2),失败后虚拟机+ vbox(vmware) shared dir, IDEA source depoly, samba, nfs(失败) 四种方案,最终选择了 samba
为了在主机和虚拟间共享项目文件夹, VBox 的实现性能太低而且不支持软连接(npm install 要炸)、 IDEA 的代码部署可以全量上传下载,但是 sync 时也有点慢、 Samba 配置要禁用 unix extensions 并启用 follow symlinks, wide links 只是偶尔卡、NFS 在 Windows 下文件无法重命名,而 Linux 下则显示来自奇怪的用户,并且依然卡……
个人观点:没用过 Qt 以外的跨平台,不过我是从来只在本地测试的……
Forwarded from 新蛤社
https://book.wy-lang.org/ #web #js
说一下这个索引的生成方法。
欸我写这个干什么呢……
说一下这个索引的生成方法。
val category by helem()
val book by helem()
fun generate() {
for (i, c) in chapters.map(::generateChapter).withIndex() {
category.appendChild(element("div", withClass("chapter-ref"),
element("img", withDefault(), chapterIcons[i])), c.firstChild/*h1*/.innerText)
book.appendChild(c)
}
}
其实是function generate() {
var i=0; for (let c of [...chapters.map(generateChapter)]) {
category.appendChild(<div class="chapter-ref">c.firstChild.innerText<img src=icons[i]></img></div>)
book.appendChild(c)
i += 1
}
}
当然也可以写成 onChapter 的形式:function onChapter(i, c) {
categories.appendChild(/**/)
}
function generate() {
var i=0; for (let c in /**/) {
book.appendChild(c); onChapter(i, c); i += 1
}
} 欸我写这个干什么呢……
book.wy-lang.org
wenyan-book
An Introduction to Programming in Wenyan Language
duangsuse::Echo
关于 Kamet 里 val/var 和 let 的区别,本来我的意思是要除掉 let 的,但它的语义也的确不同 最开始, Kamet 只有栈上局部变量 var 和 const var (即后来的 val) 后来 Mivik 可能是发现 fun add1(n:Int) { val res = n+1; return res } 完全不需要实际栈上分配而可以内联,于是又新加入了 let 看起来 var / val 和 let 是各司其职、其区分无可厚非,我相信这种做法仍是不好看的,并且 val 应该默认具有…
现在想来 Mivik 必须区分 val/let 的问题,除了局部 struct/array 分配的必要性,大概是对
这有关于 inline 开销——无论是先算完存下来(就必须在栈上分配),还是每次去算都好,该取最优化的结果;譬如
和函数的 inline 不同,因为
选择让用户决定无可厚非,但不利于代码的可移植性和语义泛用性,而且这样容易引起麻烦—— let 和 val 后面都可以跟任何表达式,但
其实 kamet 的处境也很麻烦——全部栈上吧,不知道 LLVM 是否会有优化(目前只已知 mem2reg 的 alloca 寄存器分配优化),不想分配多余栈空间
全部 IR 节点内联吧,如上例不科学;而自动选择是内联还是缓存变量, LLVM 貌似没提供(只有函数级别的内联开销,不适用)
所以就只好分出了 val/let ,当然我个人是拼命不会用这种做法的(我大概就会做成有 1 层计算
(xs.size-1) inline 还是局部分配计算&引用的问题。这有关于 inline 开销——无论是先算完存下来(就必须在栈上分配),还是每次去算都好,该取最优化的结果;譬如
xs.size 是 struct(named product type) 上的解指针,完全可以内联,而 x+1*2/3 这种复杂计算显然不应该到处内联;但开销除了计算量也是关于引用处的分数,譬如 val size = xs.size 解指针计算量小,但如果有许多引用则还是作变量缓存比较好。和函数的 inline 不同,因为
inline val lastIndex get() = size-1 是绝对的内联表达式,不会存栈帧局部分配。选择让用户决定无可厚非,但不利于代码的可移植性和语义泛用性,而且这样容易引起麻烦—— let 和 val 后面都可以跟任何表达式,但
let user = User() 接着 user.name = "wtf" 是有效的,但应该是不可行的;这会降低语言的一致性和安全性。其实 kamet 的处境也很麻烦——全部栈上吧,不知道 LLVM 是否会有优化(目前只已知 mem2reg 的 alloca 寄存器分配优化),不想分配多余栈空间
全部 IR 节点内联吧,如上例不科学;而自动选择是内联还是缓存变量, LLVM 貌似没提供(只有函数级别的内联开销,不适用)
所以就只好分出了 val/let ,当然我个人是拼命不会用这种做法的(我大概就会做成有 1 层计算
a.name 式的就内联,否则就局部分配的形式... 很反智,不知道有没有更好的方法https://github.com/JetBrains/kotlin/blob/master/compiler/backend/src/org/jetbrains/kotlin/codegen/FrameMap.kt 草,这个算局部表么…… Kt 的编译器好复杂,找不到它是咋用 JVM 栈的
https://github.com/JetBrains/kotlin/blob/master/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt#L95
不过倒是找到了 is, as? 的生成代码…… 原来 Adapter 是这么用的草
https://github.com/llvm-mirror/clang/commit/3c1c202adacce7479418fdb83d8257e2d9e0f125
看不懂,但找到了许多冗余代码…… 不愧是 C++ ,不过我看 Kotlin 也没法规避更多的吧
https://github.com/JetBrains/kotlin/blob/master/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt#L95
不过倒是找到了 is, as? 的生成代码…… 原来 Adapter 是这么用的草
https://github.com/llvm-mirror/clang/commit/3c1c202adacce7479418fdb83d8257e2d9e0f125
看不懂,但找到了许多冗余代码…… 不愧是 C++ ,不过我看 Kotlin 也没法规避更多的吧
GitHub
JetBrains/kotlin
The Kotlin Programming Language. Contribute to JetBrains/kotlin development by creating an account on GitHub.
https://lingdong.works/ #life #tech #cs 真的好无奈,这些前端类大佬,虽然并不真正了解你的领域,但基于数据结构算法的基础也可以轻松做一个能用的玩具出来,这能灵活利用他们的智商。
而且他们的行动力超强,即便是这种麻烦的设计,也是在他们眼中“不起眼”的小把戏,好打击自信呢。
而且他们的行动力超强,即便是这种麻烦的设计,也是在他们眼中“不起眼”的小把戏,好打击自信呢。
lingdong.works
Lingdong Huang
Projects by Lingdong Huang and collaborators.
#reveng 草,之前听到过,不过不知道可以动态 hook 各种函数…… 当时不理解它说的 "magic" 是啥玩意,我运行过测试但啥输出没有
Forwarded from dnaugsuz
人家都 root 了你对抗个毛啊…… 这里知道这个工具的人估计都少
去 StackOvf / Stack Exchange 或者 SegFault 什么的看看? 🤔
去 StackOvf / Stack Exchange 或者 SegFault 什么的看看? 🤔