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

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

suse的小站:https://piped.stream
ps 另有别名 popf.rip
ʕ•̀ω•́ʔ✧ 🐶🍎🏠生死🐜
(>ω<)岂因祸福避趋之 一鿕
Download Telegram
#kt #plt 不用脚本引擎,设计几百张效果卡牌 https://t.me/kotlin_cn/76449
duangsuse:
你这相当于在kt里造全局变量域的Lisp.. 还不如用jdk 的Nashron JS

用函参模板是性价比最高的序列化方案, 也不会和配置文件那样难写

在强类型里实现AST真的没好果汁吃 ,一般的游戏都是暴露棋局API给lua js啥的

用组合函数+as强转 就等于这种方案
#py #java #meme 这个 meme 更适合 langchain😅 .ref

比如什么 aspectJ.HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor
https://www.zhihu.com/question/550314430/answer/3098679716


超长 类型名

*: chain.run() 的参数会填写对话上文, 按推导自由度temper 回复
翻译器的上文是:

>!你是翻译{input_language}为{output_language} 的好帮手
>{text}


👇 #kt T? 有"多少种" Nullable 注解
duangsuse::Echo
#android #dev 面试题。上条则是简化版的答案 🧐 仅供参考,可能我解释的太抽象了,涉及一些淘汰的远古技术, 不符合标准答案。 - Handler 基础,Looper 怎么和 Thread 绑定,怎样提高 MessageQueue 优先级 - 进程间通讯的方法,对 AIDL 的了解,对 ContentProvider 的了解 - (根据项目) 自定义 View 的方法和注意事项、事件分发、View 复用 - 写过 demo 吗,什么时候会写 demo - 对 MVVM 的了解,对 Jetpack…
#android #hack #aop 继续,加上奇怪.. 的知识

Magisk 是 Android 版的 Docker (overlayfs),能管理root、去广告加皮肤、安装字体、模拟位置、利用权限骗过 SafetyNet DRM
它让 /boot/initrd 挂载(--bind) /sbin/.magisk tmpfs 来遮住 /mirror/system vendor 树,因此需要TWRP刷zip(和root时一样) 或fastboot刷入kitchen过的原机boot.img

新设备可能不区分boot分区(A/B 切换来OTA),修改内核强制使用 initrd(boot.img) 里的 init(PID0) 程序

简单说,#Linux 启动的传统是kernel解压启动 initrd 内存盘(recovery,Magisk)去寻找真'/',然后 chroot /sysroot /init (systemd,各类run-command,.)

Zygisk 和 Xposed 都是AOP框架,分别拦截和修改 Java android.*/JNI 函数的调用,从而实现对系统和应用程序的功能修改。Zygisk 是基于 Riru 的一个模块,使用 Zygote 注入技术来加载自定义代码。Xposed 是通过替换 /system/bin/app_process 程序来控制 Zygote 进程,使其在系统启动时加载 XposedBridge.jar 文件,从而完成对 Zygote 进程和 Dalvik 虚拟机的劫持。

Zygisk 是 Riru(#cpp .so 函数替换,靠魔改某项linker_PRELOAD) 的免安装续作,开启后不能规避检测,但支持文件/JNI重定向、实现了模块黑名单。 LSP和Ed-Xposed分别支持二者(不能共存)

.internal.os.Zygoteapp_process 的起点,它负责注册JNI、创建 SystemServer(PM,WM,AMS处理的Intent),之后便执行Xp模块
LSP 用 env->RegisterNatives(动态注册版Java_), jni_method_map[T][id][sig].fnPtr 来JNI替换,Zygisk 提供了 {pre(包名),post}AppSpecialize(args)
PRELOAD=libxposed.so 利用 env->FromReflectedMethod(由java查找).{access_flags|=ACC_NATIVE, (Dalvik|ART inlined jmp)nativeFunc=callHooked} 做函数替换

RegisterNatives 本身就能让JNI函数基于jobject clazz 派发,所以比ART hook 简单
FakeXposed 作者的博文

#kt #code
import de.robv.android.xposed.*
import de.robv.android.xposed.XposedHelpers.*

val reg={
val NoPrint={
setStaticObjectField("java.lang.System", "out", PrintStream(OutputStream()) )
}
findAndHookMethod("java.lang.System", cl, "<clinit>", object: XC_MethodHook() {
override fun MethodHookParam.afterHookedMethod() {NoPrint()}
})
}
//assets/xposed_init 写下类名
class My: IXposedHookLoadPackage {
fun LoadPackageParam.handleLoadPackage() {
if(packageName.equals("com.example.app"))reg()
cl=classLoader
}
}
duangsuse::Echo
感觉虽然有些收获,也都是没啥意思的问题…… 面试呢,或许对我这种数学渣就都做不到的吧? #statement 我讨厌这种AI都能写的问题,这些”深刻思考“有什么价值呢? 总是一些算法,让编程变成一种不快乐的任务、变成帮出题人自问自答的”寻宝“ 这些出题人又有多聪明呢? 大众都在润色70年前,世上还没电脑时就有的问题, 而小众又能成什么气候,又如何让他们的沧海遗珠给时兴编程带来价值呢? 如果用《算法图解》那种小说口吻去讲,做一些有弹性的科普视频,倒是有娱乐价值;如果写代码只是为了复制粘贴「能用的东西…
举例, #ts 上有”交并集类型“ (有人认为 hs, Rust 没有子类型所以不存在集合论的,确实如此但 in-out 形变是Racket子语言里也有的,我找不到原文但TRack 是有)
(我一点也不羡慕没有重载和this模块等多态技术的圆括号 😅, 模型的缺失是拿宏手动兼容 a.b.c 所弥补不了的, 就像 F# 的 |> 比不上 xx.let{}, kt 的元组 destruct 比不上 ES6 let[x,y]=P, ES6的解构又不如 Prolog 的 unify [x,1]=[2,y]...

观摩王垠《别再欺负我们读书少》:
- int -> int | bool ->bool 表示的确实是一个intersection type(^),而不是union type(|)
- id(itself) “同时”是int->int和bool->bool,而不是表示它“有时”是int->int,而另外的时候是bool->bool。
- 所以,id(1)一定是int。如果你输入id(True),它推导出的一定是bool。
- 否则,调用id(1)会报错,因为id的类型有可能是bool->bool,不能接受int的输入。调用id(True)也会报错,左右不是人。


但我习惯拿 成员交=union ,成员并=insect ,绝口不提“同时”“有时” 这种抽象说法乃至术语
- int -> int | bool ->bool 表示的确实是一个重载,而不是Either
- id “必须”是int->int, bool->bool ,而不是“可为” int->int | bool->bool。 when(x) { is Int, is Str } 这种情况才是“x可为二者”
- 否则,调用id(1),id(True)都会报错,因为id的类型有可能是bool->bool,不能接受int的输入,或者反之。

严谨性绝对是次于创造力的,况且,含糊的说法对同时使用和实现不利
虽然这些都是小小的细节,但每个细节都注重可读性,随着设计的步进,最终会形成巨大的差异。即便都是用AI,我的实现也会有很多不同
duangsuse::Echo
#py #math 《优雅不是奢侈品》 “如何才能让编程者们相信,简单性和清晰性——简而言之:数学家所说的“优雅”——不是可有可无的奢侈品,而是决定成功与失败的关键因素?” ― Edsger W. Dijkstra,“计算机著作精选:个人观点”,第 347 页。 简单明了的代码就是优雅的代码。这些都是代码中非常理想的属性。Dijkstra 又补充道: “……在软件不可靠性的情况下,最大的成本因素是复杂。 一个可靠的(因此简单的)程序的开发和使用成本,比一个(复杂的因此)不可靠的程序要廉价。” 人们…
#py 周刊
- 《优雅不是奢侈品》
- nogil 最新情报
- #web Django ORM 最佳实践
- Django 自带的JWT 路径验证和登录页
- #ts 阮一峰 入门, 纯JS入门

- #linux #rust Nush: 不是 Powershell
- #js npm依赖图
- #ai #tool realsizer4x 超分辨
- #rust pixi add cowpy 强化pip
- #ui Toga: 跨平台的 TkGUI

- #ml Viberary: 开源书籍检索引擎
- Khan 为何从Py2移植到 kt,go
- #parallel 用asyncio分享查询,防止缓存失效时并发卡爆
- #plt Rust vs Idris,Zig: 渐强类型的解药 #1

单进程 cron
from apscheduler.schedulers.background import BackgroundScheduler

cron = BackgroundScheduler(jobstores=sqlite)
.add_job(print, 'interval', seconds=5)
.start()

并行 multiprocessing: #2
with mpire.WorkerPool(n_jobs=5) as pool:
results = pool.map(getFiles, range(10), progress_bar=True)


- 修改语法ASDL,实现 map( (x)=>x*x, [1]) [Parser/Python.asdl] [30行实现]
- 奇怪的for赋值, 魔术方法
from xx import*明确化:设置好 xx.__all__ = [exports]

实现 lazy load:
importlib.import_module

⭐️import pyforest 自动导入np,pd 等变量
#code 修改语法 __import__('cv2') -
from lazy import cv2

import types,sys

class lazy(types.ModuleType):
def __getattr__(self, mod):
import importlib.util as _
if None==(r:=sys.modules.get(mod)):
id = _.find_spec(mod)
# get it inserted into sys.modules.
_.LazyLoader(id.loader).exec_module(r:=_.module_from_spec(id))
return r

sys.modules['lazy']=lazy('-L imports')
— 仅供学习,import 语句本可以是局部。 (GPT怎么变蠢了
#ts
#1为什么静态类型的C,Go,C++ 不是弱检查 就是太复杂

代码练习: 不需要 type WTF<> = 就可以检查 htmlTag, funcPipe, nthArg, printf("\d") 等调用的类型

int[10] 的实质、 #Kt 类型推导的原理
duangsuse::Echo
#py #math 《优雅不是奢侈品》 “如何才能让编程者们相信,简单性和清晰性——简而言之:数学家所说的“优雅”——不是可有可无的奢侈品,而是决定成功与失败的关键因素?” ― Edsger W. Dijkstra,“计算机著作精选:个人观点”,第 347 页。 简单明了的代码就是优雅的代码。这些都是代码中非常理想的属性。Dijkstra 又补充道: “……在软件不可靠性的情况下,最大的成本因素是复杂。 一个可靠的(因此简单的)程序的开发和使用成本,比一个(复杂的因此)不可靠的程序要廉价。” 人们…
#kt #design 刚才审核绝句 句级跳转&主语域时,意识到 break continue 这些必须和 if 搭配使用 ☺️,以及
- 因为使用 (0~9):[i] break i==5 的语法函数化, break n 必须=return^n*2+1^ ,就像 this=you^0
- tailrec 是 at xxx=let: return^0^ any 里的(ret赋值&break) 的平替

fun IntRan.forEach(fn:(Int)->Unit) {
var i=first
do { fn(i);i+=1 } while(i<=last)
}

- Rn<Int>.`|`(:Fn1<Int>)
at now: i A
let:
fn(i)
loop(i+1): i!>B //i<=B

// AI的编程效率高于补齐,阅读速度上还在用 map-forEach, let-apply 这些的话是不够的
((0~9) : +1) == (1~10)
(1~10)|: [x]
say(x-1)

👀 过滤操作时 (0~9){>5}: say(this) 是绝句里单项和列表通用的搞法
"a arm bar ada".Sep.firsts{it[0]=='a': if !this{say("End")} } 则关于break,因此本应抛弃单层循环的break
我勉为其难地支持了,但写法必须比较丑

- Str find(sub:Str) Idx
at N=sub.Cnt
(0~Cnt-N):[i] //N=1,则 i=0~iLast
(0~~N):[iS]
breaks^1^ this[i+iS]!=sub[iS] //也可以每次iS=i 然后blabla.. OIer 日常的面条代码?
return i
return -1

- 文 找(:文) 针
在N=文的计
(0~计-N),[i]
首否(文、位=i) 去路,回i。
回-1


- 字串.找位置(sub:字串): 数 “降质版: 易😋语言”
变量 N=sub.长度 ‘’它可变吗
(0~长度-N)去对所有:[i]
(0~<N)去对所有:[j]
跳过^1^ 我[i+j]!=sub[j] ‘’它真的ijkPlayer,我哭死

“如果 本对象[i+j]!=sub[j] { 到循环尾^1^ }”
回i
回-1

易语言化还不够给力,这个翻译得一点也不爆笑 (虽然但是,吴涛对Winform和计绘是比大部分人都资深 😁

- if else 是函数,里面不能写 break ,只有 loop: when: 是真正的流控
但语法函数化的好处多多, 通过提高语言一致性,能方便AST匹配和宏、节点图形化编程 ,允许顺语序的去路() 等块函数

虽然,代价是丑陋的写法显得丑陋 ;但语言变漂亮就够了 🥰
duangsuse::Echo
#blog #meme 看到易语言还在VB++ 的范式旁徘徊 😅,并且觉得编程语言 是种必须特色和备案的「核心技术」… 我想复刻下这2007年文章的口吻: “绝句.ju”十分钟入门教程 作者:转载必须注明出处 亲爱的朋友,您愿意花十分钟的时间,来了解一门全新的编程语言“绝句.未公开”吗?(搞笑向 btw. 很难想象标准库与ES7接轨,拥有函续、不/可变数据集、流/叠加、双主语的绝句,还能用“合规”的记法支持VB7时代的“正统中文编程”👀 - 起点 将123写到屏幕 100.123:[x] …
#java 看到一篇维基挺有趣

'T'物 泛型类
造于 此刻,
值 可变<T>
- 读=值
- 写(:T)
值=它

- 方法1
泛型类<数>,
写(5);说(我去读)
- 方法1
泛型类<N>,
写(5.5);读() (说)

绝句不使用“元类”。 T同名例、T 的变量域是隔开的(T上没有“静态”),类型保存在TYPE里

物 值() .地址 “函数,管道 等对象不能是key”
- 特征码 数
-
=(:值?) $YN

类 地址
- 文 文
同名例 TYPE
在 词: 名动词表
在 物名="值"到"ju.Any"

也支持trait (代理基类,扩充接口)
'T'(T 两序) 物 盒(:T)
'T'物- 盒 作 两序
-| 较(:盒)=它 去较(盒的它)


如果 #kt 支持的话应该是
data class Box<T:Comparable<T>> (val it:T)
fun<T> Box<T>.as() = object: Comparable<Box<T>> {
override fun compareTo(box:Self)= it.compareTo(box.it)
}

对我而言,编译器是“做语言”的手段, 可是一些人觉得,编译是“语言”存在的目的... 他们设计语言和框架,是为了让自己新学新想的奇技淫巧跑起来, 因为那些破事如果不能“攀附上”某些实际问题,就会暴露其设计性的廉价(

相当务实!他们大概和最新款的 Cortex-A9 SoC 很聊得来吧。走GPT的路,让计科无路可走… 😄
duangsuse::Echo
#zhihu #PLT 又看到有趣的中文编程设计 ,做些科普。 👀 1.打这些太极 还不如就叫真假,另外,加语法糖并不是以混淆基本语法,以编程的一致性为代价. PHP,Ruby,Py2 和VB已经玩烂过这套“大小混写”了(你怎么不用神奇GPT编译呢?) 2.子类型对应的是强制兼容,而非隐式数值转换。 进制只是表示法,SQL那种类型只是验证位数 你说的不需要看(隐式新建类型变量)、运行时可见,Haskell、Kotlin也支持,但你对连 List<T>,T->R 都还没懂的人弱化类型,就利于他们学用新接口了?别把隐类型当成无类型…
#statement #kt 反思: 数据绑定DSL val xx by int() default 100
> int()返回一个可读(写)变量 ,同时接受"xx",也能实现 lazy{}懒加载

obj HTTP {
val maxReq by int(or=100)
}
怎么样

感觉好鸡肋:这其实就是一种JSON按类型绑定啊…… 只是序列化器没支持而已

有时感觉弱类型真的挺自由的,除了大部分 str,int 就不会写什么多余的声明
你说既要验证 data classes ,反射库又那么鸡肋,还没有官方的模板代码生成器…… 2017到现在连个能比 argparse 的CLI环境绑定都没有

稍微把反射库用好一点,就不会要写这些定义DSL
(但是又不要靠 @VarName("wtf") .. 总之就没绝对优美的封装办法

duangsuse, [2023/9/5 16:49]
稍微想了下,把类型和定义当成元数据,是可以避免 @Default("wtf")
js
HI(class xxApi {
'/index'(){}
'/user/$'([id], {nameMatch}, resp) {}
})

kt
data EnvVars(maxReq=100): Mapper
Map.load<EnvVars>(environ)

这样可以避免注解,其实就是靠查参数表;所以JVM反射和编译期生成可以取代绑定DSL

duangsuse, [2023/9/5 16:55]
强类型真的挺鸡肋, 手写签名只是为避免强转开销? 框架却不能规范和利用这些定义信息?
真的道阻且长啊

听说 #Rust impl<T> List<T> 就是把类型参数当kwarg造成的

我了解了下:关联类型不是只在传参上像kwarg,也不是为方便override,而是做了类似 FnOnce 的保证

1. type R : struct = 1:1,一个 struct 拥有关联 Trait 的唯一 impl
2. R变量不能被struct或fn新建

因此 fn distance<N, E, G: Graph<N, E>> 里G的约束就不必写了,而是替换为 G::N,G::E

还是很鸡肋啊.. 为了三行碎代码😐,为了一个保证而新建语法,破坏语言一致性
即便把泛型改成按名传参 -'NE' Graph.distance(:N,:N) 都比新增语法要一致
是Self类型的一种扩充,因为 -'N'(N Sort) max(:N,:N) N 无需解出N以外的变量

duangsuse, [2023/9/5 17:13]
是不是懒得升级编程语言的社区生态, 都开始急着加无工程意义的特性了

这种能靠推导出事情交给GPT不就好了…… (编译期性能就拉倒吧) 为框架和社区干点正事,多研发点教程文档不好吗
编译这种事情没啥价值啊, 如果数据类型、class这些定义结构,只方便编译,而对框架是负担,那对开发者和用户也是种反模式吧

我是希望Kotlin能像Python那样发展的,但看来py也有不方便大项目的地方

py最近加的match都不是在types上的扩充,我想kt可能是语法太丰富, 但是这个API绝对不够用啊
duangsuse::Echo
这是一个完整的Java式类型系统,支持泛型。 class List<T>{} 的语法对应Fun(T,ID())的数据。 Unit,Fn可视为不属于Any -'TR' Ln<T>.as(:Fn1<T R>)=Ln<R>(0) 也就是对 Arg((Fn),TR) (赋参数),深度遍历到 Ln.To,T.to(Int).. 就知道T具体是啥(还要支持map{map{}}..) 在T未知时结果是 List<R> ,但要生成代码时R一定被固定在Arg。这类把Var作为值的算法叫“合一 unification”。这是关系式(而非“顺序”)的,…
#FP #math 的一些 #statement
#tool html bookmarklet data:text/html;utf8,<body ContentEditable>

—10÷3=3…1
被大佬建议写成 =(3)3+1 即m=qn+r (r<q)形式的“短除法” ,理由是...没交换律
“理论家布尔巴基有个笑话: 1+2当然是2加1,因为整数对加法构成阿贝尔群”

当然,纠结这些除和除以工程意义不大
ax+i=b; x,i=divmod(b,a) 的可变量元组数学里可是没有。函数只是“关系”,没有sympy那种条理分明的元编程化简法,py那种无论匹配或访问都易懂的“类型化数据”

a%b 余数在进制计数法,KB MB单位,乃至红绿灯🚥 ,猜拳、[123]*3重复 里都可以用到,四则符号的推而广之是很方便的
但GL的vecM和距离函数, 对偶的cos atan2才算是真正的「函数图像」

对软件来说,值之间的关系、算式的归类、代换(元编程) ,都是值得思考的,这远比重复流行的技术栈重要。 形式化的语法,正是物理和编程比数学广泛的一点

— 纯函数的不可变吧…… 不是类型上'final' (btw. KT-override class 理论讨论)
意义真的不大, 无非是把堆里的变量放栈上来重赋值,或者栈变量换伪递归,拿能够DFS的写法却只做列表处理, 有什么用…… 又麻烦又慢 😓

变量关系式编程(LP)里, 函数式的 Memo f()=x+1 可以直接表达为 f(out y,x) 的细粒度重计算,解构时也一样! 不仅不存在“赋值”,也不需要那些纯函数的过度检查

一些人觉得 React是什么FRP,functional响应式 。但其实把可变数据,理解为含Var的不可变, 比纠结于List纯不纯好玩的多

类型姑且还是对心智模型的硬化, 纯度这些可都是虚无缥缈的风格格调了。有趣的软件未必靠FP来写。某些函数式lib的样板代码不比rs,go的少 ,代码质量只能是看人,是否憎恨冗余

—我想用 for()await varAssign; 替换组合力很低的 for await(x of {async*f(){ }}.f()){} 异步迭代器,也方便RPC/跨语言 的对接 #PLT
异步流每次next()只是Promise,但换成两个async()赋值--单监听, 用 var.Saw.to(x=>新值流)+AbortSignal 更一致

async()=> 的实现要调用 yields={*f(){ res=yield }}.f(), s.next(1) 里f的yield会把值和'自动回调'赋值到s.next,交给调用方调度。throw也可以直接next回调链表(CoroScope)里有catch的那层。
Iterator显然只是调度的一种特例,是把i++等流控 继闭包地从栈分享到堆。不能牵强地把等待恢复、迭代混为一谈

在ES5里,可以用一个 co(asy()) 来遍历 task.then(next) 并搭配 yield* tasks(下级)#Kt 协程则是直接把回调交给timer()等待,无遍历:

#js #code
wait=(n,ret)=>setTimeout(ret, n*1000)
we={*f(co, ret){
setTimeout(co.nt, 1000); yield //函续已经交出去了,现在该返回 就像f只是登次记
wait(1,co.nt); yield
alert('2s'); ret()
}}

_await=(f ,c={},s=f(c,()=>Job完成))=>(c.nt=x=>s.next(x), s.next())
_await(we.f)

把f变成大switch并不难,但Lua,Rb,Py依然在用运行期魔法实现yield:

we.f=(co)=>(co.nt=()=>{[ //先把f(yield)外提为x=
()=>setTimeout(co.nt, 1000),
()=>wait(1,co.nt),
()=>alert('2s')][co.i++]()
if(co.i==3)co.ret('like,co=Promise')
})()
we.f({ret(){'此谓调用约定,ABI'}, i:0/*func*则会等待1次next*/})

把co暴露给调用方更像JSPy (缺点是要由main调度then(next)),而把co暴露给下级 更Kt,Lisp (虽然更像回调, 但太隐式, 比如yield(x)需向Iter对象赋值 脚本没这作用域)
到了OS这级,键鼠事件,异步只是赋值+触发回调

—翻译一下, suspend fun f() =f1()+1

首先f()要是一个闭包(即 匿名class .new ),kt,Java ()->会自动实现这一步
然后,f1接受第二个this: (Int)->Unit 实现其return 。这就是JS的Promise.then 。你说的local vars 就是指 Promise or Continuation函续 or Async状态机(大switch) or Future..

f的执行也不能卡线程栈了,它也要靠回调,比如runBlocking等待其他Thread的信号量,或者在IO,Main等 Queue(函序) 调度

这么说,call queue 和单CPU多线程本质上都是分时复用,只是设备中断/SIGTRAP 被改为更高层的函数回调,CPU cycle 换成主循环(监听轮询poll)。 因此王垠觉得Lisp比C更适合写OS

Go,JVM,Ruby,Lua 的 stackful 模式允许不标明await 且仍支持返回值,而基于CPS回调的协程则兼容性好
不能把await 调用理解为有返回值的多进程,相反,函数自身是消息队列内的Task(即线程,可sleep),才能去"非阻塞"await

语句就是种顺序表达式, val x=1; f(x,x) 本该也能写成 f(x:=1,x) ,往往只是外提为val,所以await()就像 f(a?.let{return} ?: b) 是可以的

还有coroutineScope, sequence, select 等复杂的结构化信息。 这样能实现大goto(call/cc) 的功能,比如直接resume给某个 caller 的 catch(IO Monad) ,或者 yield 到 gen .next() ,DFS防止栈溢出等

yield的一种用途就是遍历Rx流,但它们生成的流却非异步(尽管它能"push"无穷项)。 另外我觉得RxObserver=next 比async yield 更合理

—「值和引用」别扯到C上
栈就是“非常容易做GC”的堆, 只因为在堆上就叫ref不算值 是不太定义式的,这暗示了 N2(x,y) 这样的数据“不该可变”-即便它说了xy都是变数
别把JVM当成C++的框架。调用栈是内存的一部分,函数值和对象都是“栈转堆”,return在内联后只是赋值;goto,参数并不配特立独行

copy和ref 的区别,只应在于后者是Var(mutable v:T)。 含var的struct也能纯复制,List也可以存栈上(调用在栈顶时,可以追加 int a[num])
只是对集合/事件/闭包等应用层共享,就必须有GC,Rc 来修剪对象图

绝大部分val=struct 的实现依然是堆内共享,与内联函数相当。只有int这样机器mov的值不用传指针

—编译和优化
>AI没答到点上。 我觉得synchronized和Mutex有什么区别, 就是取消 object.wait()才隔离出的

>竟然是让 withIndex() 驱动 get(it).. kotlin-stdlib 里的一些实现是自己在 for each 外 var i = 0 计数的……
智障,就像标准库不写 val x get() 写 fun getX
自己破坏自己提供的特性

>list set stdlib 里的这些集合库的indices属性都有优化
我说的是一般的 for (a in list) 优惠成 indexed for loop 去掉迭代器这种

都能让你手动改写法优化了, 要编译器和有两种IR的虚拟机是干什么?

编译器已经是优化了,虚拟机还要JIT, 结果应用层还是不能满足……
是啊,我就是觉得这种现况很可笑。kotlinc 还特别自己弄了一个内部IR,不知道是用于翻译goto 和协程还是啥

编译优化全都是不可见的, 你也不能知道llvm,ktc 执行完优化是啥样子,非得反编译
当然,clang,llvm 是可以导出IR的,但许多优化用的表示IR层级太低,正常人看不懂

这种情况的解释,就是IR的语意不能用语法来保存了, 但其实 loop/重复算式的外提,并不会破坏程序结构,甚至DCE都是要由IDE重做一遍

玩编译器那帮人根本不懂如何做交互式编程、图形化框架。 这一点 dnSpy 一个反编译器都比90%的编译器做得好
更别说同时有TUI,Qt,Web 三种界面,支持无数种bin格式的 radare2 了