duangsuse::Echo
杀人者死,伤人及盗抵罪。 — 引记法 绝句.符号 「之」 事 严明执法(此人:人) 为 若此人之曾杀人,杀(此人)。 若你此人或之曾伤人或之曾盗窃,此人去抵(此人的罪)。 fun judge(one: Person) { if (one.killedSomeone) kill(one) if (one.didHurtSomeone || one.didThief) one.payFor(one.sin) } 还好,就这个程序来说不必劳烦 判 语法了。 然后我觉得,反正绝句里「你」…
尽管好像是那样的,但「对…里的你……」和「若你(且/或)……」的用法是不一样的,「对」里的可省略「你」这个主语,另一个不行…… 反正「你」已经是苛性构词了,就是作用域结构上的差异,具体是否加入以后再考量吧。
duangsuse::Echo
尽管好像是那样的,但「对…里的你……」和「若你(且/或)……」的用法是不一样的,「对」里的可省略「你」这个主语,另一个不行…… 反正「你」已经是苛性构词了,就是作用域结构上的差异,具体是否加入以后再考量吧。
对了,为什么不把这个
……可那样
唉
其实
可是我们不能让
这绝句越设计越像自然语言了,可这……真的没问题么;我感觉第二人称文法是个潘多拉盒子,支持了指不定会怎么样。
不过「对…里的你……」中引用可不带主语「你」 的特化处理给去掉呢?反正去掉也不会使得代码更难看啊!这样不就一致了吗?「你」就像是对表达式的一个标签,不存在作用域处理上一致性的问题。……可那样
对…里的你 和 对…里的…… 还有什么区别啊???那就只能删掉这个用法了……唉
其实
对…里的你…… 也是有语言一致性的,因为「你」本身就代表作用域混合。可是我们不能让
“……”
若此人之曾杀人,杀(此人)。
若你此人或之曾伤人或之曾盗窃,此人去抵(“此人的”罪)。这种代码通过啊?!
这绝句越设计越像自然语言了,可这……真的没问题么;我感觉第二人称文法是个潘多拉盒子,支持了指不定会怎么样。
duangsuse::Echo
对了,为什么不把这个 不过「对…里的你……」中引用可不带主语「你」 的特化处理给去掉呢?反正去掉也不会使得代码更难看啊!这样不就一致了吗?「你」就像是对表达式的一个标签,不存在作用域处理上一致性的问题。 ……可那样 对…里的你 和 对…里的…… 还有什么区别啊???那就只能删掉这个用法了…… 唉 其实 对…里的你…… 也是有语言一致性的,因为「你」本身就代表作用域混合。 可是我们不能让 “……” 若此人之曾杀人,杀(此人)。 若你此人或之曾伤人或之曾盗窃,此人去抵(“此人的”罪)。 这种代码通过啊?!…
这么说吧,其实这个选择也就是绝句是走「倾向自然语言」还是「倾向更规范的编程语言」的区别,也就是设计的分岔路。
不错,其实绝句完全可以不多作考量就立刻以我上面那个折衷法立刻准备加入正式设计的,可我觉得还是有点问题需要讲明白。
这个语法,它不像
就绝句未来而言,我觉得我的看法和 Matz 是一样的,不能把语言设计得太『简单』或过分数学、过分强调语言理论准确性,我不希望绝句成为『中文编程』领域的Scala(的确我也没那个水平),但是我觉得『自然』也是有限度的,不能没有章法。
第二人称文法其实本身就是一种会扰乱语言表达规范性的特性,支持它可以让语言、对程序的描述更直白、更自然,有很大的积极作用,唯一的问题是——它是对作用域定义的扩充,利用它可以写出莫名其妙的程序,而绝句不可能检查这种情况,因为首先它们本该符合语法,其次这种检查是吹毛求疵的行为。
下面有相似的三个例子。
上面的『名字』『年龄』,很自然就能知道是指『存于办公室的某人』。(这里不提里面有很多行代码的情况,绝句里还能写很复杂很多行纯属编程方法有问题)
这里就更明显了,我们引入了一个块,谁能一眼看出『口感』是指『存于零食区的某物』的口感???
……我觉得暂时还是支持吧。毕竟这个语法虽然让绝句不是那么『严格』了,在中文表达里它也是有价值的,而上面举出的问题程序其实本身以中文的视角看都是语素残缺、逻辑错误的,或许能够以中文的思路看绝句程序会有利于代码质量的提升。
不错,其实绝句完全可以不多作考量就立刻以我上面那个折衷法立刻准备加入正式设计的,可我觉得还是有点问题需要讲明白。
这个语法,它不像
尝试…成…… 那样,它是无可替代的,绝句里没有任何其他方法可以直接代替它作为表达式的位置,因为它一是在汉语言里属于对语言表达有极其特殊地位的构词而不应该在任何情况下作为名字的起始使用,二是它可以使得 a > 1 && a in xs 这种表达式更好描述,绝句里也有类似的并例(例如「」叫括号的中缀简记)。就绝句未来而言,我觉得我的看法和 Matz 是一样的,不能把语言设计得太『简单』或过分数学、过分强调语言理论准确性,我不希望绝句成为『中文编程』领域的Scala(的确我也没那个水平),但是我觉得『自然』也是有限度的,不能没有章法。
第二人称文法其实本身就是一种会扰乱语言表达规范性的特性,支持它可以让语言、对程序的描述更直白、更自然,有很大的积极作用,唯一的问题是——它是对作用域定义的扩充,利用它可以写出莫名其妙的程序,而绝句不可能检查这种情况,因为首先它们本该符合语法,其次这种检查是吹毛求疵的行为。
下面有相似的三个例子。
对此办公室里的你,这是正常情况,也就是我觉得有必要加入此语法的理由。——况且这的确是很常见的一种模式(当然 Kotlin 也可以用
若年龄不大30且头衔是总监,说(你的名字)。
E.() -> Unit 模拟,可为了一致性最好还是加上,而且那样就没有第二人称「作用域混合」了)上面的『名字』『年龄』,很自然就能知道是指『存于办公室的某人』。(这里不提里面有很多行代码的情况,绝句里还能写很复杂很多行纯属编程方法有问题)
对里的你(办公室) { if (年龄<=30 && 头衔==总监) println(this.名字) /*注意这里就和第一人称的this混淆了,没法直接引用外层的this*/ }
Kotlin 的写法类似以上对此办公室里的你,这种情况,就没那么容易想出『名字』是指谁的名字了(甚至会与名字作为一类事物的情况发生混淆),或者说,对于以上代码可以调整「是」的语序修改,可我之前说过,严格的好语言不应该可以写出烂代码,那往往是设计思虑不够深刻导致的。
若甲君的名字[0..1]是名字,说("啊,${名字}你和${甲君}是一家的啊?")。 “开个玩笑”
对零食区里的你,
取色笔去取色(外封)令为,说("$它 $口感")。
这里就更明显了,我们引入了一个块,谁能一眼看出『口感』是指『存于零食区的某物』的口感???
……我觉得暂时还是支持吧。毕竟这个语法虽然让绝句不是那么『严格』了,在中文表达里它也是有价值的,而上面举出的问题程序其实本身以中文的视角看都是语素残缺、逻辑错误的,或许能够以中文的思路看绝句程序会有利于代码质量的提升。
duangsuse::Echo
这么说吧,其实这个选择也就是绝句是走「倾向自然语言」还是「倾向更规范的编程语言」的区别,也就是设计的分岔路。 不错,其实绝句完全可以不多作考量就立刻以我上面那个折衷法立刻准备加入正式设计的,可我觉得还是有点问题需要讲明白。 这个语法,它不像 尝试…成…… 那样,它是无可替代的,绝句里没有任何其他方法可以直接代替它作为表达式的位置,因为它一是在汉语言里属于对语言表达有极其特殊地位的构词而不应该在任何情况下作为名字的起始使用,二是它可以使得 a > 1 && a in xs 这种表达式更好描述,绝句里也有类…
我觉得,既然都无法确定的话…… 那还是用 plan C 好了,去掉 对……我 的特殊对待,这样虽然看起来有点弱智但不至于弄乱整门语言。
对应地,「你」的『文言式作用域混合』也就是『你(言)……』的情况…… 还是保留吧。
这样看起来一致性就好多了,「你」后面跟的都是「你的」「你去」。
对应地,「你」的『文言式作用域混合』也就是『你(言)……』的情况…… 还是保留吧。
对此办公室里的你,
若你的年龄不大30且你的头衔是总监,说(你的名字)。
事 严正执法(此人:人) 为 “用起来不自然但这只是例子”
若此人之曾杀人,杀(此人)。
若你此人或之曾伤人或之曾盗窃,你去抵(你的罪)。 这样看起来一致性就好多了,「你」后面跟的都是「你的」「你去」。
duangsuse::Echo
到现在,只有贵得不行的 Oxygen XML Editor Edition 才能像话地为拥有不同内部结构与格式的 XML 文件撰写内容。gnu gettext 之类翻译工具不至于没法用,但它们的输出展示结果不可能能够应对,或者拥有 XML 的层次结构。
啊,不是,我这里指的翻译是计算机科学程序表示和转化领域的『翻译』,也就是编译器进行的『翻译』,不是自然语言的那个『翻译』……
duangsuse::Echo
你们知道么,当时编译通过的时候我都蒙了!我完全是一个字一个字敲出来的,中间没有靠任何类型检查器,而后来只是修了接口 isNotEmpty() 没加括号和另一个类型标记错误的问题,加了三个 import 就直接编译过了!!!不靠计算机简直都能编程!
艹,好像不能完全避免 bug,我改了一次后出了无数个拼写错误,而且还有两个 nullibility 的问题和一个泛型参数弄错
duangsuse::Echo
艹,好像不能完全避免 bug,我改了一次后出了无数个拼写错误,而且还有两个 nullibility 的问题和一个泛型参数弄错
不过,出错以后更好改是真的,因为总感觉自己只不过是在写字一样所以没有心理压力
https://github.com/duangsuse-valid-projects/Share/commit/d6f91d73fc59cd415c868f8ca1362d6a0426713a
像写一篇文章一样编程的好处很明显,就是思路是清晰的(虽然我这个层次也做不到一遍不错地完成,如 nullability 和 upper bound 上,但思路很明确)
尽管还是需要改很长时间,但不会觉得自己很苦逼,好像只是在写篇博文一样,尽管没有 IDE 的帮助,这种感觉很有趣。
像写一篇文章一样编程的好处很明显,就是思路是清晰的(虽然我这个层次也做不到一遍不错地完成,如 nullability 和 upper bound 上,但思路很明确)
尽管还是需要改很长时间,但不会觉得自己很苦逼,好像只是在写篇博文一样,尽管没有 IDE 的帮助,这种感觉很有趣。
GitHub
绝句(+Fix): 新的 parser 章节 · duangsuse-valid-projects/Share@d6f91d7
🐕 duangsuse's shared files(e.g. productive software projects, documents) - duangsuse-valid-projects/Share
Forwarded from dnaugsuz
这星期学校临时放假。
iseki 我这周看了那篇 Hello, declarative world 的文章,然后了解了怎么写关系式的求解系统,正准备生写 Literate Kotlin 文章讲解呢。
其实 unification 的 unify(归一) 就是让两个本来有 "相等关系" 的东西在类似 Binding,存储值的 "State" 里解出它们的实际值如
iseki 我这周看了那篇 Hello, declarative world 的文章,然后了解了怎么写关系式的求解系统,正准备生写 Literate Kotlin 文章讲解呢。
其实 unification 的 unify(归一) 就是让两个本来有 "相等关系" 的东西在类似 Binding,存储值的 "State" 里解出它们的实际值如
x+1=2 => (a)+1=1+1 => a=1,x什么的 variable 就是值被存在 State 里的 first-class 第一类项目,有点类似于模式匹配解构,unify 的过程有点类似于 UnionFind 并查集传递相等关系的过程,就是把一个本来是 a=b 关系的东西变成能直接查询出的那种。Telegram
duangsuse::Echo
https://codon.com/hello-declarative-world
Either(|) Both(&) 这不是比 disjuction, conjuction 对非英语母语的人友好多了么,我英文词感不算差偶尔脑力都跟不上辨别「disj是或」还是「conj是或」。
Either(|) Both(&) 这不是比 disjuction, conjuction 对非英语母语的人友好多了么,我英文词感不算差偶尔脑力都跟不上辨别「disj是或」还是「conj是或」。
Forwarded from dnaugsuz
大佬都懒得讲的,心理总觉得有点不舒服,为什么外国的大佬都肯讲(虽然没有一定函数式编程经验的人也不一定学得会)
国内那些我曾经以为都很厉害的人,偶尔提到这个知识都不肯细讲呢?我觉得打印的这篇文章真心是讲得不错、很细致,除了用 Ruby 所以类型不明确也没我也挑不出什么岔子,只能说是一般方法不同而已。
以前听王垠说 Friedman 是好老师,果然真是个好老师,我都不指望自己能有机会接触关系式逻辑式,听起来多么高大上的东西。
Surprisingly, these six pieces are enough to make a simple relational language called μKanren. It was presented in a paper published only two years ago, in 2013, by Jason Hemann and Daniel Friedman.
miniKanren.org 真的是非常面向小白,而且没有排斥任何编程语言的实现,引用也很得当,我没花什么力气就找到了自己想看的文章。
可这个(当然不是Friedman写的)文章结构良好,我没发现任何还没定义就使用的表达模式、概念和模型,一些大佬的博客里反而都是那种文字,没讲一个语法到底基本模式是什么、一个问题到底为什么出现上来就列代码和一些侧面化的表达,仿佛那是来自他们的直觉甚至是还在转化从别处得到的理解,但直觉这个东西是很不准确的、文章结构顺序是很重要的,我们有太多初学者没有的知识。
我之前说,从理解问题开始理解解决方案,还是从理解解决方案开始理解问题,是创造和重复最大的区别,我觉得作为计算机科学方面的知识没有任何理由不让人先理解问题本身,比如关系式的博文就应该开始列个
现在的我总是比较头疼这样的大佬,可很多大佬都是这样……
许多我见过有知识的人,他们不是很乐意把知识传递给『不如自己』的人,甚至有点发自内心排斥有求知心的菜鸡的感觉。
国内那些我曾经以为都很厉害的人,偶尔提到这个知识都不肯细讲呢?我觉得打印的这篇文章真心是讲得不错、很细致,除了用 Ruby 所以类型不明确也没我也挑不出什么岔子,只能说是一般方法不同而已。
以前听王垠说 Friedman 是好老师,果然真是个好老师,我都不指望自己能有机会接触关系式逻辑式,听起来多么高大上的东西。
Surprisingly, these six pieces are enough to make a simple relational language called μKanren. It was presented in a paper published only two years ago, in 2013, by Jason Hemann and Daniel Friedman.
miniKanren.org 真的是非常面向小白,而且没有排斥任何编程语言的实现,引用也很得当,我没花什么力气就找到了自己想看的文章。
可这个(当然不是Friedman写的)文章结构良好,我没发现任何还没定义就使用的表达模式、概念和模型,一些大佬的博客里反而都是那种文字,没讲一个语法到底基本模式是什么、一个问题到底为什么出现上来就列代码和一些侧面化的表达,仿佛那是来自他们的直觉甚至是还在转化从别处得到的理解,但直觉这个东西是很不准确的、文章结构顺序是很重要的,我们有太多初学者没有的知识。
我之前说,从理解问题开始理解解决方案,还是从理解解决方案开始理解问题,是创造和重复最大的区别,我觉得作为计算机科学方面的知识没有任何理由不让人先理解问题本身,比如关系式的博文就应该开始列个
(x=y) => x is 5 => Yes. y=5 那样的图。现在的我总是比较头疼这样的大佬,可很多大佬都是这样……
许多我见过有知识的人,他们不是很乐意把知识传递给『不如自己』的人,甚至有点发自内心排斥有求知心的菜鸡的感觉。
Forwarded from dnaugsuz
Kotlin 的 type inference 也可以那么做,我们知道,Java 7 Project Coins 的 diamond 可以省略 Type arguments,可那个特性很简单就可以实现,它不需要比老 type checker 多设计太多。
而我们的 Kotlin 非常的强大,比如说你甚至可以定义出这样的扩展方法,Java 是没法推导出
比如我们有一个
应该知道它的 constructor
(我用一种伪语法 <T, T1, ...> 去指定下文类型变量)
可以写明 SomeContainer<Int>、SomeContainer<String> 可对于
所以不可能只死板地"推导"
据说 unification 可以在给定 <T>
但是具体怎么做还是关系式编程,不了解…… 算是科普一下 Kotlin 的一些细节
关系式引用 https://minikanren.org/ http://tca.github.io/veneer/editor.html
List<String> list = new LinkedList<String>(); // Java6这就是利用静态类型系统的规则直接可以得到,何况开始设计的也几乎是说:『只有在类型参数很冗余的时候才简化』。
List<String> list = new LinkedList<>(); // Java7
而我们的 Kotlin 非常的强大,比如说你甚至可以定义出这样的扩展方法,Java 是没法推导出
R 这个类型参数的(不能以扩展函数的形式,而且也推不出来):fun <T, R> T.cast(): R = this as R有两种可以有类型的地方:提供值的地方如
val x: Int = "".cast()
//java.lang.ClassCastException
listOf<Int>()、需要值的地方如 val xs: List<Int> 但不止那个,比如函数参数的需求处也是需求处,这些地方都可以标明类型。比如我们有一个
data class SomeContainer<T>(val item: T) 应该知道它的 constructor
::SomeContainer 的类型是 <T> (T) -> SomeContainer<T> (这里请把 constructor 当成普通函数)(我用一种伪语法 <T, T1, ...> 去指定下文类型变量)
可以写明 SomeContainer<Int>、SomeContainer<String> 可对于
val x: SomeContainer<Int> = SomeContainer() 这种风格就不好看了。所以不可能只死板地"推导"
val 处的类型参数 <T> 而要根据所有能知道的信息『推导』出 T 的实际类型据说 unification 可以在给定 <T>
(::SomeContainer as ((T) -> SomeContainer<T>)) is SomeContainer<WTF> 的情况下推出那个 ((T) -> SomeContainer<T>) 里 T 的实际类型 = WTF,然后就不用手工写了但是具体怎么做还是关系式编程,不了解…… 算是科普一下 Kotlin 的一些细节
关系式引用 https://minikanren.org/ http://tca.github.io/veneer/editor.html
https://github.com/neilgall/KotlinKanren/
Kotlin 的 MiniKanren 也有了,可是 是从 Swift port 过去的,而且实现的易读性、设计的可扩展性都不够,我打算写基础的 "Literate Kotlin" 辅助 JS 脚本(临时),然后实现一个 Kotlin 的 MiniKanren(其实是 microKanren……)。
Kotlin 的 MiniKanren 也有了,可是 是从 Swift port 过去的,而且实现的易读性、设计的可扩展性都不够,我打算写基础的 "Literate Kotlin" 辅助 JS 脚本(临时),然后实现一个 Kotlin 的 MiniKanren(其实是 microKanren……)。
GitHub
GitHub - neilgall/KotlinKanren: Port of SwiftyKanren to Kotlin
Port of SwiftyKanren to Kotlin. Contribute to neilgall/KotlinKanren development by creating an account on GitHub.
duangsuse::Echo
https://github.com/neilgall/KotlinKanren/ Kotlin 的 MiniKanren 也有了,可是 是从 Swift port 过去的,而且实现的易读性、设计的可扩展性都不够,我打算写基础的 "Literate Kotlin" 辅助 JS 脚本(临时),然后实现一个 Kotlin 的 MiniKanren(其实是 microKanren……)。
我来谈谈 Literate Kotlin 的脚本应该怎么写。 #JavaScript
这个脚本,就是要允许我们在文章里嵌入 Kotlin 代码和依赖代码的示例,
然后每个相对独立且可以作为 Kotlin File 编译的部分完成后,显式一个按钮以归总一个部分的代码,并允许在 Kotlin Playground 执行它。
(感谢 JetBrains 特地包装的这个编辑器,使用一点也不困难,尽可能减少了我在无意义事情上花费的时间和痛苦)
至于 Kotlin Playground 的部分他们提供了很简单的 API:
每个独立部分 <template literateBegin /> 起始、 <template literateEnd /> 结束,其中可以有许多不可嵌套的 <template exampleBegin /> 和 <template exampleEnd />。
之前我是直接写 imperative 表述式来 filter 出 language-kotlin 的 <code>,后来我抽提了 nextSiblings 和 takeWhile,就不那么死板了:
这个 filterCode 函数直接给它起始 <template literateBegin> Element 就可以了
然后在页面渲染完成后,可以添加钩子逻辑,来在 <template literateEnd> 后插入一个 button 来显式此部分的代码 <code>。
但关键问题是,如何区分 literate 和 example,这个问题也很好解决,利用『模式(pattern)』来表达:
解析的结果是 literate element 的集合,以及 example element 的集合。
这个脚本,就是要允许我们在文章里嵌入 Kotlin 代码和依赖代码的示例,
然后每个相对独立且可以作为 Kotlin File 编译的部分完成后,显式一个按钮以归总一个部分的代码,并允许在 Kotlin Playground 执行它。
(感谢 JetBrains 特地包装的这个编辑器,使用一点也不困难,尽可能减少了我在无意义事情上花费的时间和痛苦)
至于 Kotlin Playground 的部分他们提供了很简单的 API:
playground('code') // enable on all <code>
所以我们只负责拼合代码。每个独立部分 <template literateBegin /> 起始、 <template literateEnd /> 结束,其中可以有许多不可嵌套的 <template exampleBegin /> 和 <template exampleEnd />。
之前我是直接写 imperative 表述式来 filter 出 language-kotlin 的 <code>,后来我抽提了 nextSiblings 和 takeWhile,就不那么死板了:
function *nextSiblings(e) { for (let c = e; c!=null; c=c.nextSibling) yield c; }
function *takeWhile(p, xs) { for (let x of xs) if (p(x)) { yield x; } else break; }
function filterCode(begin_e, p = e => e.classList.contains("language-kotlin")) {
let neighbors = nextSiblings(begin_e);
let section = takeWhile(notSectionEnd, neighbors);
return [...section].filter(p).map(e => e.innerText).join("");
} 这个 filterCode 函数直接给它起始 <template literateBegin> Element 就可以了
然后在页面渲染完成后,可以添加钩子逻辑,来在 <template literateEnd> 后插入一个 button 来显式此部分的代码 <code>。
但关键问题是,如何区分 literate 和 example,这个问题也很好解决,利用『模式(pattern)』来表达:
Sections = {Section}
Section = <template literateBegin/> (anyElement|Example)*? <template literateEnd/>
Example = <template exampleBegin/> anyElement*? <template exampleEnd/>
这么做是为了 literate|example 模式数据提取实现不止可用于 Kotlin 代码,之后我们从 anyElement 中 filter 出需要的 Kotlin code。解析的结果是 literate element 的集合,以及 example element 的集合。
GitHub
GitHub - JetBrains/kotlin-playground: Self-contained component to embed in websites for running Kotlin code
Self-contained component to embed in websites for running Kotlin code - JetBrains/kotlin-playground