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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
准备开始写了啊,准备彻底了解 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
Forwarded from dnaugsuz
还有 Sleepwalking,他也是真·大牛

他写的论文我们根本看不懂,他还在某信号处理期刊上发表过文章,一样是一个字都看不懂
比某些所谓的数据科学强到不知哪里去了,人家高中的时候就弄了个歌声合成引擎

现在是 synthesizerv.com 的站长,上面挂的那个卖 RMB 500 多的软件,可不是毫无理解『复杂的堆砌』能堆砌出来的,要是真能这样,一群猴子敲键盘都能敲出莎士比亚全集了

然而人家高中的时候就已经在毫无知识背景的情况下强行做了个歌声合成引擎出来,而且合成质量还能听

信号处理领域的东西,尤其是这种原创可不是随便抄抄代码复制粘贴就能弄出来的,像我这种辣鸡... 就望而却步
Forwarded from dnaugsuz
世界上天才从来不在少数,留我们这些没有什么天资又没有啥机遇的辣鸡默默干自己的吧。

总是自以为理解了什么东西,自以为做出的东西很了不起,自以为自己很独特,可是慢慢发现自己没有自己想的那么完美

正是因为有上面这种人,我从来不敢说自己是什么天才,我在襄阳算是『天才』又怎么样,还不如好好学习天天向上。
dnaugsuz
世界上天才从来不在少数,留我们这些没有什么天资又没有啥机遇的辣鸡默默干自己的吧。 总是自以为理解了什么东西,自以为做出的东西很了不起,自以为自己很独特,可是慢慢发现自己没有自己想的那么完美 正是因为有上面这种人,我从来不敢说自己是什么天才,我在襄阳算是『天才』又怎么样,还不如好好学习天天向上。
自以为理解了递归,可是发现其实我连计算机科学里的子程序递归都没有彻底分析过,我无法允许有隐式的知识存在。
前几天才被数学老师打了脸,我之前幼稚地以为『数学老师讲的都不好,所以他们不如我擅长『当老师』』
谁知人家弄了个 PPT 动画图示出来... 我发现和我的直觉正好相反(我的思路正确,但是操作,递归顺序弄反了)

... 不得不说,Hannoi 塔问题我之前自己尝试解过,很可惜,到昨天我才结束了对递归不理解的尴尬情况..
#web #dev #Kotlin 插播一条消息
内存区域限制技能 get
https://ice1000.org/2018/04/27/CodeEditor/ #blog #fix

看完查找资料后,修复了我对一个单词的误解:

efficient 不是『足够』的意思,是『有效率』的意思
effective 是有效的意思
Trumeet/FlarumSDK 1+ 理解

快速阅览:

这是一个使用 Gson / OkHttp 的 Flarum JsonAPI 客户端程序

+ 它有一些客户端实例状态

Flarum API base URL

Task Executor, OkHttp Client, Gson 实例
身份验证 Token: interface TokenGetter { String getToken(); }


+ RequestBuilder 按照 base url, method, body, authentation, filters, page(*20 item/perpage) 和 json converter 生成 OkHttp 的 Request
+ internal.parser.jsonapi.Parser 将 Raw JSON Response 作为 JsonAPI 返回对象解析,返回 APIJSONObject 将被各种对象解析器 internal.parser.ObjectParser.JsonConverter<T> 读取到 Java 对象
+ Result<T> 给 T 结果附加了 OkHttp 的 raw response 和 raw api json object 以及 ID(目前为 0)
+ internal.parser.ObjectParser 定义了将 JSON 对象解析为 Java 对象的接口和辅助函数
+ internal.parser.converter. 定义了一些辅助这种转换器编写的基类
+ internal.parser.ContentParser 是空的 fallback JsonDeserializer<Content> (也是空的) 实现,如果不能作为 Api Json 解析,结果就是无意义的值
+ internal.parser.OkHttpUtils 是放错地方的 OkHttp Client API Call 请求封装,它支持同步使用 execute(request, apiManager, converters) 和异步使用 enqueue(request, apiManager, converters)

逻辑就是给原处理程序加上先判断
HTTP Status 成功、JSONAPIObject 解析成功且访问不包含错误、再转换为目标 Result<T> 的过程

+ internal.platform.Platform 是从 Square Inc 复制修改的逻辑,实际上就是弄一个 Executor... 本来目的是给 OkHttp 异步请求分配合适的执行者,可实际上它只能找到有 android.os.Build 的 Android 平台和创建利用 android.os.Looperandroid.os.Handler Executor 的(post 到 mainloop 去执行),否则默认就是新建 Thread 去执行,而且处理的地方也不在这里,在它的 Caller 那里...
这个类要是弄的好一点要使用 enum with constructor calls、java.util.Function、java.util.concurrent.Executors、java.util.concurrent.ForkJoinPool
This media is not supported in your browser
VIEW IN TELEGRAM
人生苦短,写点文字吧
duangsuse::Echo
https://github.com/duangsuse-valid-projects/Java-You-Dont-Know 过一周天这里甚至会重写我之前写的 Ruby 入门... 将会讲一些有趣的问题
没时间写内容了,看来得两个星期,解析组合子的事情也要推后了,好无聊啊,打字又变慢了
排版测试
#Cplusplus https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture

Lambda capture in C++11

#reveng https://github.com/freakishfox/xAnSo #recommended

即使作者的项目管理风格有点... 呃... 比较原始,而且作者貌似是自己能用了就跑路了,后来开了仨 issue 说是不能用或者建议作者给软件文档的也没有用的回复。

这个是看 @Trumeet 的 GitHub Star 的,不是我找的,我也不知道为啥 Yuuta 会看到这个

代码里有用 C++ 的匿名函数(比较类似 Java 的 Lambda expression,因为比起完整的『闭包』『高阶函数[1]』来说它更像一个语法糖)

如果有同学不懂的,可以去 wikipedia 看看,当然那个 [&] 是 capture all by value (copying) 的意思,不过我一般习惯指定好要捕捉哪些变量(习惯性,如果我写 C++ 的话。


[1]: 闭包(closures)可以实现高阶函数,高阶函数是可以接受函数和返回函数的函数(类似数学里的高阶函数)
在函数(functions)是 first-class 的时候可以实现,但把函数作为“值”[2]传递往往要考虑到一些东西,比如局部变量和 lambda calculus 的 lexical scoping 可能捕获到外部函数[4]的本地变量(UpValue),很多现代化的语言诸如 Lua, Ruby, Python 都支持闭包
闭包不应该和匿名函数混淆,即使在诸如 JavaScript(从第一个被 ECMA 标准化的版本开始的)一类的『函数式、脚本』语言里,他们是类似的,其类似主要是匿名函数是没有指定名字只能使用“引用”来调用的闭包

[2]: 值是 PLT(程序设计语言理论) 里的一个概念,可以类比“下面”实际目标机器『加减乘除』的参数(操作数,operands,指机器指令的操作数,比如 mov.i32/rr, add.i32)类型(机器数值),但在 PLT 里这个概念被泛化了,和 first-class[3] citizen 不应该混用,但是可以认为值是 first-class citizen
[3]: “第一类”对象:可以作为函数的参数和返回值、可以被“储存”(store)到诸如函数栈帧(frame)本地变量、全局变量的容器里,它也是 PLT 的概念
[4]: 也叫做“外部函数”(enclosing function);内部被嵌入的函数被称为“内部函数”(inner function),详情参见 wikipedia: Closure(Computer Science)
比如在 Lambda calculus (理论) 里,
true = λp. (λq. p)
false = λp. (λq. q)
这是 Church encoding 里 boolean (布耳值,详见布尔代数) 的表达方式
lambda 演算[5]是惰性求值(lazy evaluated)的,在 Haskell 里,类似的函数可以被用于替换 Haskell 内部的 if 语法
where 这里的 Haskell 是 Haskell 98 [语言标准] if 是 Haskell 内部钦定的语法,但利用 Haskell 的 Lambda abstraction if 也完全可以被替换掉,即使没啥用
在 Java 8 里,
import java.util.function.Function;

//... omitted for brevity
Function<
Function<Void, ? extends Object>,
Function<
Function<Void, ? extends Object>,
? extends Object>>
truef = p -> q -> p.apply(null);
//... omitted for brevity

(看 Java 的“FP”我都快晕了,跑,这里使用 wildcard 泛型是... 习惯,虽然这里泛型不协变(covariant)也没问题。
[5]: Lambda 演算:悠久历史(1930 年)的演算模型,其历史还可以追溯到 1920 年的组合子逻辑(Combinatory logic),和图灵机[6]鸡̶🐔你太̶美̶同一个历史时期,开始这个模型被创造来形式化描述数学(mathematics),lambda 演算是项 (term) 组成的形式化系统,其有三种项:
+ x: Variable
+ (λ x. M): (Lambda) abstraction
+ (M N): Application
基本的操作有两个,他们基于 绑定(命名): binding 和 替换: substraction 操作:
+ ((λx.M) E) _β= (M[x:=E]): β-reduction, 这是 binding 操作,替换后的 M 的上下文(context,Lambda calculus 一般名为 Γ, Gamma)里 x 变量就是 E 项了
+ (λx.M[x]) _α= (λy.M[y]): α-conversion, 这是 renaming 操作(也是一种性质),用于 abstraction variable 名字冲突时,它告诉我们 lambda 只是基于 term group 的 substract 抽象而已,和『参数』的名字无关
表示上,Lambda calculus 是左递归(Left recursive)的,这是说
λx. λy. x 表示 (λx. (λy. x))
Lambda calculus 已经被(隐式地)用于现在的绝大部分高级计算机语言,并且被诸多函数式编程语言(functional programming language)作为自己的理论基础使用,其理论已经比较丰厚繁杂,详情 wikipedia

[6]: 图灵机:阿兰·图灵大学时期于 1936 年提出的自动机计算模型,有一门叫 brainfuck 的编程语言图灵完全(图灵机兼容)可以作为图灵机的辅助理解范本;图灵机以打字机为原型,假设自己有一个无限长度的存储卡带和一个解释器,被编程的解释器读写卡带处理卡带上的数据。
和 Lambda calculus 不同,图灵机的数据[7]是线性(linear)的而不是树形的,1939 年 J. Barkley Rosser 证明了 λ 演算和通用图灵机是等价的
brainfuck 只有 8 条指令:+, -, <, >, ., ",", [, ]
brainfuck 之所以图灵等价是因为它也认为有一个无限大小的随机访问存储器,+- 用来操作当前存储单元指针下的数据、<> 用来移动数据指针、,. 用来做 I/O、[] 用于实现循环,当然也可以是不停机(non terminating) 的无限循环。
能够实现图灵机所有功能的自动机被称为是图灵等价,或者说,图灵完全(Turing complete)的
图灵机的性质比较适合进行文本处理,但实际上它只是概念上的计算模型而已
通用图灵机(universal Turing machine)启发了后面的冯·诺伊曼存储程序性计算架构(现在最通用的计算模型也是现在电子计算机技术的基础,哈佛架构优化的基础)的诞生,并且,Alan Turing 用它在 1936 年证明了停机问题(Halting problem)是不可解决的(当然他的导师 Church 同年也用 lambda calculus 证明了这个问题逻辑不可解,各自独立地)
[7]: Lambda calculus 里实际上只存在抽象而没有所谓的数据,这里是做了一个不恰当的比方