duangsuse::Echo
329 subscribers
3.79K photos
103 videos
573 files
4.9K 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://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 此次未挂起,自身也直接继续而不会返回调度
这么说:
runBlocking{
GlobalScope.async{delay}.await
async{delay}//reset timer
}

本来只期望await的暂停,结果全暂停了,因为 runBlocking 会等待所有内部suspend fun

其实就有3断续函数,作用域(基于Scope继承)在它内的 async{} 就等待,外的就得显式 await

https://zhuanlan.zhihu.com/p/156030219
Forwarded from duangsuse
sortBy{it.isMale} 就能做 partition 了(
确实 Kotlin 这有点hack,可能是为了内部优化

#Kotlin 有些小瑕疵,比如 listOf(break,return,throw Error()) is List<Nothing>
还有 run apply 是 let also 同类但命名完全不同,本来是 fun()=run{} 的,可官方自己也不用此写法
duangsuse::Echo
sortBy{it.isMale} 就能做 partition 了( 确实 Kotlin 这有点hack,可能是为了内部优化 #Kotlin 有些小瑕疵,比如 listOf(break,return,throw Error()) is List<Nothing> 还有 run apply 是 let also 同类但命名完全不同,本来是 fun()=run{} 的,可官方自己也不用此写法
问题: 呃,今天才知道 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
duangsuse::Echo
#js 同样是简洁优化,这些就很鸡肋了,尤其是这个eval DSL… 显得非常缝合,但为避免 new Path2D 不得不用 我曾说过「好的代码是横着写的」, 总结下吧,尽管我偶尔写带配置UI的应用,现在我的编程风格已经完全和“软件工程”者不同了 至于好坏…工程界的定义,蛇线驼峰 太基础,没有考虑语序和用途,我的写法会偏函数式点,命名上倾向 Kotlin ,不完全是民科 在我看来,工程界只重视代码的功能,没有顾忌代码的语义和「份量」,所以常常把简单功能写大几百行,以此为“成熟度”,或者觉得C++就必…
#statement 很多时候我不爱看自己的代码,但它之外只有量大后更难读的东西,一些问题想描述都是复杂的,何谈定义“解法”,我一直在努力简化

我就相信不管多难、多牛的人写的代码,都有更通俗的表达法——唉,大佬们总让我失望

如果连《算法》这种英美计科教科书都是不可相信的,我能信任谁呢,所以才说 #Kotlin 是好语言吧,至少它选择相信表达而非智商。 我遇到过天才,但天才尽管悟性好也曾有做得不好的时候;如果说最后他们写出来的东西还是10行能讲明白,如果他们的实践也只是6,7种方法中的一种,而每种方法各都有优劣 ,如果说完成的应用也有无数扩展的可能,我又该崇拜谁呢。

如果天才的语言也不天才,我为什么要全部照搬呢?

几乎每次我研究一个感兴趣的技术,都迭代出3,4个版本,碎碎念全放在旧版、精彩代码粘贴到新版,仿佛细胞分裂时损失聚在一边 。从正常人的视角「重复」肯定是丢脸的事,或者是项大工程,意味着你不懂或不聪明,但谁是生而知之的呢?人的能力是有限的,所以才需要方法和工具完成更多,而有时却被工具所蒙蔽,看不到更「大」的工具。

我为什么要崇拜技术呢?因为「崇拜」它能更好解决我的需求?崇拜天才能让我聪明?
我谁也不崇拜,也谁都不鄙视,只是继续看自己爱的技术; 当我描述,零碎的计算机语言概念和人话并存,而在语言中,名字是最次要的,语义最重。最后我选择了名字即语义,是自9次重写一个框架后我做第二件最正确的事,也是我找不到同道的开始。 自底向上从缘由解读名词,自顶向下靠细分写出程序,而 OOP 或 FP 都只是这种方法论的工具;那些名词,只是它们用途的片面

我相信代码有「份量」,在API在模型之上,「恰如其分」的代码和精妙的文档是绝配,因为短行数!=低功能users.map{it.age}.sum() 后缀操作链隐含了SQL和数学的前缀表示法,不同语序适合不同场合和需求,但我始终追求描述间本质上的相同、追求代码与可见应用的相同,从而简化代码-即便很少人能做的干净。
——只有你不把技巧当特殊技巧,之上才构筑出更有趣的东西;如果你觉得自己或它够牛了,你就止到这了。 就像生物里配平的化学式,已经死了。
天才是不当自己或别人天才的,自满或自卑,与他们的领域和关注点无关。
我追求既普适又不空泛的代码。 既抽象,又易看出用途;顺序位置很重要、符号统一很重要。
人赋予一些事以语序、明确表达里的上下文指代,才能忽略无关本质的多余符号。

强大和技术都是身外之物,人—才是重要的
所以我不想自称程序员了,普通人,编程爱好者有多好
https://t.me/kotlin_cn/25220 #kotlin #go 面向job/task计算称 #concurrent ,和完全平行(如滤镜图片)不同
bench=repeat(10_000);o=Any()
c=Channel<Any>()
runBlocking {withContext(Default){
launch{bench{ c.send(o) }}
launch{bench{ c.receive() }}
}}
//c.close(); launch.join()

Channel 和调度器 Dispatcher ,在浏览器有 worker.postMessage 和 onmessage

var wg sync.WaitGroup;wg.Add(2)
var token struct{}
c:=make(chan struct{})
go func(){
defer wg.Done()
bench{c<-token}
}
go func(){
defer wg.Done()
bench{<-c}
}
wg.Wait()
defer WaitGroup 在凑齐2项时传输(循环看错位)?其实是用计数看是否有job存活,都Done掉退出时再继续主线程

runBlocking{//limitedParallelism,newFixedThreadPool,single..
val produce=produce(Default){
bench{launch{send(1)}}
}
var n=0
produce.consumeEach{n+=it}
}

也有把 Channel 异步序列变得友好的做法

线程切换 >> 函数调用(没有线程切换下的协程切换) > batch之后的函数调用

>分别对应于代码实现的Dispatchers.Default + 无buffer (如果你写对了的话), coroutineScope + 无buffer , coroutineScope + buffer
Exectors singleThread asCoroutineDispatcher
>wait是指blocking的wait么?没看到channel的代码,但是可以断言里面不可能线程停住等待
>不, 是指协程底层在无可调度时的wait;能看到一半是无锁链表,一半是LockSupport.park
之前和他的差这么多,估计是被调度到一个线程上去了,不知道Default里边的策略是什么样的
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 常见类型系统
从变量/参数的赋值兼容力(即子类成员量)升序: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)->RFun<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 TypeVarMap<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等相关,要怎样计算,所以能自由拆解拼合重序代码,不局限于既定形式。
#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->这些 “靡靡之音”了,不爱“努棒性”了吗?
#learn 对我而言,编程并不是「专业技术」,只是“另一种母语”和创作方式,所以我很讨厌潦草的代码

最近一直在打磨一门自制语言的语法, 获得一个较大的成功,居然是把它的OOP术语移植到英文.. 😅
事量物例类|公私族组内
fun val data named type|same{,0,type,pkg}
储例判同造|既可未终定
\- enum -when -named made|^,impl{?,??,}

之前的版本是
事量物例类 
fun val thing insta class|
储标例况变
data anote enum case var|!,impl{?,??,}

虽然不够“面向对象”(obj->data) 了,但实在(英语化)好写不少。 我一直很讨厌 Java 那种八股文式,歪七扭八不一致的语言特质,给数据处理和调试带来很大负担

interface Closable
type Closes
fun close
-named
fun all(:Args<Closes>)...

data Door(name:Str) Closes
made(:Idx)=made("# $i")
^fun close=say("shut $name")

data class Pair<out A, out B>(val A:A, val B:B): Serializable
'AB'(get) - Pair(A:A,B:B) Send
typealias PairOf<T>=Pair<T,T>
'T'PairOf=Pair<T T>

这个就对标 #haskell data=A|B#rust enum Either<A,B>
'AB'(get)-when Either
A(v:A); B(v:B)
'R'fun way(err:Fn1<A>, ok:Fn1<B>) = when this:
A:err(v);; B:ok(v)

就体现另一种 #FP 的价值观:定义式先于不可变

绝句计划把 Var,Type, expr.E 都拉入一等公民,虽然我不清楚怎么做但相信有意义(连scala3都没更灵活的 eval fun: inline arg 还不够全)
总之,OOP 的public-private constructor 麻烦真的很大,
我又不认为 Rust,Go 那样把一切打散和到处pub fn, 冗长化 type Item=int32 就算“优于继承” — py也有自己独占的一亩地, 但它足够 "server side" 吗?
对于视频内代码的重写:

事 阶乘(n:数) 数
变数,a 1。
(1~n),[i] a=「它*i」 。

fun Ary<Int> contains(it:Int) Bool
this:[x]
if x==it: return $Y
return $N

或者更函数式(reduce 和 findIndex)
'N'fun N`!`=(1~this).Sum{*}

'T'fun Seq any(:Test<T>) = this(Sum.from($N): or test(it) )
= first { test(it) }?.i !=NO

(不得不说,绝句的变动太快了.. forEach和尖括号类型都能被删没 (我对那个 对何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.. 信仰崩塌
#Kotlin #design 谈这我就想到,绝句的 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那样用 implicit 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 虽然又蠢又冗,但至少不会贩卖问题;它解决过的都没有什么复制粘贴和坑
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标准库就开始定下了……

幸好,现在的绝句能基于做/到函数 1:[x] x+1, (0~9)|: say(+ 1), kv:[k|v]字典 ,不加歪七扭八的术语🙉

但看起来 |: 这些就很晦涩啊? 不过,绝句是用这俩的重载,取代了所有 for if filter map await Closable.use ..

"89"==((0~9) {!< 8}: "$this").Str
(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}

“对单项的filter”
"ab"{!has "a"}? {this}or "bad"
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)

现在我轮转设计的四个项目, 都逐渐迁移到了与as/to 相关的体系🥰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呢,什么 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,需要尽可能简洁,因为复杂的功能和哲学,往往带来额外的编写时心智开销