duangsues.is_a? SaltedFish
60 subscribers
609 photos
6 videos
91 files
562 links
🌶🐔🐟 duangsuse 的日常
尤其喜欢发些奇奇怪怪的东西
和转载别人的东西
Download Telegram
duangsuse, [2023/10/14 17:16]
🤔 知乎上有两种观点, 有人说前端就是写个分页路由器,哪有竞争力
有人说 Flutter 连Web的吊车尾都够不到

CSS被人诟病不模块化,但它起码有1px这种数据模型和style复用,有成熟的快速原型工具。
拿Qt,各种View Object 比DOM树就像拿canvas去比SVG。虽然用canvas的大佬云集,但它背后的思想毫无设计体系与组合力。 一旦没了API隔离的护城河,很容易被新需求冲烂(就像各种H5 WebView 一样)

不过对于Compose来说,还算是对HTML的进步了,毕竟Linus说过,XML是极少数对机对人都烂的数据语言,JSX模板也是Web的一大憾点

duangsuse, [2023/10/14 16:44]
感觉 NoPosts() 是「搜索结果页」的通用模型吧,应该做成 open class, HomeUI 是它的特例。


总之,不用滥用多态,如果null能实现用 ?.run 也挺好
原来如此,说起来 java.io 版 DataView 的bitconcat读取就是硬编码的


所以我对Java界「工业级」数据模型或算法的直观度观感不高

btw. 前几年我也被带偏了。哪有什么 int long 啊,都是 byte 4,8 ,这些private fun也不好看

Omico l Dev, [2023/10/14 17:16]
[ Album ]
kotlinx datetime 想获得下面的格式难道只能这么写?

duangsuse, [2023/10/14 17:21]
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").run{
LocalDateTime.now().format(this)
}

duangsuse, [2023/10/14 17:25]
你这个需求太奇怪了

KMP没有的接口,如果不想变通
最好是分JVM,JS,libc 去实现,这样还可以封装出去赚star,而不是自己做一个

duangsuse, [2023/10/14 17:39]
说的也是,不就记个小log呗,replace能有多大开销

只要不涉及IO通通视为0开销

duangsuse, [2023/10/14 18:00]
固定位数的 ints load/dump 可以手动divmod:

>请实现固定位数的 fun IntArray.dump(StringBuilder out, vararg n:Int)
例如, [8, 12].dump(sb, 2,2) 显示为 "0812"
请对每项 i0+=n[nth] 用itoa算法实现 out[i0+i]=数位

fun IntArray.dump(out: StringBuilder, vararg n: Int) {
var i0 = 0
for (nth in n.indices) {
val i1 = i0 + n[nth]
for (i in i1 - 1 downTo i0) {
out[i] = '0' + this[nth] % 10
this[nth] /= 10
}
i0 = i1
}
}


def dump(self, out: str, *n: int):
i0 = 0
for nth in range(len(n)):
i1 = i0 + n[nth]
for i in range(i1 - 1, i0 - 1, -1):
out[i] = chr(ord('0') + self[nth] % 10)
self[nth] //= 10
i0 = i1

dump([8,12], a:=[0]*4, 2,2)


最近免费AI的智商变低很多

duangsuse, [2023/10/14 18:01]
还好吧,人总是有事干的, AI取代动手我们就做设计 做自老板嘛
不过看起来它越来越笨 了,变成搜索引擎了,我最近一个月都没太用过

在我的想象里,
>请实现固定位数的 fun IntArray.dump(StringBuilder out, vararg n:Int)
例如, [8, 12].dump(sb, 2,2) 显示为 "0812"

就足够清晰了,但AIGC后还需要除错……

duangsuse, [2023/10/14 18:16]
记起来了,这个 for(nth 应该是一个宏,只提供赋值

typealias Add<T>=(T)->Unit
fun IntArray.tuples(to: Str
ingBuilder, vararg n: Int, f:(Int, Add<Int>)->Unit) = {
var i0=0; var i=0
n.withIndex().forEach { (n,nth)-> i=i0; f(this[nth]){ to[i--]=it }; i=0;i0+=n }
}

fun Int.Str(to: Add<T>)


(好像又更复杂了…… 我是想暴露subarray
总之这种buffer 复用是一类优化,有模板
Silence Acappella, [2023/10/14 19:08]
主流的前端框架里

Silence Acappella, [2023/10/14 19:09]
有什么是擅长交互和3d渲染的

duangsuse, [2023/10/14 19:10]
https://spline.design/
https://aframe.io/

duangsuse, [2023/10/14 19:12]
https://github.com/jagenjo/webglstudio.js
https://github.com/tentone/nunuStudio #game
https://github.com/aframevr/aframe-boilerplate

duangsuse, [2023/10/14 19:16]
看起来开源软件还是不行啊, WebGL,three,d3js 不能直接用,流行实现都是闭源的

p5是2D的,DSP比较强的Web也还是比较拉垮

https://animejs.com/
https://photo-sphere-viewer.js.org/
https://splidejs.com/ 那种GL过度特效都能收钱

duangsuse, [2023/10/14 19:23]
印象里Web的3D交互也还比Qt,DX 好一点,可惜框架太少了

除了gamedev, 3D仿佛是上个世纪的技术了

duangsuse, [2023/10/14 19:25]
我觉得最逆天的是, 3b1b manim 这样的开源弹性动画+Py式PPT
都能拔得头筹

前端和脚本界真的是天上地下,牛的牛死
M$的工程师果然牛逼, 凭着C++那种烂语法都能写出各种带3D的WinForm

不过之前看GPT好像会写弹球和植物大战僵尸的,可能就是爱看高级工程师的代码
duangsuse, [2023/10/14 19:33]
感觉还是牛逼的人都去M$, Google 了,做开源的太少
M$的开源率好像比GOOG,FB的低

KODI,OpenWRT,ffmpeg, Blender,Godot 这些都算开源界顶级,勉强能和业界接轨(?
Matlab,CAD,AfterFX,Office 那种就难了(开源界连个 Web Office 都整不出
毕竟愿意无偿写代码的大佬少

duangsuse, [2023/10/14 19:58]
写动态域可以先看我的(不含数据结构
JS 里可以直接用原型链做「嵌套KV」
[{a:1}, {b:2},kv={b:3}].reduce((A,B)=>(B.__proto__=A,B))
实现了 with(kv){
push({b:3})
b==3
pop()
b==2
}

看来你还是不愿意用JDK Nashron 或 Luajava,Rhino

手写这种/命令的话 ,最好不要做局部表
另外
Scope<*> 是无法add的
type 是干什么?隐式this吗? 那应该保存 Any

duangsuse, [2023/10/14 20:04]
你这个卡牌游戏也有点逆天…… 我拿CLI举例下

首先需要抽象的,是用于执行回合的牌桌

比如,创建每个有手牌、有pt和flag的Player ,消耗手牌也做在上面
手牌的效果,由牌桌来提供选择器、分发

发牌可能要用的概率分布等算法,定义为util fun

你把太多精力花在不必要的序列化和动态加载、「弱类型化」上面,还不如先想想特效和回合流程怎么平衡

如果你不止想做个toy ,这种游戏应该需要大量事件/await,和WebSocket那样的文本流、跨端调用

duangsuse, [2023/10/14 20:15]
所以之前就说了,可以做成组合函数,搞成嵌套数组,不就能序列化了?
a<b? log(1) : c

when(get(op('<'), 'a','b'), call('console.log',1), get('c') )

call=(k,a)=>(局部作用域)=>eval(k)(...a)
get=(...keys,fn)=>fn(keys.map(eval))

op=k=>(a,b)=>eval(a+k+b)
when=(is,a,b)=>is()? a():b()

duangsuse, [2023/10/14 20:17]
(原来ES6 在前端里真的这么不受待见

原来 React 的 tbody.map(tr=>) 真是种装酷的写法,我还以为他们迫不得已呢……

duangsuse, [2023/10/14 20:22]
既然你想做这个游戏,你能把基础玩法和灵感,先写个文档吗?
你的卡牌要有数据库, 那典型的几种选择器和效果,是什么?

这些和代码无关的,反而最值得你优化。 一些复杂性很可能只是你的需求自相矛盾

duangsuse, [2023/10/14 20:24]
感觉get不到嵌套次序
[[ary]] 应该是很少几项吧

这种写法确实很bash式参数

duangsuse, [2023/10/14 20:25]
看错了, [[ary]] 是一个语法糖
TOML 嵌套和JSON差不多

duangsuse, [2023/10/14 20:29]
看了一下, TomlNode.toStr 有700行
是你朋友写的吗? ps. 头像很福睿

duangsuse, [2023/10/14 20:31]
那你很厉害,Decoder,Encoder 的实现还挺直接
#blog #tr 《PL 表示法有碍于入门》

#PLT 俱乐部的人 Y 组合器身上纹,却被会员评价:字体不好看

符号可以使思维清晰。使用正确的符号,一开始就能轻松地完成工作,让不重要的部分消失
Mike Hicks 认为,像 8÷2(2+2) 这样简单的算术表达式也难倒各种人,妨害 PL 研究的影响力
最好的符号是简洁的;它们在视觉上具有暗示或继承性,

有人抱怨使用函数化命名而不是数学符号看起来不那么 PL
但——这就是简化记法的一个理由!我们作品的美学很重要,但PL已经以深奥的符号而闻名。
大部分论文能将一两个符号改为文字而进步

作者建议:
-增加清晰度/减少混乱将扩大我们工作的范围并减少协作障碍
-标准化设计清晰的单字符体系
-无论类型理论、语言还是 API——都要做复杂性预算, 作为警示
-总是用简单、易发音和众所周知的符号代替,顺序更要自然

比如说,小步语义的 ⟶(暗示“从左到右”),
子类型的 <: ( : 让人清楚构造器的类型,但对于 Java 程序员来说读不懂)

SKI,Y 函数里,I至少表明了恒等(Identity),但Y()做不到
建议换为rec/递归, fix/不变点

Guy Steele 整理了 POPL 中使用的 28 种不同的等效写法,e[v/x] 的e=v是最常见的

渐有类型和契约的文献,类型转换有3种难看写法,都被内嵌于BNF:
<S=>T>e; <T<=S> e; e : S=>T

C 表示法,(T)e 在泛型里不好用,但这些都是技术细节,问题是没有人认真提出将这些强制转换作为编程语言的一部分
cast(e,S,T) 就更加明确

--评论区后续

><t=>U> <s=>T> e ~= <s=>U> e 比嵌套
cast(cast(e,S,T),T,U) ~= cast(e,S,U) 好看
而且AST上的信息比调用树多不少,难写明

A.中缀运算符很难0基础解析
B.嵌套不易写
目标.写法相同的算式,更能读懂语意联系

e :: S => T 相对简明,但箭头不支持组合
但其实,这种转换根本不存在。作者在POPL2010使用过<>符号,但他想换了

btw. 是在说推导出 e:Int=>Long 应生成 Long(e)
符号形式应是 (e:T):T0 = e:T0, T0=U , (s:T) 应自动理解为t=>U 里的变量t。另外这里(A~=B)不是指“A可赋B” 所以删了

合约是指 {x:Int|x>0} 这样“给字面量类型”
duangsues.is_a? SaltedFish
#blog #tr 《PL 表示法有碍于入门》 #PLT 俱乐部的人 Y 组合器身上纹,却被会员评价:字体不好看 符号可以使思维清晰。使用正确的符号,一开始就能轻松地完成工作,让不重要的部分消失 Mike Hicks 认为,像 8÷2(2+2) 这样简单的算术表达式也难倒各种人,妨害 PL 研究的影响力 最好的符号是简洁的;它们在视觉上具有暗示或继承性, 有人抱怨使用函数化命名而不是数学符号看起来不那么 PL 但——这就是简化记法的一个理由!我们作品的美学很重要,但PL已经以深奥的符号而闻名。 大部…
It’s Time for a New Old Language/2017
Guy L. Steele (Scheme,Emacs 作者)
对比下引文中「通用语言」与绝句术语

• Built-in datatypes: boolean, integer, real, complex, sets, lists, arrays
Str Int4,N YN N2 [Ln,Set,Ary T]
String Int,Long,Float/Double Boolean Vec2 List,Set,Array<T>

• User-declared datatypes: record / abstract data type / symbolic expression
data T(); type 样板为T0; S=[May Str [Ln S]]
绝句实现如 [Ln [Pair Enum Any]] 序列化的“元类扩展”也是一种S-表达式 执行

• Code: Inference rules (Gentzen notation)
相继式演算,和 unify(|,=流过滤) 都能证明逻辑算式
其推导步骤都是一个序列,有一个前提集合和一个结论,就像泛型 'T'(T Sorts) List sort 里的变数T的上界

• Conditionals: rule dispatch via nondeterministic pattern-matching
when, (A==0):return, '(文字匹配)?'/"输入"

• Repetition: overlines and/or ellipsis notations, and sometimes iterators
argv:[[1 rest,.]], Nd([x y z]), Seq.goesR和协程

• Primitive expressions: logic and mathematics
名/记平权: x==100 or (3<x, x!>100, not x==2), x in 4~100
x==100 || 3<x && x<=100 && x!=2

• Capture-free substitution within a symbolic expression (Church)
(λx. x y) z 可以免费把y换成w,w的值不会受到xy的影响,即f.bind(arg)

根据「类函变参皆数」原则,y=[Var Str], (Fn1:[y]Fn1:[x] x+y)(w) 能实现值上的代换

Expr BNF:
id \x:T. x
(id 1)
add \x:N.\y:N. +1(+ x y)


E=P(['',//分支. P7 都看不懂,符号复用率过低 歧义也太大
[x, 'Var k'],
[入,x,sig(T),P, 'Fn ,k,T,e'],
[':', T,sig(Tk),P, 'TYPE ,T,T0,e']
[P,P, 'Fx f e'],
])
T=P(['',
[x, 'TVar k'],
[入,P,P, 'FnT ,A B'],
['变',x,sig(Tk),P, 'TFn ,k,T0,T']
[P,P, 'TFx P T'],
//type作为值就省了,因为类型变数间有=,|关系,不应该求值
])
sig=x=>[':',x,'.', (a,x,b)=>x]
//*->* 比如 List<_>
Tk=P(['', '*',[入,P,P, 'Kind ,A B'] ])
入='\\'
说到BNF,以上PRR还支持
x? [1,x] x* [0,x]
x, [0,x,',',{a.push(x)}]
(x) [2,"()",x]
相比COBOL这些老语言的元编程文档, 算是去英文化了,就像 json.org 的图

我看不懂 Γ-> 和两段式,M: τ ×sigma 这些语法从没定义过
而且这符号冗余率也太高了

说句心里话:
这都是什么烂代码啊?行走的同义词典? 不愧是Emacs那难用编程语言的作者
duangsues.is_a? SaltedFish
duangsuse, [2023/10/14 17:16] 🤔 知乎上有两种观点, 有人说前端就是写个分页路由器,哪有竞争力 有人说 Flutter 连Web的吊车尾都够不到 CSS被人诟病不模块化,但它起码有1px这种数据模型和style复用,有成熟的快速原型工具。 拿Qt,各种View Object 比DOM树就像拿canvas去比SVG。虽然用canvas的大佬云集,但它背后的思想毫无设计体系与组合力。 一旦没了API隔离的护城河,很容易被新需求冲烂(就像各种H5 WebView 一样) 不过对…
duangsuse, [2023/10/14 20:22]
既然你想做这个游戏,你能把基础玩法和灵感,先写个文档吗?
你的卡牌要有数据库, 那典型的几种选择器和效果,是什么?

这些和代码无关的,反而最值得你优化。 一些复杂性很可能只是你的需求自相矛盾

duangsuse, [2023/10/14 20:24]
感觉get不到嵌套次序
[[ary]] 应该是很少几项吧

这种写法确实很bash式参数

duangsuse, [2023/10/14 20:25]
看错了, [[ary]] 是一个语法糖
TOML 嵌套和JSON差不多

duangsuse, [2023/10/14 20:29]
看了一下, TomlNode.toStr 有700行
是你朋友写的吗? ps. 头像很福睿

duangsuse, [2023/10/15 10:54]
https://kotlin.libhunt.com/koda-time-alternatives
val start = now + 5.minutes()
val end = now + 15.minutes()


看了一下。 我觉得Date的设计就不合理啊…… 它就是一个int2tuple 转换
直接把 plus,minus 推广到Date上,写这些 timespan 库干什么,很像 range/slice 这些同义词 😅

fun lift(op:(N,N)->N): Date.(Date)->Date = { Date.from(op(this,it)) }
plus=lift(Int::plus)

(虽说,工业界都拿 math.sumprod 当np.dot用,不知道向量怎么用 😐

duangsuse, [2023/10/15 10:55]
你直接去py群问
kt能干什么ML? 连API桥接都没人做

甚至JS都有标准的 AudioBuffer, SpeechRecog,TTS 接口
kt都没重封装JVM的工具库
stdlib https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.dom.mediacapture/ 的文档还是空页面

kt,C++这些在数理应用上都是废物,一直在阻碍AI的发展
用它们无论写理论还是app都废话多功能少

duangsuse, [2023/10/15 11:07]
看到一个有趣的:tau=2pi 被认为才是真的PI 🤔

哈哈,又是古老的重构…… 如果用 Vec.xy 取代sin,cos 应该就没这个弧度问题了

duangsuse, [2023/10/15 11:09]
以前我 let DEG=2pi=360deg ,方便给vec2设置旋转
没想到这也能叫改进…… 只有PI受伤的世界呢

duangsuse, [2023/10/15 11:12]
主要是又区分 date/time 又新建 timespan 也太离谱了

明明就是,你给long一个单位,进制换算, 结果无数个新数据类型和lib……

isekiのChannel, [2023/10/15 11:12]
你看看Go的 time.Time 和 time.Duration

isekiのChannel, [2023/10/15 11:12]
但使用起来无比丑陋,而且容易出bug

isekiのChannel, [2023/10/15 11:13]
time就是time,不是int

duangsuse, [2023/10/15 11:13]
Time= 自0时(Epoch) 开始的Duration

我就是说time是long的 inline class 嘛
明明一个重用率<5% 的type,却设计得如此膨胀

duangsuse, [2023/10/15 11:14]
是啊,所以只需要用 1.min, 1.hour 来 check就能加减了
Julia Unitful.jl就是这样

duangsuse, [2023/10/15 11:16]
这些所谓的细节(time.h , libc,.),都是需要支持+-*/ 的

如果是精度就应该用bigint 。这些开销是无法回避的
可惜比较算式化的 python 也没认真设计这些

duangsuse, [2023/10/15 11:17]
我说的不是long vs int ,我是说Date=有单位的 integer

duangsuse, [2023/10/15 11:18]
时区和显示也就是个加减问题了,但Date的本质是整数

所以,其实就是工程界普遍,无法把一个问题解偶, 导致随着App的增加,类型越来越复杂

duangsuse, [2023/10/15 11:19]
你要区分「显示形式」和实质……
物理时间,无论世界的哪个地方都是一样的,只是书写形式不同

就像编程语言,只能用范式,而不是语法糖和API来区分
那些都是跨语言的

duangsuse, [2023/10/15 11:20]
所以说,timespan 这些工具类,应该被理解为 Instant 这样的“数值类型”呗
而Date ,其实只是 from/to 构造器

duangsuse, [2023/10/15 11:22]
IO、UI的问题要分着谈啊,
为什么后端总是搞不懂,用户只会在操作系统里调时区这些设置……

就好像一些 data table 的程序,它们不会把数据给Table组件排序
而都是硬编码

如果这些处理,是分应用、框架、OS层次的, 许多技术和API就会消失

duangsuse, [2023/10/15 11:24]
我只是依照「<5% 复用率的types,都需要更多权衡」这些设计原则

duangsuse, [2023/10/15 11:26]
在JS里,Date基本只是toStr的职责,但Java可能对它做加减和距离比较

但这个类型,其实就是专门方便UI做的, 它本该更广泛, 比如读取 “10万8千” 这样的单位,加权求和

duangsuse, [2023/10/15 11:32]
这其实还是UI的问题,只能提供元祖上的加减法,由被调侧决定有多长
因为>=1month 的加减在数学上是没意义的,自然不可能涉及timespan

duangsuse, [2023/10/15 11:36]
不需要第二个类型,一个支持按tuple加减和读写的 IntVar+DateFmt+Locale 应该就是各种Date了

在用法上都是支持的

duangsuse, [2023/10/15 11:37]
比方说,你显示+1day 的日期, Date().add(days=1).Str 肯定比创建两个span,或setDays 要好看啊

duangsuse, [2023/10/15 11:39]
timespan, 按libc 的概念应该要加法有两个“Date”

duangsuse, [2023/10/15 11:40]
算了,不说这个了,反正Linux的时间API不会改,也没有千年虫问题了

Semver Cmp? Ver Semver? (|| Semver)? --N项树,不是+-*/
Cmp /\^~=|([<>]=?)/
Ver v di(. di)?(. di)?(- Str)?
di /\d+|\*/

semver 判断区间的方法,应该是把 1.20.3 转为 1203 吧,这样大版本不同也不能兼容
最好是每个点固定1_0000等位数,这样也避免判断麻烦

pkg manager问题有那么严重吗,都要上二分bisect了…… lock文件可以缓存吧
>=12 <14 || >10 應挑選 10 这一条我觉得有点奇怪,虽然语法是对的,但这就是个区间过滤器,其实不能当成算式联立去编写。
^12 应该也是>12 的意思吧

其实现在有种观点是,apt那样各种版本限定符太严苛了,npm重得太可怕
pip; pacman; npx 那种全局单版本依赖更流行
duangsuse, [2023/10/16 13:21]
感觉取消不应该抛异常啊…… 比如fetch() 下载文件,主动取消,有什么该处理的呢

duangsuse, [2023/10/16 13:23]
比如上面那个delay的例子,取消就是 Dispatcher 去run() 时啥都不干了,就叫取消了

就像进程的exit() 一样

duangsuse, [2023/10/16 17:53]
翻译:
骰子是一个 OldVal<AddAttr<Int>>(v, used=false) { fun invoke() }

结果是 N个骰子.groupBy点数.eachCount

duangsuse, [2023/10/16 17:55]
建议你搜索 Trie
其标准实现是正则匹配
或者 dir.list()

duangsuse, [2023/10/16 17:58]
你看,只支持 trie[a][b] 的嵌套情况,反而比递归的复杂些

duangsuse, [2023/10/16 18:11]
其实就是 Map<X, Map<Y, Z>>.get(X)= get().values
这个重载…… 第二个Y当然可重复啊

不知道是怎么说得那么复杂的, 好像比trie简单。

duangsuse, [2023/10/16 18:12]
Mongo不是 java.util的外置化吗
为啥比SQL厉害

在我看来,直接绑定为 List,Map 就好了,除了 connect("") 就没有差异

duangsuse, [2023/10/16 18:16]
其实呢,你做个 A:User follow B 就知道SQL对1:N的支持更好
用dict-list 的反查需要写 user.filter{ b in it.follows }

TEXT[] '{,}'pg也是支持的

duangsuse, [2023/10/16 18:23]
其实你应该用 operator fun get, 是支持多参的

另外,如果你支持 getVar():MMap.Entry 就不需要支持set+remove了

duangsuse, [2023/10/16 18:25]
kv2.flat{it.entries}.findKey

duangsuse, [2023/10/16 18:25]
可是过度Java化也是没意义的,你都已经kt化了

duangsuse, [2023/10/16 18:26]
python 里list[:] 和numpy的切片甚至是多维的
而你写的复杂度,还没达到算法(实现性差异)隔离的要求

duangsuse, [2023/10/16 18:28]
能自创这样 dict[(a,b)] 的数据结构,我看提需求的人也没重视性能……
duangsuse, [2023/10/16 18:58]
现在有这种 get()= field 子类型的写法了

虽然我觉得很茴字四种写法,但似乎比两个val好

duangsuse, [2023/10/16 19:18]
太逗了,应该 val get 的做成 fun
大概要退化到Qt那样,用 v(), set_v() 好了

duangsuse, [2023/10/16 19:43]
实在是太混乱了,和某些JS“函数式框架”的 freeze()一样,kt集合可变性纯属过度工程

duangsuse, [2023/10/16 19:46]
当一个纯属语义检查的玩意,被附加“缓存池” “纯度高” 等抽象的政确后,就变成似乎是另一门编程语言一样麻烦。

duangsuse, [2023/10/16 21:51]
我是说 List无论是否Mut,都应该映射为 util.List ,因此 toList 不能有复制语义
runtime 时不可变是无意义的

duangsuse, [2023/10/16 21:55]
其实分那么细,没意思了

我有个想法,把 let/run代换成 1.as:[x]
also/apply代换成 user.to: name=""

或者说 1:+1 ; user|: age=:+1

map,forEach同理

duangsuse, [2023/10/16 21:56]
没错,我没打算给这些老语言提建议

它们根本看不见每行开头的冗余

duangsuse, [2023/10/16 21:57]
这就说明你作为程序员,不重视软件的本质
所以你的思考就会被篇幅所占满,

别忘了你用的libs 也一样。 这就像生态系统的毒素一样,是传递性的

duangsuse, [2023/10/16 22:04]
这样滥用as 还有个好处,可以让流控消失掉
for(x in users)
if(x.isAdmin) print(x)

users:[x]
x.isAdmin: say(x)

1{>2}==NO //takeIf,f
irst,filterMap
users{name=='Jack',age<10}!
users.if{it.isAdmin}: say(it)

甚至函数式都会消失
"abc".firsts("a")==$Y // takeWhile
[(0~9),. (0~9 by -1),.].firsts{it==0}.N==1

包含跳转:
for(x in users)
if(x.isAdmin) print(x) else break

users:[x^]
x.isAdmin { say(x) }: return

duangsuse, [2023/10/16 22:23]
这种语法很变态,但依然有意义,是因为它能够被整理为2个情况

1. if,to,as 多单项函数: filter,forEach,map ,正好是SQL小礼包
2. 1,[1]. as{it==1}, isXX {$Y}:$N, Either{A}{B} 多单项选择

这种可不是语法上的可读性,而是整个编程范式都易学了
比较类似把YAML,SQL,numpy 的功能刻印到kt上,但不干扰之前的OOP体系

为了这样的体系,和旧语法割席还是做得到的
在设计ita函数时,我还在考虑响应式(StateFlow)、树同步( [1,x]=[2,y] 这种) 等情况,

无论是对事件变量,还是树形结构;无论是列表处理,还是单项与流控, as, to (invoke,赋值) 都有正确、一致的语意,其地位也直击要点。
let, also 做不到这些。难怪Kt把这个改进弄销声匿迹了

只拿它区分茴字两种写法实在是暴殄天物(就像它没发现 x as Int 不如 .as<Int> 易写)。with,by 这些助词就是天选之子,偏偏kt把它加在奇怪的位置,用一种老式OOP的方法(当然也比jspy好了

Koshin, [2023/10/17 08:03]
歪个楼,每每关于现有kt语言的观点,(作为日常写业务的菜鸡)有点看不懂,感觉每次吐槽完,也没什么然后。请问,下一步是打算做点什么来弥补所看到的缺陷(比如贡献一些库)?还是说只是在学习这方面的内容真的只是在讨论

duangsuse, [2023/10/17 08:34]
真的只是说一句,反正不会有人听的,而且现在kt支持的 operator fun 也不够用

你觉得GPT味,是因为我说的比较细。 单用YAML的逻辑去理解上面的代码,是容易的

Kotlin 现在不好的,在改良的特性也很多,就比如那个 typed companion(namespace) 和 private Mutable(私用 field:)
我现在在设计一种CLI序列化器
fun main(a:Argv)=a.Dict<Hello>()
class Hello /*:CliktCommand */ (
var name:Str,
var source: Ln<FStr>,
var out: File,
var r:Fire,
var count:Int=1,
var v:Boolean=false,
):CLI("""
c Number of greetings
id The person to greet?Your name?
v enable verbose mode(or .env)??
""", "name id") {
fun main() {
(1..count).forEach{ r+"Hello $name" }
out.Eq("") {it+source.joinToString()} //append
}
}

duangsuse, [2023/10/17 08:36]
如果 filter,map 你看不懂,说明你没写过html模板,或者没尝试“理解”SQL

firsts(takeWhile) 和 users:[x^]return 没懂是可理解的,毕竟和 startsWith 混一起了,而且你们也不会用 forEach{+return}

duangsuse, [2023/10/17 10:25]
>webp对BW纯黑白图片有特殊压缩吗?
WebP 使用了一些特殊的压缩技术,如预测编码和分段压缩等,这些技术可以在一定程度上提高压缩效率。但是,对于纯黑白图片,由于其像素值只有两种可能,因此 WebP 的压缩效果可能不如彩色图片明显。

duangsuse, [2023/10/17 10:26]
>Java 有没有标准 2D Mesh 实现
Java 提供了 java.awt.geom 包来支持 2D 图形操作,其中包括了一些基本的形状类,如 Rectangle2DEllipse2DLine2D 等,以及一些变换类,如 AffineTransform。但是,Java 并没有提供标准的 2D Mesh 实现。

不过,你可以使用第三方库来实现 2D Mesh,比如 tridentjzy3djogl 等。这些库提供了丰富的 2D 和 3D 图形渲染功能,包括 Mesh 渲染。你可以根据自己的需求选择合适的库来使用。

duangsuse, [2023/10/17 10:28]
你这个图形在SVG里叫path=""

二维bool数组有点奇怪,bitmap更奇怪,因为你遍历时是要解压的

拿编程的API去理解物理世界的计算,是我没想到的。 GL,SVG都有对应的技术,可以文GPT

duangsuse, [2023/10/17 10:34]
你先编号,不就没这个问题了??
y*w+x

duangsuse, [2023/10/17 10:35]
既然你想「不可预估的」扩展性,Set+dataclass 好了

duangsuse, [2023/10/17 10:35]
感觉你在做比 Terraria 更复杂的游戏

duangsuse, [2023/10/17 10:36]
如果没有Unity之类物理引擎的使用经验,最好不要

斜着可不止麻烦一点点

duangsuse, [2023/10/17 10:39]
实在不行可以
>用KD-Tree 做坐标集合,但是要连续

import numpy as np
from scipy.spatial import KDTree

# 坐标集合1
coords1 = np.array([[1, 2], [3, 4], [5, 6]])

# 坐标集合2
coords2 = np.array([[7, 8], [9, 10]])

# 连接坐标集合
coords = np.concatenate((coords1, coords2), axis=0)

# 构建 KD 树
tree = KDTree(coords)

duangsuse, [2023/10/17 10:43]
那你这不是典型的 bitmap(canvas) composite 问题吗?

>有两个黑白 A,B: PIL.Image ,C=二者And逻辑门的结果
请使用 composite Mode ,不用循环

from PIL import Image, ImageChops, ImageOps

# 对图像A进行反转操作
img_e = ImageOps.invert(img_a)

# 对图像A和B进行逻辑与操作
img_d = ImageChops.logical_and(img_a, img_b)

# 将图像E和D进行合成
img_c = Image.alpha_composite(img_e, img_d)

duangsuse, [2023/10/17 10:43]
没用过像素图的人把bitset误读成bitmap
偏偏他们是大多数

duangsuse, [2023/10/17 10:45]
往大了说,bitset,map 都是vector,都是 ndarray,但前者是1D的

bits压缩不是没代价的。不要只是 CPU换内存开销
duangsuse, [2023/10/17 10:51]
😒 我以为他真的要「几何」
没想到只是像素

既然只是测试相交的话, bitset也可以实现二维
反正宽度是固定的

duangsuse, [2023/10/17 10:58]
为什么你的实现方法都这么ast啊

tree只是数据结构的一种情况吧

duangsuse, [2023/10/17 11:03]
如果真要这么推广,就到点面相交的碰撞检测了

duangsuse, [2023/10/17 12:09]
我看你是要重造sd函数

duangsuse, [2023/10/17 12:11]
总而言之就是俩字,逆天

这么复杂的东西,想实现起来都未必
即便你搞了个快速原型,其必要性也是存疑的,大概率对软件没有帮助

duangsuse, [2023/10/17 12:14]
我们有一万种理由强化自己对编程和某些项目的理解

但没理由做一些跨界的事,因为那容易把问题搞复杂,
要么你系统性地跨界,要么就换其他的功能点做, 不要做半拉子, 自古以来的垃圾软件和大佬,都是半拉子

真是越想FP,PLT 圈就越来气。 他们浪费了我多少宝贵的创作时间,去理解一些基本的写法和设计模型, 就是因为自己瞎设计一些自己不懂的「跨界术语」导致的

明明有更简洁自然的定义式/关系式手段可以做的框架,偏偏要把一些概念和算法混在一起, 这样拿其他学科领域的功能骗赞的技术,消失也罢

duangsuse, [2023/10/17 12:38]
既然你要的是可变集合,那Set或2D数组就是最好做法

Silence Acappella, [2023/10/17 12:42]
我要是要算两个点之间的具体距离,直接x^2+y^2开平方根不就好了,如果是算走过的格数,我x+y直接求近似值

duangsuse, [2023/10/17 12:59]
不不,换成两个三角形,存Mesh岂不是有C语言担保的快(

太抽象了,你有线性代数的潜质

那些人就是把xyz的集合理解为超平面之类的玩意
但其实,坐标是不设限的集合, 是物理概念,将他们混为一谈,有时就是种负担

btw. 澄清一下,我讨厌不简明的线代。 我和所有复杂的东西划清界限
虽然我不懂线代, 但我讨厌没有模型和可视化,就在解题的一些人

我历来反对强调问题复杂的理论。那是与PLT和计算工具相悖的价值观;持有这种思想,学什么都会泯然众人,
“无非是自己搜到资料的多少,决定了问题复杂与简单”, 像这样的缝合不应称为理论。

只要我还碰电脑一天,我就会去用工程的语言消灭这些理论,就像python做的那样
无所谓好不好玩。 shadertoy.com 的DSP才好玩呢
duangsuse, [2023/10/17 18:28]
这就要看价值观了。
- Java里的null和catch问题,Haskell提供“有不同形态”的Maybe,Go则喜欢到处res,err:=,到Kt里就是简单的 ?.run 和 ?: 而已
- C++ 里的头文件根本没法解决,但Kt,Rust 不仅没有这个耦合度,更支持“外部扩展”
- npm,mvn 里复杂的版本管理,在今天被用于各种跨领域模型工具的python 却只是 pip setup ,最多加个venv ,基本没啥可优化的

在安卓里,就存在许多Web没有的问题。 CSS今天有响应式单位、模块化 ,许多“原生排版”甚至只有整数和颜色。 有些人泡图书馆3个月的成果,是H5一上来就会送给他的。

你并没有从最终用户的视角看问题,也没有脱离单一语言的世界观。 编程里许多的范式、魔法和设计模式,都是为了解决「代码自己产生的问题」
随着语言和生态的进步, 它们自然会消失;它们的消失,会让软件更好用。

如果肯静下来,拿笔纸去记录,经常性的反思, 删除一切显得聪明的技巧
并且,标明每行代码对需求 为何必须
你才能直面「根源问题」

duangsuse, [2023/10/17 18:59]
说到「地狱」类问题, 我倒是想起回调地狱一词。

其实答案在50年前就给出了: 传递回调,就是流控-return 的另一种实现法
线程栈vs协程栈。 就像创建SAM函数值时,外部函数要被做成对象;调用协程时,自己也要被做成状态机+回调。

但直到async()=>和同样基于“铺平,只添加return后续”的Promise 出现,异步触发始终是地狱
而一些静态语言里,新的Future, Rx 带来了另一些不一致性

那么函数式这段时间在干嘛呢?把「自动回调化」命名为 CPS,Continuation“续体” (函续..),callcc

然后,就连它们自己也没解决“异步触发return” (delay)的问题,因为纯的世界没有UI,UX
好像细化了。 但还不如协程来得直观

如果函数粉和 JSer一起,运行前/后的,“窄化所带来的地狱”都可以消灭
但它们就是不肯好好说话

duangsuse, [2023/10/17 19:13]
呃。。可能是我看线程(调用栈)的方式不同吧

你知道汇编里,栈必须保存ret_addr
就像调用时,要传回调。 那样的话,就可以让CPU返回主循环,复用一个线程,且保留call-ret 时序

duangsuse, [2023/10/17 19:20]
怎么会呢?

- main Waits: say(f())
- f Wait:
1s; say("good"); 2


补充下, Waits 只是给一个 [Fun1 [Cont *] ] 传递取消阻塞线程的cont

duangsuse, [2023/10/17 19:24]
我是为你能看懂啊
1.sec
return 2


Kotlin 的 {2} 块是有返回值的吧?

[Fun1 [Cont *] ] 你看懂也没看懂
Cont<*>.()->Unit

duangsuse, [2023/10/17 19:30]
named Round
data Obj(radius:N) [impl?]
data Hole(radius) Obj()
- getRadius TODO""
- fits(:Peg) radius!<peg.radius

data Peg(radius) Obj()

duangsuse, [2023/10/17 19:32]
>= 就是不小于
我不是故意这么写的,是为消除 isNotEmpty

duangsuse, [2023/10/17 19:35]
确实,比如 a~b . has(x)
x!>a, x!<b 看起来很丑,这只是被迫

list.!isEmpty()
list: !zero, this[0]=="A"
list !zero

duangsuse, [2023/10/17 19:36]
图中的方法都是冗余,你看看那些函数签名、 class is method.. constructor..

直接把对象,当成共享了构造期局部变量的多函数,不香吗?

duangsuse, [2023/10/17 19:38]
如果复杂度不转移给电脑, 我们就让它解体、消失

duangsuse, [2023/10/17 19:42]
那API设计我也在做啊

你为什么觉得我只做语法糖呢
直接把对象,当成共享了构造期局部变量的多函数,不香吗?

duangsuse, [2023/10/17 19:45]
这种语法的文件级包含:
data now made type named 
语句级: return at now
用于Data,Enum,sealed,隐转适配器: when- when--

也没有流控什么的,还是相对好学的

duangsuse, [2023/10/17 19:55]
涉及非常复杂的比较, 但总之,绝句不是一种OOP 或C-like语言

-- qsort(it:[Ary Int],range=iEach)=range: (A<B): “two”
at now:
mid this[A]
a A+1; b B
as:
a!>B, it[a]<mid loop: a.goesR
b!<A, it[b]>mid loop: b.goesL
loop(a!=b)
less(a,b) “交换逆序ab”
less(A,b“min”)
qsort(it,A~b-1); qsort(it,b+1~B)
^now
at less=Fn2:[A B]Var.swap(it[A],it[B])

duangsuse, [2023/10/17 19:55]
- main
at story Fun1[Animal]: speak()
at c Animal.Cat
c.story
c.水豚.story

type Animal
- speak Str
when-- as
Cat; Dog(name:Str)

when- Dog.to Animal
^now
- speak "good $name"
when- Cat.to Animal
^now
- speak "meow"

when- Animal 水豚
^now
- speak "..."

when--'AB' Way2 “Either”
A(:A); B(:B)

duangsuse, [2023/10/17 19:58]
我上面说了,Wait: 是支持返回值的
只是它 await() 的方法是隐转

在Wait{}块内,是一个以回调为this的函数

duangsuse, [2023/10/17 20:17]
那绝句也有函续作为值啊

data 'T'Seq(do:[Cont _ T], now, got:T,posR=$Y)
- add(:T, :Cont)
got=it “yield=休眠”
- set(:Cont) [our]
do=cont “初始=休眠”
- goesR“ight”() T
do(NO); return got
^named
-'T' as(:[Fn2“双this”[You Seq Cont] ]) this|:
Waits{posR=$N “no hasNext”}:
this: set(); fn()



- main
at ln [1 2 3].reversed (Sum(A=NO): Link(B,A))
traverse(ln): say("I got {it}")

data 'T'Link(x:T, xs:Link?)
-'T' traverse(xs:Link?) Seq: when xs:
NO{}
Link: add(x); traverse(xs)

duangsuse, [2023/10/17 20:24]
OOP 就是缺乏这种东西,才搞出 Factory

Rust都没有办法简洁地“分支出”新数据

Kt在设计 inner class 时可以稍微思考一下,把它做成一种 ext fun
duangsuse, [2023/10/17 20:36]
是的。比如 水豚 可以从 Cat,Dog 强转
就像
data Rect'wh'(:N) [impl?]
- Square'l' Rect(l,l)

when- Rect Pos'xy'(:N)

- main
Rect(10,20).Pos(0,0)

duangsuse, [2023/10/17 20:38]
Kotlin 的写法:
fun main() {
Rect(10,20).Pos(0,0)
}
typealias N=Double
open class Rect(val w:N, val h:N)
fun Square(l:N)=Rect(l,l)

inner class Rect.Pos(val x:N,val y:N): Rect(w,h)

Loney Chou, [2023/10/17 20:51]
fun Rect.Pos(
x: Double,
y: Double
): Pos {
return Pos(x, y, this)
}

open class Rect(
val width: Double,
val height: Double
)

fun Square(dimension: Double): Rect {
return Rect(dimension, dimension)
)

class Pos(
val x: Double,
val y: Double,
rect: Rect
) : Rect(rect.width, rect.height)

duangsuse, [2023/10/17 20:55]
''N=_N8
''Int=Int4


这个 ''typealias 也不是乱加的
''Cnt=Int{>0}
when-- 'AB'as
Pair(B:A,B:B)


'A'T 代表“T是A类型的单位”
就像 'AB'KV, [KV Int Str]

duangsuse, [2023/10/17 21:00]
背后是有体系的
单位类型、from/to 转换、单组/多组/多种 类型,正好能适配序列化器的创建

Int就被视为单组var
User是多组
Any是多种


'' 这么省是方便移植公式
- lerp'ABt' t*B+(1-t)*A

fun(:Double)= 就不知道有多长了

duangsuse, [2023/10/17 21:03]
Int4,8 也是为了避免麻烦
大家都是按Byte读写

没人会做bitflags 这样的事了

duangsuse, [2023/10/17 21:03]
$Y,$N 是 YN, Bool
NO 是 NO?, Nothing?

duangsuse, [2023/10/17 21:05]
bit 我也重构了,趋向与BitSet一致

1.Bit+2 or
- and not
1.Bit in 1 and交集
xor就是xor, shl8 是 1.Bit(+8)

这样,拼接8bit 的算法可写为

[1 2 3 4](Sum(0x0): A.Bit(+8)+B)

duangsuse, [2023/10/17 23:39]
#FP 读了一篇文章
data 'T'Box(:T)
//map:: (a -> b) -> Container a -> Container b
- 'TR'Box as(:Fn1) Box(fn(it))

Box(2): it+2
Box('flamethrowers'): it.toUpper
Box('bombs'){it+' away'}{it.n} //10

when-- 'T'Maybe
No; Just(:T)
- isNothing as[No]!=NO
-'TR' as(:Fn1) as[Just]?{fn(it)}:No

(0~3):[i]
Maybe('abc'){it.get(i)}: say(it)

when-- 'AB'Either
Left(x:A); Right(x:B)
//Left<A>(): Either<A,*>
-'ABR' flatMap(A:[Fn1 A]-[Either A B], B:[Fn1 B]-[Either A B]) when this:
Left: A(x); Right: B(x)
-'ABR' as(A:[Fn1 A], B:[Fn1 B]) flatMap(Left,Right)

duangsuse, [2023/10/17 23:40]
🤔 剩下两章不看了。 其实绝句的fn{}{}: 比任何语言(比如,do记法)都适合写Functor, 而 '1'(Eq(toInt,toStr)):+1 ,比 T.[Fn A B]->[Fn [T A] [T B]] 更像lift的语意

如果用CPS(调用都返回给'函续')理解Monad,IO,Either的职责就是一个协程调度器,负责链式if,传递catch
纯函数不支持全局(堆),也难以靠多this这样来组合算式,这么依赖栈来“赋值”和IO,很好理解

从这个角度 我觉得教授Franklin比我狂,他大方表明了PF粉对重赋值的厌恶,即便 ^^从工程的眼光^ 来看,PF函子只是用拙劣的模型实现了注入变数的函数。它们没比逻辑式编程通用到哪去,我观察到F口中的优雅是“>10次出现,未定义”+“定义后未使用”
而且,注入这种烂特技,在Java里都要被模块替代了

范畴论有点奇怪。 既然 f:A->B 是一个1:1的映射,就说明 f: B->A 也该存在,不然强调1:1干嘛呢?直接说调参可memo更严谨。

把反函数补上,就解决了数据绑定乃至IO问题,这正是React的取代者所号称的Signal>State ,然后函数式的身价就会像React诞生时一样飙高。
虽然React,Ramda对定义式编程完全是个白痴,它的写法和术语背后是另起炉灶+东拼西凑。 那些PF粉丝说的优点,他们自己可懒得践行。对代码质量的追求再高点,可不会被纯度挡住定义式的心智模型

不可变的数据树 很“确定”,但你还是要把它绑到参数里memo,重写。直接在参数改变时重算,与调用栈和对象的层次解偶,还用memo什么呢?如果type checker 没副作用,这么做也不算,它只是替调栈做一次模式匹配而已。
duangsuse, [2023/10/17 14:22]
看多了代码,已经不习惯写议论文体了吧

这样的话,你维护的项目,也一定缺少一个大纲或设计思想。

duangsuse, [2023/10/17 14:33]
这种事情GPT比较懂,你问它好了

一般来说,群成员多样化应该是好的。 我见过一些书籍分享群,没几个人说话

duangsuse, [2023/10/17 14:40]
还真是。 我在写的一篇总结文,就打算囊括我这几年整理出的一些术语的定义

基本上,一篇就可以抵过我5年的试错史了;这类文章我每天都在写,不然还真写不出来

Omico l Dev, [2023/10/17 14:42]
其实无外乎就几种情况:
融汇贯通,盖棺定论。
似懂非懂,犹豫不决。
自以为是,似是而非。
不懂装懂,口出狂言。

而上面这种就是第二条,所以看不懂就先放着。

duangsuse, [2023/10/17 14:46]
-科学就是盖棺定论, 不追求代码API的一致性,就会像py2to3, kotlin 那样改来改去
-我刚刚还批评过Silence的犹豫不决, 并且明确说过,我反对不易懂的解法
-比如? 无论据批评==似是而非
-同上,你的论据?

duangsuse, [2023/10/17 14:49]
我的批评,一般对事不对人

我引用的链接,不代表我懂那些东西。上面也说了,只是观点

duangsuse, [2023/10/17 14:50]
无论据批评==似是而非

看似你批评了,但其实不涉及具体编程问题

duangsuse, [2023/10/17 14:51]
对我来说,只需要有观点和写代码的精力, 哪里有甚么懂不懂的

编程是种模棱两可的抽象, 只要能完成需求,你只用AI也是懂的
懂别人的才叫懂? 那些软件缺了哪种“优化技巧”,照样转。

duangsuse, [2023/10/17 14:55]
对于既有的理论, 确实有「懂不懂」的说法

但对于解决某种(根源问题)的方法, 就只要有不同的观点,就这
duangsuse, [2023/10/19 17:47]
你也自己处理一点啊, 你这提的点子都是什么地狱灵感

Ketal _Q_ray 🍥, [2023/10/19 17:49]
线程成本太大了复用不香吗

duangsuse, [2023/10/19 17:49]
他讨论 的是并行加速吧

duangsuse, [2023/10/19 17:50]
就像游戏一般用UDP而非流式TCP

如果读写竞争,造成的是浮点级的误差,还是可以忽视的
你想多CPU,就线程, 只是想做事件,就协程

isekiのChannel, [2023/10/19 17:51]
我估计他不知道什么是CPS

duangsuse, [2023/10/19 17:51]
传函续调用,自动回调呗
delay(1s, callback)

如果你连并行(parallels)和并发都分不清,还是不要处理读写竞争问题了
并发是不会有竞争的

Silence Acappella, [2023/10/19 17:54]
那能不能这样,一个scene就一个线程,然后访问啥的,全部由scene内部的这个线程将信息发给玩家

duangsuse, [2023/10/19 17:54]
说起来,如果你需要传Blob
WebTransport https://developer.chrome.com/zh/articles/webtransport/
已经成熟几年了

Silence Acappella, [2023/10/19 17:54]
一个时间点只有一个指定的人能操作

𝗿𝘂𝗮𝘁𝘁𝖽 { 𝗍𝗁𝗋𝗈𝗐 𝗻𝘂𝗹𝗹𝗽𝘁𝗿(𝒊𝒕); }, [2023/10/19 17:54]
你应该考虑把信息交互做成非阻塞而不是考虑用多个线程

duangsuse, [2023/10/19 17:55]
唉,又是这样的伪需求((

Silence Acappella, [2023/10/19 17:55]
我原本用的是springboot思维,多少个service多少个线程

duangsuse, [2023/10/19 17:57]
>这让我想起了 server-socket() 的 bind() accept(N) 问题

其实这个N很难决定,一般都是框架做调整

—今日玩笑
AI回复我:
🤔👨‍💻💻🔌🔗📡🤝

不愧是Java,自己造了一个WS子协议

我以为吧RPC映射到 /http/?params 已经很离谱了,把已经靠“endpoint”拿到的WS,也转换到http路径, 不就又凑到了大量字数?
真的很Enterprise
C线程就是Linux调度的协程
协程不能并行,没有CPU竞争问题,语义上被确定为调用返回

所以,要read()就需要占线程,阻塞它的调用栈; 靠创建线程sleep太耗时了,而且不能返回值
要并行用SIMD和numpy GPU就行
不然应该是要锁和原子加减法
这也是OS在支持 epoll(select) 的原因

理论上,OS就像VSC那样,可以单线程运行和IO,而其他Workers 只负责加速
Forwarded from dnaugsuz
>请用Kotlin KSP 实现为每个 class A_XXX {} 模式的类的 companion object{} 添加 val XXX="ok"
AI完成的不好,但给了大体思路。请参照
-moshi 修复类同名例的生成
-KSP入门

package com.example

import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*

class AddValProcessor(private val codeGenerator: CodeGenerator) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation("com.example.A_XXX")
symbols.forEach { symbol ->
val packageName = symbol.containingFile!!.packageName.asString()
val className = symbol.simpleName.asString()
val file = codeGenerator.createNewFile(
dependencies = emptyList(),
packageName = packageName,
fileName = "${className}Companion" //
)
file.appendText(
"""
package $packageName

class ${className}Companion {
companion object {
const val ${className.toUpperCase()} = "ok"
}
}
""".trimIndent()
)
//if (symbol !is KSClassDeclaration||symbol.classKind != CLASS||symbol.modifiers.contains(ABSTRACT)) {return@forEach}
}
return emptyList()
}
}

dependencies {
implementation "com.google.devtools.ksp:symbol-processing-api:1.6.0-1.0.0"
ksp "com.google.devtools.ksp:symbol-processing:1.6.0-1.0.0"
}
>我就想拿来拼个变量,整的太费劲了
你要感谢Java支持多行版本的这个,因为MyBatis等SQL Mapper 实际上做的就是这个值模板工作

https://openjdk.org/jeps/430#:~:text=String%20interpolation%20is%20dangerous

预期的STR实现: https://cr.openjdk.org/~jlaskey/templates/docs/api/java.base/java/lang/StringTemplate.Processor.html

>请用 Java STR."txt \{arg}" 模板字符串语法,实现对for列表模板的支持

var a="Jack Rose".split(" ")
TXT."hello:\n \{a}{'.'\n}"
hello:
'jack'
'rose'

AI不会,可能它会JS版的。

>请用 ES6 fn`txt ${arg}` 模板字符串语法,实现对for列表模板的支持
好吧,它不会。但基本上,可以这么写

STR=(s,...a)=>a.reduce((sb,x,i)=> sb+x+s[1+i], s[0])
STR`100${2}4${2}` //'100242'
#PLT #design duangsuse:
好用编程语言的标准,首先是好读

绝句有 Int/Inc1,2,4,8 代表有无符int, _N4,8 代表浮点,N2向量实现了复数,没有无理数

Inc.Ln 实现mutableList, Nd实现矩阵 ;所以这些命名都是既准确又广泛,因此译为 i:_数4 size:增 arr:增.行 也没毛病

这种堆砌偏旁八卦表示整数的语言…… 不得不佩服作者打字的功底

https://docs.racket-lang.org/ming/preface.html

我觉得最离谱的是…… 作者好像是基于认真的学术目的,来做这个设计的……

哪怕把 if else 换成 if or,统一下 Nullish 和 a||print 都比面向字母编程好啊

复数真的是纯负担。计算机人不该研究复数。虚数就叫imag,本来就没语意的玩意,翻译个 🐤

shadertoy.com vec2多好啊,xy的语意性比实虚好太多

Python还有呢,写FFT时还不是被3b1b解释为向量旋转(而且根据欧拉公式,就是物理上的矩阵运算)。

再说线代的东西,也可以理解为“超平面”,但那些B连 sympy.plot(x=y隐函数) 都不会用,还在讨论空间

这么离谱的设计,还说Scheme有复数

有没有是一会事,能不能用另说。
lisp系的模块化太差了,这些 (num? 不就是搞原型链查找吧

number? 就是123常量的类型,但它的加法是用不可扩展的方法def的,就是说Lisp系的类型系统没有比VB进步太多

Haskell class Num 算是一种多态做法,但它的类型判断要靠模式匹配

弱类型不适合区分整数/正数这些概念,像JS那样 BigInt(11n ) 就挺好。 你与其区分数值是否exact,不如像 Ruby 那样直接加obj.taint,“避免注入攻击”,或者学 sympy.evalf(自由精度)

凭什么builtin 就比用户def高一个档次呢,不是一等公民4

就是因为不可扩展,或者说框架级无序,才会复杂。numpy哪里复杂了

假设hs是基于 data May2=A a|B b 的弱类型,那就能直接判断

这就是我最讨厌的一点,因为类型和值域是要区分开的

exact不就是个bit标记吗

weak是指检查弱
dynamic是指不在符号期(重载查找)检查

我一般说弱=动态类型,然后C是弱检查,py是强检查

你都已经不区分类型了,区分值域就很搞笑。 那是在混淆数据的check和type

总之,类型是一种先验的特质, 晚检查实际上就是不对def进行归类。 而把 positive? 当类型,就势必要在序列化或传参时实现validate,不然没意义

就是说,Haskell的 tagged union 才算弱类型

举例评价下此「中文编程」设计思想,格式为
名:文档
^绝句的写法
批语

双(阳阴) : 把两个数据配成对,即成一个双
^ [数 文 俩项] 1|"2" [数 仨]
^ "12"==p:A+B
考虑过三元组?

字?/象形 : 【MORE】 = char-graphic?
^ Str.AZ.graphic/'c', 'c'(Upper), (Symbol:'#:1')
泛用数据类型,不要硬编码

丫,并,戈(或),􏸣、􏸟:流控if
当、肖,夬:流控when
^ (1==1)(2、3)==2, arg/IS_GOOD: say:'wtf'
^ 问,x>0,。 x<0,。 或,。
泛用数据类型,而非泛化符号字面


􏿴,阳之阴阳 : 将一个双的阴位放置另一个双
^[1 2], 1|2|NO
不要滥用链表和访问链,多用集合类或解构

甲,末 : 第一个的意思
^ a[0], a[_]?, a[_-1], a add 2
不要结构化列表

􏾺 ,𨚞: 从􏿴中左起依次取出来N个元素并组成新􏿴返回 【MORE】 = take
^ a.if{!=0}, a.takes{!=1}, a.posR.takes{==2}

􏹈分 : 将􏹈和余下的分离开(输出结果是一个复值) 【MORE】 = partition
^a.sep([a.n*0.5])

^[1 2 3](Sum) 支持了min,max,avg , a(Sum.n%: /10) 实现了分组py.Counter
#cs #design #haskell https://blog.vero.site/post/noulith

max(map(sum, map(ints, puzzle_input.split("\n\n"))))
puzzle_input split "\n\n" map ints map sum then max

ask().Str.Sep("\n\n") (Ints){you(Sum).sum}.argmax
at Ints [Str Fun1]:Sep{Int()}

0 <= x < n; 0 <= x && x < n
a < b < c
(0~n-1)/x: "good"
(0!>x, x<n): "good"
[a b c].ToNext:A<B

a (zip +)= [4, 9, 2];
at a [4 9 2](Sum(Fun:+))

x = [[0] * 10] * 10
at x Nd([10 10]).zeros

at op when Rand(0~3) in {
0 N.!<|N.<
1 N.+|N.*
2 N.*|N.+
}
say:'{op.A(1,op.B(2,3))}'

真APL狠人
[1, 2, 3] zip [4, 5, 6] zip [7, 8, 9]  =>[[1, 4], 7]

at A [
(1~9),.
]%[3 3]
A.T 矩阵转置就是[1, 4, 7]

x := [3, 4]; x := "奇怪的作用域“优化”";

*Crafting Interpreters* 认为这可以简化REPL,但看IPython就知道这不是乱搞语法的理由

def f(x, y, z):
print(x + y + z)
for x in xs:
for y in ys:...

一些人可能知道 for x,y in itertools.product(xs,ys),不过绝句从语法层面解决了这个
xs:[x] ys:[y] zs:[z]
say:'{x}{y}{z}' //f的内联定义

adders = [lambda x: x + i for i in range(10)]
at addFns (0~~10):[i] [Int Fn1]:you+i

for (a <- as; b <- bs; c <- cs; d <- ds; if cond(a, b, c, d)) yield k:v
adders := for (_ <- 1 to 10) yield (
i += 1; \x -> x + i
)

Seq: (0~9): add you //这不比推导式强多了
(0~9).KV: you|you+1

漂亮吗? 还停留在for if的语言可做不到这种直白度



if (a) for (b <- c) if (d) e;
if a { for b in c { if d { e }}};
print(if (a < b) "a is less" else "b is less or equal")
say:'{(a<b)("a is less", "b is less or equal")}'

a: c:[b]
d: e //无语意的命名会让语法显得难看
a.n<5: a:[x]
x!=NO: x //结构相同,但换掉ijk变量名

xs := [2, 7]; switch (xs)
case 1 < 2*a < 2*b + 1 < literally 3*3 ->

这个必须靠穷举法……查找两次还不行

- a/b的类型 是基于a:Int or N 分派所以不用//
- %不是取余((/).rem),而表达分组
- ^不是XOR或(**),上标在编程领域应该避免
- a<=>b通过type 'S'Sorts 的元类提供 at sortFn: [S S YNo Fn2],另外 >= <= 是!< !>
- 通过 a.Bit +,in,() 实现 |,&,<< 来减少~,^的负担
- 如果说列表a+b 没有交换律,用 [a,. b,.], [*a,*b] 优于 a add b
- Java里-0x80000000 可以, -(0x80000000)不行
duangsues.is_a? SaltedFish
#blog 看到易语言还在VB++ 的范式旁徘徊,并且觉得编程语言是种必须特色和备案的「核心技术」… 我想复刻下这2007年文章的口吻: “绝句.ju”十分钟入门教程 作者:转载必须注明出处 亲爱的朋友,您愿意花十分钟的时间,来了解一门全新的编程语言“绝句.未公开”吗? #1 只有十分钟,时间紧迫,让我们立刻开始,不多说一句废话(这一句话本身算不算废话?哈哈)。 请去拜读易语言官方提供的《“易语言.飞扬”白皮书》——这本书写的很好,文笔比我强多了!本文大量参考该白皮书。 #2 绝句的大概: - 物…
名 启动类
^名
- main
说,'祖国您好!'

将123写到屏幕
100.123,[x]
(将x)写到屏幕


名 'T' `将`(:T) “名记平权”
- [文 将]`写到屏幕` 说,'{它}'

典 游戏
- 猜
猜 猜数字().[游戏 也]
猜去猜

(0~10)(x), “如果(0 < x < 10)”。
(0~~10)(x), “如果(0 < x \< 10)”
(0的右~10的左)(x), “如果(0 \< x \< 10) ,因为数学(>18) 不自然,我换了”

这时,a 1;b 2
变数去换(a、b)
""{a==2, b==1}!


''名龄=[文 计 俩项]
''合法名=文{平台(有关领导)去请示 }
- 华夏 ("中国"~~5_000)

华夏(),[名~~龄]
名去[合法名 也]“require”
"🐭"{=="🦆"}!

^name
os sys random:rand
cmd Cmd
猜数字().cmdloop

data Cmd 猜数字(x=rand(1_000)/10)
now:
数 0; 最接近 100
历史 [数 ]!
- `$default ` 'ln'
ln.Int?{数=me} \: say()
历史 add 数; on(数)
- on'num'
num==x { say(); sys.exit() } :
say:'太${(num>x)("大","小")}了'
接近了(): say:'不过接近咯'

- 接近了 历史.argmin{(x-A).abs}: Var.ifPut(最接近,me)

名 猜数字 内(内定数字 = 66) 游戏
- 猜数字() 做,
在n=获取数()
说(n、 NL="")
内定数字 .:
==n,说,'猜对了,恭喜';$Y
\<n,说,'太大了';$N
\>n,说,'太小了';$N
^典
- 获取数 听("请猜1-100中的一个数:")去数
^典 函定
- 猜 做,
这时 猜数字() 不“停”,。

物 猜数字 全自动猜数字 内(这时、n=1)
- 获取数 n去右移

典 游戏
- 猜数(听用户:函.[数 a0])


name BaseModel
- main /??/TODO "explain why 'Base' is a good class name"
- badFloats(:[Str [N Pairs] KV])
- main'abc' as:
a+b.[N too]

- someJob(x=NO)
x? {say:'1'} \: return
- guessNum(ask: Fn.[Int a0]) Try:
return Error("{aNum} 后置")
^name
- aNum 0
^name
- goodBoy(vecs:[N2 Ln])
觉得你的两篇文章很好,就附注一下了
#learn #PLT #OOP #design

https://jason5lee.me/2022/08/24/my-views-on-programming-languages/
1.编程就是表达想法
鼓励简化和复用,而非面向CPU去if for
API和SQL结构适合定义式,处理逻辑适合函数式;说到底这就是Excel表格矩阵+过滤器
算法适合过程式,1次性任务适合CLI脚本或js

2. data class UserInfo(
val userName: String,
val nickName: String,
val birthday: Date? = null,
)
val userInfo UserInfo(
userName = "Jason5Lee",
nickName = "Jason Lee",
)
userInfo.copy(birthday = Date(1997, 12, 17))

我倒觉得伪代码是:
- UserInfo(name,nickname,birth)
user UserInfo("Jason5Lee","Jason Lee",NO)
{{user}, birthday:Date(1997, 12, 17)}

强类型:
?? Info Column
User'name nickname birth'(_:Str, birth \: Date) //歪嘴表情

copied user.as() :.
-birthday Date(1997, 12, 17) //bash格式的apply{}

3.编程语言的静态类型,对沟通很重要,因为类型算是最廉价但全面的“示例代码”

4.Vue等框架就是为表现力诞生的,所以我觉得语言层面,最主要还是有扩展性
这方面Lisp系绝对是反例,而Go的泛型和err,nil都很糟糕。 仅仅是语法简单或简短,不能掩盖框架性的缺失

5.可以预先学习jspy等实用语言,再把Excel,脚本精灵等通俗软件的需求场景,泛化到不同语言(SQL,FP,.)的差异
专业软件一定是对的,它们比黑框框白页页们多经过几十万人的筛选,而且有钱可赚

6. Visitor 在 import ast 里作为 NodeTransformer 存在,只是因为static语言不能 for T def'visit_{type(T)}' 要手写样板而已
同样, window.TreeWalker 是一种用途还不如RegExp grep或glob多的工具

多态(multi-typed) 是js极少的一个缺口,哪怕py对模板abc class的生态都好很多
考虑到Android小白会把 Listener override+super 而非 div.onclick=()=>事件冒泡 用来写UX,且不习惯 setTimeout,localStorage
我觉得JS的弱化class简化View 是极端正确的选择

7. 领域化设计很重要,但以上技巧,其实都是编程领域特有的。 现在人学编程太缺失这些设计思想了


https://jason5lee.me/2022/08/30/my-understanding-of-oop-and-fp/
1. 封装性上,`private,abstract protected` 最终还是会被全局util fun 代替(另外 open val (getset) 真是太罕见了
Rust很少用private,因此在class级控制太多算是过度设计

多态上,考虑到无默认override的fun数目应在1~3项,1~2层继承, FP的filtermap等函数 技高一筹

考虑CPP(Cat,Person,Point 3例) 的同类项,你会发现class的本质只能是接口

?? Animal //行=多态  列=字典
Cat(name:Str)
Dog(name:Str, owner:Str)
Animal() //可是,你不能这么做

于是,你用正确的类型重构:

?? HasName
name Str
- funnyID askGPT(name..)
Cat()
Dog(owner:Str)
Animal()

过度泛化的Animal,会导致funnyID无法被重用,这就是Adapter爆炸的元凶,是OOP的原罪

2.FP是OOP的子集。 对象是共用构造期局部的「多方法」函数,而 class{open fun} 就是另一种默认参数

只要把对象视为1~3个主要方法,就能推理出其构造参数;只要说闭包=对象,就能明白JS为何把函数当构造器(原型链只是一种不变量外提)

这再次证明了,Object 是个包含无限大,意义无限少的 abstract nonsense ,暴露构造期细节、不易扩展fun 是语言设计者低能的表现

比如Builder吧,它无非是把局部的全面赋值,绑到堆对象,从而弥补了默认参数(复用)

3. Optional,Result 是FP的潮流败笔,Rust的?和kt!! 甚至语义相反。 除了Kotlin “悲伤路径语法”都可以说是编程界的耻辱

在我看来呢,除了 u.name\:"Jack", u(":("):name+1 ,最好把 (may: throw()) !:"fail" 也加入nullish,语法else,||,assert 也该为之改变

4. filtermap 就是 select where ,根本不必提名字或it,只要运算符和函数平权, film{score>60}:id , (0~9){<5} 才是合理写法

就像Object,FP的纯函数也是性质无限大,功能无限少的 not even wrong ,因为语言研究者不懂类比查重,却陶醉于专业主义

5. 纯函数和不可变对象,只能存在一个。 函数是纯的,返回值就是0丢弃的,赋值就根本不可能有副作用 或者能够useMemo

因为这就是 Reactive。函数是值,参数和模匹变量也应该是。 比起用伪递归风格的while去伪造Excel的功能,不如向定义式编程正统的Prolog好好学习

Ruby的"str" “装箱” 给一致性带来了灾难。尽管Rust和Go的 listVar append x 才完全一致,kt的Mutable至少是合理的,但各种mapTo就是自作多情了

如果有OS=JVM 这类概念,过度的验证是合理的,但纯函数和freeze依然是扫把星

6.value class 是对OOP的误解。 对象是共用构造期局部的「多方法」函数,子类型是C式struct间的「隐转函数」

并不存在那么多 asXXX XXAdapter ,更不用说 Int.plus(:莫名其妙的宽化重载) 和 IntArray, Stream$Int 这些模板类了

7.ADT data Way2=A a|B b 并没有那么好用,它不能是open class,而联合类型虽然能强转Any,却缺乏结构性(不能说 catch(A|B ) 是应该写的

enum和模式匹配暗示了多态data不能有名字,这是幼稚的断言,会导致理论与实用时的割裂,而且难以被接口化

OOP在这方面的语法烂但经验极为先进。 ADT,record和trait的自由扩展写法一致,可以隐this而非复制粘贴元组, enum可以用static实现

在类型基础上,FP玩的更花,但那却只是因为它们处理的最简状况太简单。 实际上,一些简短的语法,会随着程序的扩大而轻松被割裂,让你熬一整晚去重构简化
#recommend #learn 可以说OS级的工具,App级都重新造了一遍, 这不仅暴露了应用对生态环境的无视,也说明OS级的设计无法满足实际软件

SOCKS代理-socket() 函数替换
序列化-注册表,睡眠休眠
ORM和Web后端-ACL, 文件树属性

协程-进程池,LWP池, 甚至因为能等resume(),代码应该可以在RPC或FFI上执行
函数-busybox,进程
环境变量,单例,多例如用户组-YAML
BSON和二进制-mmap, sized vec

我比较喜欢Web平台的API,其实大一点的编程框架,内部都和OS内核一样繁忙

涉及的历史包袱那么大,怎么可能一两年就完全领悟呢?

比方说吧,赚钱的Web编程,后端,HTTP API?

popen://git/submodule/init/?depth=1 User-Agent=ansi 也是一种
Cookie或者说Handle,是一个限时RPC对象,ORM就是为了方便外套一层RPC数据验证。
不过是为了换个方式用Excel,做一些人类语言能描述的列表处理,学习了多少可笑的语法…… 甚至函数式在zip,chunk这些模式上也并非统一的

bash也不免是像 py fire 或pwsh里说的,是 git.submodule.init('.', {depth:1}) 的单行简写
它们在数据和算法上,都一样,但不少人还为了 import cffi 去学一种低等范式的语言,学Qt学Android,进入那些欺骗Devs “行数越多越幸运”的框架

YAML,HTTP,SQL Schema 和编程语言的struct,又有什么差异呢? 带来这些割裂,是因为编程生态圈缺时间没精力吗?
而那些用途不明的虚拟机和-O3,就是“形式语言”程序员,比业余创作者牛逼的?

Python不过是做了JSON的超集,带点简洁的布局,就让科学界用电脑做了很多有意义的事,一些只有“渐进式设计” “交互式编程”能做到的。 这并不是理论或设计模式,打败程序员的,往往不是同行,反而是跨界


既然整个Web,都可以导入为class: def ,那么前端呢?

React高等的useMemo和useEffect(x=>, [x]),Vue的html for模板 ,其实都导向一个结果:[a,1]=[2,b] 是检查期就不能表达的,匹配模式并不是值,b=a.map(x=>x+1) 间也并没有“纯粹”的等价关系,可变量不是值

你觉得let[]=[], ()=> 和HTML组件、视图绑定有何关系? 其实React团队们拼命追求的水合、性能优化,大概就是 img({src})=e, e.childNodes=a.map{div(x)} 这样的逻辑吧。
JS曾经的回调地狱,也是靠 yield, await 实现单Thread多任务来解决。最终还是自己造了一个OS内核啊

同样,try{}catch{} 和 0||"default" 无法统一地被默认、被链式调用,也暴露出了Error并不是一种null值。 十万美元错误,就是因为null不被视为错误造成的


稍微给知识查个重,就会发现其实不需要学习什么,因为现代编程语言和lib的设计是一摊拖泥带水的遮羞布,连错误都是抄来的,当然会落在地上呗

只要肯花时间探索,道路会不断延伸

#sql JS里这种查询的合理写法是 {a:1,b:2, c:[1,2]} ,可以支持 x=>区间
https://gitee.com/Tencent/APIJSON#apiauto-展示-apijson
是这种的

比较搭配BATE都有的0代码 CRUD

虽然用途上就像 sklearn vs pytorch 十分尴尬, graphql 式语法还是应学习的
感觉编程和设计小白用低代码也写不好的


我的编程范式,还轮不到一个在当跨平台复读机和CtrlCV家,却自以为懂一切的人评论

你真的不在乎那些纸上的「好看」吗? 我看你,只是执着于把好看供奉起来,避免与实际用途有交集

在我眼里编程语言不过是写法框架的外沿, 写出的任何代码都要有应用层定义力。因为语言本来就是用于交流记录的

学着把最简示例+心智模型明着说拆着说,许多难度都是浮云。 所有的思考和语言技巧,都不是通过语法和filtermap 这些术语传达到的,而是跨越软件的惯用法

如果只是为了做脚本而写程序,GPT反而更合适吧,那样无论做什么都不需要搜文档