duangsuse::Echo
711 subscribers
4.24K photos
127 videos
583 files
6.44K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
#HR #java 回答安卓面试题 [AI标准答案]

- 做过哪些项目,用过哪些 Android 开发相关的东西
没有,H5赛高
- 「大学生活质量指北」是什么(?(然后我真的讲了七八分钟这个项目的来龙去脉和作用
不过VS Alt-S 同行数多光标可以列粘贴
- Java 里 LinkedList 和 ArrayList 的区别
链表适合单遍历,不需要resize (1 (2 null))
- 栈和队列的区别,如何用栈实现队列,Android 里哪些地方用到队列
Queue.add-pollFirst 队列 add-poll 栈。Looper Handler.post; Stk.poll()=len==1? pop() : (x=pop(),r=递归,add(x),r) 。转换的话,LIFO两次==FIFO
- 上面我提到了 LRU 缓存,所以什么是 LRU 缓存
eg.已满100项{arg:ret}则删掉最早1项、取时下移

- HTTP 和 HTTPS 的区别
HTTP(SSL(connect(IP:port) )) 公钥加密的有无
- 进程和线程的区别
有无内存,fd资源隔离
- 有哪些方式保证线程安全
原子和Reent锁,或者向量化 各自隔离
- 堆内存和栈内存的区别
堆new的对象不会在return时删除、栈很小(Linux 8M),Java 的话应该全叫堆引用才对,避坑。
- StackOverflow 和 OOM 分别会在什么时候发生,如何避免
-Xms:8G -Xss:1G(划掉) 栈爆只会在DFS的输入太大或无基线,类似的OOM是BFS没有记忆而无限回环 ;真的是搜索图太大,可以用 DeepRecursiveFunction 栈调转堆回调
- 算 6&5 和 6|5
4+2+0, 0b110&|0b101, 4,7 AI都算得对

- Activity 里什么时候会保存状态、恢复状态
onRestore/SaveInstanceState(强类型KV), 请AI实现 V:Parcelable
- Activity 屏幕旋转的时候会经过哪些生命周期
请正读-反读 pause-resume stop-start destory-create (天哪..究竟孔乙己到什么地步才会把框架的“生命”细节公摊给App?
- 如何计算一个图片会占用多少内存
nByte=w*h*单像素bit/8
- 项目中用过哪些第三方库,能否分别给出介绍
没有,安卓生态冗得像罚抄
duangsuse::Echo
还有一些FP的错误 #design »=: (我们知道,OOP对象 constructor() 就是一个“多方法函数”,等同 when(arg0, {run:(self)=>overridedFun ,.})的闭包。是这样的「高阶函数」 - 函数作为值并不稀奇, 相反,滥用 partial(f) 与compose而非this链来隐藏参数,虽等价于 obj.bind.f ,却是一种无序亦无类型的表达习惯。typeclass是和C一样的无心智模型,这种散漫 不值得被崇拜 Python,Rust,Go 都…
https://www.zhihu.com/question/631144121/answer/3299457578

#js #java #web #news React系还有一张刁图,让我感叹 sql`${}` 居然都能成为稀奇事(虽然之前我想用但没找到包。貌似用BaaS有 prisma
目前还只有JS能做str安全注入

当然20年前C#就支持ASP, Razor还支持 <button formAction="@( () => await Db( $"INSERT INTO Bookmarks VALUES ( {slug} )" ) )" >

前后端同构当然更合理(并不是像PHP那样的伪共用),但不要区分use client和use server更好

原来Javaer才意识到自己只是 CRUD boy??
duangsuse::Echo
昨天提到的头疼点,现在修好了,希望以后能实现吧 顺便读篇#zhihu 文吧 https://www.zhihu.com/question/40675600/answer/3310038891 >代数数据类型是所有高级特性的基础, 比如 0 = never, 1 = unit, 2 = bool.. NaN=void >定义和类型以及积类型(sum prod), 所有类型就都可以组合出来。相同的 ADT 编码意味着这两个类型本质上相同 首先,你想用实例的个数表达「类型」? SQL Table 就是如此啊,但是有啥用…
#design #java 🥰 我的编程范式,目前由2类的重载重写构成

# 行列式多态 tabular polymorphism
class,dict,struct 等类型的本质是“电子表格”,而方法只是有特殊前缀的全局函数

因此,类型就是行和列(=定长字典和键)

?? Animal
- name Str //<> 列方向共有的,叫接口
Cat(name)
Dog(name, owner:Str) //^v 行方向新增的,叫构造器

其形式为 C=A+B :

?? C A
- b1 Str
- b2 [Int sets] //可变量
?? A-exists B /
/Animal 表已穷举,不可继承
//-
A已存,无法添加新的列
C(但是行可以=1.0)

枚举则表明,类型也是数据
?? Food now Rows(): //简造器: [Str Enum KV]
Apple; Tomato; Beef

因此,Pair(Col2) 继承自Columns ,Maybe(may2) 继承自Row
error(): NO类型, voidFn(): over类型

构造vs简造器
构造器constructor= 由变量组合成的struct
简造器lit= 由字面等价出的enum等type,必须属于既有表格


# 转为式多态 too polymorphism
加参器instructor、加构器costructor、段造器OOstructor 「3种三段论」

默认值+值=值
给定值+值=对象
默认函+值=对象

z counter(0) :
me(1)==1 me(2)==3
//z==$Yes

Dog("Hachi").[Movy too].move(0)

??- counter(x:Int, ac=0) //加参器可以避免class的滥用,或为监听等闭包 声明可变量
ac =:+ x
over ac

??- Animal.Dog(owner="Jack") //加构器可以避免继承得没有主次
??- Dog.too() Movy //且允许从impl{}扩充函数 平滑过渡到方法或参数更多的类型
- move(dxy) $N !:"躺平了"

??- Activity AbstractMain
now: aField 0
- onCreate as:
main()
Name.asSuper
- onDestroy ‘TODO’
^??
- main() // 段造器是能
作为参数的函数字典,它直接与OOP对应
- fetch(:URL) "STUB!"
- openVal sets(0)

对人脑而言,模拟执行代码,也需要发音。
在不同的(??)语境下,-函数调用有由参数确定的“声调tone”,俗称多态或 类型判断/自动转换
有3种词支持新增声调: 类型(??-) 多方法函数(??) 单方法函数(-)

??- [Activity 函确定]() Main() //无/有构造器的类型,默认确定性为 funcs / funcs! ,因此无需trait{}。只需去掉^?? 就默认final
^name
- statics也可以有元类接口
??- Main
- 同文件的扩充可以mark private

??- 这是个函数() 0
.:
- 它不该有局部fun
??- 或匿名()Object()

↘️ 为了方便跨平台或mock,应该在编译期依赖注入, 称为 os-依协议工厂
比起抛开constructor 而使用 Factory.createXX() ,应当允许 ext fun 按作用域选择性内联,类似于导入并覆盖

os.exec("echo 1") //返回动态类型"NO"
??- os-droid()
- exec(:Str) "install busybox!"

# 运算链
右链左表括歪嘴(rchain lswitch wheezynul)

y 1 .:
Vec2(me+1).x //sin
-2+3

3==(counter .: -ac 3).ac
//右下链,是Rust允许{let}遮盖同变量名的理由 🙄
//那根本不现代,和C的int a=(b=1), “now 1: a;b” 一样是瞎猫吃死耗子,祈祷不被[有心人]滥用呗

除了可多行的bash式参数,还有「类型即表格」—class可以随处创建
那些总是在 fn(a=a,b=b) 的def 也可以消停了,让人用得上才叫OOP嘛

yNew y :.
<0: -1
>0: 1 ; or: 0
//左下表,单行缩写为 (y rem- 0).{0"平" 1"剩" -1"负"},支持bool函数和匹配解构

(1==1) \: // 这个\: 替换为.{$Y 1 $N 0} 就是ifelse了
say:'CPU有毛病'

ada User(NO) // 非常可爱的、文化中立的表情,取代了让人头痛的异常、弱类型||、null ?.let ?:
ada.age ("UNK") : "☹️{me+1}"
(ada.age🫤 \: 17)+1
may{u.age.orThrow} !: "😬need be checked"

?? Row
User(age\:Int) //val age:Int? 不应该出现在结构体以外,除非写为
- age [Int mayNO]

🦄
解决了一个心腹大患,开心,现在和Kotlin加那一堆data seal enum 修饰词的完全不一样了,而且类型上既Rust又Go 🦀,值上既YAML又JSON ,而且可能让Haskell GADT和Monadic链吃瘪了

然后,还有比GraphQL都好看的免术语区间和filtermap 🥭 ,无需open()的文件保存/另存为抽象, 总之,这个范式绝对不是单纯的面向函数。 不仅仅是强类型+DSL,它比py更擅长处理数据
我最喜欢这样看着土,实际从各个角度都博采众长的东西。 和任何编程语言都不必比较,因为它不需要门槛,会Excel和bash都能懂, 有序自然+简洁+文化中立

但我必须做一个前端框架,吃上饭才有时间写编译器啊 😅
https://t.me/kotlin_cn/110933
#java #code serde codegen
用jshell API 实现了一个ini序列化,大概比直接靠javac 简单
>以下代码实现了 dumps(Pair::class) (Pair(0,0), mutableMapOf("first" to 3))

fun dumps(T:KClass<*>, ld:T=JS("(void)(${T} o, java.util.Map<String,Object> m){"+
T.memberProperties.joinToString(""){" m.put(\"${it.name}\",o.get${it.name.capitalize()}());"}+"}")!!
)=fun(o:Any, m:Map<*,*>)=ld.main(o,m).let{m}



所以说py真的太解压了.. setattr() 就算动静态隔离,typehint还能做格式验证
js稍微乱点
java 连个规范的元编程方法都没有,一群魔法师

我是觉得一个老古董语言就不要和jspy 比面向event和类型反射
Compiler 和 JShell API 就是tools.jar里的,做不到比 CLI更强的功能,就是调用快点
JS("") 和runtime其实是完全隔离的,它的classpath 相当于是编译期的,你可以把生成的代码按行号缓存下来,不需要defineClass
vs

// 定义一个 data class
data class UPair(val A: Int, val B: Int)
@Mapper
interface UPairMapper {
// 定义一个映射方法,用于将 Map 转换为 UPair
fun mapToUPair(map: Map<String, Int>): UPair
}
val mapper = Mappers.getMapper(UPairMapper::class.java)

mapper.mapToUPair(mapOf("A" to 1, "B" to 1))

https://github.com/mapstruct/mapstruct/issues/1672#issuecomment-969265894
https://gist.github.com/duangsuse/d022c7ad037bb7fed446f72ec9b38ef7
#learn #js #kt #java 🧵 📥
借机聊下线程、协程间的对应性,以及UI/UX应用与单次脚本间因何不同。(全栈)

调用返回要靠 -Xss 指定大小的线程栈,数组
调用异步要靠 ret() 参数指定的回调栈,链表, 也可以封装为 new Promise((ok,err)=>ok(0)) 。内部执行前都要传入then步骤,但不需要看调用栈
你可以把异步栈保存到[]{}里按需执行,称为调度。协程(async stack)和linux调度器的区别,仅仅是后者能跑死循环(分时复用CPU)
总之 线程栈=调用栈,异步栈=回调栈。

ps|head -n1 这样的管道write() 其实就是yield。这时read()不会等待/dev/disk/的CPU.IO信号,而视ps下一块缓冲的bytes (C对象的Channel)
信号,不是死循环轮询poll,它看注册推送push。不过Looper,HTTP-epoll请求响应 这种ddloop(detect-dispatch) 模式会混合两者
本来,为了不卡死主线每次IO或延时也要 launchThread{b=f.read(); rest(b)} 。封装为 f.read(回调) 就异步了:线程无关
生成器, yield(x, Ret) 会保留首次调用偷偷建的状态机Ret,第二次next(v),调Ret(v如异步结果)后即可返回x。 asyncFn=(args, op=0, Ret=(v)=>switch(op++){} )=>相当于协程对象

主线程sleep()往往要卡死UX,但 yield ret=>setTiemout(ret,1s) 却会立刻返回,同时允许ret()上文切换到其他线程池(ddloop,scheduler)继续执行
造成以上区别,是因为push比poll有普适性,它跨CPU地执行同一个函数,且有event/flow based 范式帮助模块复用。libuv和DOM就是对os.read,sleep.. 跨平台的线程池优化

既然如此,好像有UI+IO两个线程就够了,你干嘛~要多开线程
上文切换,只因,为能更好地压榨多核线程池
DOM代替大家做了划分,为多线提供了内存安全的Worker,但kt,go,py里暴露的技术细节有点多!

线程和 asyncio/suspend 相比有何劣势? linux上进程内是创建慢的进程组(fork)。在不调用OS资源时,永远使用协程"套娃"能减少到内核态的上文切换和内存消耗。像线程池存在的意义,就是免线程创建http连接等单任务
需要mutex锁的独占性资源,用协程读写更节省轮换
单协程轻量到1个回调就能保存,并发控制如 join(coroutineScope),go select,channel 可以用Promise.all,race,postMsg来"阻塞",因为它提供了进程模型所缺少的返回值。
线程即共享内存的进程,无需手动封送(marshall RPC)就能互调用,而json本意是保存会话(对象树)。 如果内存会话和机器都要隔离,就需要 Proxy(by=cookie酷卡/fd句柄) 验证对象API权限了
通过句柄而非密码访问API,是因为句柄能定期吊销,也便于审计。代理有时叫注入,Mapper,绑定

那么jdk19 虚拟线程 又如何? 有100w级的并发1s内完成的低开销,类似py的GIL
但绕过JDK的IO走 JNI Unsafe 读写文件或网络是无法实现异步调度,未实现 suspendCoroutine{it.resumeWith(Ok(0))} 这样的yield的扩展性
var vs = Executors.newVirtualThreadPerTaskExecutor(); //Executors.newFixedThreadPool(200)
for(var Y= new int[]{0}; Y[0]<3;Y[0]++)
vs.submit(() -> { int y=Y[0]; try{Thread.sleep(java.time.Duration.ofSeconds(y*1));} catch(InterruptedException e){}
System.out.print(y + " "); }).get();

最后,再了解经典的「并发模型」 就能读懂90%的企业级服务了

- ForkJoin,MapReduce 如把文件预分块(shader) 读http区间多线程下载
- Actor 直接按函数参数,自顶向下来分块(RPC)
- CSP 是上面说的多进程,靠 Channel<in T>, chan<- T 递交任务,流式的 make -j8
- 线程&锁 互斥资源不能被linux多核调度改乱套了,所以得加锁(synchronized)
duangsuse::Echo
#huawei 虽然API上各方面都没啥突破(亦如ark.ts),但这个demo tutorial举例比rust,go的更有趣 可以说团队的脑子没有被八股文的驴踢 #锐评 https://t.me/dsuses/5319
#java #ts https://www.zhihu.com/question/659506359/answer/3538805082?utm_id=0
看到“高级编程语言”的数据结构我就捉急呀。

类型就是表格。纵行是其变种,横列是其数据, obj :. A(x):; B(x) 手动模拟if isinstance多态性
表格可以相互混入,传参时只要有覆盖该表就能调用
若无构造器,默认定义为纯模板 fn?? ,亦可含fn?项
否则表格默认全员锁定!fn,相当于struct。 写明的fn用于扩充既有类型或seal接口
- f(x.[Int Str may2]) Col2(1 2).A
?? 'AB'Row fn
Col2(A.A B.B)
?? 'AB'may2
A(x.A); B(x.B)

这不轻松把OOP interface abstract open final enum ADT match 给讲明白了,顺便消除了“代数”数据与子类型的鸿沟,易读和扩展性全都要。本身就是小学生都能搞懂的把戏嘛,真是啰啰嗦嗦一大堆啊

什么积类型和类型,你是Prolog? 给你俩Byte你能穷举出256**2个值,那才叫 prod type! 然而自称支持这些的,你的 patten match 等号两边能反过来写吗?
moonbit和仓颉,主流语言的那些小九九一个也没落下。 您是为计算机系开心写代码,还是为使用者开心而写?

再比如Go的 struct mixin。OOP的inner class本意也是一样,可惜被执行坏了,结果反而不如FP的tuple拼接

其实哪有什么构造器呢?拿函数签名生成的新类型吧。不过就是你们在模仿gpt该做的烂活,或者请IDE“代码生成”。。明明语言从语法API就必须解决掉的东西

如果从更大的复用性来看“class”,90% 的情况都是把重复的args打包起来,避免传一大堆参、允许部分修改,比如那寥寥无几的 open fun,“函数值参数”

因此py即便不爱用class也不瓶颈到工程的规模、Go早期干脆不做泛型。捆绑几个参数嘛,dict更好做

至于协程(N:M线程),await和yield(then vs next)其实是一个东西,但前者更合理,因为它只是把回调交出去,然后自己return
yield看似符合直觉,但缺少了重要的东西,例如buffer N项一页yield 大家都不支持。我们真的缺语言级iter吗?
spawn{}隐藏了调度级的“异步”,线程随便开,这很好

cj的过程宏,目前 import std.ast.* 后可以parse FuncDecl 啥的,也有quote()内插,还算比rust易用

我们程序员的奇技淫巧很超前,我们的软件工艺落后太远。

btw. 官方文档注 https://zhuanlan.zhihu.com/p/704858976?utm_id=0
https://www.zhihu.com/question/523049017/answer/3537896490?utm_id=0
#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
#reveng #java #net
>一眼盯疹,11年前的这编译器还不如EDSL,不就相当于加个auto x=mat2x2() ,这算什么简化gl

至少我手上需要读取fn.kwarg ,要提取({k=1})=>的默认,你说该不该留源码

jvm/clr那种栈机,高级版gnu dc, 一个jadx/dnspy就还原了,不il2cpp不混淆掉命名,怎么都没必要
py还默认发布pyc呢

duangsuse:
对了,说起来jvm->clr应该可以转化吧,这样就能用对方的反编译器

https://github.com/ikvmnet/ikvm/blob/main/README.md
- Convert bytecode to a .NET assembly to directly access its API in a .NET project

上位虚拟机当然能兼容执行jar了

dnSpy(wine) v6.final Install-Package IKVM
一共200m https://github.com/dnSpy/dnSpy/releases
https://github.com/ikvmnet/ikvm/releases/download/8.8.1/IKVM-8.8.1-image-net8.0-linux-x64.zip

可以配合调试 unity games https://github.com/K0lb3/UnityPy?tab=readme-ov-file#mesh
#java #news #algorithm https://www.ithome.com.tw/news/163820

当我听说这个月Gosling退休时,其实我挺开心的,因为java API在我看来普及了不少无语意的知识,为八股文爱好者提供了极大方便,可以说是糟粕
这样给程序员带来麻烦的老灯,退休当然是好事,让他们的OOP繁衍下去是浪费人类的逻辑

但另一方面,这并不是JDK本身或 Doug Lea 等工程师的问题。与C++相比,java并不难。除了简化发布流程,还自带电池,提供了许多xml这类最终被滥用的工具
尽管在数据结构/IO上灵活性低,以及导致了十亿美元bug(nullish),java API并没有做错什么.

错就错在跨领域研究编程范式的人太少,以至于过去20年里没有新模型,Rust go 这些还是在拿interface 模仿OOP,没有一种把 json struct enum union override,FP 混合起来的通用编程方法
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作为类加载器动态翻译