现在我又不得不说,他的博客,看一年,还真的看不完啊... 😶 真的是时间可以改变一切
的确,一篇博文里引用的书、论文都够我看几个星期了... 而且还得一遍一遍的看,看几遍才能彻底 get 到大部分的知识点...
... 视角改变一切。
的确,一篇博文里引用的书、论文都够我看几个星期了... 而且还得一遍一遍的看,看几遍才能彻底 get 到大部分的知识点...
... 视角改变一切。
Forwarded from duangsues.is_a? SaltedFish
还总是看淫王的博客,技术水平高的人可不止他一个,他博客看了一年还看不完?
duangsuse::Echo
(看了那个博文那个章节后突然发现说得好啊,而且可见王淫还是蛮有水平的(废话) 其实我刚才说的弄不懂是我在吃饭的时候考虑了一下拿 foldl 定义的 reverse 函数 Haskell(Scheme 的太长不复制了) foldl :: (a -> r -> r) -> r -> ([a] -> r) foldl f v [] = v foldl f v (x : xs) = foldl f (f x v) xs reverse = foldl (\x xs -> x : xs) [] 能用(F**king…
再看看这个,和我之前所认为的 Haskell,不是 #Haskell 变好看了,是我对问题的思考方式真的贴近了 Haskell...
曾经我所以为的不符合直觉,只不过是因为我的『直觉』和 Haskell 的创造者的『直觉』不一样罢了...
我根本不懂递归,不知道 GADT 是什么,没用过模式匹配,我看不见栈、看不见实际上的运行环境,我『看不到』一张数据结构图而只能看到一堆符号,也没实际去分析什么并非过程式的程序,拿倒垃圾的简单算法的思维方式去考虑使用递归定义的程序,当然觉得它莫名其妙!
以前我用 Java 程序员的思维方式看那些其实我根本没看懂的 Haskell 代码、APL 代码,我觉得他们很难看,觉得这种『自以为是』的简洁是『最智障』的方式
其实不是 Haskell 的简洁不对,只不过是因为我没有以他们的方式去思考问题,听不见音乐的人认为那些跳舞的人都疯了!😐
现在我用 Haskell 程序员的思维方式写 Haskell 代码,我发现 Haskell 的表述方式就成为了我的直觉...
其实是因为我在以 Haskell 的方式而不是 Java 的方式思考问题啊... 🤔
直觉真的不是一个『一成不变』的东西啊,值得好好培养 emmmm(
曾经我所以为的不符合直觉,只不过是因为我的『直觉』和 Haskell 的创造者的『直觉』不一样罢了...
我根本不懂递归,不知道 GADT 是什么,没用过模式匹配,我看不见栈、看不见实际上的运行环境,我『看不到』一张数据结构图而只能看到一堆符号,也没实际去分析什么并非过程式的程序,拿倒垃圾的简单算法的思维方式去考虑使用递归定义的程序,当然觉得它莫名其妙!
以前我用 Java 程序员的思维方式看那些其实我根本没看懂的 Haskell 代码、APL 代码,我觉得他们很难看,觉得这种『自以为是』的简洁是『最智障』的方式
其实不是 Haskell 的简洁不对,只不过是因为我没有以他们的方式去思考问题,听不见音乐的人认为那些跳舞的人都疯了!😐
现在我用 Haskell 程序员的思维方式写 Haskell 代码,我发现 Haskell 的表述方式就成为了我的直觉...
其实是因为我在以 Haskell 的方式而不是 Java 的方式思考问题啊... 🤔
直觉真的不是一个『一成不变』的东西啊,值得好好培养 emmmm(
duangsuse::Echo
实在是没有那个力气开几个理论向学习,因为定理证明、PL 理论那些已经够累了... 代数程序逻辑依然在学,反正理论向都是均衡发展但都很薄弱就是了 现在具体来讲就是 The Little Schemer 终于熟悉了一点这个列表处理语言... 不过我觉得还是 Haskell 好,因为 Haskell 更符合直觉(看很多用 Haskell 讲程序分析的论文就知道),Scheme 一类的一大堆 car cdr 让不让人活了 具体就是(拿 foldr 和 foldl 举个例子) Haskell 里(比较简单比较…
如果觉得这个例子不好的话,刚才看这篇博文(教你们拿 Racket,一个 Scheme 实现写基于 Lambda Calculus 的解释器的)的时候突然发现这个例子非常不错(实际上,很多 #Haskell 入门教程都会拿这个做例子)
首先我们的 Haskell 的确是静态强类型(statically strong typed, type inference supported)的语言,所以类似 Scheme 那样直接拿链表抽象一切就免了(
当然,如果我们写『完全等价』的呢?
t1 = [1, 2]
t2 = [1, [2, 3]]
t3 = [[1, 2], 3]
t4 = [[1, 2], [3, 4]]
treeSum' :: [Int] -> Int
然后就写不出等价的来...
<del>
treeSum' :: [Int] -> Int
treeSum' xs
| length xs == 1 = head xs
| (x : xs) = x + treeSum' xs
| otherwise = treeSum' (head xs) + treeSum' (head (tail xs))
因为这个逻辑实在有点复杂,貌似简单一点的 Haskell Cons 模式匹配弄不了,只好使用 Guard Pattern(
</del>
『好的程序应该反映出它所处理的数据结构』
这话不是我说的,看完上面的小学生水平 Haskell/Racket 代码后,大家应该理解了这句话吧。
如果有喜欢 #Scheme 的同学,必须记得看完 The Little Schemer(轮子哥管它叫『儿童书』)先再出去『吓人』(悄悄告诉你们... 我就是还没看完所以连 #FP 的 QQ 群都不敢进... hhhh 🤔
(define tree-sum
(lambda (exp)
(match exp ; 对输入exp进行模式匹配
[(? number? x) x] ; exp是一个数x吗?如果是,那么返回这个数x
[`(,e1 ,e2) ; exp是一个含有两棵子树的中间节点吗?
(let ([v1 (tree-sum e1)] ; 递归调用tree-sum自己,对左子树e1求值
[v2 (tree-sum e2)]) ; 递归调用tree-sum自己,对右子树e2求值
(+ v1 v2))]))) ; 返回左右子树结果v1和v2的和
(tree-sum '(1 2))
;; => 3
(tree-sum '(1 (2 3)))
;; => 6
(tree-sum '((1 2) 3))
;; => 6
如果用 Haskell 写几乎一样的程序呢?首先我们的 Haskell 的确是静态强类型(statically strong typed, type inference supported)的语言,所以类似 Scheme 那样直接拿链表抽象一切就免了(
data BinaryTree a = Leaf a | PrimNode a a | CompNode (BinaryTree a) (BinaryTree a)(为了方便起见,大家可以看到 Haskell 的版本里那个 data 其实不是『等价』Racket 里我们所预期的表结构的)
t1 = PrimNode 1 2
t2 = CompNode (Leaf 1) (PrimNode 2 3)
t3 = CompNode (PrimNode 1 2) (Leaf 3)
t4 = CompNode (PrimNode 1 2) (PrimNode 3 4)
treeSum :: BinaryTree Int -> Int
treeSum (Leaf n) = n
treeSum (PrimNode a b) = a + b
treeSum (CompNode l r) = treeSum l + treeSum r
main
= (foldl f v) $ (println . treeSum) <$> [t1, t2, t3, t4]
where
println x = print x
f = (>>)
v = putStr ""
当然,如果我们写『完全等价』的呢?
t1 = [1, 2]
t2 = [1, [2, 3]]
t3 = [[1, 2], 3]
t4 = [[1, 2], [3, 4]]
treeSum' :: [Int] -> Int
然后就写不出等价的来...
<del>
treeSum' :: [Int] -> Int
treeSum' xs
| length xs == 1 = head xs
| (x : xs) = x + treeSum' xs
| otherwise = treeSum' (head xs) + treeSum' (head (tail xs))
因为这个逻辑实在有点复杂,貌似简单一点的 Haskell Cons 模式匹配弄不了,只好使用 Guard Pattern(
</del>
『好的程序应该反映出它所处理的数据结构』
这话不是我说的,看完上面的小学生水平 Haskell/Racket 代码后,大家应该理解了这句话吧。
如果有喜欢 #Scheme 的同学,必须记得看完 The Little Schemer(轮子哥管它叫『儿童书』)先再出去『吓人』(悄悄告诉你们... 我就是还没看完所以连 #FP 的 QQ 群都不敢进... hhhh 🤔
This media is not supported in your browser
VIEW IN TELEGRAM
写累死了,而且思路不清晰,算了,然后书单又没有发...(跑,不过话说了
开始写实际应用喽
开始写实际应用喽
duangsuse::Echo
如果觉得这个例子不好的话,刚才看这篇博文(教你们拿 Racket,一个 Scheme 实现写基于 Lambda Calculus 的解释器的)的时候突然发现这个例子非常不错(实际上,很多 #Haskell 入门教程都会拿这个做例子) (define tree-sum (lambda (exp) (match exp ; 对输入exp进行模式匹配 [(? number? x) x] ; exp是一个数x吗?如果是,那么返回这个数x…
#PL 题外话,这篇博文还会讲到 Lexical Scoping 和 Dynamic Scoping 的区别,其实 PL 爱好者们偶尔也会讨论这些问题,不过有时候入门的话纠缠不清... 这里讲得可以说是很友好了
duangsuse::Echo
GeekApkSpecShort.pdf
懒得整理了,就用这个(接近 5 个月之隔
https://start.spring.io/
如果弄好了,那就临时以一个早已死去的并且不会进化的早期 #GeekApk 的名义(反正我也算是早期成员吧,呵呵)自己部署然后试用,寒假可能会稍微包装一点拿来暂时用一下(H2O2 能用之前)
我以为我现在的工程能力,包括 Trumeet 那个 MiPushTester Vertx Server 我都完全能理解,并且流程我都会走,Future(就是 Promise) 、HTTP、JSON 之类的都不是事(而且部分技巧我现在还不需要会,只是 trivial 的描述一下模型和要做什么就可以了)... 和 Dockerfile 一样,即学即用,比 Haskell 的自动 HM 类型推导算法好学『使用』多了
说的也是,JavaEE 一直以来的问题就是难以开启一个新项目(不是我说的,这可是 JBoss 项目的某个 dalao 的看法)
Spring Boot 可以说是完全解决了这个问题,非常的简单,实现上面那个 pdf 里的服务需要什么模式一条消息文本长度限制内都可以解说明白
https://start.spring.io/
如果弄好了,那就临时以一个早已死去的并且不会进化的早期 #GeekApk 的名义(反正我也算是早期成员吧,呵呵)自己部署然后试用,寒假可能会稍微包装一点拿来暂时用一下(H2O2 能用之前)
我以为我现在的工程能力,包括 Trumeet 那个 MiPushTester Vertx Server 我都完全能理解,并且流程我都会走,Future(就是 Promise) 、HTTP、JSON 之类的都不是事(而且部分技巧我现在还不需要会,只是 trivial 的描述一下模型和要做什么就可以了)... 和 Dockerfile 一样,即学即用,比 Haskell 的自动 HM 类型推导算法好学『使用』多了
说的也是,JavaEE 一直以来的问题就是难以开启一个新项目(不是我说的,这可是 JBoss 项目的某个 dalao 的看法)
Spring Boot 可以说是完全解决了这个问题,非常的简单,实现上面那个 pdf 里的服务需要什么模式一条消息文本长度限制内都可以解说明白
先准备测试用数据库(指 Postgres
sudo /usr/bin/postgresql-setup --initdb
sudo systemctl start postgresql.service
sudo su postgres
psql
CREATE USER geekapk WITH PASSWORD '1234567';
CREATE DATABASE geekapk;
GRANT ALL PRIVILEGES ON DATABASE geekapk TO geekapk;
sudo /usr/bin/postgresql-setup --initdb
sudo systemctl start postgresql.service
sudo su postgres
psql
CREATE USER geekapk WITH PASSWORD '1234567';
CREATE DATABASE geekapk;
GRANT ALL PRIVILEGES ON DATABASE geekapk TO geekapk;
duangsuse::Echo
(((((
写了一点 Model 层的东西,然后发现懒得写视图(因为太花时间
发现一个规律:每次我要写实际应用的时候都会熬夜一个通宵... #life 🤔
写出如此模式化的代码,羞愧,不过我觉得能抓到老鼠就是好猫,优化后来可以谈。
这个应用我对它的预期就是起个头,它基本就是参照上面的那个 SpecShort 实现的,只有些许修改,然后就是那种典型的 MVC(不过,没有 View 只有 Model 和 Controller)应用程序,真的是没什么技术含量相当模式化
今天是继续完善模型
预计今天内能上线,不过没有客户端(
发现一个规律:每次我要写实际应用的时候都会熬夜一个通宵... #life 🤔
写出如此模式化的代码,羞愧,不过我觉得能抓到老鼠就是好猫,优化后来可以谈。
这个应用我对它的预期就是起个头,它基本就是参照上面的那个 SpecShort 实现的,只有些许修改,然后就是那种典型的 MVC(不过,没有 View 只有 Model 和 Controller)应用程序,真的是没什么技术含量相当模式化
今天是继续完善模型
预计今天内能上线,不过没有客户端(
duangsuse::Echo
写了一点 Model 层的东西,然后发现懒得写视图(因为太花时间 发现一个规律:每次我要写实际应用的时候都会熬夜一个通宵... #life 🤔 写出如此模式化的代码,羞愧,不过我觉得能抓到老鼠就是好猫,优化后来可以谈。 这个应用我对它的预期就是起个头,它基本就是参照上面的那个 SpecShort 实现的,只有些许修改,然后就是那种典型的 MVC(不过,没有 View 只有 Model 和 Controller)应用程序,真的是没什么技术含量相当模式化 今天是继续完善模型 预计今天内能上线,不过没有客户端(
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
geekapk_spring_0.zip
对了,现在这个项目已经度过最开始编写基础代码的时期,可以在 GitHub duangsuse/GeekApk 访问了(虽然我是写了两天
目前代码基础已经有了,正在编程控制器来驱动测试和模型层 Repository 们的完善(模型层我希望是能做到 JPA 里的不要专门给 Controller 设计辅助函数,毕竟 JPA 这个名字就很『大』嘛)
欢迎大佬们前来指导实践。(尤其是曾经写过 SpringMVC 的,我现在发现我作为一个 #PL 爱好者居然连 #Java 里
真是岂有此理 😡
目前代码基础已经有了,正在编程控制器来驱动测试和模型层 Repository 们的完善(模型层我希望是能做到 JPA 里的不要专门给 Controller 设计辅助函数,毕竟 JPA 这个名字就很『大』嘛)
欢迎大佬们前来指导实践。(尤其是曾经写过 SpringMVC 的,我现在发现我作为一个 #PL 爱好者居然连 #Java 里
enum 有 enum VS { int a; String b; Constructor(int i, String s) { a = i; b = s; } Constructor(1, "1") } 这种语法都不知道真是岂有此理 😡
GitHub
duangsuse/GeekApk
GeekApk, the dying SpringBoot(a.k.a. Sping initializr) server for GeekApk(a.k.a 极安) (R - duangsuse/GeekApk
duangsuse::Echo
类似这样,当然都是很模式化的代码不必说
顺便提一下,因为要 AOP 动态生成具体的 AOP 子类,这些
@Controller 什么的标记的类都必须不能是 sealed 的,我用了 Kotlin 编译器插件 all-open 所以不必显式把 open keyword(modifier) 写上