Forwarded from duangsuse::Echo (duangsuse /'dʊɔːŋ sjuːz/ | [⃪PLD, FPλ])
浪费了一天时间写了一篇纯函数式编程半通不通半理论不实践的教程…… 咱来谈谈范畴论
duangsuse::Echo
浪费了一天时间写了一篇纯函数式编程半通不通半理论不实践的教程…… 咱来谈谈范畴论
真正的无知不是知识的匮乏,而是拒绝获取知识;真正的理解也不是能懂得或者能造出晦涩难懂的知识,而是能把晦涩难懂的知识讲得通俗易懂。啥时候我才能有一个这样的朋友,就不愁进步不够快了。
聪明的人学到了往往是只有自己学到了而懒得管其他人,不聪明但是很想聪明的人学到了却是大家都学到了,不知道知识到底应该何去何从。
“这个世界里,”汤川说道,“有些谜是无法用现代科学来解释的。但是,随着科技的进步,迟早一天,那些谜也会被人们解开的。那么,科学是否有极限呢?如果有的话,那么这极限到底是从哪里来的呢?”
汤川用手指着恭平的额头,说道:“那就是人。人的大脑。比方说,在数学界里发现了新的理论时,要验证该理论是否正确,就必须要有数学家们来动手检验。然而,如今发现的理论开始变得越来越高精尖,如此一来,能够检验理论的数学家也就越来越少了。那么,如果该理论太过费解,其他人都无法理解的话,那又该怎么办呢?要让该理论有所定论,那就必须等待另外的天才出现了。正是因为这理由,我才会说科学的极限来源于人类的大脑。你明白我的意思吗?” — 《盛夏的方程式》第八章可是每个人都是不一样的,很可能一千人里无人能解决的问题,再遇到一人就能解决。如果一开始就让他们丧失了对知识的兴趣,那知识的实际意义在哪里呢?它还能继续好好地发展下去吗?还是最终变成一个『大家都去崇拜某位先哲』的纪念馆呢?
能够发自真心地教别人一个知识,摒弃了偏见和敌意、热爱和欣赏知识本身,能够理解和容纳同道幼稚的误解并且加以疏导,『我只是想让你明白』,那才是真正的贤人啊。
#life #Telegram 为了方便大家认识我,我把名字里的一些东西移动到 bio 里
这句话的源头是冰封哥 @ice1000 的『菜是原罪』
后来我发现,我不应该尝试跟在他的后面怎么样,每个人都有自己的风格,何况冰封哥不喜欢菜鸡跟在后面的。
Telegram bio的空间很宝贵,我暂时不想在那里放格言,那就简单放一个自己的领域介绍吧。
现在的 first name (名)是 duangsuse,没有 last name(姓)
Technical unfamiliar is origin sin 这句话的源头是冰封哥 @ice1000 的『菜是原罪』
后来我发现,我不应该尝试跟在他的后面怎么样,每个人都有自己的风格,何况冰封哥不喜欢菜鸡跟在后面的。
Telegram bio的空间很宝贵,我暂时不想在那里放格言,那就简单放一个自己的领域介绍吧。
/'dʊɔːŋ sjuːz/; [PLD, FPλ]; @dsuse@dsuses 日常讨论笔记文档代码 17yo CC-BY 现在的 first name (名)是 duangsuse,没有 last name(姓)
duangsuse Throws pinned «真正的无知不是知识的匮乏,而是拒绝获取知识;真正的理解也不是能懂得或者能造出晦涩难懂的知识,而是能把晦涩难懂的知识讲得通俗易懂。 啥时候我才能有一个这样的朋友,就不愁进步不够快了。 聪明的人学到了往往是只有自己学到了而懒得管其他人,不聪明但是很想聪明的人学到了却是大家都学到了,不知道知识到底应该何去何从。 “这个世界里,”汤川说道,“有些谜是无法用现代科学来解释的。但是,随着科技的进步,迟早一天,那些谜也会被人们解开的。那么,科学是否有极限呢?如果有的话,那么这极限到底是从哪里来的呢?” 汤川用手…»
duangsuse Throws
真正的无知不是知识的匮乏,而是拒绝获取知识;真正的理解也不是能懂得或者能造出晦涩难懂的知识,而是能把晦涩难懂的知识讲得通俗易懂。 啥时候我才能有一个这样的朋友,就不愁进步不够快了。 聪明的人学到了往往是只有自己学到了而懒得管其他人,不聪明但是很想聪明的人学到了却是大家都学到了,不知道知识到底应该何去何从。 “这个世界里,”汤川说道,“有些谜是无法用现代科学来解释的。但是,随着科技的进步,迟早一天,那些谜也会被人们解开的。那么,科学是否有极限呢?如果有的话,那么这极限到底是从哪里来的呢?” 汤川用手…
懂的人其实也不在少数,但最好是首先要明白人群的价值,不要霸占着话题、不允许别人提出「反对」的见解,把所有求知的人视为独立平等的个体,是两个灵魂之间的交流,而不恃才傲物;如果别人是对的,你就又纠正了自己的一个错误,即便别人是错的甚至错得很幼稚,你也得到了学习更好表达自己意图的方式以及与他人辩论的机会,同时别人也得到了自我提升以及进一步学习的机会。
认为自己的知识是自己的,还是认为自己的知识是跟世界复制来的;并且真心感谢其他人的帮助哪怕自己付过费,这是两种观念,但持不同两种观念的人将有巨大的不同。
一个争端,世界上就平白无故多了两个对某个知识有印象的人!为什么不去做呢?
认为自己的知识是自己的,还是认为自己的知识是跟世界复制来的;并且真心感谢其他人的帮助哪怕自己付过费,这是两种观念,但持不同两种观念的人将有巨大的不同。
一个争端,世界上就平白无故多了两个对某个知识有印象的人!为什么不去做呢?
Forwarded from dnaugsuz
哈哈哈,我之前只听说过类似百度镜子那样 LR(horizontal) 翻转的( '{' 到 '}' 那样 ),没见过上下也能翻转的……
Forwarded from duangsuse::Echo (duangsuse)
#Kotlin Write once in one language, run anywhere on all platform.
编程就应该是这样,语言表达无关、平台无关,什么『专有』…… 都弱暴了! M$ 之前那么宠 C# 和 .NET,最后还是只能给它官方开源跨平台了呵,不是想弄成Windows专有的技术么。
编程就应该是这样,语言表达无关、平台无关,什么『专有』…… 都弱暴了! M$ 之前那么宠 C# 和 .NET,最后还是只能给它官方开源跨平台了呵,不是想弄成Windows专有的技术么。
#school #life 呃…… 今天是星期五,本来本校换了个校长以后不经常放假了,趁着高二高一生中午放学的时间我也跟出来了……
还是和以前一样啊,本来到学校的时候可能啥都没有打算干,可后来又莫名其妙设计了一堆(嗯,的确是『设计』出的),虽然实现不了偶尔看见许多前端和PHP、Android们弄出来的东西心里酸酸的。(绝望)
襄阳昨天受孝感4.7级大地震影响,学校教学楼中间裂了个缝,正好是在高三的我们班…… 说什么『整体浇铸』只是裂了表面,假还是照样不放,生艹。
刚才USB绑定连WiFi上网或者用流量什么的不行了,手机不在家里,所以这段消息是离线编辑的(我也是习惯了,虽然之前我不上机是啥都懒得干的)
还是和以前一样啊,本来到学校的时候可能啥都没有打算干,可后来又莫名其妙设计了一堆(嗯,的确是『设计』出的),虽然实现不了偶尔看见许多前端和PHP、Android们弄出来的东西心里酸酸的。(绝望)
襄阳昨天受孝感4.7级大地震影响,学校教学楼中间裂了个缝,正好是在高三的我们班…… 说什么『整体浇铸』只是裂了表面,假还是照样不放,生艹。
刚才USB绑定连WiFi上网或者用流量什么的不行了,手机不在家里,所以这段消息是离线编辑的(我也是习惯了,虽然之前我不上机是啥都懒得干的)
duangsuse Throws
#school #life 呃…… 今天是星期五,本来本校换了个校长以后不经常放假了,趁着高二高一生中午放学的时间我也跟出来了…… 还是和以前一样啊,本来到学校的时候可能啥都没有打算干,可后来又莫名其妙设计了一堆(嗯,的确是『设计』出的),虽然实现不了偶尔看见许多前端和PHP、Android们弄出来的东西心里酸酸的。(绝望) 襄阳昨天受孝感4.7级大地震影响,学校教学楼中间裂了个缝,正好是在高三的我们班…… 说什么『整体浇铸』只是裂了表面,假还是照样不放,生艹。 刚才USB绑定连WiFi上网或者用流量…
提示:这条广播好像发错地方了……如果不适请跳过,深表歉意。
刚才我登了一下小号,因为感兴趣 @drakeet 现在的发展看了下 @drakeets ,发现他虽然进步不快但也依然是蛮有创意,感觉实在是服气。
尽管他是拉黑了我,而且我也曾经很出言不逊(当然,我是真心的),不过我不喜欢给自己树敌,所以权当不认识这个人(嗯,现在两边都一样了)。
之所以说是有创意,是因为居然有native markdown render和LaTeX渲染,以及desktop版本虽然它没有截图所以我不知道是什么层次,虽然我其实还是蛮为drakeet现在没全换Kotlin感到有点可惜。
开始看到 "native" markdown render 之所以吃惊是因为(我开始只当他是完全自己实现的,后来我一想解析器形式化语言问题可不是个简单的主儿啊……就觉得解析器部分应该不是他实现的)
Markdown 完全可能是一种递归的结构,既然他给纯纯写作支持了渲染到 Android View 的功能(还支持 checkbox 控件什么的),就说明他是写了处理递归结构的算法……
比如,
所以你不可能只用 forEach 来渲染,当然我很清楚渲染子视图本来不应该依赖顺序来维护某种上下文的,可所有 UI 框架的绘制子程序基本都会顺序执行 drawLine, drawRect, addChildView 什么的。
那么我当然不可能只是这么浅显地吐槽一下,Visitor Pattern 我肯定必须谈的。
Visitor 是什么呢?考虑一下你有这种东西:
首先我们可以利用面向对象的虚方法(virtual methods),Add (+) 和 Literal (0-9* integral number) 都是 Expr 的「子类型(subtype)」,上面都可以有 eval 方法(求值操作),然后我们把他们的语义实现到这个 eval 方法上。
然后在子类 Add 和 Literal 里实现 eval 方法,计算表达式。
也可以直接利用 Kotlin 的
递归的时候,要记住并且只看自己的函数是要进行一个怎么样的操作,就不会觉得难以理解了,Add 的 a0 可能是另一个 Add(继续递归),也可能是 Literal(递归的基线)。
而 Visitor 呢?它是为了抽象出「eval 类」Tree walker 函数的行为,让它能够做许多操作,比如 show, render, typeInference, compile……
还是不能理解?那么,也可以说
也可以认为,它是『不对接在面向对象「虚方法多态」』上的方法 overriding,所以不必修改类定义即可工作(实际上很多设计模式,比如Strategy、Observer都是这样弄的……)。
当然上面的 Visitor 是一般工程界的风格,我的风格略有不同:
所以要我实现的话我会怎么实现呢?首先我得有一个渲染器就行。
然后 LaTeX 也是我很奇怪(或许不尊重,但是我是真心这么想)drakeet怎么会知道TeX,这令我有点怀疑是不是他有偷看我频道(我一直没见过他写真正需要Math排版的内容) 😂
不过这个功能很有创意,但也不是很困难,实现 TeX 太困难了,我更愿意相信他是使用了网络 API 比如 https://codecogs.com/png.latex?\LaTeX 这样的在线渲染服务
要是我会怎么实现预览呢?假设我一定要把本来可以由布局控件实现的网络下载操作实现到这里的话(当然是需要 Async task 抽象而不能阻塞的)
我们的父层抽象,是完成渲染后(别问我为什么瞎设计,方便教学。)
对特定 Image Link 视图进行一些后期处理(这样就可以实现一些诸如检查 href link 可达性的功能,相信大家编程的时候都会这么弄,而不是一定要把这个逻辑写在渲染完成后本该直接返回的那一坨)
或者,也可以做一个
最后我真的不了解Android的View抽象,目前也懒得学了,错了请彬彬有礼地帮我指出雅正,谢谢。
刚才我登了一下小号,因为感兴趣 @drakeet 现在的发展看了下 @drakeets ,发现他虽然进步不快但也依然是蛮有创意,感觉实在是服气。
尽管他是拉黑了我,而且我也曾经很出言不逊(当然,我是真心的),不过我不喜欢给自己树敌,所以权当不认识这个人(嗯,现在两边都一样了)。
之所以说是有创意,是因为居然有native markdown render和LaTeX渲染,以及desktop版本虽然它没有截图所以我不知道是什么层次,虽然我其实还是蛮为drakeet现在没全换Kotlin感到有点可惜。
开始看到 "native" markdown render 之所以吃惊是因为(我开始只当他是完全自己实现的,后来我一想解析器形式化语言问题可不是个简单的主儿啊……就觉得解析器部分应该不是他实现的)
Markdown 完全可能是一种递归的结构,既然他给纯纯写作支持了渲染到 Android View 的功能(还支持 checkbox 控件什么的),就说明他是写了处理递归结构的算法……
比如,
- [ ] Binarie Project这实际上就是带递归的
- [ ] Reader Abstraction
- [ ] MarkReset
- [ ] Writer Abstraction
- [ ] ByteOrder
- [ ] ByteConverts.kt
<ul> (unordered list)<ul><div>虽然我不知道是不是 checkbox 也可以这么弄,但是 +/- 的 markdown list 的确是可以嵌套的。
<li><input type="check"><div> <!-- 这里就回到了针对 div tag 的渲染 -->
<ul>
<li><input type="check">
<li>……
所以你不可能只用 forEach 来渲染,当然我很清楚渲染子视图本来不应该依赖顺序来维护某种上下文的,可所有 UI 框架的绘制子程序基本都会顺序执行 drawLine, drawRect, addChildView 什么的。
那么我当然不可能只是这么浅显地吐槽一下,Visitor Pattern 我肯定必须谈的。
Visitor 是什么呢?考虑一下你有这种东西:
sealed class Expr /*四则expression*/ {
data class Add(val a0: Expr, val a1: Expr): Expr()
data class Literal(val n: Int): Expr()
}
编写一个程序来对加法进行求值操作。val _1p0p9 = Add(Literal(1), Add(Literal(0), Literal(9))) assert(eval(_1p0p9) == 10) //1+(0+9) = 10 首先我们可以利用面向对象的虚方法(virtual methods),Add (+) 和 Literal (0-9* integral number) 都是 Expr 的「子类型(subtype)」,上面都可以有 eval 方法(求值操作),然后我们把他们的语义实现到这个 eval 方法上。
sealed class Expr { /*...*/ abstract fun eval(): Int } 然后在子类 Add 和 Literal 里实现 eval 方法,计算表达式。
也可以直接利用 Kotlin 的
when is test 这么写:fun eval(expr: Expr): Int = when (expr) {
is Expr.Literal -> expr.n
is Expr.Add -> eval(expr.a0) + eval(expr.a1)
//sealed class 的子类是在相同文件内确定的,所以不用为了 branch exhaustiveness(分支情况穷尽性)加一个 else branch
} 递归的时候,要记住并且只看自己的函数是要进行一个怎么样的操作,就不会觉得难以理解了,Add 的 a0 可能是另一个 Add(继续递归),也可能是 Literal(递归的基线)。
而 Visitor 呢?它是为了抽象出「eval 类」Tree walker 函数的行为,让它能够做许多操作,比如 show, render, typeInference, compile……
sealed class Expr { fun <R> visit(vis: ExprVisitor<R>): R }
interface ExprVisitor<out R> {
fun visitAdd(e: Expr.Add): R
fun visitLiteral(e: Expr.Literal): R
} 还是不能理解?那么,也可以说
Expr.visit 方法就是上面的 when (expr) { is VariantA -> ...; is VariantB -> ... } 这个子类判断分支、ExprVisitor 的各种 visit 就是 when 判断里 case 后的结果表达式,它被抽提出来了。也可以认为,它是『不对接在面向对象「虚方法多态」』上的方法 overriding,所以不必修改类定义即可工作(实际上很多设计模式,比如Strategy、Observer都是这样弄的……)。
当然上面的 Visitor 是一般工程界的风格,我的风格略有不同:
sealed class Expr { fun <R> visitBy(visitor: ExprVisitor<R>): R }
interface ExprVisitor<out R> {
fun see(e: Expr.Add): R
fun see(e: Expr.Literal): R
} 所以要我实现的话我会怎么实现呢?首先我得有一个渲染器就行。
fun renderMarkdown(text: String): Unit? {
val markTree = MarkdownParser.tryRead(text) ?: return null
val render = MarkdownViewRender(ctx) //不是特别了解Android的View布局系统,或许只需要ViewGroup就够了?
markTree.visitBy(render).let { contentView = it }
}
其实一般而言 Unit? 这种类型不该出现的,我这里是想表达 Rust 的 Result<()>,或者说 enum class Ok { Okay, Failed },不过这里是示范。然后 LaTeX 也是我很奇怪(或许不尊重,但是我是真心这么想)drakeet怎么会知道TeX,这令我有点怀疑是不是他有
不过这个功能很有创意,但也不是很困难,实现 TeX 太困难了,我更愿意相信他是使用了网络 API 比如 https://codecogs.com/png.latex?\LaTeX 这样的在线渲染服务
要是我会怎么实现预览呢?假设我一定要把本来可以由布局控件实现的网络下载操作实现到这里的话(当然是需要 Async task 抽象而不能阻塞的)
我们的父层抽象,是完成渲染后(别问我为什么瞎设计,方便教学。)
对特定 Image Link 视图进行一些后期处理(这样就可以实现一些诸如检查 href link 可达性的功能,相信大家编程的时候都会这么弄,而不是一定要把这个逻辑写在渲染完成后本该直接返回的那一坨)
val layout: ViewGroup //...嗯这样可能需要 Render 使用一个在我们这儿处理后的 strategy pattern 来实际渲染,免得它看不到我们的解析结果。(我觉得很奇怪,但这是因为我举的例子本身设计上就有颠倒顺序的问题)
const val CODECOGS_LATEX = "https://codecogs.com/png.latex?"
fun onRenderedImageLink(img: ImageLink) = when {
img.href.startsWith(CODECOGS_LATEX) -> tasks.add(Http.download(img.href)) { img.render = Bitmap.read(it) }
/* where Http is a singleton global state; Http.download: () -> ByteArray */
else -> {}
}
或者,也可以做一个
ReplacableView (相当于二重指针,Box<T>(var item: T) )来允许我们随便替换。最后我真的不了解Android的View抽象,目前也懒得学了,错了请彬彬有礼地帮我指出雅正,谢谢。
Forwarded from duangsuse::Echo (duangsuse)
其实我真是蛮酸的,尤其是看到自己的无人问津(当然我不怪Telegram)和CMU高材生的后生可畏。
他们是大学生啊,我可是高中在读的很不称职的高中生啊,羡慕人家的光明正大。
现在还得弄Binarie和ParserKt,绝句虽然最近就可以设计,也只能暑假开始了,我完成至少是ParserKt才可以动工(还好,ParserKt的DSL,PKNF, ParserKt Normal Form暂时不需要动)
他们是大学生啊,我可是高中在读的很不称职的高中生啊,羡慕人家的光明正大。
现在还得弄Binarie和ParserKt,绝句虽然最近就可以设计,也只能暑假开始了,我完成至少是ParserKt才可以动工(还好,ParserKt的DSL,PKNF, ParserKt Normal Form暂时不需要动)