#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) 就更加明确
--评论区后续
>
而且AST上的信息比调用树多不少,难写明
A.中缀运算符很难0基础解析
B.嵌套不易写
目标.写法相同的算式,更能读懂语意联系
e :: S => T 相对简明,但箭头不支持组合
但其实,这种转换根本不存在。作者在POPL2010使用过<>符号,但他想换了
btw. 是在说推导出 e:Int=>Long 应生成 Long(e)
符号形式应是
合约是指 {x:Int|x>0} 这样“给字面量类型”
#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} 这样“给字面量类型”
SIGPLAN Blog
PL Notation is a Barrier to Entry
Research in programming languages offers powerful tools, but our systems of notation stymie outsiders. Can we change our notational approach and broaden our audience—without compromising on c…
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:
我看不懂 Γ-> 和两段式,M: τ ×sigma 这些语法从没定义过
而且这符号冗余率也太高了
说句心里话:
这都是什么烂代码啊?行走的同义词典? 不愧是Emacs那难用编程语言的作者
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说到BNF,以上PRR还支持
(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'] ])
入='\\'
x? [1,x] x* [0,x]相比COBOL这些老语言的元编程文档, 算是去英文化了,就像 json.org 的图
x, [0,x,',',{a.push(x)}]
(x) [2,"()",x]
我看不懂 Γ-> 和两段式,M: τ ×sigma 这些语法从没定义过
而且这符号冗余率也太高了
说句心里话:
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
直接把 plus,minus 推广到Date上,写这些 timespan 库干什么,很像 range/slice 这些同义词 😅
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]
以前我
没想到这也能叫改进…… 只有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加减和读写的
在用法上都是支持的
duangsuse, [2023/10/15 11:37]
比方说,你显示+1day 的日期,
duangsuse, [2023/10/15 11:39]
timespan, 按libc 的概念应该要加法有两个“Date”
duangsuse, [2023/10/15 11:40]
算了,不说这个了,反正Linux的时间API不会改,也没有千年虫问题了
最好是每个点固定1_0000等位数,这样也避免判断麻烦
pkg manager问题有那么严重吗,都要上二分bisect了…… lock文件可以缓存吧
>=12 <14 || >10 應挑選 10 这一条我觉得有点奇怪,虽然语法是对的,但这就是个区间过滤器,其实不能当成算式联立去编写。
^12 应该也是>12 的意思吧
其实现在有种观点是,apt那样各种版本限定符太严苛了,npm重得太可怕
pip; pacman; npx 那种全局单版本依赖更流行
既然你想做这个游戏,你能把基础玩法和灵感,先写个文档吗?
你的卡牌要有数据库, 那典型的几种选择器和效果,是什么?
这些和代码无关的,反而最值得你优化。 一些复杂性很可能只是你的需求自相矛盾
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()看了一下。 我觉得Date的设计就不合理啊…… 它就是一个int2tuple 转换
val end = now + 15.minutes()
直接把 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项树,不是+-*/semver 判断区间的方法,应该是把 1.20.3 转为 1203 吧,这样大版本不同也不能兼容
Cmp /\^~=|([<>]=?)/
Ver v di(. di)?(. di)?(- Str)?
di /\d+|\*/
最好是每个点固定1_0000等位数,这样也避免判断麻烦
pkg manager问题有那么严重吗,都要上二分bisect了…… lock文件可以缓存吧
>=12 <14 || >10 應挑選 10 这一条我觉得有点奇怪,虽然语法是对的,但这就是个区间过滤器,其实不能当成算式联立去编写。
^12 应该也是>12 的意思吧
其实现在有种观点是,apt那样各种版本限定符太严苛了,npm重得太可怕
pip; pacman; npx 那种全局单版本依赖更流行
GitHub
tomlkt/core/src/commonMain/kotlin/net/peanuuutz/tomlkt/internal/emitter/TomlElementEmitter.kt at master · Peanuuutz/tomlkt
Multiplatform TOML encoder and decoder, powered by kotlinx.serialization - Peanuuutz/tomlkt
duangsuse, [2023/10/16 13:21]
感觉取消不应该抛异常啊…… 比如fetch() 下载文件,主动取消,有什么该处理的呢
duangsuse, [2023/10/16 13:23]
比如上面那个delay的例子,取消就是 Dispatcher 去run() 时啥都不干了,就叫取消了
就像进程的exit() 一样
duangsuse, [2023/10/16 17:53]
翻译:
骰子是一个
结果是 N个骰子.groupBy点数.eachCount
duangsuse, [2023/10/16 17:55]
建议你搜索 Trie树
其标准实现是正则匹配
或者
你看,只支持 trie[a][b] 的嵌套情况,反而比递归的复杂些
duangsuse, [2023/10/16 18:11]
其实就是
这个重载…… 第二个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 的反查需要写
duangsuse, [2023/10/16 18:23]
其实你应该用
另外,如果你支持
duangsuse, [2023/10/16 18:25]
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)] 的数据结构,我看提需求的人也没重视性能……
感觉取消不应该抛异常啊…… 比如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)] 的数据结构,我看提需求的人也没重视性能……
Gist
Trie data structure in kotlin
Trie data structure in kotlin. GitHub Gist: instantly share code, notes, and snippets.
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=""
或者说
duangsuse, [2023/10/16 21:56]
没错,我没打算给这些老语言提建议
它们根本看不见每行开头的冗余
duangsuse, [2023/10/16 21:57]
这就说明你作为程序员,不重视软件的本质
所以你的思考就会被篇幅所占满,
别忘了你用的libs 也一样。 这就像生态系统的毒素一样,是传递性的
duangsuse, [2023/10/16 22:04]
这样滥用as 还有个好处,可以让流控消失掉
这种语法很变态,但依然有意义,是因为它能够被整理为2个情况
1. if,to,as 多单项函数: filter,forEach,map ,正好是SQL小礼包
2.
这种可不是语法上的可读性,而是整个编程范式都易学了
比较类似把YAML,SQL,numpy 的功能刻印到kt上,但不干扰之前的OOP体系
为了这样的体系,和旧语法割席还是做得到的
现在有这种 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)duangsuse, [2023/10/16 22:23]
if(x.isAdmin) print(x) else break
users:[x^]
x.isAdmin { say(x) }: return
这种语法很变态,但依然有意义,是因为它能够被整理为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序列化器
如果 filter,map 你看不懂,说明你没写过html模板,或者没尝试“理解”SQL
firsts(takeWhile) 和
duangsuse, [2023/10/17 10:25]
>webp对BW纯黑白图片有特殊压缩吗?
WebP 使用了一些特殊的压缩技术,如预测编码和分段压缩等,这些技术可以在一定程度上提高压缩效率。但是,对于纯黑白图片,由于其像素值只有两种可能,因此 WebP 的压缩效果可能不如彩色图片明显。
duangsuse, [2023/10/17 10:26]
>Java 有没有标准 2D Mesh 实现
Java 提供了
不过,你可以使用第三方库来实现 2D 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 做坐标集合,但是要连续
那你这不是典型的 bitmap(canvas) composite 问题吗?
>有两个黑白 A,B: PIL.Image ,C=二者And逻辑门的结果
请使用 composite Mode ,不用循环
没用过像素图的人把bitset误读成bitmap
偏偏他们是大多数
duangsuse, [2023/10/17 10:45]
往大了说,bitset,map 都是vector,都是 ndarray,但前者是1D的
bits压缩不是没代价的。不要只是 CPU换内存开销
无论是对事件变量,还是树形结构;无论是列表处理,还是单项与流控, 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 图形操作,其中包括了一些基本的形状类,如 Rectangle2D、Ellipse2D、Line2D 等,以及一些变换类,如 AffineTransform。但是,Java 并没有提供标准的 2D Mesh 实现。不过,你可以使用第三方库来实现 2D Mesh,比如
trident、jzy3d、jogl 等。这些库提供了丰富的 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换内存开销
GitHub
Share/Others/snakes/snake.c at e89301b326713bf949bcf9fbaa3992e83c2cba88 · duangsuse-valid-projects/Share
🐕 duangsuse's shared files(e.g. productive software projects, documents) - duangsuse-valid-projects/Share
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才好玩呢
😒 我以为他真的要「几何」
没想到只是像素
既然只是测试相交的话, 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才好玩呢
Inkfood
Collision detection with SVG
Check if an object collides with an another one. With fast collision detection or with precise collision detection.
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]
怎么会呢?
补充下, Waits 只是给一个
duangsuse, [2023/10/17 19:24]
我是为你能看懂啊
Kotlin 的 {2} 块是有返回值的吧?
>= 就是不小于
我不是故意这么写的,是为消除 isNotEmpty
duangsuse, [2023/10/17 19:35]
确实,比如 a~b . has(x)
list.!isEmpty()
图中的方法都是冗余,你看看那些函数签名、 class is method.. constructor..
直接把对象,当成共享了构造期局部变量的多函数,不香吗?
duangsuse, [2023/10/17 19:38]
如果复杂度不转移给电脑, 我们就让它解体、消失
duangsuse, [2023/10/17 19:42]
那API设计我也在做啊
你为什么觉得我只做语法糖呢
直接把对象,当成共享了构造期局部变量的多函数,不香吗?
duangsuse, [2023/10/17 19:45]
这种语法的文件级包含:
也没有流控什么的,还是相对好学的
duangsuse, [2023/10/17 19:55]
涉及非常复杂的比较, 但总之,绝句不是一种OOP 或C-like语言
我上面说了,Wait: 是支持返回值的
只是它 await() 的方法是隐转
在Wait{}块内,是一个以回调为this的函数
duangsuse, [2023/10/17 20:17]
那绝句也有函续作为值啊
OOP 就是缺乏这种东西,才搞出 Factory
Rust都没有办法简洁地“分支出”新数据
Kt在设计 inner class 时可以稍微思考一下,把它做成一种 ext fun
这就要看价值观了。
- 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 *] ] 传递取消阻塞线程的contduangsuse, [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() - mainduangsuse, [2023/10/17 20:24]
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)
OOP 就是缺乏这种东西,才搞出 Factory
Rust都没有办法简洁地“分支出”新数据
Kt在设计 inner class 时可以稍微思考一下,把它做成一种 ext fun
Liaoxuefeng
使用Future
小白的零基础Java教程,从入门到顶级架构师!
duangsuse, [2023/10/17 20:36]
是的。比如
就像
Kotlin 的写法:
这个 ''typealias 也不是乱加的
就像 'AB'KV,
背后是有体系的
单位类型、from/to 转换、单组/多组/多种 类型,正好能适配序列化器的创建
Int就被视为单组var
User是多组
Any是多种
'' 这么省是方便移植公式
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一致
- and not
xor就是xor, shl8 是
这样,拼接8bit 的算法可写为
#FP 读了一篇文章
🤔 剩下两章不看了。 其实绝句的fn{}{}: 比任何语言(比如,do记法)都适合写Functor, 而
如果用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 没副作用,这么做也不算,它只是替调栈做一次模式匹配而已。
是的。比如
水豚 可以从 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(duangsuse, [2023/10/17 20:55]
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)
''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 没副作用,这么做也不算,它只是替调栈做一次模式匹配而已。
llh911001.gitbooks.io
第 10 章: Applicative Functor · 函数式编程指北
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/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]
对于既有的理论, 确实有「懂不懂」的说法
但对于解决某种(根源问题)的方法, 就只要有不同的观点,就这
Telegram
duangsuse in Kotlin CN
虽然我不懂线代, 但我讨厌没有模型和可视化,就在解题的一些人
我历来反对强调问题复杂的理论。那是与PLT和计算工具相悖的价值观;持有这种思想,学什么都会泯然众人,
“无非是自己搜到资料的多少,决定了问题复杂与简单”, 像这样的缝合不应称为理论。
只要我还碰电脑一天,我就会去用工程的语言消灭这些理论,就像python做的那样
无所谓好不好玩。 shadertoy.com 的DSP才好玩呢
我历来反对强调问题复杂的理论。那是与PLT和计算工具相悖的价值观;持有这种思想,学什么都会泯然众人,
“无非是自己搜到资料的多少,决定了问题复杂与简单”, 像这样的缝合不应称为理论。
只要我还碰电脑一天,我就会去用工程的语言消灭这些理论,就像python做的那样
无所谓好不好玩。 shadertoy.com 的DSP才好玩呢
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
已经成熟几年了
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() 的
其实这个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 只负责加速
你也自己处理一点啊, 你这提的点子都是什么地狱灵感
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 只负责加速
Chrome for Developers
尝试使用 WebTransport - Chrome for Developers
WebTransport 是一种新的 API,提供低延迟、双向、客户端-服务器消息传递。了解有关其用例的更多信息,以及如何就实施的未来提供反馈。
Forwarded from dnaugsuz
>请用Kotlin KSP 实现为每个
AI完成的不好,但给了大体思路。请参照
-moshi 修复类同名例的生成
-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"
}
GitHub
Fix companion object names not being resolved by ZacSweers · Pull Request #549 · square/moshi
This slipped through the cracks before the release
Fixes #546
Fixes #546
>我就想拿来拼个变量,整的太费劲了
你要感谢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
AI不会,可能它会JS版的。
>请用 ES6
好吧,它不会。但基本上,可以这么写
你要感谢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'cr.openjdk.org
StringTemplate.Processor (Java SE 21 & JDK 21 [ad-hoc build])
declaration: module: java.base, package: java.lang, interface: StringTemplate, interface: Processor
#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
好用编程语言的标准,首先是好读
绝句有 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
- 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)不行
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]*Crafting Interpreters* 认为这可以简化REPL,但看IPython就知道这不是乱搞语法的理由
at A [
(1~9),.
]%[3 3]
A.T 矩阵转置就是[1, 4, 7]
x := [3, 4]; x := "奇怪的作用域“优化”";
def f(x, y, z):一些人可能知道 for x,y in itertools.product(xs,ys),不过绝句从语法层面解决了这个
print(x + y + z)
for x in xs:
for y in ys:...
xs:[x] ys:[y] zs:[z]漂亮吗? 还停留在for if的语言可做不到这种直白度
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
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)不行
blog.vero.site
Designing a Programming Language to Speedrun Advent of Code
“shouldn’t this have been published a few months ago?” yeah, probably. I even considered submitting it to the AoC contest. time is a real beast.
The title is clickbait. I did not design and implement a programming language for the sole or even primary purpose…
The title is clickbait. I did not design and implement a programming language for the sole or even primary purpose…
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.
4.Vue等框架就是为表现力诞生的,所以我觉得语言层面,最主要还是有扩展性
这方面Lisp系绝对是反例,而Go的泛型和err,nil都很糟糕。 仅仅是语法简单或简短,不能掩盖框架性的缺失
5.可以预先学习jspy等实用语言,再把Excel,脚本精灵等通俗软件的需求场景,泛化到不同语言(SQL,FP,.)的差异
专业软件一定是对的,它们比黑框框白页页们多经过几十万人的筛选,而且有钱可赚
6. Visitor 在 import ast 里作为 NodeTransformer 存在,只是因为static语言不能
同样, window.TreeWalker 是一种用途还不如RegExp grep或glob多的工具
多态(multi-typed) 是js极少的一个缺口,哪怕py对模板abc class的生态都好很多
考虑到Android小白会把 Listener override+super 而非
我觉得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的本质只能是接口
2.FP是OOP的子集。 对象是共用构造期局部的「多方法」函数,而 class{open fun} 就是另一种默认参数
只要把对象视为1~3个主要方法,就能推理出其构造参数;只要说闭包=对象,就能明白JS为何把函数当构造器(原型链只是一种不变量外提)
这再次证明了,Object 是个包含无限大,意义无限少的 abstract nonsense ,暴露构造期细节、不易扩展fun 是语言设计者低能的表现
比如Builder吧,它无非是把局部的全面赋值,绑到堆对象,从而弥补了默认参数(复用)
3. Optional,Result 是FP的潮流败笔,Rust的?和kt!! 甚至语义相反。 除了Kotlin “悲伤路径语法”都可以说是编程界的耻辱
在我看来呢,除了
4. filtermap 就是 select where ,根本不必提名字或it,只要运算符和函数平权,
就像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.
并不存在那么多 asXXX XXAdapter ,更不用说 Int.plus(:莫名其妙的宽化重载) 和 IntArray, Stream$Int 这些模板类了
7.ADT
enum和模式匹配暗示了多态data不能有名字,这是幼稚的断言,会导致理论与实用时的割裂,而且难以被接口化
OOP在这方面的语法烂但经验极为先进。 ADT,record和trait的自由扩展写法一致,可以隐this而非复制粘贴元组, enum可以用static实现
在类型基础上,FP玩的更花,但那却只是因为它们处理的最简状况太简单。 实际上,一些简短的语法,会随着程序的扩大而轻松被割裂,让你熬一整晚去重构简化
#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 Column3.编程语言的静态类型,对沟通很重要,因为类型算是最廉价但全面的“示例代码”
User'name nickname birth'(_:Str, birth \: Date) //歪嘴表情
copied user.as() :.
-birthday Date(1997, 12, 17) //bash格式的apply{}
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过度泛化的Animal,会导致funnyID无法被重用,这就是Adapter爆炸的元凶,是OOP的原罪
name Str
- funnyID askGPT(name..)
Cat()
Dog(owner:Str)
Animal()
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玩的更花,但那却只是因为它们处理的最简状况太简单。 实际上,一些简短的语法,会随着程序的扩大而轻松被割裂,让你熬一整晚去重构简化
Jason5Lee Personal Blog
My Views on Programming Languages
There are many debates about the good and bad aspects of programming languages, and I will present my own viewpoints in this blog. I will also explain the keys to learning a programming language, and
#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?
Cookie或者说Handle,是一个限时RPC对象,ORM就是为了方便外套一层RPC数据验证。
不过是为了换个方式用Excel,做一些人类语言能描述的列表处理,学习了多少可笑的语法…… 甚至函数式在zip,chunk这些模式上也并非统一的
bash也不免是像 py fire 或pwsh里说的,是
它们在数据和算法上,都一样,但不少人还为了
YAML,HTTP,SQL Schema 和编程语言的struct,又有什么差异呢? 带来这些割裂,是因为编程生态圈缺时间没精力吗?
而那些用途不明的虚拟机和-O3,就是“形式语言”程序员,比业余创作者牛逼的?
Python不过是做了JSON的超集,带点简洁的布局,就让科学界用电脑做了很多有意义的事,一些只有“渐进式设计” “交互式编程”能做到的。 这并不是理论或设计模式,打败程序员的,往往不是同行,反而是跨界
既然整个Web,都可以导入为class: def ,那么前端呢?
React高等的useMemo和useEffect(x=>, [x]),Vue的html for模板 ,其实都导向一个结果:
你觉得let[]=[], ()=> 和HTML组件、视图绑定有何关系? 其实React团队们拼命追求的水合、性能优化,大概就是
JS曾经的回调地狱,也是靠 yield, await 实现单Thread多任务来解决。最终还是自己造了一个OS内核啊
同样,try{}catch{} 和 0||"default" 无法统一地被默认、被链式调用,也暴露出了Error并不是一种null值。 十万美元错误,就是因为null不被视为错误造成的
稍微给知识查个重,就会发现其实不需要学习什么,因为现代编程语言和lib的设计是一摊拖泥带水的遮羞布,连错误都是抄来的,当然会落在地上呗
只要肯花时间探索,道路会不断延伸
#sql JS里这种查询的合理写法是
https://gitee.com/Tencent/APIJSON#apiauto-展示-apijson
是这种的
比较搭配BATE都有的0代码 CRUD
虽然用途上就像 sklearn vs pytorch 十分尴尬, graphql 式语法还是应学习的
感觉编程和设计小白用低代码也写不好的
—
我的编程范式,还轮不到一个在当跨平台复读机和CtrlCV家,却自以为懂一切的人评论
你真的不在乎那些纸上的「好看」吗? 我看你,只是执着于把好看供奉起来,避免与实际用途有交集
在我眼里编程语言不过是写法框架的外沿, 写出的任何代码都要有应用层定义力。因为语言本来就是用于交流记录的
学着把最简示例+心智模型明着说拆着说,许多难度都是浮云。 所有的思考和语言技巧,都不是通过语法和filtermap 这些术语传达到的,而是跨越软件的惯用法
如果只是为了做脚本而写程序,GPT反而更合适吧,那样无论做什么都不需要搜文档
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反而更合适吧,那样无论做什么都不需要搜文档
Gitee
腾讯开源/APIJSON
🏆 零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构
#sql #ts 你试试把 Boolean 表达式作为主力,能不能写出typescript checker
真假和逻辑是不一样的,
保留bool变量毫无意义,只有作为函数有意义
关系式和函数式,如果语法都好的话差别不大,只是前者是原生支持模式匹配
vs
包括SQL JOIN
当然,关系式SAT还支持||回溯,相当于DFS
函数式想模拟DFS就不好写了,比如说 0+1 关系
那么
解释下
如果静态检查只是找
看起来很高端,也就那样。
真假和逻辑是不一样的,
x=1|x=2 能得到x=1|2 而真假值算不出这些保留bool变量毫无意义,只有作为函数有意义
User(x), x.name=Jack, sort(x.id), [x]如果Prolog更人性化一点,就是更好的SQL
关系式和函数式,如果语法都好的话差别不大,只是前者是原生支持模式匹配
(0~9):[a] nums:[b] "a={a} b={b}" vs
in(a, 0,9) in(b, nums) ret="a={a} b={b}" 包括SQL JOIN
当然,关系式SAT还支持||回溯,相当于DFS
函数式想模拟DFS就不好写了,比如说 0+1 关系
[Add 1 0]=ret
Add
|[a 0] a
|[a b+1] [Add a+1 b] 那么
[Add x 0]=1 {x:1}
[Add x y]=1 {x1y0} {x0y1}
总之,函数式的(=) 不满足交换律,只是一种命名,而关系式里(=)和加减法是平等的解释下
x0y1是通过
[Add a1 b0]=1 推理的,非常绕但是可以用流过滤实现 https://minikanren.org/#:~:text=veneer如果静态检查只是找
numOp(int,int, ret=int) 的重载,那其实就是 SQL Select。但一般的FP语言,是可以完全只写参数名(buildList{add} ,.) 也没有泛型之类的限制看起来很高端,也就那样。
#java #backend #design
>用 jvm bcel 生成
int 要扩充到对int,char
Fn1要扩充到 Fn3
kotlin 2空格 减少变量名
🤔 我看生成构造器和方法签名还挺简单的
不过此例也不涉及 this.x=arg0
你试试让AI写becl 它应该能基于getClass()反射生成Builder
主要是感觉jvm 一定要dump bytecode,有点太做作了,因为jvm是有Compiler() API的
明明把源码放 thymeleaf for if 一下,def()参数列表随便换行也能生成吧,这样就0依赖了
这种元编程如果AI也能好好完成, 也是只要能用就行,闲下来的时间可以多设计些语法, BECL这些技术 好像也不如cglib.Enhancer 的头尾hook流行了
老实说如果Kt有Zig那样的 comptime foreach 和TS的 type dict ,Builder就不是问题 。当然这就是 lisp 系的 (unquote '(+ "x" 1)) 宏了
按道理来说JS里不是魔法的Proxy重载 o.xx 运算符,Java也是没什么的,但是Javaer们反射序列化的搞得太复杂了,或者说编译期API的贫瘠导致了「两门语言问题」
Zig的设计当时让我眼前一亮。 虽然它不像D支持enum作为dict type ,但Zig的 println! 比 Rust 说的宏还好用
Kt实现默认重载的方法像Ruby一样,没有反射接口,不过把 fun 提升为class 就能知道默认值了(虽然这需要改变框架……
这点.NET的 dnSpy 也能做到,因为bc本质上就是 List<元组enum> 的bytes形式 ,编辑它最本质的做法就是 mmap() 文件到内存,然后绑定数组增长,0拷贝
不过无论语言,目前都没有能把read-write 统一起来的fmt IO lib ,JDK的R/Wer 流模式都是一式两份的
直接用msgpack管理加载保存二进制,倒是能避免冗余
但,它们都不是二进制格式的绑定框架。 其实绑定bytes列表和DOM树所用的模式还是一样的, 这点 010 Editor 这个闭源十六进制编辑器,反而清醒得多
Radare2 也是支持编辑javabc格式 ,所以lib的质量不是看语言,还是要看人、看思想
这么评价也是有点道理的。 函数式data构造API ,都是helloworld 很美观很易懂,但对接实际就拉垮了
比如 import struct 的
不就是因为 序列化struct的模型 本质上和C的 unsized 数组一样,都忽略了重要的文件结构信息吗?
不就是不想独立出 malloc() 对象,想只复制参数到新bytes() ,结果只要修改个变量,代码可读性就炸了,工程难度飙到需要Protobuf 这些DSL玩意
其实只要让read/write 都作用到同一颗对象树,绑定一下,就不需要拿局部变量写什么RW流了
React就是这样被后来者取代的
>用 jvm bcel 生成
class T{ static int intFn1(char _0) { return 0; }} int 要扩充到对int,char
Fn1要扩充到 Fn3
kotlin 2空格 减少变量名
ClassGen cg = new ClassGen("T", "java.lang.Object", "T.java", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC, Type.INT, new Type[] { Type.CHAR }, new String[] { "_0" }, "intFn3", "T", il=new InstructionList(), cg.getConstantPool());
il.append(InstructionFactory.createReturn(Type.INT));
mg.setMaxStack();
// 创建一个对应于方法的MethodGen对象
cg.addMethod(mg.getMethod());
cg.getJavaClass().dump("T.class"); 🤔 我看生成构造器和方法签名还挺简单的
不过此例也不涉及 this.x=arg0
你试试让AI写becl 它应该能基于getClass()反射生成Builder
主要是感觉jvm 一定要dump bytecode,有点太做作了,因为jvm是有Compiler() API的
明明把源码放 thymeleaf for if 一下,def()参数列表随便换行也能生成吧,这样就0依赖了
这种元编程如果AI也能好好完成, 也是只要能用就行,闲下来的时间可以多设计些语法, BECL这些技术 好像也不如cglib.Enhancer 的头尾hook流行了
老实说如果Kt有Zig那样的 comptime foreach 和TS的 type dict ,Builder就不是问题 。当然这就是 lisp 系的 (unquote '(+ "x" 1)) 宏了
按道理来说JS里不是魔法的Proxy重载 o.xx 运算符,Java也是没什么的,但是Javaer们反射序列化的搞得太复杂了,或者说编译期API的贫瘠导致了「两门语言问题」
Zig的设计当时让我眼前一亮。 虽然它不像D支持enum作为dict type ,但Zig的 println! 比 Rust 说的宏还好用
Kt实现默认重载的方法像Ruby一样,没有反射接口,不过把 fun 提升为class 就能知道默认值了(虽然这需要改变框架……
这点.NET的 dnSpy 也能做到,因为bc本质上就是 List<元组enum> 的bytes形式 ,编辑它最本质的做法就是 mmap() 文件到内存,然后绑定数组增长,0拷贝
不过无论语言,目前都没有能把read-write 统一起来的fmt IO lib ,JDK的R/Wer 流模式都是一式两份的
直接用msgpack管理加载保存二进制,倒是能避免冗余
但,它们都不是二进制格式的绑定框架。 其实绑定bytes列表和DOM树所用的模式还是一样的, 这点 010 Editor 这个闭源十六进制编辑器,反而清醒得多
Radare2 也是支持编辑javabc格式 ,所以lib的质量不是看语言,还是要看人、看思想
这么评价也是有点道理的。 函数式data构造API ,都是helloworld 很美观很易懂,但对接实际就拉垮了
比如 import struct 的
pack("I", 0xff) 读取导出(u32,) 吧,你parse一个wav 数组的shape很易懂,但仅仅是拼接下 乃至改个序列号 就要从0写入整个文件流不就是因为 序列化struct的模型 本质上和C的 unsized 数组一样,都忽略了重要的文件结构信息吗?
不就是不想独立出 malloc() 对象,想只复制参数到新bytes() ,结果只要修改个变量,代码可读性就炸了,工程难度飙到需要Protobuf 这些DSL玩意
其实只要让read/write 都作用到同一颗对象树,绑定一下,就不需要拿局部变量写什么RW流了
React就是这样被后来者取代的
kristoff.it
What is Zig's Comptime?
Let's take a quick look at what compile-time execution looks like in Zig.
duangsuse, [2023/12/31 10:29]
Kt有规范的async{}异步啊
Blocking 是占用1Thread完成耗时操作,这样是不用suspend的, 因为没有线程上文切换
另外,inline fun 自动支持异步
duangsuse, [2023/12/31 10:30]
可能是语法上的限制,因为suspend需要一个返回状态机参数
duangsuse, [2023/12/31 10:33]
Kt的无栈coro不会返回东西,是通过传回调,async ES6会返回
用inline fun 可以异步
如果都要用Task取代Thread了,性能其实不用太执着,因为真正的瓶颈是并行
duangsuse, [2023/12/31 10:48]
所以你的问题就是await 的传染性呗,在kt目前无解,因为需要把Thread当单核CPU来调度
https://stackoverflow.com/a/69462100
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
但是Loom虚拟线程 好像可以用了,这样f是否异步都可以suspend
duangsuse, [2023/12/31 10:49]
ES6 是弱类型,很难隐藏await(如果引擎不支持虚拟线程的话),不过Kt这么做其实就有点迂腐了, 因为 async 与否都不影响程序语意的
只能说被业界带偏了
duangsuse, [2023/12/31 10:51]
与之相比,Linux 的 sleep() 和 fork() 就是很好的协程实现,跨CPU调度,但完全没有干涉到C语言标准库。 DOM的全异步就更天才了,直接封装掉了并发问题,还提供监控所有fetch() 的F12
反观最近支持async的语言,因为java stdlib 会卡栈就要手动new一大堆有的没的,理论还没Lua,Ruby强 ,可以说只有设计错误是原创……
Kt有规范的async{}异步啊
Blocking 是占用1Thread完成耗时操作,这样是不用suspend的, 因为没有线程上文切换
另外,inline fun 自动支持异步
duangsuse, [2023/12/31 10:30]
可能是语法上的限制,因为suspend需要一个返回状态机参数
duangsuse, [2023/12/31 10:33]
Kt的无栈coro不会返回东西,是通过传回调,async ES6会返回
用inline fun 可以异步
如果都要用Task取代Thread了,性能其实不用太执着,因为真正的瓶颈是并行
duangsuse, [2023/12/31 10:48]
所以你的问题就是await 的传染性呗,在kt目前无解,因为需要把Thread当单核CPU来调度
https://stackoverflow.com/a/69462100
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
但是Loom虚拟线程 好像可以用了,这样f是否异步都可以suspend
duangsuse, [2023/12/31 10:49]
ES6 是弱类型,很难隐藏await(如果引擎不支持虚拟线程的话),不过Kt这么做其实就有点迂腐了, 因为 async 与否都不影响程序语意的
只能说被业界带偏了
duangsuse, [2023/12/31 10:51]
与之相比,Linux 的 sleep() 和 fork() 就是很好的协程实现,跨CPU调度,但完全没有干涉到C语言标准库。 DOM的全异步就更天才了,直接封装掉了并发问题,还提供监控所有fetch() 的F12
反观最近支持async的语言,因为java stdlib 会卡栈就要手动new一大堆有的没的,理论还没Lua,Ruby强 ,可以说只有设计错误是原创……
Stack Overflow
Are Kotlin coroutines colored?
Somewhat famous article about state of asynchronous programming model of many languages, states that they have a "color" problem, which, in particular, divides the ecosystem into two sepe...