duangsuse::Echo
https://zhuanlan.zhihu.com/p/34064655 #zhihu #fp 这是个物理爱好者18年的 CPS 解释器实现文 这个代码质量.. 其实我是讨厌看lisp 系的,非常讨厌嵌套括号,而且这个人似乎在代码里插debug print ,以C的方法写Racket .. ,那我就把要点挑出来看看 函数式除了伪递归也可做尾调用优化,当 f=()=>g(), g=()=>1 时g可return 到f.retAddr ,类似函数内联。CPS也是尾调用 显然return/即 callstk.pop()…
#PLT #Kotlin 作为编程语言爱好者的我怎么能「只知其一不知其二」呢? 😤x
我对VM/struct,GC(空闲链表标记清除) 都有了解,可就是不懂栈->寄存器 和 Kotlin CPS 不靠 #JS Generator awaiter 怎么实现 async 调用等待
1. 并不是最大栈高度=寄存器数,1+2*3 按结果看有2个,但其实1就够了
思考 x+2*3 ,其实只要1寄存器,但 x+2*a.n ,因为数字和obj 冲突需要两个,那么 a.n.inc 这样的计算链其实也只要一个寄存器!是关于类型的吗? 尽管Dalvik 寄存器有类型
思考 (1*2)+(3*4) ——是因为运算优先级吗?其实是临时位置! 如果 1*2*3 , (2)*3 的位置就可复用,但 *+* 里先算的俩就需2寄存器,+ 在其一上计算
x+(2*a.n) ,首先 a.n 然后 2* 在其上计算,最后+x ... 其实就是一个SSA问题。 但把+-*/. 变节点并不难,就是分配不知咋写..
后计算的尽量复用先算结果的位置,栈->寄存器指令
break/continue 们串成链表,while 结束回填
if jmp-B a jmp-C else b c 记录俩位置,else 回填 jB, end 回填 jC 。递归下降法兼容 if else if 嵌套
2. Kotlin协程和ES6都是基于变量闭包+状态机化,但 JVM 没有 awaiter(IO loop,负责帮忙等待yield的任务并resume 其func*,因此嵌套等待 yield 就行了)
在状态对象上ES6是 Generator{then,throw},Kotlin 是 Continuation{context,resume/WithException} ,分别在this、末参数
在Lua里是基于 lua_State(虚拟机)单步执行权,就有点像pthread了。 但不管Kt,Py,ES6,Lua 的 await/async 都是基于协程实现。 我觉得 CPS 化的最优雅 😊 新学到
StateMachine 是自动生成基于context的cont.resume实现。 在 suspend? fun 内调用休眠函数自会生成其 Cont 实现,把自己的cont注册给它就行
类似ES6(yield),函暂停的位置肯定有 suspend fun 调用,CPS变换给它加自身cont 参数(这是自动回调吗.. 好吧也算),挂起回调度器Dispatcher ,与 __awaiter 不同的是f把 f1.then(cont=f) 指派好了(ES6就不行,因为你要返回调度队列让它找机会的,不能私自叫then 。但Kt 就支持调用时手动指定何时真Cont)
状态机化就是 swith case 0:f(); st++ return; case 1: 这样的
实现上如果内部 suspend call 此次未挂起,自身也直接继续而不会返回调度
这么说:
本来只期望await的暂停,结果全暂停了,因为 runBlocking 会等待所有内部suspend fun
其实就有3断续函数,作用域(基于Scope继承)在它内的 async{} 就等待,外的就得显式 await
https://zhuanlan.zhihu.com/p/156030219
我对VM/struct,GC(空闲链表标记清除) 都有了解,可就是不懂栈->寄存器 和 Kotlin CPS 不靠 #JS Generator awaiter 怎么实现 async 调用等待
1. 并不是最大栈高度=寄存器数,1+2*3 按结果看有2个,但其实1就够了
思考 x+2*3 ,其实只要1寄存器,但 x+2*a.n ,因为数字和obj 冲突需要两个,那么 a.n.inc 这样的计算链其实也只要一个寄存器!是关于类型的吗? 尽管Dalvik 寄存器有类型
思考 (1*2)+(3*4) ——是因为运算优先级吗?其实是临时位置! 如果 1*2*3 , (2)*3 的位置就可复用,但 *+* 里先算的俩就需2寄存器,+ 在其一上计算
x+(2*a.n) ,首先 a.n 然后 2* 在其上计算,最后+x ... 其实就是一个SSA问题。 但把+-*/. 变节点并不难,就是分配不知咋写..
后计算的尽量复用先算结果的位置,栈->寄存器指令
break/continue 们串成链表,while 结束回填
if jmp-B a jmp-C else b c 记录俩位置,else 回填 jB, end 回填 jC 。递归下降法兼容 if else if 嵌套
2. Kotlin协程和ES6都是基于变量闭包+状态机化,但 JVM 没有 awaiter(IO loop,负责帮忙等待yield的任务并resume 其func*,因此嵌套等待 yield 就行了)
在状态对象上ES6是 Generator{then,throw},Kotlin 是 Continuation{context,resume/WithException} ,分别在this、末参数
在Lua里是基于 lua_State(虚拟机)单步执行权,就有点像pthread了。 但不管Kt,Py,ES6,Lua 的 await/async 都是基于协程实现。 我觉得 CPS 化的最优雅 😊 新学到
StateMachine 是自动生成基于context的cont.resume实现。 在 suspend? fun 内调用休眠函数自会生成其 Cont 实现,把自己的cont注册给它就行
类似ES6(yield),函暂停的位置肯定有 suspend fun 调用,CPS变换给它加自身cont 参数(这是自动回调吗.. 好吧也算),挂起回调度器Dispatcher ,与 __awaiter 不同的是f把 f1.then(cont=f) 指派好了(ES6就不行,因为你要返回调度队列让它找机会的,不能私自叫then 。但Kt 就支持调用时手动指定何时真Cont)
状态机化就是 swith case 0:f(); st++ return; case 1: 这样的
实现上如果内部 suspend call 此次未挂起,自身也直接继续而不会返回调度
这么说:
runBlocking{
GlobalScope.async{delay}.await
async{delay}//reset timer
}
本来只期望await的暂停,结果全暂停了,因为 runBlocking 会等待所有内部suspend fun
其实就有3断续函数,作用域(基于Scope继承)在它内的 async{} 就等待,外的就得显式 await
https://zhuanlan.zhihu.com/p/156030219
知乎专栏
Kotlin Coroutine 的 CPS 变换
一般 coroutine 的实现大多基于某种运行时的 yield 原语,然而 kotlin 并没有这种下层支持,在没有 yield 指令支持的 jvm 上仍基于 CPS 变换实现出了 coroutine 其实很厉害,想了解一下是怎样做到的。CPS Transfor…
duangsuse::Echo
sortBy{it.isMale} 就能做 partition 了( 确实 Kotlin 这有点hack,可能是为了内部优化 #Kotlin 有些小瑕疵,比如 listOf(break,return,throw Error()) is List<Nothing> 还有 run apply 是 let also 同类但命名完全不同,本来是 fun()=run{} 的,可官方自己也不用此写法
问题:
其实 Kt 的问题不少,比如 Common 改名 Multiplatform 还有些隐藏关键字(typeof..),型参约束可以用 where,主要是太实验性,1.3 的时候字节码生成还有问题,不支持 j.l.invoke API
甚至一些?类型优化也有bug
但Kt确实是 #java JVM编程现阶段最好的选择,full interop ,完善带extfun OOP (只是Android上默认proguard规则还不够好什么的……
当你第一眼看某大佬的Kt 时着实被 let run constructor init companion 这些搞眼花了…… 一时觉得比Rust不明觉厉 🤪 Kotlin 初期的stdAPI命名 是个问题
>啥叫partition
school.partition(男女)
>不是有groupBy了吗
school.groupBy(领导教师学生)
那么 associate (toMap,还带 By-With介词) 和 all,any,none ("exists"=any,none=allnot) 也很容易忘,尽管相比JS和Scala 这是最好的
谈到Kt冷知识,我想再提 UnsafeVariance https://t.me/dsuse/15959
我能断言指定
其实它本身同时是 in, 但为了写存储的兼容被迫暂作 out 了而已。
然后匿名 object{} (即
#recommend #kotlin #scala #reveng 关于coro底层的代码示例 https://t.me/kotlin_cn/25062
呃,今天才知道 Kotlin 的 Boolean 是 Comparable, true > false 。感觉有点坑啊
其实 Kt 的问题不少,比如 Common 改名 Multiplatform 还有些隐藏关键字(typeof..),型参约束可以用 where,主要是太实验性,1.3 的时候字节码生成还有问题,不支持 j.l.invoke API
甚至一些?类型优化也有bug
但Kt确实是 #java JVM编程现阶段最好的选择,full interop ,完善带extfun OOP (只是Android上默认proguard规则还不够好什么的……
当你第一眼看某大佬的Kt 时着实被 let run constructor init companion 这些搞眼花了…… 一时觉得比Rust不明觉厉 🤪 Kotlin 初期的stdAPI命名 是个问题
>啥叫partition
school.partition(男女)
>不是有groupBy了吗
school.groupBy(领导教师学生)
那么 associate (toMap,还带 By-With介词) 和 all,any,none ("exists"=any,none=allnot) 也很容易忘,尽管相比JS和Scala 这是最好的
谈到Kt冷知识,我想再提 UnsafeVariance https://t.me/dsuse/15959
(items[i] as IO<IN, in @UnsafeVariance T>).show(s, v)这关于
IO<INPUT, T>
的定义,T 是 out 的,不然 Seq<Any>(io1:<String>,io2)
就会报错,如果要把 Reader 和 Writer 写在一起就会出问题,但代码复用偏偏必须写一起我能断言指定
items: List<(IN)->R>
位置[i]
的 show 可以接受(in) T ,因为它本来就是被取并集损失了精度的,于是写了这种代码,其实它本身同时是 in, 但为了写存储的兼容被迫暂作 out 了而已。
然后匿名 object{} (即
new ArrayList(){{add(1)}}
,常量糖..)的IDE特性也很多,不过 inner class 才正常呢……#recommend #kotlin #scala #reveng 关于coro底层的代码示例 https://t.me/kotlin_cn/25062
Telegram
duangsuse::Echo
上逆变 是什么😳
(T as T1) 的转换?如果是类型安全的话就子类型兼容了,为什么要靠强转断言类型安全?
嗯…… 如果你说有类型损失的,需要断言回来(UnsafeVariance),我这有个例子 ,但是代码复用整到这个程度,估计也没谁了🌚(草
items 的是 <out T>, 如果安全的话就把 out 去掉,但那就不能真正做到 Tuple 的复用了。
我能断言指定 items[i] 位置的 func 可以接受 T ,因为它本来就是被取并集损失了精度的,于是写了 (items[i] as Con…
(T as T1) 的转换?如果是类型安全的话就子类型兼容了,为什么要靠强转断言类型安全?
嗯…… 如果你说有类型损失的,需要断言回来(UnsafeVariance),我这有个例子 ,但是代码复用整到这个程度,估计也没谁了🌚(草
items 的是 <out T>, 如果安全的话就把 out 去掉,但那就不能真正做到 Tuple 的复用了。
我能断言指定 items[i] 位置的 func 可以接受 T ,因为它本来就是被取并集损失了精度的,于是写了 (items[i] as Con…
duangsuse::Echo
#js 同样是简洁优化,这些就很鸡肋了,尤其是这个eval DSL… 显得非常缝合,但为避免 new Path2D 不得不用 我曾说过「好的代码是横着写的」, 总结下吧,尽管我偶尔写带配置UI的应用,现在我的编程风格已经完全和“软件工程”者不同了 至于好坏…工程界的定义,蛇线驼峰 太基础,没有考虑语序和用途,我的写法会偏函数式点,命名上倾向 Kotlin ,不完全是民科 在我看来,工程界只重视代码的功能,没有顾忌代码的语义和「份量」,所以常常把简单功能写大几百行,以此为“成熟度”,或者觉得C++就必…
#statement 很多时候我不爱看自己的代码,但它之外只有量大后更难读的东西,一些问题想描述都是复杂的,何谈定义“解法”,我一直在努力简化
我就相信不管多难、多牛的人写的代码,都有更通俗的表达法——唉,大佬们总让我失望
如果连《算法》这种英美计科教科书都是不可相信的,我能信任谁呢,所以才说 #Kotlin 是好语言吧,至少它选择相信表达而非智商。 我遇到过天才,但天才尽管悟性好也曾有做得不好的时候;如果说最后他们写出来的东西还是10行能讲明白,如果他们的实践也只是6,7种方法中的一种,而每种方法各都有优劣 ,如果说完成的应用也有无数扩展的可能,我又该崇拜谁呢。
如果天才的语言也不天才,我为什么要全部照搬呢?
几乎每次我研究一个感兴趣的技术,都迭代出3,4个版本,碎碎念全放在旧版、精彩代码粘贴到新版,仿佛细胞分裂时损失聚在一边 。从正常人的视角「重复」肯定是丢脸的事,或者是项大工程,意味着你不懂或不聪明,但谁是生而知之的呢?人的能力是有限的,所以才需要方法和工具完成更多,而有时却被工具所蒙蔽,看不到更「大」的工具。
我为什么要崇拜技术呢?因为「崇拜」它能更好解决我的需求?崇拜天才能让我聪明?
我谁也不崇拜,也谁都不鄙视,只是继续看自己爱的技术; 当我描述,零碎的计算机语言概念和人话并存,而在语言中,名字是最次要的,语义最重。最后我选择了名字即语义,是自9次重写一个框架后我做第二件最正确的事,也是我找不到同道的开始。 自底向上从缘由解读名词,自顶向下靠细分写出程序,而 OOP 或 FP 都只是这种方法论的工具;那些名词,只是它们用途的片面
我相信代码有「份量」,在API在模型之上,「恰如其分」的代码和精妙的文档是绝配,因为短行数!=低功能 。
——只有你不把技巧当特殊技巧,之上才构筑出更有趣的东西;如果你觉得自己或它够牛了,你就止到这了。 就像生物里配平的化学式,已经死了。
天才是不当自己或别人天才的,自满或自卑,与他们的领域和关注点无关。
我追求既普适又不空泛的代码。 既抽象,又易看出用途;顺序位置很重要、符号统一很重要。
人赋予一些事以语序、明确表达里的上下文指代,才能忽略无关本质的多余符号。
强大和技术都是身外之物,人—才是重要的
所以我不想自称程序员了,普通人,编程爱好者有多好
我就相信不管多难、多牛的人写的代码,都有更通俗的表达法——唉,大佬们总让我失望
如果连《算法》这种英美计科教科书都是不可相信的,我能信任谁呢,所以才说 #Kotlin 是好语言吧,至少它选择相信表达而非智商。 我遇到过天才,但天才尽管悟性好也曾有做得不好的时候;如果说最后他们写出来的东西还是10行能讲明白,如果他们的实践也只是6,7种方法中的一种,而每种方法各都有优劣 ,如果说完成的应用也有无数扩展的可能,我又该崇拜谁呢。
如果天才的语言也不天才,我为什么要全部照搬呢?
几乎每次我研究一个感兴趣的技术,都迭代出3,4个版本,碎碎念全放在旧版、精彩代码粘贴到新版,仿佛细胞分裂时损失聚在一边 。从正常人的视角「重复」肯定是丢脸的事,或者是项大工程,意味着你不懂或不聪明,但谁是生而知之的呢?人的能力是有限的,所以才需要方法和工具完成更多,而有时却被工具所蒙蔽,看不到更「大」的工具。
我为什么要崇拜技术呢?因为「崇拜」它能更好解决我的需求?崇拜天才能让我聪明?
我谁也不崇拜,也谁都不鄙视,只是继续看自己爱的技术; 当我描述,零碎的计算机语言概念和人话并存,而在语言中,名字是最次要的,语义最重。最后我选择了名字即语义,是自9次重写一个框架后我做第二件最正确的事,也是我找不到同道的开始。 自底向上从缘由解读名词,自顶向下靠细分写出程序,而 OOP 或 FP 都只是这种方法论的工具;那些名词,只是它们用途的片面
我相信代码有「份量」,在API在模型之上,「恰如其分」的代码和精妙的文档是绝配,因为短行数!=低功能 。
users.map{it.age}.sum()
后缀操作链隐含了SQL和数学的前缀表示法,不同语序适合不同场合和需求,但我始终追求描述间本质上的相同、追求代码与可见应用的相同,从而简化代码-即便很少人能做的干净。——只有你不把技巧当特殊技巧,之上才构筑出更有趣的东西;如果你觉得自己或它够牛了,你就止到这了。 就像生物里配平的化学式,已经死了。
天才是不当自己或别人天才的,自满或自卑,与他们的领域和关注点无关。
我追求既普适又不空泛的代码。 既抽象,又易看出用途;顺序位置很重要、符号统一很重要。
人赋予一些事以语序、明确表达里的上下文指代,才能忽略无关本质的多余符号。
强大和技术都是身外之物,人—才是重要的
所以我不想自称程序员了,普通人,编程爱好者有多好
Telegram
duangsuse::Echo
#algorithm UnionFind、三角分形(精简版)
如果要实现 Set 你会怎么做?每次 add(x) 时去重遍历 uniq() 吗?
现在按数组Array(N).fill(0).map((x,i)=>i) 实现 Set<Int> 。每位与一个索引关联,初始是和自己
当加一对 a-b ,把它们的位置赋上彼此,就能知道在不在同集合内——不行,如果还有a-b-c 咋赋值?
答案是 a->b 关联 b->c 再关联,因此 find() 变成链表遍历后最终同一。然后 add(a,c) 先找这个"b",把它…
如果要实现 Set 你会怎么做?每次 add(x) 时去重遍历 uniq() 吗?
现在按数组Array(N).fill(0).map((x,i)=>i) 实现 Set<Int> 。每位与一个索引关联,初始是和自己
当加一对 a-b ,把它们的位置赋上彼此,就能知道在不在同集合内——不行,如果还有a-b-c 咋赋值?
答案是 a->b 关联 b->c 再关联,因此 find() 变成链表遍历后最终同一。然后 add(a,c) 先找这个"b",把它…
https://t.me/kotlin_cn/25220 #kotlin #go 面向job/task计算称 #concurrent ,和完全平行(如滤镜图片)不同
线程切换 >> 函数调用(没有线程切换下的协程切换) > batch之后的函数调用
>分别对应于代码实现的Dispatchers.Default + 无buffer (如果你写对了的话), coroutineScope + 无buffer , coroutineScope + buffer
Exectors singleThread asCoroutineDispatcher
>wait是指blocking的wait么?没看到channel的代码,但是可以断言里面不可能线程停住等待
>不, 是指协程底层在无可调度时的wait;能看到一半是无锁链表,一半是LockSupport.park
之前和他的差这么多,估计是被调度到一个线程上去了,不知道Default里边的策略是什么样的
bench=repeat(10_000);o=Any()Channel 和调度器 Dispatcher ,在浏览器有 worker.postMessage 和 onmessage
c=Channel<Any>()
runBlocking {withContext(Default){
launch{bench{ c.send(o) }}
launch{bench{ c.receive() }}
}}
//c.close(); launch.join()
var wg sync.WaitGroup;wg.Add(2)defer WaitGroup 在凑齐2项时传输(循环看错位)?其实是用计数看是否有job存活,都Done掉退出时再继续主线程
var token struct{}
c:=make(chan struct{})
go func(){
defer wg.Done()
bench{c<-token}
}
go func(){
defer wg.Done()
bench{<-c}
}
wg.Wait()
runBlocking{//limitedParallelism,newFixedThreadPool,single..也有把 Channel 异步序列变得友好的做法
val produce=produce(Default){
bench{launch{send(1)}}
}
var n=0
produce.consumeEach{n+=it}
}
线程切换 >> 函数调用(没有线程切换下的协程切换) > batch之后的函数调用
>分别对应于代码实现的Dispatchers.Default + 无buffer (如果你写对了的话), coroutineScope + 无buffer , coroutineScope + buffer
Exectors singleThread asCoroutineDispatcher
>wait是指blocking的wait么?没看到channel的代码,但是可以断言里面不可能线程停住等待
>不, 是指协程底层在无可调度时的wait;能看到一半是无锁链表,一半是LockSupport.park
之前和他的差这么多,估计是被调度到一个线程上去了,不知道Default里边的策略是什么样的
Telegram
Michael Corleon in Kotlin CN
其实我也见到 stackoverflow 上有人发现 kotlin coroutine 是轻量,但是并不快…尽管通常来说轻意味着快
duangsuse::Echo
#ce #plt 带步骤的四则计算器。递归逆波兰。22行代码 浅先=`;=;+ -;* / %` 流=(a, _s=[...a].values())=>()=>_s.next().value 切2D=(s,sp0,sp1)=>s.split(sp0).map(s=>s.split(sp1) ) {let t={},k; 切2D(浅先,';',' ').forEach((x,i)=>{for(k of x)t[k]=i}); 符深大=t} 符链=(s,l)=>{let a=[],add=x=>a.push(x)…
#plt #typing #kotlin #java 常见类型系统
从变量/参数的赋值兼容力(即子类成员量)升序:
对函数
而检查期 1,"str" 和
类型的强弱看隐式转换,动静即语法有无分出“编译期已知项”如class结构,类型推导能让静态类型更智能。
现在你已经知道「类型标记」只是仅编译可知,用来
类型的交集&(有
+*类型即分支组合类型,与其配对的是不兼容子类型的系统,那些系统里元组/具名数据类型也算”类型“,但有些奇技(如typeclass函数重载)来解决OOP里有或没有的问题。
A&B 成员集小,兼容力比A或B大,但在严谨的OOP子类派生里,只有 A|B 被用于多态(函数覆盖:多义, Any null?),而交集参数仅混合接口。
感觉有点好笑,我一个看编程语言的,话却越来越少了。 以前很喜欢技术,但感觉越学知识越少了。
从变量/参数的赋值兼容力(即子类成员量)升序:
Any<任何类型<Nothing
,类型 T 比T?兼容力强,因其不含null,error():Nothing
可容任何类型,因后续计算中断。对函数
(Any)->R
连Any都能收,当然是 (Int)->R
,也即 Fun<in T, out R>
,型参值 T=Int 反接受小的 T=Any。是消费-生产 in=?super,out=?extends "通配符",但可直接在写<T>
时指定仅在 in/out 位置,及 Array<out Int>
变量R在两个函数类型里唯一,都来自<T,R>型参列表,对R的每位置归一可推导出R再检查。可以发现,(T)->R
和 Fun<T,R>
都是从类型组合出类型的语法,而检查期 1,"str" 和
Int,String
型变量都是类型(Type.can
haveSubtype),a[0]=1
时问 Array<Any>.set(Int,Int)
是否 params.all{it,i-> it.can(arg[i].type) }
,像在执行一般检查每条算式,能提早报错并加速内存分配。类型的强弱看隐式转换,动静即语法有无分出“编译期已知项”如class结构,类型推导能让静态类型更智能。
现在你已经知道「类型标记」只是仅编译可知,用来
chk(AST.FCall): i=0~nArg; scope["print"].arg[i].can(call.arg[i].type )
的 Type.can(Type):Bool
实例,正如 Python 的 from typing import TypeVar
。Map<K,V>
也是编译期调用,只是class 里创建型参<A,B,..>写法和函数前不同,不是”特殊语法“。类型的交集&(有
where T:A,T:B
"交集上限" )并集|(兼容操作支持俩类型,如 Any? vs Any,AST vs Call If For):子类&父类=子类, A&B=Nothing 、A|B=最近共同超类+*类型即分支组合类型,与其配对的是不兼容子类型的系统,那些系统里元组/具名数据类型也算”类型“,但有些奇技(如typeclass函数重载)来解决OOP里有或没有的问题。
A&B 成员集小,兼容力比A或B大,但在严谨的OOP子类派生里,只有 A|B 被用于多态(函数覆盖:多义, Any null?),而交集参数仅混合接口。
感觉有点好笑,我一个看编程语言的,话却越来越少了。 以前很喜欢技术,但感觉越学知识越少了。
Forwarded from duangsuse
(知乎的草稿箱真太卡了
JS的一些技巧都注释了,感谢你的建议;这个确实烂代码写久了自己认识不到难看
其实我觉得,编程是没有水平一说的,就和人讲话一样,知道原因就够了,技巧我实在是我讨厌的(尽管我在用 )。 我不把编程当技术,即便自己是编译原理爱好者
这篇文章穿插了JS和Py ,但你会发现画布都叫 g G,这是我现在的编程规范。
层次感是因为我想教的太多了…… 🤪 在这样的文章引入代码生成。 坦白说只要函数名不滑坡,现在我的代码已经没有规范可言了,感觉我成了自己之前讨厌的人(那种变量名只起1字,也没公式的),现在是因为我需要比代码更高的东西,代码的语义、算法的理由。
我的命名由一个物理命名法(链接“名字即语义”)规范,所以对大家还是奇怪的。一切都是为了语义 😭, 如此我编程时便可仅思考问题,而对问题的符号不假思索,因为我从实现子目标开始就知道一定有某类型符号,和谁1:N等相关,要怎样计算,所以能自由拆解拼合重序代码,不局限于既定形式。
JS的一些技巧都注释了,感谢你的建议;这个确实烂代码写久了自己认识不到难看
其实我觉得,编程是没有水平一说的,就和人讲话一样,知道原因就够了,技巧我实在是我讨厌的(尽管我在用 )。 我不把编程当技术,即便自己是编译原理爱好者
这篇文章穿插了JS和Py ,但你会发现画布都叫 g G,这是我现在的编程规范。
层次感是因为我想教的太多了…… 🤪 在这样的文章引入代码生成。 坦白说只要函数名不滑坡,现在我的代码已经没有规范可言了,感觉我成了自己之前讨厌的人(那种变量名只起1字,也没公式的),现在是因为我需要比代码更高的东西,代码的语义、算法的理由。
我的命名由一个物理命名法(链接“名字即语义”)规范,所以对大家还是奇怪的。一切都是为了语义 😭, 如此我编程时便可仅思考问题,而对问题的符号不假思索,因为我从实现子目标开始就知道一定有某类型符号,和谁1:N等相关,要怎样计算,所以能自由拆解拼合重序代码,不局限于既定形式。
Telegram
duangsuse::Echo
#statement 很多时候我不爱看自己的代码,但它之外只有量大后更难读的东西,一些问题想描述都是复杂的,何谈定义“解法”,我一直在努力简化
我就相信不管多难、多牛的人写的代码,都有更通俗的表达法——唉,大佬们总让我失望
如果连《算法》这种英美计科教科书都是不可相信的,我能信任谁呢,所以才说 #Kotlin 是好语言吧,至少它选择相信表达而非智商。 我遇到过天才,但天才尽管悟性好也曾有做得不好的时候;如果说最后他们写出来的东西还是10行能讲明白,如果他们的实践也只是6,7种方法中的一种,而每种方法各都有优劣…
我就相信不管多难、多牛的人写的代码,都有更通俗的表达法——唉,大佬们总让我失望
如果连《算法》这种英美计科教科书都是不可相信的,我能信任谁呢,所以才说 #Kotlin 是好语言吧,至少它选择相信表达而非智商。 我遇到过天才,但天才尽管悟性好也曾有做得不好的时候;如果说最后他们写出来的东西还是10行能讲明白,如果他们的实践也只是6,7种方法中的一种,而每种方法各都有优劣…
#java #kotlin
>也亏他说得出口,没有受检异常,只会让所有kotlin程序要么发生崩溃,要么catch Throwable。或者,遍历整个调用路径,找到全部抛出异常的地方。
Java先进的异常系统被糟蹋成这这样子,真是人笨怪刀钝。 https://t.me/vvb2060Channel/745
你可以看看.kt的生态发展快、易用好,还是老腐朽 jawa。 kt 的 null?. 其实就删掉许多Throwable 的需求了,要再逼人给 ArgumentError, FileNotExist 这些根本不可能发生的case去写一堆“error prone” “error torrent”(人话: 错误框,方案候补)?那JDK为何定义 RuntimeExc_ ,它先进,为何有人还爱 catch过泛 呢?
异常🌚本来就是非局部跳转-给全局handler,adb log 好了。怪不静态检查,那为何不用 Result? runCatching{} 能满足你说的必须catch才编译 ,直接把fun=catching{}。能写成这样说明你对相关API没有做过预测试,或者方案不够跨平台,就像Google自相矛盾的注解 https://t.me/vvb2060Channel/718
代码自身混乱的七七八八🤪,不能怪语言不守旧。类型必须对算式有利用价值:人不该敲不会执行的字!
#js 就是我们的榜样,Promise.catch.then 里catch{}是可复用的,比之Jawa SEH语法,像拿C与py相比,灵活性爆杀。甚至它标明了哪里会出异常, 而非尾一堆catch{}
😔
Jawa8的类型变量推导算法本是可用在函事var和class量上的,却仍要求写 int x=1; 然后语序上丑到有<T> void f() 比之 class Box<T>。今天到Java11又开始支持var,record类型,List.of和switch->这些 “靡靡之音”了,不爱“努棒性”了吗?
>也亏他说得出口,没有受检异常,只会让所有kotlin程序要么发生崩溃,要么catch Throwable。或者,遍历整个调用路径,找到全部抛出异常的地方。
Java先进的异常系统被糟蹋成这这样子,真是人笨怪刀钝。 https://t.me/vvb2060Channel/745
你可以看看.kt的生态发展快、易用好,还是老腐朽 jawa。 kt 的 null?. 其实就删掉许多Throwable 的需求了,要再逼人给 ArgumentError, FileNotExist 这些根本不可能发生的case去写一堆“error prone” “error torrent”(人话: 错误框,方案候补)?那JDK为何定义 RuntimeExc_ ,它先进,为何有人还爱 catch过泛 呢?
异常🌚本来就是非局部跳转-给全局handler,adb log 好了。怪不静态检查,那为何不用 Result? runCatching{} 能满足你说的必须catch才编译 ,直接把fun=catching{}。能写成这样说明你对相关API没有做过预测试,或者方案不够跨平台,就像Google自相矛盾的注解 https://t.me/vvb2060Channel/718
代码自身混乱的七七八八🤪,不能怪语言不守旧。类型必须对算式有利用价值:人不该敲不会执行的字!
#js 就是我们的榜样,Promise.catch.then 里catch{}是可复用的,比之Jawa SEH语法,像拿C与py相比,灵活性爆杀。甚至它标明了哪里会出异常, 而非尾一堆catch{}
😔
Jawa8的类型变量推导算法本是可用在函事var和class量上的,却仍要求写 int x=1; 然后语序上丑到有<T> void f() 比之 class Box<T>。今天到Java11又开始支持var,record类型,List.of和switch->这些 “靡靡之音”了,不爱“努棒性”了吗?
Telegram
南宫雪珊
又想大骂kotlin没有受检异常。
Adding checked exceptions to Kotlin would be a major breaking change, and as such, would require very strong new arguments in favor of it. At this time, given the experience of many different languages which do and don’t include checked…
Adding checked exceptions to Kotlin would be a major breaking change, and as such, would require very strong new arguments in favor of it. At this time, given the experience of many different languages which do and don’t include checked…
#learn 对我而言,编程并不是「专业技术」,只是“另一种母语”和创作方式,所以我很讨厌潦草的代码
最近一直在打磨一门自制语言的语法, 获得一个较大的成功,居然是把它的OOP术语移植到英文.. 😅
interface Closable
绝句计划把
总之,OOP 的public-private constructor 麻烦真的很大,
我又不认为 Rust,Go 那样把一切打散和到处pub fn, 冗长化 type Item=int32 就算“优于继承” — py也有自己独占的一亩地, 但它足够 "server side" 吗?
对于视频内代码的重写:
唯一能确定的是, 绝句最终的语法和std不会保留冗长且含糊的概念,至少中文绝句不会 (比如 try catch finally 就变成语法函数化+
也不会刻意与py,rb,js 的传统术语分离,一定是小更改换大收益 😋
希望它能打破解释和编译的隔离吧 ,虽然我根本不知道咋做.. 语法风格颠覆的太快
不过我还是很高兴学习过弱类型 metaprogramming ,又掌握了解析和编译原理,所以不必受制于既有的 syntax 和 API,或者对象图框架,而能创造DSL
btw. kt 的 Sequence实现 居然和 yield() 无关 ,居然只是 sequence{} 在创建只读的协程吗
😅而且复制给Array,Set,Str.. 信仰崩塌
最近一直在打磨一门自制语言的语法, 获得一个较大的成功,居然是把它的OOP术语移植到英文.. 😅
事量物例类|公私族组内之前的版本是
fun val data named type|same{,0,type,pkg}
储例判同造|既可未终定
\- enum -when -named made|^,impl{?,??,}
事量物例类虽然不够“面向对象”(obj->data) 了,但实在(英语化)好写不少。 我一直很讨厌 Java 那种八股文式,歪七扭八不一致的语言特质,给数据处理和调试带来很大负担
fun val thing insta class|
储标例况变
data anote enum case var|!,impl{?,??,}
interface Closable
type Closesdata class Pair<out A, out B>(val A:A, val B:B): Serializable
fun close
-named
fun all(:Args<Closes>)...
data Door(name:Str) Closes
made(:Idx)=made("# $i")
^fun close=say("shut $name")
'AB'(get) - Pair(A:A,B:B) Sendtypealias PairOf<T>=Pair<T,T>
'T'PairOf=Pair<T T>这个就对标 #haskell
data=A|B
和 #rust enum Either<A,B>
了'AB'(get)-when Either就体现另一种 #FP 的价值观:定义式先于不可变
A(v:A); B(v:B)
'R'fun way(err:Fn1<A>, ok:Fn1<B>) = when this:
A:err(v);; B:ok(v)
绝句计划把
Var,Type, expr.E
都拉入一等公民,虽然我不清楚怎么做但相信有意义(连scala3都没更灵活的 eval fun: inline arg 还不够全)总之,OOP 的public-private constructor 麻烦真的很大,
我又不认为 Rust,Go 那样把一切打散和到处pub fn, 冗长化 type Item=int32 就算“优于继承” — py也有自己独占的一亩地, 但它足够 "server side" 吗?
对于视频内代码的重写:
事 阶乘(n:数) 数或者更函数式(reduce 和 findIndex)
变数,a 1。
(1~n),[i] a=「它*i」 。
fun Ary<Int> contains(it:Int) Bool
this:[x]
if x==it: return $Y
return $N
'N'fun N`!`=(1~this).Sum{*}(不得不说,绝句的变动太快了.. forEach和尖括号类型都能被删没 (我对那个
'T'fun Seq any(:Test<T>) = this(Sum.from($N): or test(it) )
= first { test(it) }?.i !=NO
对何forall<AB>
的还执着了好久,因为很"函数式"😭 ) , 这两天对于‘带代码’行注释
和事/物 内量的区别对待、C++式iter与可变<T>的统一、 #Kotlin require check 之类“特技”的归一化 也很难抉择 ,所有简写竟都是全新的,而且都能涉及到编译期API)唯一能确定的是, 绝句最终的语法和std不会保留冗长且含糊的概念,至少中文绝句不会 (比如 try catch finally 就变成语法函数化+
试做 接应 皆应
+试:可空 , 之前是 尝试 接迎 终焉
)也不会刻意与py,rb,js 的传统术语分离,一定是小更改换大收益 😋
希望它能打破解释和编译的隔离吧 ,虽然我根本不知道咋做.. 语法风格颠覆的太快
不过我还是很高兴学习过弱类型 metaprogramming ,又掌握了解析和编译原理,所以不必受制于既有的 syntax 和 API,或者对象图框架,而能创造DSL
btw. kt 的 Sequence实现 居然和 yield() 无关 ,居然只是 sequence{} 在创建只读的协程吗
😅而且复制给Array,Set,Str.. 信仰崩塌
YouTube
Why You Shouldn't Nest Your Code
I'm a Never Nester and you should too.
Access to code examples, discord, song names and more at https://www.patreon.com/codeaesthetic
Correction: At 2:20 the inversion should be "less than or equal", not "less than"
Access to code examples, discord, song names and more at https://www.patreon.com/codeaesthetic
Correction: At 2:20 the inversion should be "less than or equal", not "less than"
#Kotlin #design 谈这我就想到,绝句的
就是两回事,避免歧义
get(Idx)T 就应该是方括号
设计语言时要顾虑一致性,不能为了理论优雅,就抛弃语文美感
vs
复杂不一定坏,只要扩展性和性能上有优势
最开始我只是把 py 的缩进给了 Kotlin,但最后,我没有把新手可读性 放在考量里
正则和DFA
说起来对同T 的多个implicit
Scala的优点和败笔同时是implicit。不知道怎么评价,就像你提供了技巧,但没约定好写法
^ val by 可以用 provideDelegate()=ReadOnlyProperty 定义
你没有把defaultFn 传到非 inline 的 fun/var (如forEach {}? ) 里,所以不应该加 crossinline
{cross,no}inline 只是用来禁用函数式参数的ret跳转内联的
好奇在 nonlocal return@ 上, kt 是如何内联的,假如参数内联可以靠IR模板的话
很好奇
OOP是强求了继承关系,或许正常来看
但我讨厌滥用接口trait,应该
感觉py的渐有类型换成全局infer 会更快(? TS 可能有(infer from usage),但是作为IDE功能了
我喜欢用成员交、成员并 表达 union 和 intersection types
java里成员并对接口(&)有点用, 甚至能为 tuple实现Func
—
现在用GPT, 有时感觉编程语言是没必要逐个去学的
但其实语言也能简化问题,方便编程创作;微调时用中文写需求,就很烂
这种有方向特色的创作,是GPT暂时做不到的;目前我只写这种代码
—
#Java圈莫名其妙的不做代码复用,像 Logger 和 Repo 这样就可以依赖注入进去
但变量是应该由
Javaer 的设计模式,除了Builder这种解决语法贫瘠的,都是做了一半, 留了一半给人当CV boy
PYer 虽然又蠢又冗,但至少不会贩卖问题;它解决过的都没有什么复制粘贴和坑
KV<Int Str>
和 [1 2 3].lets:"+$this"
的 Fn1<Int Str>
就是两回事,避免歧义
[1 2 3](Sum)
[1 2 3](Sum{*})
才真正应该是函数调用get(Idx)T 就应该是方括号
设计语言时要顾虑一致性,不能为了理论优雅,就抛弃语文美感
"a".mayAs<Int>?.Str !
(1~9)(Sum{+}.byStep )
(1~100 by 2~101) ( Sum{[a b]a+b } by: it%10 } )
vs
("a" as? Int)?.toString !!
(1..9).scan{A+B}
1..100.zip(2..101).reduce{a,b->a+b).groupBy{it%10}
复杂不一定坏,只要扩展性和性能上有优势
最开始我只是把 py 的缩进给了 Kotlin,但最后,我没有把新手可读性 放在考量里
- 'TR' T lets(:Fun1<T R>) = fn()
fun<T,R> T.lets(fn: T.()->R)=fn()
at N id= +0
val N.id get()=this+0
—正则和DFA
说起来对同T 的多个
fun T.xx
,是可以像Scala那样用 inline class
?Scala的优点和败笔同时是implicit。不知道怎么评价,就像你提供了技巧,但没约定好写法
^ val by 可以用 provideDelegate()=ReadOnlyProperty 定义
你没有把defaultFn 传到非 inline 的 fun/var (如forEach {}? ) 里,所以不应该加 crossinline
{cross,no}inline 只是用来禁用函数式参数的ret跳转内联的
好奇在 nonlocal return@ 上, kt 是如何内联的,假如参数内联可以靠IR模板的话
很好奇
List<get T>
在Go里为何不存在OOP是强求了继承关系,或许正常来看
'T'(T Num Sort)
才是List<Int>的类型但我讨厌滥用接口trait,应该
type Num Sort
感觉py的渐有类型换成全局infer 会更快(? TS 可能有(infer from usage),但是作为IDE功能了
我喜欢用成员交、成员并 表达 union 和 intersection types
java里成员并对接口(&)有点用, 甚至能为 tuple实现Func
—
现在用GPT, 有时感觉编程语言是没必要逐个去学的
但其实语言也能简化问题,方便编程创作;微调时用中文写需求,就很烂
这种有方向特色的创作,是GPT暂时做不到的;目前我只写这种代码
—
#Java圈莫名其妙的不做代码复用,像 Logger 和 Repo 这样就可以依赖注入进去
但变量是应该由
abstract class
来声明 ,不应该留样板代码,否则要设计模式干啥?Javaer 的设计模式,除了Builder这种解决语法贫瘠的,都是做了一半, 留了一半给人当CV boy
PYer 虽然又蠢又冗,但至少不会贩卖问题;它解决过的都没有什么复制粘贴和坑
Telegram
duangsuse in Kotlin CN
在有真子类型前,我还写类型函数(当然这些很无聊,本该由编译器自推)
'AB'type Eqv
- cat(:A)B
- cut(:B)A
!- pipe(:Args<Eqv<* *>>)管<args>
“类型体操版compose()。 函数体无法构造 管<> 类型(来形式证明),故仅调用处受检 ”
!- 管(串:组<类型>) = 串[0]的参[0] 令其,[A]
串去叠(A),[a b] b的参[0]有a;b的参[1]。令其,[B] 类型.参(可同、A、B)。
'AB'type Eqv
- cat(:A)B
- cut(:B)A
!- pipe(:Args<Eqv<* *>>)管<args>
“类型体操版compose()。 函数体无法构造 管<> 类型(来形式证明),故仅调用处受检 ”
!- 管(串:组<类型>) = 串[0]的参[0] 令其,[A]
串去叠(A),[a b] b的参[0]有a;b的参[1]。令其,[B] 类型.参(可同、A、B)。
duangsuse::Echo
🥳 EQ的第一界API集构思好了,它构造DOM的方法,是直接把模板成分和JS值对应: - it关键变量: html`文本${x}`, when(age.as(x=>[x>=100, x>=18]), ["👨🦳","👦"], "👼") - 挂载函数: div(wOSK三要素, ...继续向下), as([abc], x=>bold(x), a=>ul('没有')), ee.组件({数据}.it)(挂载点) - 递归下降$: html(..)(s) 按照s的类型挂载,与 div()(s) 唯一的不同是它不把挂载点=新建div…
效仿 #Kotlin 果然是错的决定。kt爱“术语洗稿”的风格,原来从2017标准库就开始定下了……
幸好,现在的绝句能基于做/到函数
但看起来
总之,开明的语法配上一致的规范,味道真挺不错的
唯独可惜的是, 它们越来越不能“独当一面”了…… EQ的模板与“选中按键变量” 构思好后,整个框架似乎都萎缩了(虽然仔细对比会发现功能是一样多)。当然,越易学就越好
有些新功能一旦成为体系,看起来就稀松平常了,少到让人觉得是否会“不够用”…… 但它们曾显得非常helpful
幸好,现在的绝句能基于做/到函数
1:[x] x+1, (0~9)|: say(+ 1), kv:[k|v]字典
,不加歪七扭八的术语🙉但看起来
|:
这些就很晦涩啊? 不过,绝句是用这俩的重载,取代了所有 for if filter map await Closable.use .."89"==((0~9) {!< 8}: "$this").Str“对单项的filter”
(0..9).filter{it>=8}.map{"$it"}.joinToString("")
resp.isOk or good: A
(x==0) { A }: B “多个参函”
if(resp.isOk()||good) A
if(x==0){A}else{B}
"ab"{!has "a"}? {this}or "bad"现在我轮转设计的四个项目, 都逐渐迁移到了与as/to 相关的体系🥰像
at v = [|key v] ["k"] or: return
"ab".takeIf{"a" !in it}?.run {this} ?: "bad"
val v = mapOf("key" to "v")["k"] ?: return
at now:
x Way<Int Str>.A(0)
y x {+1} {error}
var x=Either<Int,String>.Left(0) //同Result
var y=x.fold({it+1}, ::error)
when(age.as(x=>[x>=100, x>=18]), HTML分支)
这样的变量总之,开明的语法配上一致的规范,味道真挺不错的
唯独可惜的是, 它们越来越不能“独当一面”了…… EQ的模板与“选中按键变量” 构思好后,整个框架似乎都萎缩了(虽然仔细对比会发现功能是一样多)。当然,越易学就越好
有些新功能一旦成为体系,看起来就稀松平常了,少到让人觉得是否会“不够用”…… 但它们曾显得非常helpful
#kotlin #statement 🤔 新身份:Java黑、React黑??😓
duangsuse, [2023/9/30 22:17]
感觉自己最近有点狂了, 看见有人问2D矩区的问题,我的第一反映居然是「这提问不会是认真的吧,xywh加减乘除是简单的吧」
问了下AI,发现这种 Image.crop()也没有直接给出思路或代码,它们变蠢了
应该改改了…… 真的有点奇怪,说不出是哪里错了,可能是反感流行框架不直白吧,但 我不应该教人做事
不过 java awt 确实有点过分,连类似Pair<AB>的模型都没有,许多人都是单独处理 width,height 的,
连 size=2w,1h 这种都要写两个赋值……和numpy太不搭
JDK这些人物理单位都不懂,却搞一堆设计模式,真是在买椟还珠的时候就格外努力……
Android呢,什么
duangsuse, [2023/9/27 15:56]
还是H5
一个毫无意义的区别,让设计师拿来作为特色竞争力,妙呀
duangsuse, [2023/9/30 22:42]
唉,我现在在设计的前端框架,包含一门用于滤镜图/RPC的解释器, 真希望以后就不要再接触JVM界, 完全弱类型好了
感觉配合Java(哪怕Kt)界的窄模型思考,真的很费力。 许多对现实生活的简明抽象、比数理公式更优秀的写法,它们不去收纳整理,反而搞出与其他用途会冲突的抽象, 这样循环互害下去…… 大量学习成本就出来了,总是有新版本能+bugfix+feat
他们根本不懂如何写文档, 有些该单靠demo 传达到的被写成一锅粥,文档主要是原理。但 demo-文档-代码 给它们写成 文档-实现-汇编了……
duangsuse, [2023/9/30 22:50]
py 甚至全局用obj.dict ,这有什么影响。 人的脑容量才是限制IT进步的瓶颈。 优秀的算法和API移植,比8个byte 优化的效果多几百倍
总之对我而已,语言和runtime 只是实现解决方案的工具, JVM是可有可无的,只要它的libs我能自由调用。
一个lib 所提供的价值,等于其 public API+struct 的价值,不含运行时,因为具体实现可以被别人换掉。
库所用的结构是对领域模型的摘要,而API是对应地,实现功能的选项和途径
语言的语法和stdlib,需要尽可能简洁,因为复杂的功能和哲学,往往带来额外的编写时心智开销
duangsuse, [2023/9/30 22:17]
感觉自己最近有点狂了, 看见有人问2D矩区的问题,我的第一反映居然是「这提问不会是认真的吧,xywh加减乘除是简单的吧」
问了下AI,发现这种 Image.crop()也没有直接给出思路或代码,它们变蠢了
应该改改了…… 真的有点奇怪,说不出是哪里错了,可能是反感流行框架不直白吧,但 我不应该教人做事
不过 java awt 确实有点过分,连类似Pair<AB>的模型都没有,许多人都是单独处理 width,height 的,
连 size=2w,1h 这种都要写两个赋值……和numpy太不搭
JDK这些人物理单位都不懂,却搞一堆设计模式,真是在买椟还珠的时候就格外努力……
Android呢,什么
AnimatiableVector
, 向量根本不是动画(卡过点的属性渐变)所专有的概念, 要支持就直接起Vec2这种规范点的名字。 还歧视H5和CSSOM的模型。 编程就是被这群B搞坏的,真正的屎山框架代码。duangsuse, [2023/9/27 15:56]
还是H5
<meta name="viewport"
好,就只有基于dpr的 px vw wh, 然后 sp=rem, @media(device-pixel-ratio:1)
不会因为放大到200% 就蹦出一个更新的单位。SVG里都一样 一个毫无意义的区别,让设计师拿来作为特色竞争力,妙呀
duangsuse, [2023/9/30 22:42]
唉,我现在在设计的前端框架,包含一门用于滤镜图/RPC的解释器, 真希望以后就不要再接触JVM界, 完全弱类型好了
感觉配合Java(哪怕Kt)界的窄模型思考,真的很费力。 许多对现实生活的简明抽象、比数理公式更优秀的写法,它们不去收纳整理,反而搞出与其他用途会冲突的抽象, 这样循环互害下去…… 大量学习成本就出来了,总是有新版本能+bugfix+feat
他们根本不懂如何写文档, 有些该单靠demo 传达到的被写成一锅粥,文档主要是原理。但 demo-文档-代码 给它们写成 文档-实现-汇编了……
duangsuse, [2023/9/30 22:50]
py 甚至全局用obj.dict ,这有什么影响。 人的脑容量才是限制IT进步的瓶颈。 优秀的算法和API移植,比8个byte 优化的效果多几百倍
总之对我而已,语言和runtime 只是实现解决方案的工具, JVM是可有可无的,只要它的libs我能自由调用。
一个lib 所提供的价值,等于其 public API+struct 的价值,不含运行时,因为具体实现可以被别人换掉。
库所用的结构是对领域模型的摘要,而API是对应地,实现功能的选项和途径
语言的语法和stdlib,需要尽可能简洁,因为复杂的功能和哲学,往往带来额外的编写时心智开销
Telegram
duangsuse::Echo
#tool tty canvas #ai 编程失败
>用py实现 sudo hexdump /dev/input/mice -ve'3/1 "%d " "\n"'| for X,Y in lines: 叠加x=0,y=0 并移动终端光标
(很烂而且没有避print换行的坑)
gpmm() { #鼠标光标
stdbuf -o0 hexdump /dev/input/mice -e '3/1 "%d ""\n"'|awk -v kx=$((COLUMNS / LINES)) -e '!/*/{x+=$2/k*kx;…
>用py实现 sudo hexdump /dev/input/mice -ve'3/1 "%d " "\n"'| for X,Y in lines: 叠加x=0,y=0 并移动终端光标
(很烂而且没有避print换行的坑)
gpmm() { #鼠标光标
stdbuf -o0 hexdump /dev/input/mice -e '3/1 "%d ""\n"'|awk -v kx=$((COLUMNS / LINES)) -e '!/*/{x+=$2/k*kx;…