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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
#life #school #China #dev
说起来,这个 TCO 函数我现在居然能直接通过原理自己想出来了(虽然和上面的不一样)

//export default tailrec;

function tailrec(rec_fun) {
let stack = [], isTailCalling = false;
let lastresult;

let tailcalls = (args) => {
while (stack.length !=0)
{ lastresult = rec_fun(...stack.shift()); }
return lastresult;
}
let cont = (...args) => {
stack.push(args);
if (isTailCalling) return;
else { isTailCalling = true; }

let result = tailcalls(args);

isTailCalling = false; return result;
};
return cont;
}

module.exports = {tailrec};

Node 对 ES6 的支持折腾了半天.... Node 的 ES6 Module 支持,真的很辣鸡
看起来,大部分 JavaScript 前端甚至『全栈工程师』的平均水平,还真是不如纯 Java『后端』呢,因为 James 他们给 Java 9 加了很好的模块化系统,可 Node 作为『最流行』的玩意,这方面比起 Java 来就显得 Java 很『学术派』了,emmm...

debug 了半天.... 对 Expansion operator 使用不够熟悉;现在还有点鬼畜,不能好好 Handle optional arguments
但是我 REPL 的时候没有问题,辣鸡 Bable CLI;前端程序员的细节水平果然辣鸡,如果你写的程序无限运行,你甚至不可以用 SIGQUIT 和 SIGINT,它给我的感觉就是 Node 太可怕了... 居然退出不了...

啊,终于发现问题在... 我的测试程序写错了,我这个数学渣渣... 应该拿去给 Engima 的设计者好好批判一番... 😭

function factorial$() { var rec = (ac, n) => n===0?ac: rec(ac*n, n -1); return (y)=> rec(1, y); }
tailrec(factorial$())(100)

当然 sum2 函数就好写多了

sum2 = tailrec((x, y) => x===0?y: sum2(x-1, y+1));

我忘记了,任何数乘 0 还得 0... #math
说起来这还是我最不搞笑的低级错误;最搞笑的莫过于把 『除数不能为 0』弄成『被除数不能为 0,除数可以,如果除数是那结果是 Infinity... 等等』

ghci> 0/0
NaN
ghci> 1/0
Infinity
ghci> 0/1
0.0

Prelude> 1 `div` 0
*** Exception: divide by zero
Prelude> 0 `div` 1
0

显然分母不能为 0...

哦对了 #fix 一个之前关于 #PLT 的隐式定义:在 Product type 里;如果两个乘类型都是 Zero sized type,那结果也是 Zero sized type
我之前说过 ZST 好像就是 Product /sum type 的 1 来着,1*1 可是还得 1.... 啊?好像也没错...(说了 1 是 ZST... 所以说数学辣鸡 duangsuse...)

替换了原来的短路式伪分支逻辑
if (!active && (active = true))
因为我觉得它不够明确
并且也没有使用书上的两个 if 风格,而是使用了 return 在更大区间上操作控制流
至少;现在的我比以前又强了一些,需要继续努力!

(别人之前的是)

function tco(fun) {
var value = null, active = false, accumlated = [];
return function accumlator() {
accumlated.push(arguments);
if (!active && (active = true)) {
while (accumlated.length != 0) value = fun.apply(this, accumlated.shift());
active = false; return value;
}}}

上面的代码会在过会的一些(当然会往 gh 上发的)文字上出现
duangsuse::Echo
#Math Tips: 为什么任何数乘 0 都得 0,乘 1 都得原数?(放松一下系列) (好吧,虽然我平时都不是很轻松(大嘘)) 考虑一下自然数(正整数)的定义 data Nat = Zero | Succ Nat 我们这么说:一个自然数可能是零,也可以是另一个自然数的『后继元(Succeeder)』 那么 1 就是 Succ Zero(1 + 0)、3 就是 Succ (Succ (Succ Zero)) (1 + 1 + 1 + 0) 那么,对于 Nat 这个 GADT(不准喷为什么用 GADT…
#Haskell 一个关于 Haskell Rank-N-Polymorphism 的小贴士

虽然不是很明确,Haskell 是一门崇尚彻底抽丝剥茧的语言,它应该拒绝我这种一知半解的...

说起来,最近又学到了点 Agda,也是幸运,因为我有在学 type theory 的说,所以 Agda 写的是什么我能猜出来,加上之前我已经猜过了(只不过那时我还太菜;类型系统对我来说就是个黑盒,我只知道一点点微不足道的知识甚至不足以使我看懂 #Agda...)

这里也不会教大家啥是 Monad, 啥是 Functor, 啥是范畴(含宏半群)啥是 flatMap 操作;只需要看懂 do notation

上面就是这里喽

main = do
print $ natToInt (add one three)
putLine
foldl (>>) (putLine) os
putLine
print $ natToInt (add three five)
putLine
printNat $ mul three five
printNat $ mul five three
printNat $ mul Zero five
where printNat = (print . natToInt)
os = print <$> (natToInt <$> [one, two, three, five])
putLine = putStrLn []

好辣鸡... 其实我可以用 Destruct 的,那时候我还 Niave 🐸 些不知道

(Succ four) = five


比如这里有一个小 IO 程序

{-# LANGUAGE ExplicitForAll #-}

module ExplicitForalls where

main :: IO ()
main = do
printLn "1 + 1\n = "
printLn 2
where
printLn :: forall a. (Show a) => a -> IO ()
printLn = putStrLn . show

这里是没有问题的;可是如果用 TypeClass、TypeInstance 的话会怎么样呢?

(然后就突然发现自己讲的很没有意义)

🐕
自作聪明以为把下面的 a 换成 (forall a. a) 就可以解决类型推导失败的问题呢,可是
Illegal polymorphic type: forall a1. a1
GHC doesn't yet support impredicative polymorphism

这已经不是 rank n polymorphism 了,rank n 是(当时我打印的版本好像比较老旧,作者使用的表达方式我看了好久也只有一点感觉....)

rank 0:
单态 t
1:
变态 forall a b. a -> b (Rank 1)
2:
forall c. (forall a b. a -> b) -> c

看 Rank 几直接数 forall 有几个就好了

总之,这很明显嘛。Haskell 的 RankNTypes 默认是 Rank2

∀c → (∀a b. a → b) → c

这里假设给柯里化过的第二个参数起名 f, 那 f 的类型就是可以确定很多次的,只要是 forall a b. a -> b 就可以了
∀ 是 Universal qunatifier,相关知识是高二的推理和证明,这里 forall a. a -> String 表示对于任意类型 a 都有某个名字的 a -> String 这个操作存在,比如 aInt; Int -> String, aIO Int; IO Int -> String (这里不是 Constraint,何况 IO a 本身也是一个类型,Haskell 的 => instance 查找只是隐式了一点而已)
→ 就是一个 Function 类型架构器;放到 Kotlin 就是 Function<in Q, out R> (kotlin.Function<_,_> 当然是做了声明处型变的,我这里写出来只是强调)
a b c 都是 Hindley-milner 的 Type variable

而如果不开 ExplicitForAll,就默认是

∀a b c. a → b → c

f 就只能是第一次推导出的类型喽,比如 String -> Int; String -> IO ()

{-# LANGUAGE UnicodeSyntax, RankNTypes #-}
play :: forall c. (forall a. Show a => a → c) → [c]
play f = [f 1, f "Int"]

ok = play show

然后
ok 是 ["1","\"Int\""]
总之,就是要记住类型是命题... 然后不要老想着去抄别人的,对于理论们,真正的理解不是抄能抄过来的。
— 这个是复制的
rank2 :: forall b c . b -> c -> (forall a. a -> a) -> (b, c)
rank2 b c f = (f b, f c)

rank2 True 'a' id
-- (True, 'a')

— Scala 没有 RankNTypes 就只好模拟喽
def rank2[B, C](b: B, c: C)(fnk: Id ~> Id): (B, C) =
(fnk(b), fnk(c))
rank2(true, 'a')(FunctionK.id[Id])
#book 今天买到了

#Python #Machl 《零起点 Python 机器学习快速入门》 河海群,电子工业出版社
#hardware 《手把手教你学 FPGA 设计》 潘文名 et al. 北京航空航天大学出版社
Forwarded from duangsuse Throws
加起来一百多... 有点小贵

FPGA 那本的水平,虽然我只是撇了一眼,但是我觉得应该不低的,语言我没看,怎么有点汇编的感觉,可是 FPGA 作为逻辑门矩阵模型当然是和存储程序型冯洛伊曼计算机是不一样的
稍微又找了一会,感觉是 VHDL,里面还设计了信号处理的逻辑组合程序,dalao

Python 那本,至于一提到 Python 大家的评价是什么样的... 算了,当然这里的大家如果是说学程序设计语言理论的人,那恐怕评论不容乐观(当然一些刚刚入门 Python 的小白就不要急着说公道话的,上面说的某些大佬现在在写的程序,在讨论的理论你们可能一辈子都懒得去涉足,程序设计语言理论的当然也不是吃白饭的)

至于用 Python 的人... 当然,公平地说 Python 是一门很流行的语言,包括 Pandas, Scipy.learn, Tensorflow, matplotlib.pypolt, numpy, PIL 在内有很多优秀的数据处理和分析库和各种封装
在日常使用方面上,现在很多教学都会直接上 Python 而不是 C 或者其他『难以理解』的语言,比如(新)学校的 STEM 课程,比如各种课外培训班(除了上 Scratch 这种专门教学向的『图形化编程』)
在各种应用程序集成方面上,Python 可以和众多知名生产力、CAD、特效、表格数据处理、3D 软件集成
Python 在应用编程(比如事件驱动、基于 HTTP 和各种 C/S 架构框架应用、比如各种 Spider 或者说 crawler) 上也是硕果累累,除了其官方实现 CPython 优化有点辣鸡鸡肋(我想 Python 虚拟机线程同步起来怕不是 GIL 锁{就是强调 Global}的也有点难受吧,和别的竞争者比);所以一些人去 migrate PyPy, YaPyPy, Cython
Python 几乎什么都能干、甚至是高性能计算、计算机图形学、机器学习、计算机视觉,这方面它比 JavaScript ES5 还强(恐怕也是因为 JavaScript 名声不好,即使是 ES6 给语言又支持了不少新特性、改进、历史遗留问题变通和语法糖,即使有 Typescript,没太多人去做好一点的 binding... emmm...)

但是,作为一门编程语言来讲,哪怕是 Python3 对程序设计语言爱好者们来说都有令人感觉不够满意的地方,尽管,是的,它的确 works,但是它对某些问题的处理不足够“优雅”

上面说到至于用 Python 的人... 排除那一部分 core dev 和大型底层库的开发者,Python 最不好的一点就是积弱,就是生态太好了,所以有不少永远长不大但是却在做正经的软件工程的工程师、以及一大堆还在成长过程中 Dunning Kruger 那一段会莫名奇妙觉得自己还很不完全的的小发现小创作很 NB 的人

这本书的作者... 我觉得我没啥好评价的,但他的确教了这些算法拿什么数据怎么使用,另一方面,其实他主要是在用 Python 做诸如字体设计、数据分析方面的工作,还弄了个 zwPython 解释器和一些著名 Python 库打包
所以和我的主要方向不是一致的... 俗话说得好,隔行如隔山(也就是说我不想以一个 PL 爱好者的视角去评价什么,显然这没有任何意义,而且对作者也没有帮助,而且我也在成长),但我依然对他的真实水平保持不清楚的态度。
#PL #life https://t.me/dsuses/2959

刚刚和某位大佬聊了一下一个比较特殊 case 的 #NLP 自然语言处理问题:识别切分沾粘的姓名们

😫 真的还是太菜了啊

还是继续马上讲一些理论吧

雷玉嗣 杨翠兴 卢弟积 钟婷婷
房堰佳 高奉善 吴源述 余超伟
李丹丹 李恒佰 朱芳芹 邓恒瑞
许星星 鄧超超 陈婷淑 邓红艳
罗章元 苏梅金
(这些人名经随机打乱其『名』部分,姓依然是第一位)

如果这些名字全都是沾粘的,或许可以用『姓』来作切分符
可是这样又不准确
看来真的是不使用机器学习很难解决的问题呢。

duangsuse /'dʊɔːŋ sjuːz/ | [⃪PLD, FPλ], [15.06.19 20:50]
如果有『解析到某个位置可能出现分支情况』这种问题还不算是问题
最大的问题是『语法本身有冲突』

比如说 Kotlin 里的 >= 在分词时就不能处理,当然这还比较特殊
Haskell 里语义缩进文法也是有冲突分不清谁是谁的问题


这种问题看起来和 if () 悬垂问题有点像,都是二义性

if (a)
if (b)
if (c)

请问如果不看缩进,那 if (c) 语句是 if (a) 块里的呢.... 还是 if (b) 里的?
当然 Java 里可以分,因为 Java 里可以带上 {} 决定语句块结束;而不带的就是就近原则(上面这种 if(c) 属于 if(b))

但我觉得... 你上面说的不是无法消除的二义性
#web #dev 学到老活到老
Forwarded from dnaugsuz
(绝望 redis.org 不 OK
Forwarded from dnaugsuz
内存数据库、消息队列储存维护、缓存容器?
主要用于跨进程共享数据?
还有 LRU 缓存清除算法?
而且还支持比如 list, hash, hyperloglog 概率型数据结构, geolocation, bitmap 这种高等一点的数据类型?
还支持 sorted set 和范围限制查询?
还有 Lua 扩展?
还能集群、有事务模型、支持不同程度的持久化?
Forwarded from dnaugsuz
关系代数?(

关系代数把关系型数据库里的表抽象为一堆相同构造元组的集合

rel Boy (name: String, arg: Int, joined: Time, role: String)

每一条记录都是一个元组

boys = {
(duangsuse, 17, 🕐, 菜鸡)
}

然后可以进行关系代数运算

— 查询名叫 duangsuse 的 boy 的年龄

Πage(σname='duangsuse'(boys))
#Java ... 其实这是属于差点资料就能找到的,我本来想讲一些有趣的东西,自己太拖、时间太离散...
Forwarded from dnaugsuz
== 是 Java 的 Primitive 操作...(引用类型相等性,JDK8 里 JavaVM 的)... 等等好像有三种 case, 还不全是 JVM 的引用 comparasion...

编译器的代码详见 jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java#L787

equalsjava.lang.Object 的一个 boolean 虚方法(可被多态重写的方法)

两者好像 不是一种东西 不存在什么区分的关系啊(
#life #school #dev #task 今天的最后,发一下任务列表

很可惜我什么都没有讲、什么也都没有做。

+ (无线电通讯,电信)FDMA, TDMA, CDMA, GPRS, EDGE, LTE... 等知识
+ Engima encoding 写一个加密程序出来
+ ML,Python 的 Pandas 和 Mathplotlib 的使用
+ Jsonist Java JSON 解析和序列化库
+ 不同风格的 Lexer control flow: 怎么写程序更好看:if/switch
+ Para Kotlin Parser Combinator(后置了)
+ DFS 1004.C 修改建议
+ RandomPicture 从头至尾彻底重写
+ BluetoothUtils 默写: 我记忆力是真的变好了... 啊
+ e2immutable 默写: NDKBuild 不好记又怎么样,照样记得住 LOCAL_SRC_FILES 什么的
+ #FP Functional DFS 重写: 比 16 年的冰封还菜... 有时差啊
+ CheerIO Spider: 重构,因为已经记住了主要的库函数方法,而且它真的比较长...
+ #PL Dynamic scoping vs. lexical scoping
+ CMake 如何编写 基于 xxx-config 的 findPackage 函数: 重写 FindLibClang.cmake
+ Hannoi 塔问题、数学和逻辑

点名批评 duangsuse 瞧不起数学和数学老师,结果自己被大脸,其实你又有几时真正理解过递归?又有几时分清了啥是递归啥是计算机科学里的递归子程序?

+ kotlin.Intrinsics 和 -assumenosideeffects, 我之前居然不知道它到底是什么?

+ 树状数组离散化(下个星期的)

数状数组,就是有 void add(path, int); int sum(path); 的数组,然后时间复杂度空间复杂度我不知道
然后离散化和逆序对这可不是简单的题目啊... 以我的辣鸡数学水平
然后我现在连 Gauss-Jordan 算法都不会,怎么入机器学习线性规划啊,怎么入计算机图形学啊,怎么入系统编程啊....

+ C++ 的 template 实现 Nullable<typename T>,注意这个是工程下乡,我不应该被喷太菜(如果只是因为我讲它的话)

+ 编写 Java 的解析组合子框架;当然也是一个解释器、语言工具框架
+ 编写 Java 的 TypeBlackmagic Annotation Processor

— 这个库给 Java (8, 因为至少得有 Type annotation) 提供了:
类上的 @sealed@inner 断言
类泛型参数和方法泛型参数上的 @reifed 内联(实际 Class<T> 提供给某个 instance field 或者 local variable)
@kind 传递内联将 raw type 作为 type constructor 传递(或许有点天真?)

是因为必须得写这种代码:

abstract class Functor<T, A, B> {
abstract Function<? super T<A>, ? extends T<B>> fmap(Function<? super A, ? extends B> morphism);
}

但这代码真的有效吗?T 明明是泛型参数,可以正常解析吗?如果是 Kotlin 的话,可以加限制,不知道 Java 可不可以有

@in 和 @out 声明处型变
@override 小写版本 Override

@readonly @property 自动生成访问器

@properType 自动实际类型 Class<T> 注入

因为我想有一个 abstract class DynamicCheckedSealed<@reified T> {
  abstract Class<T> reifiedT;
@properType abstract static Class<T> REAL_TYPE;
static { checkSealedInstance(REAL_TYPE, klass); }
}
duangsuse::Echo
#life #school #dev #task 今天的最后,发一下任务列表 很可惜我什么都没有讲、什么也都没有做。 + (无线电通讯,电信)FDMA, TDMA, CDMA, GPRS, EDGE, LTE... 等知识 + Engima encoding 写一个加密程序出来 + ML,Python 的 Pandas 和 Mathplotlib 的使用 + Jsonist Java JSON 解析和序列化库 + 不同风格的 Lexer control flow: 怎么写程序更好看:if/switch…
之前还有 C, Crystal Fibers 的并发 du 程序和 kotlin 的 Numeric 类自动运行时类型提升的

明天要讲的东西,现在已经写在我的草稿本上了,主要是 Java 的泛型和 Type wildcard

晚安喽.... 只要可能,明天我会先讲完某些芝士点.... 然后写一个好用的 Java 8 解析组合子,虽然可能不能好好的函数式编程

虽然我知道不仅不可能写任何一个字的解析组合子,连讲是否讲得完都会成为问题
准备开始写了啊,准备彻底了解 Java 的同学可以期待一下
#web https://vertx.io/docs/vertx-service-proxy/java/

给人的感觉就是 Vertx 可以利用 Event bus 集成外部服务,然后 Proxy 可以消除 boilerplate code

// 下面是 C++ alike 语法

const String vActionHandlerArg0 = "action";
fun DeliverOptions.addActionHandler(name: String) = this.addHandler(vActionHandlerArg0, name)

const String vDbServiceID = "database-service";
auto sendToDb = vertx.eventBus()::send.curried(vDbServiceID);

Json message();

message["collection"] = "users";
message["document"] = jsonObject("name".to("tim"));

DeliverOptions deliveryopts = new DeliverOptions()
.addActionHandler("save");

sendToDb(message, deliveryopts, [](result) {
if (!result.succeed()) { ...; return; }
// else
});

这里 deliverOptions 的 actionHandler 假设了某个 receiver(面向对象术语,但这里是说消息队列的监听者)有这个 handler
并且要求这些 Handler 去 handler 这个 message;这里 save Handler 会存储信息到数据库

你也可以理解为一个动态派发的 Java 方法;当然 Ruby 元编程里的 method_missingdefine_method 更好理解一些

Json newlover = jsonObject("name" to "Jack", "lover" to "Rose");

DeliveryOptions methodSave = new DeliveryOptions().addActionHandler("save");
vertx.eventBus()::send.curried

("databaseService") . (methodSave) (jsonMap("collection" to "lovers", "document" to newlover))   
databaseService . save (collection = "lovers", document = newlover);

不过区别在于它是通过 Vertx 的 Message 队列派发的;不是通过反射也不是能直接 invokevirtual 的对象

有的时候就想;能不能把这种 call service (using vertx messageque) 的东西做成『抽象类』的形式(面向侧面编程;AOP)
因为不断定义操作;感觉很垃圾

我们想想,如果不使用 Annotation Processor 这种搞基一点的技巧(实际上已经不算是技巧了,因为很多人连 Visitor Pattern 都懒得写...)
Reflect API + Annotated Element 会怎么样呢?

abstract class VertxServiceInterface {
abstract VertxServiceInterface(EventBus bus, String address);
}

@ServiceInterface
abstract class DatabaseService extends VertxServiceInterface {
...
}

然后数据库服务会有一个 action: save

public AsyncResult save(String collection, Json document);

想想是『弄一个 Function<AsyncResult> 参数好呢,还是直接返回 AsyncResult 好呢』
我觉得还是直接返回好,怎么看和 GC 性能什么的也没有关系;何况这种优化都做得你怎么不去用 C++

然后实际使用的时候就直接

static DatabaseService DB = new DatabaseService(vertx.eventBus(), "postgres-database-service");
...
val saveToUsers = DB::save.curried("users")
DB.saveToUsers(jsonOf("name" to "duangsuse", "feat" to "funny"));

函数式风格写多了抽提控制不住了

— 那实际上呢?

Vertx-service-proxy 是这么弄的(我给翻译成 Kotlin 了,要不然很长感觉很垃圾)

interface SomeDatabaseServiceFactory {
fun create(Vertx vertx): SomeDatabaseService = SomeDatabaseServiceImpl(vertx)
fun createProxy(Vertx vertx, String address): SomeDatabaseService = SomeDatabaseServiceVertxEBProxy(vertx, address)
}

@ProxyGen interface SomeDatabaseService {
// 俩创建自己(constructor)和 Proxy 的接口

companion object: SomeDatabaseServiceFactory

fun save(String collection, JsonObject document, Handler<AsyncResult<Void>> resultHandler)
}
羽毛的小白板
尝试对服务器 API 做现代化改进
这让我想起了 Perl,<> m!! ~= //....
Forwarded from dnaugsuz
https://liolok.github.io/

你应该去问问 Liolok 大佬,他玩过给 Kernel 加 syscall
至于 Kernel hack 是我要学嵌入式工程的时候才会的.... 现在我的时间真的不多
Forwarded from dnaugsuz
大神从来不少,刚才那个 ice1000.org 就是你无法想像的大佬

人家现在都出国留学了,学的数学和 CS,之前还在 Pingcap 给 TIKV 数据库写过 Rust 代码
现在满博客的 PLT 理论和逻辑学,也只比你大两三岁

不要说博客文字少,看看这个,高产赛母猪(划掉)

不要说只会弄理论工程摸瞎,人家写过 Java Swing 程序2D 游戏引擎、写过 Android 应用写过自己的编译器用过 DevOps,自己博客的主题也是自己写的(CSS/HTML)、写过 IDEA 插件、写过完全自己写连存储都做了理论准备的文本编辑器
写过 JavaScript ES6 的爬虫.... 只是现在才成仙了去搞逻辑学
Forwarded from dnaugsuz
This media is not supported in your browser
VIEW IN TELEGRAM