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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
举例, #ts 上有”交并集类型“ (有人认为 hs, Rust 没有子类型所以不存在集合论的,确实如此但 in-out 形变是Racket子语言里也有的,我找不到原文但TRack 是有) (我一点也不羡慕没有重载和this模块等多态技术的圆括号 😅, 模型的缺失是拿宏手动兼容 a.b.c 所弥补不了的, 就像 F# 的 |> 比不上 xx.let{}, kt 的元组 destruct 比不上 ES6 let[x,y]=P, ES6的解构又不如 Prolog 的 unify [x,1]=[2,y]...…
#FP Prolog 和 Racket 一样都有严重的语法缺陷:没有真正的等号,语法一致性也很差;也就比 #SQL 好了
或许 Lisp 的嵌套链表很”统一“,但统一并不等于简单而一致

number(X) 就是 X=num() 的意思,很多算式本该有”一个值“,而不是为了”X=1 返回 [{X:1}]“ 就放弃简化
Res 变量应该被掩盖掉,就像Go等所有现代语言都抛弃了 struct*, char**

那样👆e(X) 就可以不用”宏“ 或 Monad 来实现隐式参数,化简3参数的 S=X+R, "2x"==2+'x' , 直接 num=[S,X,R] 就能被 repeat() 修饰了, num=["12a",X] 优于 phrase(num(X), "12","a")

(话说 hs 也真是垃圾🙉 连伪递归纯函数 都强制化了,却仍然不能求解出 x+[2,3]=[1,2,3] ?? 递归再回溯,不就是为了方便DFS吗?

确实 inc1(x)=2 可能需要闭包和重载,所以我说圆括号很垃圾,因为不够”广义“的等号,和那些扭来扭去的数学希腊字或者VB,PHP一样

🥰我最爱的方向是:
- 定义式/py,rb,元编程,跨平台接口
- 关系式/模式匹配,读写转化,typing知识
- 响应式/Vue ,await和协程, 编程时所见即所得
- 跨领域/基于物理,OS,libc 等根源问题的搜索习惯
duangsuse::Echo
#tech #recommend #js 🧐从『函数』的定义就能知道,#编程范式 的发展史 👉 地址symbol、子程序void()、对象 SAM object、算式 x=>y 或文档树、 模式查询select [a b], a=1|a=2 : x86无结构:是弱检查指针、面条流控、256项字符集,定长数组,栈分配,加载到内核mmap(rwx..不能为READ 段错误) 是dll内地址 C过程式:是向调用栈赋值后跳过去等返回,是子程序 C#OOP:捕获了局部变量(cellvar,可变)、原型虚表到t…
#py 周刊

- Excel 支持 import pandas, statsmodels, matplotlib / seaborn 了, Guido 亲自推广(可能是云计算,要订阅)
- PowerToys添加“可交互”的截图
- Google 等各种大公司的技术blog #list
- #apple #design 设计师法则
- #learn 看美军的脏话官话(F-words)学英语 。

- 单靠 #sql 如何保存数据
- APL 里有的 py 基本列表处理式
- FastAPI 最佳实践 list
- async stdlib: 对比理解各种流行实现

- fixit linter: py 版本的 IDEA 自动迁移 (无AI), cffi: 我用什么 C parser 链接到.h 文件
- 用 difflib 开发一个文件比较工具
- KeymouseGo, ahkunwrapped py : 类似按键精灵的鼠标键盘录制和自动化操作
- quivr:生成式 AI 打造你的第二大脑, trafilatura: GUI 文本/评论 爬虫
检索非结构化的信息,可以理解成支持人工智能的 Obsidian。可以处理各种形式的文件如文本、图片、代码、音频和视频等,依赖于 ChatGPT、Docker、Supabase

- FastAPI + SSE new EventSource('/http流') API 下发文本消息
- 用py编写代码高亮图片生成 (carbon.now.sh ..)
- Streamlit 地图高亮生成
- Streamlit GPT4文件摘要工具

- Mojo #ai #rust: 对Py的渐强类型&优化 的语法改进 [waitlist]
def mandelbrot_0(c: ComplexFloat64) -> Int: #CPU FMA优化, 1Mojo = 15Numpy = 89CPy
z = c, nv = 0
for i in range(1, 200): #清晰度
if abs(z) > 2: break
z = z*z + c
nv += 1
return nv

👀 Rust 确实是资本的语言,融资1亿刀乐

#code #algorithm 埃氏素数筛
def gen_primes():
"""Generate an infinite sequence of prime numbers."""
D = {}
q = 2
while True:
if q not in D: D[q * q] = [q];yield q
else:
for p in D[q]: D.setdefault(p + q, []).append(p)
del D[q]
q += 1
duangsuse::Echo
#sql #ts Prolog 牛逼! 正确的关系式搜索+ 同时实现 parse 和 toStr 😱 #zhihu 灵感来源 e(E) -->{E = [I,Ea,Eb]}, %重写规则, 'eX'为优先级 %利用 链|e1(E) 括住内"*/" e1(Ea), op(I,"+-"), e(Eb); e1(E). e1(E) -->{E = [I,Ea,Eb]}, e2(Ea), op(I," */"), e1(Eb); e2(E). e2(X) --> number(X); ("(",…
#PLT #sql https://zhuanlan.zhihu.com/p/646479383

Z3-SMT 是SAT(可行性求解器)的增强版,即一种sympy 。比Prolog更擅长解数值,甚至能解数独(迫真 ,解决cargo的依赖版本(原神

from z3 import *
A, B, C = Bools('A B C')
# 创建一个求解器
s = Solver()

# 添加约束条件
s.add(Or(And(A, B), And(Not(A), C)))
# 检查是否存在解
if s.check() == sat:


Z3的API这么复杂,又要add check 又.model的, 不如和Keras做个联动,支持机器学习+逻辑编程好了。 哦,原来 state.add(x==1) 只能执行1次 不是flowgraph啊?
这API还真挺Pythonic
这种问题貌似Prolog不用限定类型都能解。 定义 Bool(A) 无非是为了重载,那And(bools) 有啥别的语意-即搜索范围呢? 强类型逻辑式编程?好奇怪的搭配


稍微对比几个同类项,都不会这么白象化逻辑式编程


#zhihu 上看到一些逆天观念,C的设计错误:

1:单返回值这个设计可能是受了数学上的f(x,y...)的影响
真的需要多返回值的时候,C就只能用指针搪塞一下了
2:连续不等式
如果 a > b > c, 则……
3: void不是类型

1. Go就支持func (ret, err) 。所以不仅调用难以组合,Err体系也给弄成错的,因为err!=nil时函数不可能有值
2. 写成 (a > b > c) 还是 (a>=x>=c) & (a~b)(x) ? 过了这个村, for(x) 和 x inbounds range 就不可能一致了
3. 数学没有void,所以我赞成省略类型=void

还有一些不逆天的C错误:

"\0" 不是数组,argv无法单作为值
赋值是表达式,而且允许
for(;b-c;) c+ --b; b--;//c+b-1, b-=2
强制转换语法 (T)+xx、类型前置,这个的影响非常深远,带来的麻烦无穷无尽
if, while, for 的小括号和大括号,switch break
for (i = 1; i <= 10; i++) ,这个 (1~10):[i] 也很毒瘤了
#learn #bash with #tool 入门+优质冷知识 😋
图为 asciinema.org/explore 。没有 #linux 的极客可打开 WebVM.io
Linux Deploy; (Mac)Git Bash; winetricks; screenfetch 甚至 bashttpd; pacman/OpenRC init 基于bash

shell 是类似 Windows.ps1 但使用纯文本或行IO的脚本编程语言。 每当你看见awk|sed|grep ,那就是在 #sql select访问属性、文本替换、where过滤了
Dijkstra说,用BASIC编程的人“脑子已经坏了”,作为运维你要尽力避免这一点。用AI写命令思路也是要正确! 😨

因此在思考时,你应当用pwsh的API模型: Get-Date|select Year; dir|?{$_.CreationTime.Year -lt 2024} ,而不止是 date '+%Y' ; find . -maxdepth 1 -type f -not -newerct 2023.12.31
更不是 网关=ip r|awk '{print $3}' 这样的糟粕

— 快捷键 (bind -p|grep '"\\C')
⬆️⬇️滚动历史, Alt/Fn⬅️➡️ 跳词/跳行,Tab补齐, ls \ mydir 或fc:多行命令
nl $HISTFILE|tac|less 默认保留500条可清空
^=Ctrl, M=Alt e=ESC
^M T 打开cmd窗口 ^L清屏 ^D退出
!cd 执行最近1次cd开头的命令, sudo !! 补齐为上一条命令
touch a; ls $_
#操作同一个文件
^a^b 改参数重执行

^U ^Y 剪切和粘贴行,nano同款
*.mp4 ^xg #查看符合正择的文件,免ls|grep
^A# ^E# 意为正则/^$/。script录制时(例如 history 3) 添加注释

^M F1~F6 一般含几个tty串口,通过 echo>/dev/tty2 即w;write,您可以装得像电脑有第二个人在用一样 还需要协作 😅
橘橘橘子汁 & 🍊
https://zhuanlan.zhihu.com/p/707493606 虽然确实是可行的但是这是什么玩意😇
#您知道吗#cs #dnn #wasm 计科长青树一瞥:递归下降、梯度下降 (1)

*编程的赞歌就是(组合compose)的赞歌,软工的伟大就是(复用reuse)的伟大!*
复用就是腾讯嘛!但,什么是组合?流行乐队是组合?

在《几何原本》里有这样一条公理:“整体”是由部分构造堆上去的。 无论物理的原子分子、化学的单质单剂、生物的组织系统、儿童编程的二分查找,甚至您编写的{语句}(算式) 定义表(),总少不了分治算法的影子;而与递归对应得最直观的树,除了带kwarg的视图描述树XML、文件夹管理和正则匹配的前/后缀树Trie、OIer的必修KMP图(: Trie+FailGoto),更有梗图里常被实现为SortedSetOrMap的红黑树RBTree(: AVL) --作为按int KHash()预分组K-V查找的一种补充。

不过,今天咱调戏的不是高深的算法或数理化,而是程序员的自我修养:表达式、解释、编译、类型检查和推理。
🤓不少语法看似是ES6,Kotlin,Java20+,C++里高深莫测的新特性,其实,只是因为它们的设计混乱带来的大误会! 软件工程界的基岩,原本很简单?

- 计算器🧮("1+1"):数据值 是不支持forif或(vars)=>函数/JSON文档的解释器,最简单的理解是 x=1; eval[+,1]。对内存的利用方式过于单一,就像🔑C语言的.o .so 只是靠LD互调用的object{static{}},或者VB一代难加函数的"红石命令",毫无扩展性还要另写头文件 自然被淘汰
- 解释📠("expr(1+1)"):值或行为 程序员唯一必须调用的接口。tree-walk(递归遍历算式)非解释器的专利、VM不是编译器的秘技。对x86汇编的执行也叫硬件解释,旧安卓通过转译arm汇编.so库到x86做兼容,就像IKVM对“JVM汇编”仍能再次转译到IL
- 编译 就是解释器的缓存📑:记住自顶向下遍历时的套路,直接自底向上组装值(lisp转RPN),很像二叉树vs(堆,一种树状数组)!这除了要重新实现重复/判定/ret&&break跳转的流控,还可将RPN栈指令集优化为局部读写-按类型复用。
要求手动编译的语言均属慢速原型,会标注或推理出类型签名,从而🔑以限界实现提速和多态(重写重载、记住变量名的指针,即担保栈size恒定)。 ANTLR等“状态机”编译器的输出便是自底向上,正好颠倒于主动read()流到js栈的PEG,不过,它们其实是慢的虚拟机。

类型的本质是简洁的🔑常量「黑盒测试」,它与表达式同构,执行方法也相同!
- 类型检查 就是只解释 def f(x:T):R 里":右侧"的算式,以插入 (f T R) 这样的SQL行。x编译后是arg[0]:一个空悬指针,但T.fns却是有血有肉的"反射"常量。把每个 x:T=1 换为 x=T!
x+x 的语意为查询 (+ T T)、1+"" 查找函数签名 (+ int str)、 u.id (.id User Ret?) 便能检查误拼写和空指针
不难发现,这些都是效仿numpy重载个运算符就能实现的,并不需要学编译原理写解析器!这也是 hamcrest.org http Test库断言组合器的原理

泛型class/fn/var和赋值 的推理规则是一样的。
例如把 <TR> as([Box, T], T=>R):R 与 as(Box(1), str) 深度重合时,新建两个TypeVar(void),它们会在 Int==T, R==str 的检查时被向上赋值,从而填充[Box,int]里的类型T、as调用里的R,并照顾到 i32->i64等转换及子类规则
同为编译期遍历,你还可以思考下 let[x0,x1]=a 如何被实现的,以及在运行期是否能模拟?

学习元编程有何好处🌝?因为可以从根源理解yield/await、纯函数、模式匹配、模板宏等“新”特性,凭什么能简化旧实践!
- 闭包和协程closure&coro 便是编译比解释好实现的两个特性。 compiler 通过{let;}的动态作用域(原型链..) 区分符号的LEGB来源(Local Enclosed外层局部 Global Builtin常量),从而能把 (x=>y=>x+y) 化为对象值 f_y=((x,y)=>).bind(x);Lua能查出跳转到表达式的指针,y=yield x 便能在return前,把函数的局部栈保存回 g.next/pr.then
- 模板constexpr 让闭包关于常量创建,如何? ((x,y)=>x+y).bind(1) 就是 1+y, ((k,s)=>s[read+k]() ).bind("Int") 就是readInt,*[map(print,0~9)] 就是循环展开,这些就是预处理的价值!反射和const只是对eval(并缓存)之「二段求值」的阉割
- 副作用effects #FP bros异常抨击print这种“无法被值存储的、有非局部干扰的赋值”并推广他们的赎罪券:Monad……这却是因为他们并不懂「定义式编程」!
React signal(x=0) (1) 就是一个不纯的赋值,但,它导致的x=1却能被广播为参数、被保存和复现!🔑这还能叫“状态变更泄露难题”么?
并且,它还偷走了"FP独有的模式匹配"。对赋值副作用的录制,更是bash,vimrc类格式经久不衰的原因

说准点,这些都是 #SQL 的老大Prolog所原创并推崇的-:变量作为值,逻辑式编程!
*整体大于局部;与另一结构重合的结构,之中的值相等 --几何原本*

在通读本文时,也可以参考以下实例:
coroutine=由用户run()的线程
*调用栈是数组,协程栈是回调构成的链表
诸分治排序可视化
手动babel脱糖一个async函数
知乎:分词解析vs解释
实现一个HTTP DSL
Var(signalObj)如何跨越进程和网络:句柄、登录cookie、JWT
def(): return this 是何方神圣?
在解释时缓存代码的Tk GUI
Trie们和字典输入法的实现
关于class Visitor {se(e:Add_AB), se(e:Int)} 和Eval/Dump接口的融合
实现文本流递归下降、四则运算逆波兰、 JSON.org
Prolog binop #parser
计科原神:认识WASM/LLVM IR和JIT, webVM.io
dnaugsuz
#java oop 面试题 https://www.bennyhuo.com/2023/08/29/new-book-metaprogramming/#more 哈哈😄,这个好玩 1.(final T)在Gradle里是开发规范,但和final var一样对性能无影响 凑字数 final class是常用法,有些人在使用了虚方法(=构造期传函数)时会对其他项打final,幸好kt里是非open var即封闭、不可变 2final的类名上变量支持常量折叠如 if(DEBUG) 3 JVM.utf16文本…
duangsuse:
nonlocal x=的那条? 总比在C++里到处[]() 或move||要好

大家都不知道闭包捕获引用这些,这首先就要把那些XXer 的SAM类变成函数,然后才有非局部赋值问题

java虽然总八股值和引用,但大家总是不重赋值或深拷贝
我举那个py的例子算是好的,因为py这个畜生是直接把局部创建的cell()给捕获了。。
for a[0] in range 是有效的,许多人搞不明白

duangsuse:
orm就是把class 带上where sort 绑定到sql TABLE
基本上还应该带pager

Spring负责把http路径转到类路径,绑定个函数签名

理论上,pgsql 应该直接回应http请求的😂
90%的代码不过是做鉴权这样的中间件AOP
这一切,都是从PHP和XMLHttpRequest开始
唉,万能http

所以说AOP啊,pre post一加
你看有多少不是纯CRUD

不少小公司和C#的都是直接调用sql函数,不用后端
结果最后还是让程序员充当aigc了是吧。。

那些代码看一眼都算码农啊。。
怎么能容忍90%都是跨端复制的逻辑呢?

你不写,他们也会以合规为由要求写
jpa难道不能和sql模板打配合?

graphql.io 好,百度也有个json ql叫啥 https://baidu.github.io/amis/zh-CN/components/crud?page=1
凑字数能力很强

#sql 可垃圾着呢,我还写过生成sql的查询语言 https://tttttt.me/dsuse/17740
读着自然?都是骗人的, SQsu 都比它更“人类”

select id from 狗 where (月龄>6 and 高>40);
aka 取狗(月龄>6 and 高>40)

正宗的关系式写法是:
狗(id,高,月龄), 月龄>6, 高>40

区区filterSort的模板不值得从ORM,CMS,低代码 这些里面分出个后端开发来
http路径就是类路径,类结构就是方便转码和校验sql数据

绝大部分的app并不需要后端框架,只要pg支持http风格的sql语句和json化,加个鉴权分页什么的。
如果不是pg存储过程的语法垃圾没类库,它就登顶了

#haha #bilibili
pg的存储函数没有类库,也不好 json io, java 才充当了这个协议转换垫片
因此许多SaaS对象存储都是NoSQL的,因为这种RPC架构冗余代码太多🌚

然而在EE程序员逆天才的智锐随变下,无论是生成xml或暴露路由表对象的服务器,绑定函数的方法都非常冗余, demo的匮乏程度更是让人叹为观止
甚至连五星逼格的rust都不禁这样评价:

它们好像连classpath就是URL模板的这回事都搞不清楚,方法签名绑定也做不好,还@什么原神数据来codegen😋
很牛逼吗?fastapi,django, 正常语言到处都在用,放javakt就是高手了,这是🐮逼还是装嫩?

完全无法理解MyBatis为什么比jpa流行,还煞有介事的搞面试题
一个 sql``${} 调用模板罢了
一个被专门做来AI生成的语言,那肯定是垃圾

甚至,ORM都是一种浪费,因为70%的字段根本不会被访问,只是复制到数据库,又复制回js或php式模板侧

连最基本的程数同构都没学过,compose 后才开始搞DSL,更谈何避免Header绑定和分页参数的重复、PUT DELETED POST三方法的多态融合,更别说理解http调用与sql、与bash命令行的同质了。

人家import fire可是0代码就能提供命令行,甚至colab UI。
java元编程能吗?逆天 才EE程序员没那个心智模型!🌝
#dalao https://www.kxxt.dev/blog/programming-thoughts/2022-04-16/
https://lutaonan.com/blog/code-artists/ #ai #dev 第二次提及了,不符合刻板印象的 #js👍
把 AI 当作是你的员工,就像某一天你突然只需要 $20 一个月就能招无数多愿意帮你打工的人,你很快就会发现,你最终会面临两种局面:

局面1:你将手足无措,你突然发现如果你不是实现函数的那个人,你就不知道你应该做什么了。从前你沾沾自喜的手写快排,手写红黑树突然变得一文不值,无处施展。
局面2:你将如虎添翼,你突然发现你曾经有很多想法没有精力和时间去实现,现在突然有这么多廉价劳动力将不厌其烦地帮你写代码

在这里我要申明,这篇文章我是写给有一定经验的程序员看的。对于没有什么经验的程序员,多写点代码总是好的
就像下面这个例子,我只要说一句 add tanstack query provider 就能让 AI 帮我把 @tanstack/query 加到我的程序里,但如果你没有任何代码经验,你连 query 是什么都不知道

#sql
https://github.com/duckdb/pg_duckdb
https://github.com/asg017/sqlite-vec
#asm C语言的变量符号
https://tttttt.me/kaedeharakazuha17/3548?comment=26435
https://evian-zhang.github.io/learn-assembly-on-Apple-Silicon-Mac/1-底层的整数.html
https://nan-archive.vercel.app/debugger
#bash
https://github.com/kxxt/tracexec?tab=readme-ov-file#origin
可是 stra execve 也可以
alias stra='strace --quiet=attach,exit -f -e "signal=!chld" -e'
duangsuse::Echo
#PLT #learn 文中提到一个Futa对应关系(第一类二村映射 first Futamura projection), 展开讲讲还蛮有趣 🙉 首先,js人都会写计算器的,和 echo input/server 一样的难度 1+2*3 十(1, X(2,3)) -7 十=(A,B)=>A+B 这被称为「前缀式polish notation」,是Lisp的国是 教个小诀窍:js里函数只是一种字面常量,可以被for生成 Object.entries("十一Xノ").forEach(([i,x])=> …
>火之魔女: 不过unification我是想写好久了(应该按年计)但是一直没写的(
https://github.com/duangsuse/mkey 写过,不过落后很久了 #sql

这算法就是 unify(a,b); unify(a,1); unify(1,a) 得出 a.v==1==b.v
reify([a]) 解引用一下=[1] ,其实也挺有趣,包括npm也在牵强附会这玩意,真让人搞不懂从哪看的

http://minikanren.org/ 使用了一个自有的def: yield 实现,对 a&b 顺序执行,a|b 保存a的回溯以及交替yield ,但 inf(a,x): a=x|inf(a,x+1) 这种递归好像要套一层

append-out 生成加法表是比较知名的范例 https://www.adamsolove.com/microScopeKanren/
https://tca.github.io/veneer/editor.html https://swish.swi-prolog.org/
https://tomstu.art/hello-declarative-world

logicalVars 的真正力量是用在AST里实现函数参数、类型参数及推理等等,比如 vars(x=> Fn([x], [x 1 +])
所谓的HOAS ... 还真挺搞笑的,PLT人怎么会用字符串表示变量??

可以在js里直接解释,也能被整齐替换为为 iload_0 之类的编译
也包括推理 fun let(:[T Box], :[Fn1 T R]): [R Box] 了, unify([T Box], [Int Box]) 一下就出来了,再给[(R=Any) Box]做一个freeze(reify),比模式匹配不知道优美多少倍

然并暖。 国内讲这个都都是局限于那几个术语和过程,真够无聊的。
unification(变-量叠合) 不是解方程的办法(不能取代sympy.solve),但React都在用它,只是在用一种很低性能的赝品(Svelte和Compose也是,快但丑)

PHP拼接SQL而不是用 (?)生成匿名函数, 一群PHD也这么搞,结果现在搞出个 AST v2,就“数学且高阶”了。指望这群人纠正IT界的错误实践? 呵
Prolog已经50岁了,Lisp计算图和深先遍历则更久远,它们的思想稍微补丁一点,就能对今天的编程产生巨大的改变。 只是把"变量"这个概念初次写对,就说是Higher-Order tree了,真幽默啊PLT
(Lua lparser.c 在第一遍历就会查好栈/闭包/全局表的具体地址,这是所谓“不理论”的算法人,人家的var最开始就不是str,更别说Ruby和C符号呢。 PLT人只是目标更简单,并非语意更明确!)

如果ES6支持模式匹配时直接把Prolog的变量作为值学过来,React就可以带着它随地大小变的"FP" memo消失了
full: https://tttttt.me/dsuses/5341
duangsuse::Echo
duangsuse: #读写线 #bin #FP #algorithm 1.所以我认为这种partial是错的,比如lexer吧,至少把Node的wsPre 保留下来-比如对注释文档,这样rust fmt/doc也会好写很多。 2.你举得例子太tricky了,而且JSON就不是一种minimal dynKV- 它有一大堆无效的;, 需要过滤 3.内存buf问题应该交给linux swap处理,而且用 fit(inoutT参数) 替代read():T 并不会阻止windowing 4.所以只要在pu…
#sb https://tttttt.me/im_RORIRI/16616
的作者 心理学博士 @losses_don ,就像 @drakeet 一样🥰

因为我谈了下"http 为什么变得只有POST方法有人用" ,解释到 #SQL 不能无方向IO的问题
(即,必须区分 select vs insert Into ,即便数据的结构完全一致! )
导致必须用双函数实现 /user/? 和 /user/new 两个业务,因此为RPC方便,选择支持body的POST; 而如果不使用返回值,只传入State('')或者说指针,就能利用到 HTTP Method 的语意 这回事

结合上次冲突(那是因为'二进制'parser冗余代码的问题)👆 居然把她整破防了🥰

>你还好吗? 这么久没回来发帖,这就不告而别,态度还真像“技术激进主义”的支持者呢?

另外,我是认真的。 我的所有批评,都是因为懂那些代码是什么东西,里面有哪些是“私货”,而且,我与你们不同,我以复杂性为耻,
那是表里如一地讨厌:旧的、新的、规范的、自己的,那些无意义的过度工程,而非作为一种精英主义、小圈子自嗨的资本。

当然,除了真正的ORM,逻辑式编程范式最好的地方还是可以省掉前端“响应式框架”

ww.Counter=({n=0})=>
div(fx{tap:n ((x,to)=>+x+1)},
input(n),
u(n)
)
https://tttttt.me/dsuse/19901

而它的唯一技巧就是用“回调变量”而非返回值,并且为list,when等数据类型支持这种成员

为什么如此玻璃心呢? Hz和我谈的挺好
不如等这些由同一种理论所驱动的框架发布的那天,你再来看看编程,是不是我说的这样。

🌚 大家可能觉得我在搞民科, CRUD Boy 都这么写(读写分2个函数实现),怎么可能有缺陷呢?

我反问一句: 你们听说过能「听」不能「说」,能「读」不能「写」的人类语言么?
我只知道英语是拼音语言,哈哈。(能听说就能读写)

js(json dump/load),sql ,这些编程语言所谓 v=readXX writeXX(v),其实都是这样的,而我设计的那个编程范式,愉快的副作用之一就是支持反函数。

我的理想就是让「编程」不那么机械,我觉得身为程序员应该为代码所独有的简明精巧而自豪!
并不是为算法、数学或几何的「应用」,而是我们所用的语言,有这些学科未曾意料的,独到的一面,实为软件工艺。 #statement

很可惜,就像罗翔说的那样,技巧学多啦,反而丧失人性。
🦄2
#china #sql #java #security #recommend
省流: fastjson 作者实现了前端都不能的 JSON.parse('{"__proto__":{"name":"FakeClass"}}') instanceof RealClass
它比JSer在类型检查上更 👈🤡

fastjson 窝槽, Ali 的架构师设计也真是逆天啊!! 2020的分析,今天才看到,狗屎程度堪比 antd 事件
Jackson 真是多亏同行衬托 😅 温高铁​还煞有介事在下面装无辜, 晒自己咋优化 Latin-1(8bit)+UTF8 转wchar(16b) 比赢JDK

# xx toJSONString : {"sale":{"price":0.5},"name":"Hollis"} 的类结构
.:
- Store-name-sale ["" IFruit]

.: IFruit
- Apple-price [0]
- Free

-xx Store "Hollis" (Apple 0.5)


这里有个问题, IFruit 其实是 sealed interface IfFruit{ Apple; Free } ,前者有"price":Int 后者没有field或setter,因此 parse<Store> ("{..}").sale as Apple 只能失败。

那 IFruit 凭啥能在无 backing field 的情况下被databind出来?new java.lang.reflect.Proxy ……😂 var by mapOf(); 没错,他搞笑呢,从性能和structure对应性上这都是fatal
那咋实现 OOP=封装+多态继承 呢? 通过严格定义的 sealed/enum ADT{} ?通过XML?都不是,他懂, Auto "@type"...
{
"@type":"com.hollis.lab.fastjson.test.Store",
"fruit":{
"@type":"com.hollis.lab.fastjson.test.Apple",
"price":0.5
},
"name":"Hollis"
}
// 正确做法
{"sale":{type: Apple, "price":0.5},"name":"Hollis"}
// Rust默认做法
name=Hollis
[sale]
Apple={price=0.5}

脚本引擎都弄出来了呀…… 这画风和js的JSON迥异,生硬如同 new WTF({kwarg:..})
于是计算器就出来了 {@type:com.sun.rowset.JdbcRowSetImpl, dataSourceName: "rmi://localhost:1099/Exploit"} ,数不清的注入点。
{"@type": "jdk.jfr.internal.JVM", "memorySize": 1} , {@type":"com.ibatis.sqlmap.engine.transaction.jta ... 变游乐场了

第一次知道这么脑洞打开的 workaround ,是把 List<*> =Any 泛型擦除当真理了吗, 真当子类多态就是一切皆Object 一切有@type呢, 其实那就是 enum { A(int) B(str) } 的特例而已!👈🤣
最搞的是JDK和这家伙一样喜欢玩魔法,开 1.2.25 blacklist 后 lazy(loadClass)("[Lcom.sun.rowset.JdbcRowSetImpl;") 等为方便ASM和反射也是合法类名,和温大佬异想天开的不一样, 修得和安卓 utf8_casefold 大小写合并bypass 一样弱智。真是不能期待他们在RCE 0day后,对OOP和json的强类型理解会有所反思,
因为直到 1.2.47 ,他都用类似 breakwa11 的黑名单「闭源」来防,拉黑算法还有bug…… 恕我直言,common sense 缺到有点好笑。 还@type呢, {"": "Apple"} 都是合法json,这不得快得废弃来?
(子类多态,var_a:T=b as T1 合法, Fn1<in T,out R> 就可以兼容赋值?super T ,override同理,这才叫懂八股..)

和log4j一样级别的。有时候我都好奇,在一个a[i]的 i±1 都绝对报错的代码世界,在try{return} 都会跳到finally{close..}的事务性严谨圈子里,在 sudo kill -9 随意但弱密码和Thread.stop不允许的稳健文化下,SQLi这种让WAF替你修的语意性混淆咋被容忍的。 弄得好像骇客们RCE进封闭系统如探囊取物,硬件主权全无效似的。
——
compile('select {}+1') (232) 是怎么能和 eval(f'{232}+1') 混为一谈的,代码和常量就这么拼接了?一个扁平一个嵌套分不清吗? 我 模仿JS元编程20行 INI.dumps() 都未曾设想的逆天类型观 ,这就像幻想「富文本」里会有 <script>、fetch() 会带站内cookie执行任意 curl 能做的事,真拿人html/DOM就瞎用,丢的岂止隐私?

唉,草台班子。 「你就说弹calc.exe快不快吧」
这不禁让我想到「一种游戏服务器RPC返回Object的方法」: 直接把0xcafababe..的对象指针传客户端。 😓你怎么验证那句柄是否有效,能够安全写入? set<usize> 还不如 map<int,usize> 快
如果客户端瞎JB暴力指向了admin密码上,或ROP覆盖了return“回调”的函数呢,你是否还记得 x=malloc(N) free(x) 为啥要对「整数x」严格限界、正确配对?

libc 和 Linux 防但防不住的,就是这种撒手掌柜啊 🤡
真是群爱等编译的脚本小子。 Talks
duangsuse::Echo
😓 最近头疼死了,自己都跟不上自己设计的进步。 就拿序列化为例,之前我用 TrimLits+Imp[T](TParam..) 模式,它这样编解码 Pair(A:str,B:int) .: Pair-A-B ["" 0] .: Pair static As: (Pair "" 0) #空可变实例 Types: {} #非sealed Tvars: ["A" "B"] Tr-it-key: key :. #重载 "A": it.A=fmt -Tr(it.A) "B": it.B=fmt…
一个设计者就是这样推倒、再来、再推导、再来…… 😓 #life #statement

幸好,这是最后几朵乌云了, 只需要解决RPC的基本规范, HOLP的整个强类型IO体系就可以移植给java那些能丰富简历的平台了,
这个优雅到能放在README上的算法,肯定是能吊打JavaKt一众「魔法版」序列化库(至少 Fastjson https://tttttt.me/dsuse/20186 😅😅😅

当然,HOLP 被设计为「语言之中的语言」。它本身有自己类似yaml+bash的语法,独立于电脑而存在,却又能联合OOP+FP+SQL的代码范式。 只不过依我的元编程写法,Trim*这些技巧仿佛背后并不存在一个体系……
如果以后您能见到一些漂亮的语法,那大概是HOLPful的节选和变体
-user {-id "Amy" -age 20}
-vs {.id="Amy", .age=20, }
pass user
if u.age>18 {}
or u.age>10 {}
or u.age<0 not {} --or{NO}

class {
-Pair(A,B){}
-Tri(A,B,C){}
}
-tbl Tri{
1,2,3,
'a','b','c',
{-[]Pair{666,233}}
}
tbl [3]A pairs [1]B==233
tbl [2]C=='c'

-f(x,) {x+1}
pass fsql"SELECT 1, 2" for(2,) { A+B } -- bash式参数!


我总是在闭关,看起来很闲,但做的就是这样的工作。 七年的积攒,只能是为了开创性的工作。

如果我家人稍微不粉红那么一点,我就不需要急功近利,可以耐心归纳,代码质量想必能突破一个个「单一用途」的桎梏。
其实他们才是最不爱国的,和某公子一样,只爱自己赢。
#sql #dontknow https://avi.im/blag/2024/sqlite-facts/

>It is maintained by three people. They don’t allow outside contributions.
CREATE TABLE t(value SPONGEBLOB) --- This is BLOB type!

最崩不住的一条语法无检查
最近设计一种跨语言ABI,很苦逼, 没啥灵感, 就评论点文章吧 🙉 #learn #sql #web #design

作者是DBMS的维护者。谈到面向表单+外键的数据库,应该说SQLite的质量很高,它不会是为了过度设计而做的东西,但内存数据库和今天广泛用于 Geo/Vec/全文搜索/timestamp 的Pg方向不同。
而王垠是我同行,他对SQL的观点是:必然要连ORM,Redis这些套子,还不如直接 new $KV_HashMap +loaddump 解决了,反正索引算法都是BTree二分查找嘛,像读写配置文件那样CRUD,比夸张的创造一种RPC协议又套一次要简单
我的态度是,SQL作为API的学习成本很不必要,但从就业率和persist部署一致性的角度-我们还能做什么呢?? LINQ/JSON查询 那样架空SQL是合理的,但对企业应用,还是该有DBaaS的搞法,就像 mount -t 文件系统 有很多竞争者

但是文内还有些我不顺眼的地方,吐槽下……

>肤浅至极,给大家展示什么叫隔行如隔山。

他山之石可以攻玉,DB和OS/PL都是在x86上执行,都是靠算法PGO,说的好像换个SQL语法就爆赞了

>“就是C的struct, 就是指针, 为什么不能RPC”

struct和Row在数据类型上有动静态差异,而且SQL就是基于/tmp/shm的第一个 C RPC

>使用基本的数据结构,其实可以完全的表示关系模型以及被它所“超越”的那些数据模型
<怼:webapp在乎Bw-Tree是怎么实现lock-free的吗?用C写完了请加上一个buffer pool,WAL,disk-backed B Tree,并且写上所有高并发

王垠不该批评SQL这个API被实现为怎么样,SQL明显提供了单app做不到的缓存和事务性安全
new $KV_HashMap +loaddump 很简单,对象存储API很简单,但那并不是DBMS,倒不如说它解决了JVM的性能问题,让人们专注于优化$http.json
曾经嵌入式开发存在一些XML数据库,它们就是干啥啥不行,和JSON存储一样

>只要你有一个程序语言,你就可以发送这语言的代码,到一个“数据服务器”。服务器接受并执行这代码,对数据进行索引,查询和重构,最后返回结果给客户端
>如果你看清了SQL的实质,就会发现这样的“过程式设计”,其实并不会损失SQL的“描述”能力
<恭喜您发明了Spark。但是这怎么解决写入的问题?

unquote为常量(JSON.dump) 啊,他就是在批评SQL过于冗长罢了,其实程序员的工作范围是比Excel操作员高端的,说实话。
SQL存储函数完全能实现Java的中介功能,只不过没有直接暴露:3323:5432到公网的全栈文化罢了,DBaaS只是独立小程序的选择,许多人UAC验证都没做

>数据库的问题哪有那么困难,它其实跟“远过程调用”(RPC)没什么两样
<RPC最著名的问题就是怎么在保证性能的情况下靠近"Exactly Once"的广播call,数据库集群是一定要”Exactly Once“

类似于TCP:发送到Kafka的每批消息将包含一个序列号,该序列号用于重复数据的删除。与TCP不同,序列号将被持久化存储topic中,重启不会影响去重

>数据库系统存储设计的本质是简化以及优化程序和外存储的互动。

IndexDB确实就是更简单的类型化FS,是使用各种存储缓存的另一种范式

>DRAM读写速度大约10-20倍于SSD, 对于HDD更加明显, 硬盘延迟是80倍左右,同一份数据,在读写过程中自然地有多份copy。单独的数据库系统进程的职责就是, 在这样的硬件环境下,保证性能并且保证不会丢失数据。
>数据库的操作在加上transaction以后自带了对于断电等情况的应对,需要相对应加强代码的理论模型
>停电,系统崩溃这种事情不是人能控制的。灾难可以在任何时候发生。就算每次读写都直接走硬盘,写入的操作并不是一次完成的,简单的fprintf()都会发生只改了前缀的情况

谈到冗余备份,就不得不说 Pg VACCUM 语句和各种 &is_deleted=0 了,把笼子删了屎山只会跑得到处都是

不过就缓存&一致性问题,Linux 主流的jfs/bcache即日志文件系统/CoW写前复制 解决的蛮好的,并没有ACID那么复杂
而且说实话,真有人在乎意外断电,缓冲区的数据能不能恢复?(最多是CoW那样冲突留旧) 实时系统和RAID也不敢说啊。 软件层面试图硬抗,很天真

>我写C的时候只告诉电脑要一个变量”int a“,不告诉它要存在内存的哪里,还是放在寄存器里,也不告诉它整数是什么,存几个字节,真是一个不切实际的妄想啊。
>这年头你的数据库不把SQL编译成汇编都不好意思出去和人打招呼。

王垠对SQL的批评是,它太难配置了: [].mapNotNull() 或者简单的forif{},换成DB连接就有一大堆的麻烦的设计模式,而且SQL的数据类型(utf8mb4?)甚至语句/模板API,可以说设计得非常低级,让人欲吐不能,所以才有ORM和MVC框架的事情

基于解构匹配通配符的 Prolog 才是真正的SQL,但SQL的巧妙也确实是在有各种插件去 CREATE INDEX ,但这仍不涉及可推荐「共同好友」的图数据库

至于准备语句的JIT,恐怕也就是 template interpret 这种把switch(op[i]){case:}拼成汇编的低级玩法了,在单层for if 的SQL查询里这种内联汇编根本无关于算法优化。 PrologVM做过一样的蠢事

>由于“行”只能有固定的宽度,所以导致了你没法在里面放进任何“变长”的对象,tag数组,项目union都不行,A.B非得让B转90度竖过来,查两次
<normalization在很多情况下更高效(多个A的值指向同一个B, B表加一列等等)。
<如果是嵌套数组的,那么不止B的foreign key,A整个行的字符串都要重复好几次嵌套进去。更加不要说update的惊群效应,性能反而低
<Vertica是使用SQL的RDBMS。Column-Store诞生是为了更有效地解决大数据分析的问题(OLAP workloads),节省硬盘I/O(就是所谓列压缩),运用SIMD等等。不知道这和逃脱SQL有什么关系。

struct和Row在数据类型上有动静态差异,但确实很少有人利用动态table,这需要架构师学习
这方面王垠demo做少了, 比如 post.tags[], user.badges,.fo 确实应该单独立表,这样才能join查询。 json()数组这种存法,作为语法糖就够了,它不关系
你只是显示tags/fo数,没时间线什么的? 意识不到关系式数据库为啥「关系式」, 据说Q群就是1群1Table,就该这么用
列存储显然只是一种类似gzip的自动压缩,并不能优化双向索引

>数组需要一个字段来表示它的长度N,剩下的空间用来依次保存每一个元素,这样你只需要一个key就可以找到数组里所有的元素,而不需要把key重复N遍。
<把字典压缩理解错了?把run-length压缩理解错了?这怎么解决变长问题?

(Ary){u32 N; u8* bytes[N]} 可以解决str分配问题,如果DB有个常量池的话,套一层指针对缓存也好

>每一个“foreign key”,其实就是一个指针
>每一个join操作,本质上就是对指针的“批量访问”,找到它所指向的对象
<数据库里的foreign key不是pointer。数据库经常需要把数据更换位置来解决存储碎片化的问题,不可能用pointer来实现这个
<Join是由数据库查询优化器(Query Optimizer)来决定的,基础的算法就有nested-loop join, sort-merge join, hash-join等好几种,也会有用索引和不用索引,甚至半用索引

这就是你有所不知,bumpptr GC 全都有指针引用计数组,可以在某段页面清空后,通过memmove(to)并更新xref消除内存碎片,而不malloc
这就是为啥JVM/Lua的FFI都存在 Un?Pin(Object) ,foreign key不是pointer, 可托管内存同样不是pointer!

SELECT student.name, record.id, record.city
FROM student, record
WHERE Student.id < Record.id ;

^ 这样的join不离谱吗?我在Gitea里只见过 LEFT JOIN id=id ,还是王垠有理,SQL弱

总的来说,王垠对SQL的批评主要是流行语言的DB.API都太拉垮,私货满满了(包括ORM和KV/对象存储、配置读写等等),
他这么一说好像算法都差不多,每个app单 import db_impl 甚至json就省力气了,其实忽略了mapNotNull函数不能解决的:动态索引join、缓存和事务性安全、async并发的问题。
用FP的写法join和反查你是要写两行甚至加变量的,SQL只需prepare(fn).bind(arg)! 😅
最重要的是,C时代还不存在stdlib里有KV/ListGC算法甚至统一row格式的便利性,而那时就有json持久化和join查询需求了。就像 UNIX getent hosts , 这还是只读数据库

我觉得如果要优化,也是把 @data class 和 [x for x in if] DSL扩充下(groupBy,sort,page啥的),翻译到SQL连接上更合理,虽然数据库还涉及ABI兼容性(schema rollup)等运营日程,但Docker式DX至上DevOps的思路是正确的
👎1
duangsuse::Echo
最近设计一种跨语言ABI,很苦逼, 没啥灵感, 就评论点文章吧 🙉 #learn #sql #web #design 作者是DBMS的维护者。谈到面向表单+外键的数据库,应该说SQLite的质量很高,它不会是为了过度设计而做的东西,但内存数据库和今天广泛用于 Geo/Vec/全文搜索/timestamp 的Pg方向不同。 而王垠是我同行,他对SQL的观点是:必然要连ORM,Redis这些套子,还不如直接 new $KV_HashMap +loaddump 解决了,反正索引算法都是BTree二分查找嘛,…
https://www.fxzhihu.com/question/329153374/answer/716655357
批评:
https://www.yinwang.org/blog-cn/2014/04/24/relational

#sql 也有更好看的写法
https://duangsuse.github.io/tv/%E9%BB%91%E4%BA%86/db.htm
https://baidu.github.io/amis/zh-CN/components/crud?page=1

这么一看我发现作者没有提及批评的闪光点:
- filterMap可以简单链式,而且也并非不能优化, select 嵌套却非常难写,更是养活了一堆XML怪物

- 1:1 , 1:N N:N 这些「关系模型」其实只是把struct/array拆开, 包括允许反查,这就是同步更新俩KV表而已,并不比C/json高级

- 一个概念被冠以“关系式代数”这样的称呼,你是不敢骂它的,确实如此,「迪卡尔积」就是 A,B in itertool.product(a,b)的嵌套for,这配叫算法?

> Neo4j 设计了个古怪的查询语言叫 Cypher,不但语法古怪,表达力弱,而且效率出奇的低,以至于几乎任何实际的操作,你都必须使用 Java 写“扩展”(extension)来完成。MongoDB 等使用 JSON 来表示查询,本质就是手写编译器里的语法树(AST),不直观又容易出错。

这就是好大喜功的问题了。numpy和pd可以证明, 这些学习成本不是必须的。

关于把DBMS当成内存外HashMap的问题,yinwang也解释过,他眼里的理想OS不是按4K管理mmap(页面)swap 的libc的虚拟机,而是类似JVM,带有数据结构和分代GC的

https://www.yinwang.org/blog-cn/2013/04/14/os-design
这个系统的「进程」本就是永久的、可编辑的文件树,无关于L2L3,RAM,SSD 这些缓存,main()函数内的变量才是退出清零的,安装程序就是首次执行,卸载就是kill -9 ,不存在execve() 要通过stdio序列化数据结构的问题,一切皆函数

这么一解释,就知道不存在认知差距,只是二人对 #CS 栈的选择如夏虫语冰,但我觉得这种“免数据库进程”有点道理。
我上面说的,那种「跨语言ABI」 ,其实是想做成这样,弥和IO与变量的差距,但是就连WASM也无力创建这样夸张的“类型化文件系统”来取代new Object树, 但从代码复用的角度,内存外存大一统是很有理论价值的

😂上一段说的那么惊世骇俗, 其实已经成为现实了:Redis是内存KV表,docker run 就是这个“初次运行即安装”,main函数有状态 的系统,只是它没有突破 内存class-IO-外存MIME 的样板代码了,还需要 systemctl suspend 不关机来实现已安装软件的「首屏快取」。
王银的理想是OS包揽状态管理&GC,安软件就是安函数,main()可以如vmware那样断点续传,fork()可以像投屏/CRIU那样发给集群并行,同文同种可RPC不需要任何连接与IO,这就有点像 p9@ Bell Lab 这个系统,不止是libc的运行时。
现在流行的asyncio和BPF,本质上就是为了写FUSE/油猴那样的用户态驱动程序,+1 mainloop 模拟1CPU来粘合回调栈(亦如C栈?)罢了

所以,想象力很重要,但现实也会朝臆想前进的。
👎1
#py #FP 入演算 挺简单的介绍..
https://gist.github.com/vakila/3d5cebaebf01c4c77b289b9a0388e3c8

栏目答是「任何语言代码」背后的核心, 而编程的核心是自顶向下的组合代换,就像从[原子Atom]、生物学,到医学和人。 forif, 对应列表处理的 filterMap 都可以用"她🐑"实现!

data🐑𝛌 栏目答 = 算式Sexpr |
Sym | Abst [Sym] 栏目答 | Args 栏目答 [栏目答] — ({? (rand) exit quit} 1) 是有效的,不用 (..).call(,1)

data Sexpr = Ln [Sexpr] | Int | Str | ... # 非Line即Atom


有别于计算器的关键点是「Sym的地址」。它不能是全局表的"key",而是类似AST树洞、 x=await,可以放东西,无论是否“求值”、等多久靠谁“求值”、在编译期或调用堆叠上“求值”,只配合SDK/ABI即可实现App的运行。 Abst是Absent的缩写,求值=对单步化简(reduce)的深先替换。

栏目答喜欢宣传 Currying(颗粒化传参 A=>B=>A+B) 和 “用回调层数编码数字”,但那只是数学家的把戏。 也有人把第一层参数 (A) 称为this.A或nonlocal A ,那很有价值。官方翻译是 free vars, unbound 或 closure (module 私有)

栏目答一般用于代数(组合逻辑),它和无语句函数是等效的 (整个 callgraph /API 都不能有语句和{基本块}!因此,全局 vartree 也都没必要 let mut 了)。 JSON,XML loaddump, ...DSL 都可以用栏目答编写,有运行期/编译期template<> 的也可以! 😋

在 computation theory (类似WiFi vs 无线电理论) 上,栏目答并不太「图灵完全」 ,就像许多类型推理器,但它解决了仅为了沙箱化 while(1) 而多开线程的麻烦,越来越多工业语言在应用她。 死循环可以写 letrec 伪递归(调用 YCombinator polyfill 解决纯函数禁止全局赋值+取值自身的毛病)

f=栏目答 x: x+1
f=Abst(narg=1,nlet=0, [十(Arg$(1), Const(1)), ]) #, ...以(x+1)为参数继续调用

def Const(json)(stack): json
def Arg$(n=1)(stack): stack[-1][n]
def 十(A, B)(stack): A(stack)+B(stack) # jvm 直接把A,B默认bind到了求值栈上,这里写明,只是为了避免误解
十=(A,B)=> dumpOpcode('iadd', stack=>A(stack)+B(stack) ) # 协议的「语意」是用ID保证代码的跨端同一
@ https://tttttt.me/dsuse/21117
@ https://tttttt.me/dsuse/21179
@ https://tomstu.art/hello-declarative-world#functions-and-relations #sql 是关系式编程?

ps. 图灵完备和 Turing Award 无关,意思是可以把 QEMU.org 移植到某个编程语言里面去,但没有声音图形和点按设备。 这显然不是评价语法-语意表现力和融恰度的指标。

#tool #recommend
https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks 很好玩的 awesome-list !

#learn 纪念我在7年前的「编程入门」博客
https://gist.github.com/duangsuse/519411ab618ee57350ee2df93d33f58e
1