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
duangsuse::Echo
import java.nio.ByteOrder as NioByteOrder typealias Cnt = Int typealias Idx = Int typealias IdxRange = IntRange typealias Buffer = ByteArray infix fun IdxRange.untilSize(size: Cnt): IdxRange = this until (this+size) //0 until (0+10): 0..9 inline val IdxRange.size:…
Reader 可以是跨平台的,我去看看 Kotlin stdlib 的 io 包
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/index.html

……
还好Kotlin没有多做封装,kotlin.io 只有JVM的定义,要不然我的封装就没有意义了。

……
https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.files/-blob/index.html
这是我们的『InputStream』
(JS平台需要不一样的这个东西,所有平台提供同一个 Reader/Writer 但无法统一它造于什么东西)

https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.files/-file-reader/index.html
fun readAsArrayBuffer(blob: Blob)
需要这个东西来从用户文件提供 ArrayBuffer

https://kotlinlang.org/api/latest/jvm/stdlib/org.khronos.webgl/-array-buffer/index.html
ArrayBuffer(length: Int)
需要这个东西来弄 InMemoryWriter 的 constructor

https://kotlinlang.org/api/latest/jvm/stdlib/org.khronos.webgl/-data-view/index.html
这个是重头戏,但没有 readLong,只有 JVM 平台有……
fun getUint32(
byteOffset: Int,
littleEndian: Boolean = definedExternally
): Int


看来Common的定义只能缩水了?


但是,全部平台都有

interface BinPattern<ST> {
fun read(reader: Reader): ST
fun write(writer: Writer, data: ST)
val byteSize: Cnt?
}
abstract class Tuple<E>(override val size: Cnt, initial: E): Sized {
private val storage = Array(size) {E}
operator fun get(index: Idx): E = storage[index]
operator fun set(index: Idx, value: E) { storage[index] = value }

data class Index<T: Any>(val index: Idx) {
@Suppress("UNCHECKED_CAST")
operator fun getValue(self: Tuple, _p: KProperty<*>) = self[index] as T
operator fun setValue(self: Tuple, _p: KProperty<*>, value: T) { self[index] = value }
}
protected fun <T> index(no: Idx): Index<T> = Index(no)
fun toString(limit: Cnt): String = "Tuple(${xs.joinToString("|", limit = limit)})"
}
operator fun <E> Tuple<E>.component1() = this[0]
operator fun <E> Tuple<E>.component2() = this[1]
operator fun <E> Tuple<E>.component3() = this[2]
operator fun <E> Tuple<E>.component4() = this[3]


以及 Seq, Repeat, Cond 解析器,和 little, big; int8, int16,... 这些子结构

一时间支持 JVM 和 JS,Native 不能立刻支持。
其实 ByteReader 就是我们对 InputStream 的抽象的……
Kotlin 相较于其他『高级程序设计语言』一个最显眼的好处就是对很多东西有更抽象、更泛化更普适的描述。允许程序员只描述问题本身,而不是疯狂描述各种各样为了伺候程序控制流做的制杖事,比如 Ranges。Java 程序员用了不知多少年的 int i = 0 while (i < stop) { ...; i++; } (或许你也可以说这应该用 for(int i=0; i<stop; i++) 且带step也可以这样,但依然远远不如 Kotlin 直观,更不用说加上函数式风格的 filter/find/zipWith 了),真是忽如一夜春风来就给改 for (i in 0 until stop) ... 了,直白100倍,而且还有基于「块(code block)」的 repeat 直接 EmbeddedDSL,还能让一些程序换 tailrec 写从而更直白,真是打了某些自以为自己的算法很高级而从不考虑可读性的辣鸡程序员的脸,Java真是被爆得渣都不剩啊!这还只是程序抽象级别上的,没提到比 Java 深思更多的语言设计和新世纪以来最有用的设计成果以及19xx年都有的研究(如coroutine、closure)。

比起其他语言 Kotlin 对抽象层次重视绝对是 Scala/Haskell 的级别,但不至于把抽象本身做成一种问题而是只为实际工程服务,所以 Kotlin 还有 extension function、extension property 这些方便直观而且自然的语法及特性,某辣鸡 Jawa 和 JVM平台上什么 Decorator 呦、什么 capture 呦 PECS 呦、lazy initializer 还『双检锁』高端得跟 upvalue/continuation 一样,不仅类可以"final"而且字段甚至参数也都能"final",真是把数学式"多态"的糟粕都学干净了。还各种 XML 式的『DSL』,还上Groovy这个IDEA都不屑于给好好支持的『脚本化语言』,真是隔壁 Ruby 都比它强 1k 倍,一切皆对象但是一切皆模板,不是太模板甚至于死板就是太『灵活』。好的语言就不该有模板,为什么模板不应该用对语言/库的设计来解决?所以包含了历史沉淀渣设计的辣鸡Jawa应该退休了,立刻。
本苏是这么实现的
尽管Kotlin没法给类级的泛型弄成真泛型,但运行时许多JVM会有优化(其实也不必想这些的)
而且我们的库主要还是给人读写用的不需要太复杂。

Cond 属于之前我没想过的情况,不过还好,也写出来了。
  final override var position: Cnt = 0
private set
🤔 为什么 getter 是 public 的 open class 里的属性只能 final?
JDK 的程序员脑子里是怎么想的,为什么 FileInputStream 没有 position,RandomAccessFile 还非得自带 DataInput?真当所有东西都需要一个 DataInput???
足以体现抽提代码重要性
谁敢维护 Java 的 DataInputStream/DataOutputStream? 那样的东西看起来简直就是个噩梦 😟
不要说没自动化IDE,就算是有的时候碰见那种代码质量也会像吃了 💩 一样难受,如果有 bug 肯定要『平安夜,调试一整夜』喽。
duangsuse::Echo
足以体现抽提代码重要性
这就好像是赶一群羊,找到头羊就可以领着一起走,不然一堆代码各走各的,都不听你的。写起来简单机械一点,改起来看起来通通选择死亡。

Ctrl+V『写代码』一时爽,测试修bug火葬场。
🤔JavaScript 基于 ArrayBuffer 和 DataView 的兼容抽象部分已经写完,暂时不对其正确性作任何保证。
正在准备开源到GitHub。
duangsuse::Echo
🤔JavaScript 基于 ArrayBuffer 和 DataView 的兼容抽象部分已经写完,暂时不对其正确性作任何保证。 正在准备开源到GitHub。
https://github.com/duangsuse-valid-projects/Binarie 已经开源

这周可能不会继续开发下去了,那对我的精力来说有点勉强……

目前为止,Binarie 的 JS Reader/Writer 部分已经完成,可是 JVM 利用基础 BasicReader/BasicWriter(待写) 和BitConvert的部分待补完

应该说开发过程也是有点意外的,我开始的时候不知道自己打算用ES6的DataView和Int8Array (ArrayBufferView)来进行BasicReader实现,也没想到MarkReset在大部分子类会以oldPosition的形式被实现,略微有点不适应。
Forwarded from duangsuse Throws
#China #Low #PLT 😏中文编程也真是可怜。懂的人对它嗤之以鼻,一提到立刻说它是肤浅的、表面的,偏偏是完全不懂和半懂不懂的人稍微有点或空无一物或半通不通的『实践经验』
不知道是不是和之前的『汉芯』一样,因为易语言的4kw坏了名声?呵呵呵……但不管怎么样易语言的确是广为诟病了。
感谢之前某位细心观众提醒的用法 *?,我还以为只有加flag才能非greedy呢。
Lexical Scoping 我不用说吧,递归下降解析了解到 (lambda (a b) (+ a b)) 的 formals 里的 "a" "b" 与 body 里 (+ a b) 存在的1:1对应关系,就可以很自然地把他们联系起来了,之后怎么处理都好,例如像 Lua 一样把它们翻译为函数局部寄存器的编号,然后每次调用的时候给它们分配一对一的存储空间,caller调用侧和callee被调用侧都知道那个"a" "b"是指代哪片分配就好。
duangsuse::Echo
既然都这么弄了,还不如直接把优化写成代码算了……
虽然那个栈的中缀链貌似很高级,而且貌似递归下降的在很极端的情况下输出和 JS 不同,但我还是觉得应该选它,至少它看起来很简单,只 (base, op_left) 两个递归参数就够了,最重要的是它使用的栈是在语言层面受到支持的,而且这个支持本身实现的也很优雅很妥帖(要不然那语言还有用么……)。