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
duangsuse::Echo
思维江化,无法和曾经费了很长时间想的模型对应起来。
This media is not supported in your browser
VIEW IN TELEGRAM
想到了,原来我让 next() 去回 lastItem,然后 [1, 2, 3] 第一次 lastItem=1;next 流就是 [1,2,3],比之前 constructor: lastItem=gen.next() 多 next 一次是为了 next 出所有项目包括 peek 的。
而现在的 peek 实际上更加直白,就是让 iterator 把那个直接补回去,不必再用 tailConsumed 那一套 peek+yield in next 修补方案了,也没有 tail 需要特殊处理的问题。
而现在的 peek 实际上更加直白,就是让 iterator 把那个直接补回去,不必再用 tailConsumed 那一套 peek+yield in next 修补方案了,也没有 tail 需要特殊处理的问题。
class SaveIterator {
constructor(gen) {
this.gen = gen;
this.res0 = gen.next();
this.lastItem = this.res0.value;
}
*iterator() {
if (this.res0.done) return;
yield this.lastItem;
for (let item of this.gen) {
this.lastItem = item;
yield item;
}
this.lastItem = undefined;
this.res0.done = true; //no next
}
[Symbol.iterator] = this.iterator;
}let b = new SaveIterator([1,2,3].values())
[...takeWhile(x => x < 3, b)] //Array [ 1, 2 ]
b.lastItem //3
[...takeWhile(x => x <= 3, b)] //Array [ 3 ]
b.lastItem //undefined