duangsuse::Echo
400 subscribers
3.82K photos
103 videos
573 files
5.01K links
duangsuse技术相干订阅
这是 @duangsuse 与技术有关的发布频道
duangsuse 的另外有 throws 闲杂频道
@dsuset
转载频道 @dsusep
duangsuse 有coding,github,gitlab帐号和bilibili帐号

极小可能会有批评zf的消息 如有不适可以退出

suse的小站:https://piped.stream
ps 另有别名 popf.rip
ʕ•̀ω•́ʔ✧ 🐶🍎🏠生死🐜
(>ω<)岂因祸福避趋之 一鿕
Download Telegram
duangsuse::Echo
https://www.zhihu.com/question/31034164/answer/553533545 #plt #dalao #statement 再顺便读(因为调歌搁了几天)文章,补充自己的观点 >0:可以完全理解一问题,并且给出对应的代码就是acm在培养的东西。 这就是上条我说的How, 也就是GPT和Copilot负责的部分 看起来,不用调包不找轮子,不用学API是种精英式的进步:你能修改算法更细则的部分,而别人连调用都吃力 但这也只是所谓「拼凑尸块」。 对大部分算法来说,只要可…
#learn #plt https://zhuanlan.zhihu.com/p/674654507

…… 第一次遇到写完读后感,对对方的理论和实践感到漠然

摘:
他认为,Docker 因为使用overlay-chroot(like btrfs checkpoint),React因为有变更追踪(不太准确,是靠useState(vdom)+memo) 就是可逆计算策略(文尾有分析),而tf的自动微分、任何MVVM同构框架就更是了

多项式A有解,也叫可逆(A@A.inv==1eye),加减乘除那只是abc和0间的关系,是简写法,反函数 不能说是可逆的。不是万物都有正负和零吧
像可逆的sqrt Prolog做过,连~sqrt()都不需要,因为 inc(X,Res) 里参数、返回都能自由更新,要啥计算图。还有match语句。它们写不出通用算法!比如O(nm)的 "".startwith

CS和Math都是「人对自然的抽象」与设计,这些符号,并非“格物致知”;在CS因为自动机翻,FFI/API 的存在,它甚至不够“约定俗成”。 我努力避免做谜语人,但无法不碰上他们。
对编程而言,有价"值"的并非越多越好。 就像线性映射在0点 不能有bias,牵强地追求运算对称,忽略了CS已是Math超集的这个事实

>既然声是折线,如何在CD上刻录双声道呢?像wav和webp那样Interlace采样,渐进加载 吗? 其实不用,因为1个刻痕本身就有2面!

如果过于重视中间层的方法论,让App扁平化,会损失不少自定义性。

>现代编程语言都去VB化了,print 作为语句已经是相当负面的信号了,DeltaJ 这样烂的AOP语法趁早丢了吧,在无病呻吟里它和APL是相映成趣的。UML们是对框架生态和元编程、预处理宏的侮辱。这些脑图,真的厘清了业务流和polyfill class 的样板吗?
js界一直有自己比Blink快的错觉,就连这种过度工程都是10年前Javaer犯过的。难以否认,DOM规范是UX+CG+OS领域的结晶,管理batch和fiber patch 它早按宏微任务分好了。 不就是React diff得太慢才需要SSR加速,水合的么...
duangsuse::Echo
Photo
^1笑点解析

#linux rootfs容器化的潮流下,$ mount 跟不上时代了
apt-get; systemd 做梦也没想到有人把挂载当cp 和pm2用 😅,效仿 apk, Magisk 了,直接放弃文件读写

(其实就是OS提供给 read,write,readdir 函数的 hook ,archlinux 一直是如此做 PKGBUILD ,玩得这么花 不就是为了免 systemctl start 免分渠道发包呗
天下苦OS碎片化久矣

^2 #plt #learn
CPS变换=ES6无栈协程=自动传回调
OS调度器=有栈C语言协程=单核多任务 免回调

#haskell Cont等Monad能够和do管道链配合,实现异步、伪随机等其他语言里稀松平常的「纯函数」特技
'入'演算里,CPS变换必须不直接求值,改接受回调k ,这样它们就能跨线程组装返回值. 用人话翻译下:
(x): k=>x(k)  # 常量或sleep(1s) (k),read 等基元
(x=>A): k=>k (x=>A)
A(Arg): k=>A (K=>K(Arg))(k) #大K用来求值参数,小k回调

第二行就很抽象,「拿到流水线需要的东西」就是CPS,那么调用栈-返回也是CPS了, 但那是编程的基础课
他的本意,应该是指CPS 就像 fetch(://fn/args).then(ret=> 可以实现RPC。 kt 的 withContext(Dispatcher.IO) 和 "use server" 就是这个意思,可惜这术语也说了,用处却列不清楚

第三行的定义,按 Reactjs,Rx 都是CPS框架,只是不止能"return" 一次。 这个和指针关系不大,比如swap(a,b)是宏能定义的语法糖

^3
玩梗是很有新意,但希望各位订户记住: “高尚的是人,不是职业”

聪明的是人,不是编程语言;解决问题的是范式,不是语法规范

^4
推荐云风的Unity 3D教程。 u3d和GL使用左手y-up座标系,而不是数学的z-up
这利于2.5D横版游戏的开发
但z是“近大远小”的,和DOM翻转y理由一样。另外 cv2 是使用 bmp[y,x] 坐标,好奇怪的语法?
duangsuse::Echo
^1笑点解析 #linux rootfs容器化的潮流下,$ mount 跟不上时代了 apt-get; systemd 做梦也没想到有人把挂载当cp 和pm2用 😅,效仿 apk, Magisk 了,直接放弃文件读写 (其实就是OS提供给 read,write,readdir 函数的 hook ,archlinux 一直是如此做 PKGBUILD ,玩得这么花 不就是为了免 systemctl start 免分渠道发包呗 天下苦OS碎片化久矣 ^2 #plt #learn CPS变换=ES6无栈协程=自动传回调…
#design #plt 看 Svelte runes 有感。谈一些个人梗

《献给sets变量集和cat-cut等价性的悼词》

一个基于JSON调用图的跨语言虚拟机,所支持的函数逆运算,似乎让 Eqs(cat=toStr,cut=parseInt).flip.oncat("10", *2) 取代序列化的荣誉结束了。以后只是 await "10".as(Eqs($=>nbase$(10)), B=>B*2)

Eqs.pipe([catcut链])
不只是输在前缀重复上。担当上新的IO范式,对于异步的「链式文件另存为」 "".as(open("inplace"), txt=>) 单靠双函数的pipe也是略显突兀的,
所谓消除语法噪声,可不是咸加糖淡加盐。任何的简化,背后若无心智模型,都将像Svelte5那样180度死转弯。 async的传染性绝对是问题、协程对forkjoin的掩盖很丑陋,而混淆长短任务会造成另一种问题

让函数支持inout()参数,作为“响应式”的新信号,竟灭杀了这两对可爱的、尚待扩充的、也是从死灰中立起一年的新词,就如 div(wOP({tap:n(x=>x+1)})) 对事件监听器们做的那样,简直动摇了框架之本

曾经,第一次把 from/into 换成更明确的 load/dump 或cat/cut。这种重命名带来的是归类上的改变,意味着「文件格式」不再与数据耦合,它们自己就能构成管道

base[64].cat("") 编码cut解码看起来多直观,但和 base(64).neg() 比起来却又太孤单。 我们曾以为,Eqs,file rw, 变量sets 是三种不同的模型,可如今「另存为」让文件格式能作为值, OSON调用图的「反函数」也让Eqs有了普通到不普通的人生

cat-cut 在各方面的一致性都很好,在有标准DLC.acty模型前,将插件cat进某事件、从程序里cut掉,是和JQ一样普世易懂的调用链。但链式终究不是定义式、组合结构的对手, 因为无this作用域而产生的它们,早该淘汰了。

说到底,文件的导入导出,本就只该实现write(),不需要有两个函数。 把{k:v}.sets换成.Eqs 也是出于一致性,
唯一不满的是 sets(()=>timers, 1..sRate) 相对 inout(t=>, 1..s) 牵涉的概念更小,更DOM。 但从整体来看,「共参数-藏参数函数,共读写参数」 可以概况整个Java,JS 界的设计模式

少量使用inout参数效果是拔群的:左值不再是易越界的「指针」引用,而是能把await、回调、流统一在一起的新酒, 很好地学习了JS Promise模型,用C-like和逻辑式编程摆了FP useEffect一道

等蕴含了可变量的「Eqs等价性」出师,回头看 Svelte runes 大概更像 ruins 吧

已记不起,是何时允许把 it.let{},map,find,forEach 都写成 it.as(x=>) as(An=>name) 而不区分let,lets
取代了only,if "仅有"的at, filterNotNull 又何时取代了 filterMap和when{} 判断

但不同往日,我正把「编程范式」与语法、与RPC方法 一道设计,让它们一同成长

这并不是复制OOP,FP, Lisp 或 Prolog ,但确实是在各取所长:
OOP对字典的叠加和配置力
Prolog对响应式和SQL的理解
Monad对列表与错误处理的简洁性、FP对方法和多态的全局函数化,对list的变量化
Lisp的简洁易移植,对DSL如JSON的组合与递归, 它与宏相等的闭包

很难想象,这么多算法与编程观、语法符号、命名文字的碰撞,与那些XX至上、一切皆XX的语言比较后,会产生怎样的差异呢?
#asm 😅 https://www.youtube.com/watch?v=aD7rOQSrXl8
#learn #PLT #recommend
编程范式,是组合程序的手法,是软件设计的哲学。 Fortran的作者Backus, C的精神领袖Dijkstra 都颠覆过现有的范式
下文不止是种浪漫或讲故事,React 也是对HTML模板范式的改良而爆火
asm:
世界上第一门编程语言,是各种机器语言的文本形式:汇编
没有嵌套结构,以至于许多bot和cli命令使用它的格式接受参数、实现功能
是自由度最高的"系统编程"语言,但机器的自由,反会奴役程序员的想象力

算法范式: asm procedural(imperative) declarative(markups)
数据范式: structured/SP OOP FP
从易解析、VM实现<50行的角度看,汇编是种标记语言。拿txt写需求够用,写业务流当然很累。

下表是这些范式的原神
算法范式: LLVM/WASM C++/Scratch SQL/YAML/PyTorch
数据范式: Rust Java/JSPy TS/React

结构式Rust有比过程式C++更准确更美的类型系统,以此区分。它与Go没有构造器和继承,不算OOP,尽管它混入了精髓(self 参数的链式调用)
从原神到远古。
procedural:
67年前,Fortran 随Backus的新ACM诞生: Can Programming Be Liberated from the "Von Neumann-style"?
F90是一门基于goto行号、支持矩阵malloc和中缀算式、前置类型的语言,这些特性都是x86未提供的。汇编新函数都要手写CDEF样板代码,而那时给游戏机编程的团队也没在乎复用的概念
F90的缩进风格类似SQL,调用风格比Ruby更混乱。PRINT(*) "hi" 是向内置函数提供默认+标准2种参数,自定义函数只能用CALL f,x 模仿。这种内外不平等在PHP,VBA也很常见,Py2to3 就为此修正

structured:
随后3年 ALGOL60.org 诞生。Dijkstra创立的这种结构化编程范式,是 Pascal,Ada 风格的老祖宗
Algol 否定了汇编式的goto,引入了struct定义,划清了四则等运算栈和调用栈。反观最初的F77语言并不能定义具名元组(ADT)
因此用它能学习算法和(同年诞生的Lisp包含的)递归

OOP:
随后2年,Simula67引入了OOP的class等概念: class就是共享构造参数的多函数,函数就是隐藏this等参数的单方法接口,对象和闭包都是代码+数据 是双指针。 闭包序列化可实现RPC和printf!宏
OOP的生硬对不习惯简洁明确DSL的人更友好,因为"method"闭包可以是getsetter、 final/abstract 确定性、 public/private 可见性..
之后以 C++(39年前),Py(32),Rb(29),Java,JS(28),C#(24) 的顺序出现几门主流语言,而 Alan Kay 以启发了Scratch的Smalltalk获图灵奖,成为了OOP届的领军人物

FP:
49年前的Scheme支持了(retAddr的)闭包 以将栈vars转为堆对象(才能作为值),且默认将函数存为(全局/原型链)变量。这比Lua协程早了十年
34年前的Haskell最终让 State,Monad IO, Effect,异步Flow 等术语“组合拳”火遍JS界。 FP界相对零碎,丘奇和图灵可谓两大师
Lisp系的圆括号SEXP直观统一了运算栈和调用栈,一切流控与数学都是函数,这启发了WASM 且等效于VPL拖拽编程/flow编程

综上,老旧的语言未必是落后的
Py,Lisp(WASM,LINQ DSL),Haskell(React) 就对现在的前后端和Excel影响很大
#ai list GPT在6点方向
https://weekly.tw93.fun/posts/163-买了麻将

https://shiki.style/guide/transformers #recommend #PLT #tool
js 界的统一动态高亮+AST抽象, 就像 tree-sitter
#plt #recommend 写了一个类型推导科普
😅 完了,感觉我都要变 yinwang.org
他10年前的抱怨我全都有,而且我比他还少点实践
https://gist.github.com/duangsuse/8fa4ae8c627e5c3c6044522a84ccebf4

还好好搜了一下各种中文blog
没找到好的内容,草
明明各种大学都有开编译原理依照 static typed
做compiler前端的是吃白饭的么? 都在教一些又过时又get不到重点的东西一样

这kt编译期显然不是古早的 Matcher() 那个级别
使用Var()来收集类型信息是 https://tomstu.art/hello-declarative-world 里就有的 unification ,但那个支持dfs,比如解X+Y=1。kt可以直接拟合(fit)
现在的React也开始习惯于「变量作为值」了,不过用Signal()深赋值取代diff的还是去年,发展得挺慢

https://justinpombrio.net/2021/03/11/algebra-and-data-types.html
还是ADT更好看些
https://isomorf.io/#!/tours/of/overview/7/python #tool 这里还提了一个跨语言可视化代码编辑器

https://sokra.github.io/source-map-visualization/ sourcemap 可视化 #js
https://github.com/mozilla/source-map?tab=readme-ov-file#generating-a-source-map eval
#plt #code 谈到RPN,我昨天有个灵感想把js做成缩进的形式
就回顾了优先级算法(嵌套深度包括h1~h6树本质上也是优先级)

示例算法 sexp(tok('1 (2 3) 4')), exp(tok('1*2+3'), optab)

optab={[';']:-1}
"=;+ -;* /".split(';').map((a,l)=>a.split(' ').forEach(x=> optab[x]=l ))
exp=(s/*token x单项o算符 x..*/, l/*evels 大则深,紧 */)=>{
let o,x=()=>add(Number(s())), ord=[],add=x=>ord.push(x),
at=O=>{let A,B; x()
for(o=s();(A=l[o])>=(B=l[O]);)if(A!=B)at(o);else{add(O);x(); O=o;o=s()} add(O)
}
at(";");return ord
}

sexp=s=>{let a=[],x;for(;(x=s())&&x!=')';)a.push(x=='('?sexp(s):x); return a}
//^ 一般需配对。此省行数
sexp=(s, a=[], f=()=>{let x,i=0;for(;(x=s())&&x!=')';i++) {x=='('?f():a.push(x)} a.push(i) })=>(f(),a)
//'(a (b c) d)' 换RPN [a b c 2 d 3], 可显示步骤

tok=(cod, s=cod.split(/\s+|([()]|\W+)/).filter(x=>!!x).values())=>
()=>s.next().value



https://t.me/dsuse/19097 圆括号解析, CSS代码高亮
https://t.me/dsuse/19320 各种正则替代lex,trie 的妙用
https://t.me/dsuse/17410 带步骤 四则计算器

https://t.me/dsuse/19387 类型推导科普, 动态和词法域,SQL的方言, 转译器 sourcemap
https://t.me/dsuse/18139 bing挑战各种算法和BNF

我还想了个有意思的鬼畜kt翻译,只用 忆一事悟疑实 6个字:

忆一 忆 Pair(一 x:数, 一 y:数)

忆 Main(一 a:行<Pair>): Events {
悟 事 onInit() {
一实((x,y) 于 a) 疑{ x==Z -> 不输别玩 }
}
说的 废物 一 Z=0 //inline private
}
忆悟 Events {
道理 事 onInit()
}

可惜kt没支持 for(..a) 和 a.forEach{} 平权
不然还能更好玩
📝 明天写出来会贴gist
#sysadmin Arch #linux 一次滚挂历程(差一点)
*原因:很久没滚,GNOME mutter wm莫名有了键盘焦点的bug。 未使用 -Syu 以至于为一些旧的包 --ignore icu 的升级,谁知xml依赖它呢?另外还 --overwrite'jupyterlab/*'
*差点滚挂: 不能 systemctl restart display-manager ; pacman -S 启动不了!而且我的tty1开的是支持中文的 cage kitty (虽然不会bootloop 🙉 并非btrfs,libc 的那种死亡panic)

众所周知,所有非 gcc -static 软件,都是靠 ld.so 查/usr/lib C语言全局表,其重要好比glibc之于bash或gtk之于Ubuntu
ld虽然有 LD_PRELOAD 同名替换hack,却无法以 LD_BIND_NOT 来避免不必要的.so 文件/版本缺失,导致「极其重要的pacman完全无法运行,即便没用到那 libxml」
ldd 也是DFS算法连tree可视化都没有的主 😅 LD_DEBUG=all 性能贼慢,还不如许多黑客软件懂UIUX

😅看起来,pacman 莫名其妙地dlopen(xml)了,其实都怪 archive.so 错误地未使用 gcc -rlazy 来惰性链接xml (RTLD_NOW)
readelf -d `whereis pacman` #PLT 节
标记 类型 名称/值
0x0000000000000001 (NEEDED) 共享库:[libalpm.so.14]
0x0000000000000001 (NEEDED) 共享库:[libarchive.so.13]
0x0000000000000001 (NEEDED) 共享库:[libc.so.6]


首先当然是祈祷icuuc.so.75 的函数表没差异, cp .old .new 但失败
那就只能手动下载、补充安装icu 。gio mount -rl 查不到MTP安卓,U盘不知为何lsblk不出,只好用http上传
? import uploadserver 
ip a|grep 192.168.


然后用tar -xf *.zst; 手动cp缺失的.so文件们,直到能启动 pacman -U

教训: libc toolchain 真是傻逼,pacman它根本没用XML解析器,XML也完全没必要强制 International Components for Unicode library !
然后升级一定要-Syu
然后CPython的httpd,xml API真是神

#learn ELF
https://lecoding.com/post/2016/linux-dynamic-lib-lazy-load/
https://yxj-books.readthedocs.io/zh-cn/latest/programming/ProgrammerSelfCultivation/ch07.html#plt
https://www.coder.work/article/8000423
//cc  a.c  -zlazyload -ldl -lcaca
#include <stdio.h>
#include <dlfcn.h>

int main() {
printf("Lazy loading demo program.\n");
void *m = dlopen("libcaca.so", RTLD_LAZY);
dlclose(m);
}
glibc 支持lazybind,无法lazy mmap 。你可以用 patchelf --remove-needed
https://github.com/NixOS/patchelf/blob/7c2f768bf9601268a4e71c2ebe91e2011918a70f/src/patchelf.cc#L1719 😅明明可以暴露成json编解码的
duangsuse::Echo
华为发布了仓颉编程语言的规范。 官网 | 这里下载
😅 #plt 大失所望
qnmd 从最基本的语法表现力、API上
丝毫没有逃脱kt,swift 的刻板,与numpy,ffmpeg,web平台那种根本没法比

后端优化nmb呢? 非得制造问题硬上?
#learn #kt Benny霍评论区
协程 async。自动传回调、var都打包到其class因为,比如传给sleep()后自己要return。协程对象就比()->闭包多留个switch(nthStmt){}

把sleep()外提为赋值语句,以保留和恢复调用栈而已,linux单核调度多线程,甚至你调用IO时为了鉴权,也会这么干。 cat|head 不就会await您的键盘吗? read()就会suspend 1个C语言的“有栈”协程。
之所以要async,只是想节省pthread_create,因为你要拿mainloop去poll(定期/卡http的轮询) 触摸屏事件,设备资源是独占的。这和内核驱动(/dev/WebUSB) 才能导致死机蓝屏是一个道理

如果系统,比如Web APIs吧,只提供回调而禁止while(1),哪怕只支持epoll(查看监听)/select(poll多项),就根本不存在线程一词 -就像C里你并不知道read()本质上await在pipe前“生成器”的write()
--也有人叫它yield,那是因为我们不能靠return写入“文件变量”、不能重赋值函数参数以返回多个值.. 为此jspy还发明了“async*()=>生成器”..
完美复刻UI层State(val).onvar[]的轮子呢!可惜是难用难复用的阉割版。

VSCode只加两个js线程,就能运行得很稳,这难道不是App设计的常态吗?难道那些小程序比code更“架构”?
至于免锁或基于资源.transferTo()的多线程,WebGL/numpy/MapReduce(ForkJoin) 不需要重造OS 1Dispatcher:N Continuation(该叫class CPU: ()->isFinished吧)的轮子配什么池化,就能实现前后端们无法想象的性能提升。

ES5的 yield cont=>setTimeout(cont,1s) ,由awaiter链接timeout和g.next,已经是免编译协程API的巅峰了,Promise.then 只是省得你传cont回调。 当然,timeout也可能返回cont=> 所以then要能接受async()

另:JS是视 fetch(u,{abort:Signal}) 取消任务的,我不认为app里会需要一堆 coroScope{} 这样图文不符的结构。kt在UIUX界敢能和H5相比么?为什么语言多项功能,app的功能却少的可怜!

kt的结构化并发不比Go的WaitGroup(semaphore)有用,但新词一大堆,初心全忘了,开始比java还八股了。真可笑,屠龙者终成恶龙
那些比Promise更繁琐的,是毫无语意的知识,迟早被py AI自动完成。看来科学界也不喜欢代码圈整这些无聊的class

就问 https://python-future.org/ 2to3这么聪明又简洁的lib,java人们啥时候能学会?态度问题,不是智商低 #statement

协程线程进程,都是Job
jobs的管理上,除了^Z SIGHUP再 fg bg 恢复,内核还支持swap(整个系统的)内存页到SSD,甚至用CRIU直接把进程快照为文件。 这样的快照不仅能多拍,还可通过网络传输,简直易如截屏,又像 Termux.dev / Waydro.id / webvm.io 那样神奇;然而这样超越运行期的“时间魔法”,90%的编译器根本做不到,只能用reflect或asm模板这样的残次品搪塞;同理90%的语言里“函数值”都没有相等性--所谓闭包“值捕获”却并不能自动内联JSON,所谓RPC,protobuf还不如微软的COM,pwsh.NET普适
#os 在这一点上可比 #plt 的孤岛、围城,先进太多了
https://t.me/dsuse/19341

https://kotlinlang.org/docs/coroutines-overview.html
https://github.com/youngyangyang04/TechCPP/blob/master/problems/为什么用户态和内核态的相互切换过程开销比较大.md
http://cht.sh/podman

podman run -dt -name cnt busybox /bin/sh -c 'i=0; while true; do echo $i; i=$((i + 1)); sleep 1; done'
podman container checkpoint cnt
podman container restore cnt

https://t.bilibili.com/948850441406382096
#recommend
#plt #cs #learn 如果从「一等公民」的角度给语言打分,从计算器开始,依次有这些类型的值:

bytenum1248(char short int long u8~u64) bytes bool
tuple union{enum Tag} rwstream(sockets/libc) 很大程度被sealed class:接口重写与json消息取代了🔑

list的len(骂你呢,C) str的iter(utf8的'🔠'不总是8bit一格哦) err和null的可选链(骂你呢,java空指针.快乐悲伤路径/非局部return)
Rc/GC(如List树或KV图 而非瞎手写指针链表); fn的bind(非全局状态,即对象变量,函数值)
Thread的asCallback(小名async函数. 能被不同CPU回调的'单线程',以允许evpoll监听,如触屏手势)
ref的onvar(响应式绑定,模式匹配let) ref的map(惰性数组和变更缓存)

fn的bindLit(字符串模板/算式内重载/变量和类型作为值-反射)
wavfile的sr(自适应微分精度) vec+计算图=tensor(numpy)

C的数组没长度,union没tag不区分子类型 (说C有sizeof的杠精退散,C就是在用汇编器都嫌烧cpu时代的封建余孽,pygo ffi/asn1可完美取代)
C++一个lambda隐转SAM class可给它装到了,难写的要死,那么简单的逻辑写成下划线能加钱似的😅
C的多维数组不支持broadcast运算,当然也没有.shape
librosa的“声音采样”只是数组而不包含采样率..
sql的惰性数组,至今仍被 http 分页切成offset limit的碎片缓存

js的input() 不能和{wtf:}绑定,只能搞.value不能load,formUI了个寂寞? H5应该比qt gtk这些先进吧,结果Tk里都支持的Var()compose没移植过来😅
java的“序列化”因为反射的不透明,至今仍有各种坑,因此最基本的CLI也写不利索

我至今仍然很好奇,新语言/库对「值」的理解,会怎样在无知上继续刷新下线
然后用一大堆自身就缺陷不小的所谓设计模式、样板项目。。 来解决这些API自身的缺陷
——你们真的懂自己的lib在解决什么问题吗,如果没学过,比较过古今四海的同类api吗?

在我看来,没有统一标准Ok/Err类值(NaN,null,'',[]..) 的语言根本没法使用,只能写些不相干的ifelse🔑
而没有标准二段求值(类于py的type annotation) 的静态语言,所有数据绑定都无法完成,只能祈求它能导包,或只用写4个“属性”的load/save
连pip install 都没有,就更是对工具化使用造成致命打击了。 (什么?可以发布 shadowJar? python可不需要你懂这些,甚至cli直接fire(fn) 就有了)

然而无论OOP,FP,“多范式”.. 它们是绝对的主流😅😅😅 而且还有一堆人对那些boilerplate code奉之为圭臬
仿佛只要是个“图灵完全”的语言,有一些UI/http/CLI的接口能用上套上,代码有多烂?冗长如同手写汇编?时间来凑就够了嘛……AI都懒得用

#linux 应该不会告诉你,它也是libc算法的一部分:它负责“分配与回收.so对象的内存片” “在cat等待read()管道生成器时 让cpu跑其他时间片”,它还定义了“ELF对象格式”,这约定了.bss与全局构造器,允许你修改.rodata里的字面量、用LD_PRELOAD替换函数
它使用被称为fd(->inode)的cookie参数,调用“syscall”来鉴权,而
这种CLI有4类参数 env UID=header f -kw -is-flags arg 与http如出一辙!
https://t.me/danteslimbo/3349 ebpf

这些,都是pyjs背后会为你的代码做的事! 但,你的object()强过C的dlopen()或bash alias,你的async def强过C进程,可用于N:1轮询'用户态'触屏驱动,你的http能跨越内存或系统,不需要wine和/usr/include struct就能利用..
linux 唯一比jvm强的部分,除了能解析各种usb,ip消息驱动和fs格式,就是mem上兼容用磁盘做4Kswap,以及cpu上能让while(1) 不像js那样卡死-注意!单await不等于没有并发加速。😋
os和compiler的同构有多疯狂呢? 打开htop,你看到的其实是F12里的对象树:这包含env表的继承、killall将它们free()、新线程的数组;而对于能被多个“对象”引用的文件-如同堆内malloc,内核还使用了Rc来清理对象图..
所以,有没有感觉自己比UNIX运维乃至内核开发者高到不知哪里去了呢(笑) Linus懂个锤子异步

btw. 我说的「值」不是与ref对立的那个,而是“用于90%编程业务的必需品的心智模型”
再说,不能ref.assign/copy() 的也不叫引用
score To.b8(100) #bytes8 i64
name "仓颉"

- task -index(0L) as: dd=index #debug disp
wg CoPU.waitN #lock1, atom(0)..
(0~4):(index)
wg+CPU.add: task(index)
wg()
(0~40).forks(4, Sum.ln, CPU.fadd:(x) dd=x.0/10, 666)==[666]^4

cnt: count 0
w1 CoPU.lock1
(0~1k): CPU add:
w1: count{+1} #synchronized

?? Row
Rectangle -width-height(0L 0L)
- area as: width height
?? Flyable
- fly
?? Flyable #去掉这行变sealed
Bird()
- fly say:'Bird flying'
?? Row
Article()
-titleValue Cnt("")
-title Cnt{titleValue}: titleValue=An
?? RMem #类似函数值,只允许 a.Str, RMem.eq(a,b)
Rect --w-h(. 0L) #可选参数、类型按参数名
- area() 1w 1h
?? To.s
- printSize say:'The size is {N}'

?? IPay
- pay “?” #- pay To.s
?? Row IPay
USD -n(cnt 0.) #可变的列
- pay "${n}"
Order -payment(IPay) #对代理的重写
- pay "In-order {An^1.pay}"

?? HasArea
- area To.n
?? IDraw
- draw -g(Geo2D)
?? Shape IDraw HasArea fn?? #强行插入为接口+构造器
Square()
- area 100
- draw -g as: g.text("wtf") N2(50 50),


#plt #design 把 仓颉 的示例拿最新河图重写下 http://www.bilibili.com/video/BV1YE421A7np

现在单字符已经成为政治正确了😅
幸好,设计了 To.s 这样避免画风突变,以及策划了.pyl 洛书采用原有类型名

单字类型的好处是,非常统一,在js里能用只有一俩字不同的表达式
这样,无论在什么语言里,我的范式都是不必重新学的

我还挺需要“正常化”这些为电脑做牛马的人类编程语言了,只需约法三章:
允许块调用(){}{}: 即匿名def:(x-y str int)的装饰器,并让:_x=arg0.x,允许省略[]{}的:,
启用bash调用赋值链,即 x_1 [1x 2].0; git help() init(); vars: n 0。 a x 2; 应被自动sed为 a=[x, 2]
为小写类型支持typefns.range.as等、让f'{x}'等于f(['', ''],x),这样就能通过库跨语言粘贴简单的逻辑
inc(0,9):(i)
i%2==0: say: f'{i} even'
duangsuse::Echo
duangsuse: #kt #book 元编程 http://www.bilibili.com/video/BV1XH4y1w7mT https://drive.bennyhuo.com/zh-CN/talks/2018.11.17-%E4%BC%98%E9%9B%85%E5%9C%B0%E4%BD%BF%E7%94%A8%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B_final.pdf https://weread.qq.com/web/reader/f7632a00…
#java #plt Science Yuan:
静态和动态的元编程是完全不同的

duangsuse:
并不是,只是类型信息在不在javac -cp 里而已。 如果在,例如for(const getMethods..) 生成/加载元组是可行的
你说的「完全不一样」,无非是jdk区分了 lang.reflect vs APT lang.model,后者能访问的信息更少,至少不能对某个参数getset() ,更不能获取返回值,因为 @Marker()很难写在语句级,更不能作为表达式

但编译和eval()并不存在所谓的鸿沟,就连未知变量,例如 int[] a 吧,从里面生成静态slice(用于vararg强转&传参?),或者解构赋值,也只是loop unroll(见Zig)而已
无非是编译器弱智到只能检查类型解析个方法签名, a[i] 就只能生成 aload ,不能把i的值粘贴进去(二段求值), {x,y}就只能是anew,不能作为编译期的list生成 x=a[0]; y=..
--基本这只需要往str内联常量,也就是说 (unquote x[i] {i:1})
甚至x不知道,i:1编译期也算不出,unquote=eval 就能完美容错!

apt和XXpoet的弱智显然是不可理喻的,因为解释器、解析器更好实现 https://t.me/kotlin_cn/105813

py不像js,它还是强检查的,js里甚至没有dataclass一说 一切皆字典
但这也有些坏处,就是元编程有些开销不完全与手写相等,这点我的 https://github.com/duangsuse-valid-projects/tkgui 通过缓存化eval很好解决了
这进一步说明,过程宏绝对不是rust! 那样的魔法,整个安卓所需的一切仅仅是 for(const x: T.vars) 的apt而已

lang.reflect 和Proxy都会在运行时生成字节码,更别说lang.invoke了,它会被查找并替换为具体的invoke字节码(例如被动态编译的 LambdaMetafactory(this,"methSig").invoke 方法)
这也是为什么Android重新实现了它们,要不然就要携带一个dx.jar作为类加载器动态翻译
duangsuse::Echo
#java oop 面试题 https://www.bennyhuo.com/2023/08/29/new-book-metaprogramming/#more 哈哈😄,这个好玩 1.(final T)在Gradle里是开发规范,但和final var一样对性能无影响 凑字数 final class是常用法,有些人在使用了虚方法(=构造期传函数)时会对其他项打final,幸好kt里是非open var即封闭、不可变 2final的类名上变量支持常量折叠如 if(DEBUG) 3 JVM.utf16文本…
duangsuse:
nonlocal x=的那条? 总比在C++里到处[]() 或move||要好

大家都不知道闭包捕获引用这些,这首先就要把那些XXer 的SAM类变成函数,然后才有非局部赋值问题

java虽然总八股值和引用,但大家总是不重赋值或深拷贝
我举那个py的例子算是好的,因为py这个畜生是直接把局部创建的cell()给捕获了。。
for a[0] in range 是有效的,许多人搞不明白

duangsuse:
orm就是把class 带上where sort 绑定到sql TABLE
基本上还应该带pager

Spring负责把http路径转到类路径,绑定个函数签名

理论上,pgsql 应该直接回应http请求的😂
90%的代码不过是做鉴权这样的中间件AOP
这一切,都是从PHP和XMLHttpRequest开始
唉,万能http

所以说AOP啊,pre post一加
你看有多少不是纯CRUD

不少小公司和C#的都是直接调用sql函数,不用后端
结果最后还是让程序员充当aigc了是吧。。

那些代码看一眼都算码农啊。。
怎么能容忍90%都是跨端复制的逻辑呢?

你不写,他们也会以合规为由要求写
jpa难道不能和sql模板打配合?

graphql.io 好,百度也有个json ql叫啥 https://baidu.github.io/amis/zh-CN/components/crud?page=1
凑字数能力很强

#sql 可垃圾着呢,我还写过生成sql的查询语言 https://t.me/dsuse/17740
读着自然?都是骗人的, SQsu 都比它更“人类”

select id from 狗 where (月龄>6 and 高>40);
aka 取狗(月龄>6 and 高>40)

正宗的关系式写法是:
狗(id,高,月龄), 月龄>6, 高>40

区区filterSort的模板不值得从ORM,CMS,低代码 这些里面分出个后端开发来
http路径就是类路径,类结构就是方便转码和校验sql数据

绝大部分的app并不需要后端框架,只要pg支持http风格的sql语句和json化,加个鉴权分页什么的。
如果不是pg存储过程的语法垃圾没类库,它就登顶了

#haha #bilibili
pg的存储函数没有类库,也不好 json io, java 才充当了这个协议转换垫片
因此许多SaaS对象存储都是NoSQL的,因为这种RPC架构冗余代码太多🌚

然而在EE程序员逆天才的智锐随变下,无论是生成xml或暴露路由表对象的服务器,绑定函数的方法都非常冗余, demo的匮乏程度更是让人叹为观止
甚至连五星逼格的rust都不禁这样评价:

它们好像连classpath就是URL模板的这回事都搞不清楚,方法签名绑定也做不好,还@什么原神数据来codegen😋
很牛逼吗?fastapi,django, 正常语言到处都在用,放javakt就是高手了,这是🐮逼还是装嫩?

完全无法理解MyBatis为什么比jpa流行,还煞有介事的搞面试题
一个 sql``${} 调用模板罢了
一个被专门做来AI生成的语言,那肯定是垃圾

甚至,ORM都是一种浪费,因为70%的字段根本不会被访问,只是复制到数据库,又复制回js或php式模板侧

连最基本的程数同构都没学过,compose 后才开始搞DSL,更谈何避免Header绑定和分页参数的重复、PUT DELETED POST三方法的多态融合,更别说理解http调用与sql、与bash命令行的同质了。

人家import fire可是0代码就能提供命令行,甚至colab UI。
java元编程能吗?逆天 才EE程序员没那个心智模型!🌝
Forwarded from duangsuse
哎,没有心情看 #kt #book
看了下codegen技法,只能说近十例子里anko的风格相对优越,和html一样是用twig(类似erb)模板,然后作者函数复用还行,但也没有到90分的程度。

例如“贯穿全文”的DeepCopy(x:T)吧
js里相当于x就是T的反射,又一切皆可变,可以直接读写{...x}[ID], 只需
mapEachMember{if(it.isPrim) it else DeepCopy(it)}

kt里需要用构造器复制,先拿到 T.vars[ID].get(x)而非 x[ID],但依旧是 mapEachArg{getattr(x,it).primOrCopy} 的模式,这个至少适用于 Tuple$N的toMut和url参数绑定
这就是个小学算法,反射和List API 的良莠不齐却让它很难看。

重要的是独宠XXpoet 真的无力吐槽,和那个 https://t.me/dsuse/17514 一样,就一个不用导包,然后自带formatter。简直可以说是一碟醋级别的算法,甚至应该叫搞错重点

和我的tkgui https://t.me/dsuse/19768(py基于getattr等元编程,运行期生成等效调用赋值图代码)
都没法比,何况最近我在设计表达式级(fun{}内计算图)都能建模的跨语言、带裸类型推理、动静合一OOP元编程范式了,这种拙劣的"xml模板"实在写不起来

java确实是“病态类型”,而非什么静态检查。 连数据树的验证和walkDeep都要靠魔法,有什么资格谈类型签名的那些好处?
靠被默认值参数替掉的重载吗?

只能说,如果手头有电脑,我应该去吧那个sql dsl写了😒 而不是在这看java人像手写sql或xml那样拼接字符串
不知道 unquote(ast) 这种函数式代码生成,起码吧 quote(litOrID)做一下,免得被注入弄出无效代码啊

再说说全书结构,首先就没有谈元编程是什么,而是java老三套:环境配置、难题、抄代码

好吧,可是一个优秀的老师应该选循序渐进,但却对知识体系至关重要的例题: #learn #plt

- 为什么是靠C的#define 自主研发出易语言?预处理比str.replace多了哪些? 高亮分词后,灵活解释“常量字面”吧
> eval("[1,$x]") 是一种JSON解析器,可是x="][0]"时似乎有bug。 修好它,然后把js爆改为你希望的“易”语言(复用猜数游戏的REPL)。 完成后类似的bug应该仍然存在!
其实,js源码也有它的JSON.parse,它就是反射的原型。
- 比较下SQL的'?'、C printf、ERB/ES6模板,kt元编程最缺少的语法为什么反而是"$str"? 控制变量,就能明白pwsh和ts为何比bash和js有长期编程时的优越性

- if os==nt6: class: 与#ifdef _WIN7 凭什么是同构的? 动态类型,依旧是Java式的类型。宏,并不需要魔法
- 为什么Java8让 invokedynamic负责创建lambda,getMethod不也能.invoke吗
- 局部fun 一定要 ::引用的背后,藏着一种元编程,T.(A)与(T,A)->、(T?)!!的强转背后也是! 原来除了消除重复,她还让语言提供更有价值的“值类型”
- 为什么“闭包是穷人的对象”? C语言里回调函数去哪了?SAM接口又为何比到处new.object{}流行? 原来返回函数、重写接口也能费内存啊

- 为什么pyjs里很少人研究元编程,但却又有 python-future.org 与vue,babel这样的全民应用。 二者有何区别
- Proxy(obj)掉包属性,是动态类型元编程的专利吗? reflect.Proxy 能生成函数,还不止于DSL或AOP!
- 能不能通过函数重命名,用py风格的反射API实现KAPT的 @decorator ?哪怕只是封装Reflect?这能让你学习跨平台移植,收获超越本次需求的心智模型和视野
- Kotlin对dynamic类型表达式链条的“零修改”生成规则可以怎么实现,numpy里也可以吗? 这能帮你理解DSL和编译优化的本质

- “优秀的程序与其读写数据的结构直观对应”。纯函数式编程(例如rust的enum和if let) 做对了什么? 为什么你仍然选择不够纯的Kotlin? 这种enum能表示JSON乃至HTML的序列化结构。
- bash风格的参数有3种,其中一种如 ls -ar(all reverse) 传入enum:BitSet。用fun demo()出完整函数签名
- 以上问题和codegen无关,也没有教你具体怎么生成url/json/sql绑定类或函数,却给你了设计相关框架的能力!这次由我来回答,为什么javapoet是对pyjs里闭包list/dict的拙劣模仿,以及反射调用为什么就是在codegen!

所以。。 虽然《Ruby元编程》教你的只是一些OOP特性的“工作原理”,而案例较少,但我更喜欢它 --它让读者真正建立起了对"class"这个dict的理解,加上dyn(*arg,**kw) 本就可以用名字动态查,让读者对“把def和class 视为一种constObj去查询、实现复制粘贴、...”有了把握

而不是一个看似什么搞法和IR,ASM都贴出来了
实际上对你没有用,只是让工作失去焦点的troublemaker🌚🌝
duangsuse::Echo
#life #statement 🌚终于知道为什么千里冰封、王垠会发疯了 我现在完全不认为他们是精致利己者。 软件工程界抛弃他们,B站无人在意他们, 他们又曾拒绝过哪位求知者呢? 同是沦落人,就不要装得纯粹无私了。 我在这里用触屏“为了分享感悟” “参与头脑风暴”,打的每一个字,查的每一个链接,都是浪费时间。 应该早点返乡拿电脑写点好玩的, 直到有天重演庸俗的『山顶见』。 怎么可能呢?我是说对原理出言不逊,却在应用成功后弯道超车的道理。 如果不是图你的市场大 简单来说,中文圈,尤其是崇尚存在即合理、Talk…
有人可能觉得,我这么杠是想显得自己很牛逼,或者多管闲事 #plt #statement

但如果我为了be nice,放弃对烂代码、生搬硬套的术语、八股文和样板代码的态度
对魔法师、“生产环境就必须复杂”的观念做个好好先生,只是帮魔法们去科普而不化简重构的话……
新生程序员怎么发挥他们的创想

凭什么老程序员提出的概念、技术、样板代码,能成为技术栈选型上的错误、带偏最初的设想?
其实,今天的前端dom-url参数转JSON-后端sql或kv
有那么难理解吗,但是要学的仍然一大堆。比如cookie,handle,也就是fd=open(File) 这类RPC对象号吧,这居然能成为一种知识点么? 只要视野放的足够广,许多50行说不明白的“新技术”,都只不过是旧思想糅杂了奇技淫巧 。

我不喜欢这样,这撕裂显然是利好libs API维护者,但对用户们毫无意义。是可以统一、省略,专心为业务服务的复杂性。


我曾被 @程序员鱼皮 和 @drakeet(当然是怪我 #reveng 他的app了) 两个技术人拉黑
都是因为说了类似「后生可畏,有些人的100行代码比七八百行更管用」,今天也一样。

这就是客观存在的事实。比如 VanJs.org 用300行实现reactive,许多人还跟在miniVue后面买课还学不会呢。
用更好理解的: 《算法 in C++》 是否符合我上面说的100行代码(而不是“1万小时定律”)原理呢?
更别说 https://github.com/duangsuse-valid-projects/tkgui 的拿数据打脸了,这在元编程(比各种算法更加通用) 里,简直就是常识。

这并不是nice与否,而是对谁nice

我倾向于对未来nice,因为那才能进步。
并非不择手段,但我下决心要前进
https://ray-eldath.me/programming/three-important-ideas/ #statement #PLT
Ray: 我的一位朋友如此评论这些文章:他说真正理解抽象的唯一方式是通过抽象本身,而不是通过并不准确的类比。
「为了充分地("有用处"地)学习这些抽象,你必须去学数学,而不是通过一些糊里糊涂的文章,它们除了类比还是类比」
Dr: 要找到 “哪些代码遵循此抽象” 并不是必须的。像 Monad 这样的概念是非常抽象和通用的:它是一个描述了一套广泛的编程模式、数据结构、库和 API 的概念,其强大之处在于它们,是对如何设计和使用这种抽象的指导原则
成为高效的程序员并不需要理解全部的联系。其他人自然会强烈反对 :-)

Ray: "可仅仅知道 JavaScript 里的 Promise 本质上是 Monad,而 Functor “又是一个盒子” 并不能帮助你成为更好地程序员,而在你自己的库中使用这些词语只会让你的下游觉得不舒服"

...概念是非常抽象和通用的
等等,
逻辑学告诉我,抽象是通用的反面,就像社会是丛林的反面: 您的知识若是通用的,它一定能与各应用领域紧密联系,学生如何觉得它抽象!

人们就是讨厌空谈,所以设计各种简洁而通用的API;人民就是讨厌丛林,所以组织出了社会。 现在竟有人觉得存在通用抽象和丛林社会?? 这就像是说javadoc等机翻的玩意,比各种demo, test甚至产品更能展示项目的价值!
“靠代码行数来衡量软件功能的进度,就像是凭零件重量来衡量飞机制造的进度——Gates
靠知识点的难度衡量价值,同理。😅

我看这种观念者,确实是够抽象。 “类比”的本质是抽象,而「学习」只是用自己领域的思维,去「组合」「代换」出别人说的那种东西,带给你工具和知识图谱上的价值。
大家来到世上都是白痴,没有谁拥有无法被代换给别人的知识「原子」。写文爱用「未定义就使用的概念」,想设计新的抽象,却不谈理由?那就是 lier
无论我们用什么领域的「原子」组合出了CS的知识点,那都是潜在的价值,为空洞的术语绑定了新的语意,更摒弃了其中被“凭空捏造”的哲学。让IT人说话,天塌不下来!

难者,不会也。作者已死,凭什么说的道你就是「高等抽象」,大家能跟上的就是"糊里糊涂"的抽象? Einstein, Feynman 说物理的最前沿应该教高中生搞懂,难道你们的方法论比爱翁还科学?
人们给车设计的引擎,能达到原理极限的98%,那么 #CS 对IT的指导,除了让空指针反复造成十亿美元bug,就是让功能不变的软件,随着更新越来越臃肿和慢? 这算什么CS

Monad很图论,很优雅啊! 但它能从 x+1==2 得出x=1吗? does it run backwards?
数学的精度是无限的、数学的等号是有交换律的。 #Haskell 里有模式匹配,但有"Var(x)作为值"吗?
只要变量是值,模式匹配、类型推理、响应式,甚至函数的编译,就真是小孩都会写的栏大街了。让 let(['x','y'],a) 生成 x=a[0],y=a[1] 谁不会啊 也配叫语言特性
FP们连正反函数如 show-out(1, "1"); show(res, "1"); res==1 都没建模,无精度int、向量、矩阵和微分都不如numpy sympy,也好意思谈数学性? 起码把Fortran的矩阵搞明白再说吧

https://arendjr.nl/blog/2024/07/post-architecture-premature-abstraction-is-the-root-of-all-evil/#:~:text=achieved%20through%20a%20much%20simpler%20function
费曼家有一套《大英百科全书》,父亲常让费曼坐在他的膝上,给他念里边的章节。

有一次念到恐龙,书里说,“恐龙的身高有 25 英尺, 头有 6 英尺宽。” 父亲停顿了念书, 对费曼说,
“唔,让我们想一下这是什么意思。这也就是说,要是恐龙站在门前的院子里,那么它的身高足以使它的脑袋凑着咱们这两层楼的窗户,可它的脑袋却伸不进窗户,因为它比窗户还宽呢!”

就是这样, 他总是把所教的概念变成可触可摸, 有实际意义的东西。

“个体的经历,不过是一个庞大的(形式主义)系统下极其表面化的闪烁而已”

可那个闪烁对某一天的用户来说就是一切。 自然原理,亘古不变。如果只是发现他们就能改变世界? 工业革命可以提早数百年。
人一思考,上帝就发笑。 你们的抽象,永远概括不了现实的领域、具体的人所提供独有的组合与可能性。

知其变,守其恒,为天下式?
穷其变,悟不穷,以明我志!
不能为每个人产生普世价值,是理论的悲哀。
duangsuse::Echo
https://ray-eldath.me/programming/three-important-ideas/ #statement #PLT Ray: 我的一位朋友如此评论这些文章:他说真正理解抽象的唯一方式是通过抽象本身,而不是通过并不准确的类比。 「为了充分地("有用处"地)学习这些抽象,你必须去学数学,而不是通过一些糊里糊涂的文章,它们除了类比还是类比」 Dr: 要找到 “哪些代码遵循此抽象” 并不是必须的。像 Monad 这样的概念是非常抽象和通用的:它是一个描述了一套广泛的编程模式、数据结构、库和…
#PLT #learn 文中提到一个Futa对应关系(第一类二村映射 first Futamura projection), 展开讲讲还蛮有趣 🙉
首先,js人都会写计算器的,和 echo input/server 一样的难度

1+2*3
十(1, X(2,3)) -7

十=(A,B)=>A+B

这被称为「前缀式polish notation」,是Lisp的国是
教个小诀窍:js里函数只是一种字面常量,可以被for生成
Object.entries("十一Xノ").forEach(([i,x])=>
this[x]=eval(`(A,B)=>A${"+-*/"[i]}B`))


为了更像“语言”,可以用列表(进一步就是"1+2"的代码)实现语法,便于糖化
Eval([十,1, X,2,3]) -7
Eval=([f,...x])=>(!f.call)? [f,x] : //基线返回两项,递归就都是两项
(([A,b]=Eval(x),[B,c]=Eval(b))=>[f(A,B), c] )()


Monadic递归下降是这样AbBc的,因为不能右移流指针。不如逆波兰好看!不过这种程度的递归可以学学。

再看下「解释器interpreter」比计算器强在哪: 能够“在调用时传值”,也就是要有 argument[0] 这种“环境变量”
很厉害!现在有常数外的“语法”了,有变量了,高阶了!或许你需要学动态作用域(原型链?)、调用栈call-ret、惰性求值如&&|| blabla,还有深不可测的编译优化呢!

不就加一个箭头么。
十=(A,B)=> (env=>A(env)+B(env)) //现在知道为啥该用for生成函数?
Lit=x=> env=>x
Arg=i=> env=>env[i] //PHP写作 $x, 模仿bash的$1~$*
Fun=(n,f)=>f(Array(n).fill(0).map((x,i)=> Arg(i)))


env被称为运行时,它可以是JVM, import dis 或者别的bytecode解释器,这能减少tree-walk对递归栈的频繁依赖
这种 formSytanx.bind(consts=lit/arg/global/Types..) 的"部分传参"函数,称为编译器,而它的返回就是classFile等类型。
编译器并不需要与DSL这些技巧隔离,如果我们把 env=>x 写作 JSON(x) 而 env=>env[i] 写作$i ,既 Lit=x=> gcc? CBor.dumps(x) : (env=>x)
以这种人类或机器可读的结构序列化一些函数被"bind"到的lit,就得到了对应的代码。jvm的 lconst 1, aload_0 this参数, iadd (2->1)甚至是自动分配参数寄存器的!
https://www.yinwang.org/blog-cn/2014/01/04/authority#:~:text=partial%20evaluator。其实并不是特别神奇的东西,只需要在普通解释器里面改一两行代码就行,可是有人

二段求值。代码是流动的数据,内存是暂停的程序。本文甚至比赢王更直观: https://www.yinwang.org/blog-cn/2012/08/01/interpreter
定义个“元循环加法”吧?
十1=Fun(1, ([A])=>十(A, Lit(1)))
十1([232]) -233

//[Lit(f),x] 补丁下Eval"解析器"。计算器、解释器、编译器间,其实并非泾渭分明
Eval([十,1, X,2,X,1,3])[0]([2]) -7


如果你乐意,还可以支持基于全局表的递归 fib=f(x)=x<2? 1 : f(x-1)+f(x-2)
这一切都不会突破以上的定义框架。 If 不会,Call(f,x-1) 不会.. 这就是java的反射嘛。
我不想再写什么了。 我看过许多“编译原理书”,他们连这个=>都写不明白。 更何谈用Visitor实现(反)序列化 这些既理论又实践的approach
#haskell data Val=L Int|Op Char Val Val deriving(Show)
(Op '+' (L 1) (Op '*' (L 2) (L 3) ))

这类基于list或class{子类多型} 的 Eval(e=^^, env={proto:{..}}),与本文使用的闭包法是等价的。「闭包是穷人的对象」,Promise 给它暴露到了 obj.then(Continuation)

> 高阶的思想或许是本文的所有思想中最为重要的那一个 https://ray-eldath.me/programming/three-important-ideas/
你们知道函数的函数、类型的类型、语言的语法,却难以创造「语言中的语言」—跨越用途与界限而一致的语意。
我看numpy和 taichi-lang.org 就用的很好,比LLVM好一个世代
顺带一提,上文还使用了 Tagless FinalDe Bruijn 索引 😇 。只是…… 你甚至不需要知道它们的名字。([A])=> 经常被实现为KV["A"],但点明它的本质,却比写解释器更简单!

说到底,元编程也只是编程。就像“学会学习”只是一种策略,它对学习而言,并非例外情况。难者,不会也,譬如在谈"bind(x=1)后函数值字面是否改变"时提起「颗粒化curryArg」 当然会让人迷糊
node,graal会编译js,jvm代码(这也是为何Chrome页偶尔会segfault); JVM会使用汇编模板+JIT 的混合式优化,Cython则把“甜妹语言”翻译到C,LLVM则是个伪装成NodeGraph虚拟机的codegen
如果只用"是否该调用javac"来区分语言,认为C类型总比python更快的话,你会发现程序员钟意的都是freak!

宏,macro码可揉,是传入与生成class{}等字面的函数。和+-*/一样只是函数,而函数、类型,只是值,别被“静态分析”骗了,它们送你的class只是病态类型。
入,lambda栏目答,看x,A,B等栏目回答的算式
这点篇幅放前言都觉得寒碜吧? 可就是没人做到啊。 扶她投影?不知道的还以为是HP projector 的娘化版呢。。
PLT能对dev点化到的可谓寥寥, 但100%都是必要且急需的知识和"抽象",像Prolog的模板与响应式html编程("FRP") 什么的。 Monadic错误处理我不想吐槽什么,只能说不怕不识货,只怕和Kotlin比!

跑题了。当然,聪明的你会发现Fun的返回违背了"基线指明了递归的类型"这一原则,没生成 env=>
那C语言函数指针是这样的,env由*rbp[0:2]=[retRbp,retAddr]这些CPU变量提供,但JS里的闭包可以从env偷变量(Var作为值,mut ref),所以说「闭包是穷人的(单方法)对象」

C里还有"函数符号",那是由ld.so实现的全局表,让.o对象能先被mmap到任意地址,再去回填calls
真正的那个全局表叫 $PATH: ,以及没定义main的对象的 $LD_LIBRARY_PATH 。
duangsuse::Echo
>火之魔女: 不过unification我是想写好久了(应该按年计)但是一直没写的( https://github.com/duangsuse/mkey 写过,不过落后很久了 #sql 这算法就是 unify(a,b); unify(a,1); unify(1,a) 得出 a.v==1==b.v reify([a]) 解引用一下=[1] ,其实也挺有趣,包括npm也在牵强附会这玩意,真让人搞不懂从哪看的 http://minikanren.org/ 使用了一个自有的def: yield 实现,对 a&b…
#OOP #plt 学点设计模式
https://iota.huohuo.moe/OO-in-C.html#:~:text=一种设计模式对应一种语言特性%20%20By%20千里冰封

函数式人有许多「过度设计」,例如美 kotlin.Any.let 其名曰 #FP Functor.fmap (Arrow-KT.io)。这种(私货+算法)的泛滥,给IT带来了灾难,让许多初学者不明觉厉,也当然不能提升其应用能力(毕竟只是"指针别名"嘛)
https://kotlinlang.org/docs/scope-functions.html
https://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html

但OOP也有自己的“私货”——用于弥补语法不足的“优雅的”设计模式
例如 Builder,Utils,Adapter,Delegate.. 它们是对this参数、对interface扩展不够灵活的变通

这个长文,我会用短 #kt demo 让大家看到 refactoring.guru 🐿收录的10种流行 Design Pattern 掩盖了哪些语言特性的缺失
以及科普"OVDEP" Observer Visitor(深先iterator) decorator(单参compose) EitherAB Proxy 等不逊色于箭头函数的,超越语言的优秀工具

## 创建性-Creational

这些模式是 new 构造器() 的变体,在Rust里被 fn new=Pair{A:1, B:2} 构造字面和 impl T for T1{} //mixin T1: T 混入取代

1. StructBuilder

有一个很长的SQL row需要new,可以使用默认值,插入前也有检查

class RwCol2<A,B> {
var A:A?; var B:B?
constructor(x:A,y:B){A=x;B=y}
constructor(){A=null;B=null} //默认值
}


我们把构造器中A=x;B=y; 拆成 newThis.A(x).B(y) 两个函数,就能实现初始值的解偶
填完数据可能要验证,如编译期验证不可变 fun build()=this as Col2

与它对立的是默认参数
RwCol2(0,0).apply {B=B+1}.B; buildList{} this参数上扩展 apply(T.()->*): T
K2 value class{init{}} 也实现了构造后验证,不过大部分人仍在使用专门的反序列化和data verify框架

2. (Abstract)Factory

常见误区是,Factory类似 Pair.of(1,2) 是为了重命名掉new,或者只把构造器集结起来: doc.createElement("div")
安卓 content.Context 与Button等View(ctx)的关系更像工厂的本意: 基于(操作系统)上文验证和保留数据

interface DataJVM {
fun <A,B>List(a:A,b:B): Pair<A,B>
fun <T>List(vararg x:T): List<T>
}
val kt=object: DataJVM {
override fun <A,B>List(a:A,b:B)=Pair(a,b)
override fun <T>List(vararg x:T)=mutableListOf(*x)
}
//val py=object:DataJVM{}


与它对立的是全局对象、元类trait。
全局fun弥补constructor钉死了 open fun 且难于校验的问题。当然!它也消灭了 object Singleton{} 和“双检锁”的样板
元类允许了 static (类名上)接口,而不是让可覆盖的函数代理一下构造器:
https://docs.oracle.com/javase/8/docs/api/javax/script/ScriptEngineFactory.html

3. Prototype

Linux对pwd等环境变量的fork()是最著名的原型模式,这使得父子进程间有了T1继承T 的关系
JS里 {} 等价于 {__proto__: Object.prototype} 函数表,函数表也可以随时添加继承。有 new.target 的构造函数()只是设置原型+赋值到this的简写
一切皆对象,除了 Object(1).valueOf() 里装了又拆箱的1。无原型的,只有更慢的 Obj.create(null)

data class 会自动实现 fun copy(),但它不能继承,因为无法拷贝父类的变量。Java里很难把对象加构成更大的子类(除了 inner class)
sealed class Box<T>(val A:T) {
inner class Pair(val B:T): Box<T>(A)
}
val x=Box(1).Pair(2)


按道理是x.A=1,那么Box(1)单例就是这些Pair的原型