/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
修问题要修在 root cause
果然实践是检验真理的唯一标准,不测试无编程
/tmp/duangsuse.sock
val hanDigit = MapPattern(mapOf( *"一二三四五六七八九".asIterable().zip(1..9).toArray()) ) val hanUnit = KeywordPattern<Int>().apply { mergeStrings("" to 1, "十" to 10, "百" to 100) mergeStrings("千" to 1000, "万" to 10000) } >>> val k=NumUnitTrie(hanDigit, hanUnit…
我来说一个能解决输出问题,但是不能解决检查问题的:
val hanDigits = "一二三四五六七八九".asIterable().map(Char::toString).zip(1..9)
val hanDigit10s = hanDigits.map { it.run { "十"+first to 10+second } } // 闹着玩的,不能这么干
lateinit var hanShow: (Output<Char>, Int?) -> Unit
val hanDigit = object: KeywordPattern<Int>() {
init { mergeStrings(*hanDigits.toArray(), *hanDigit10s.toArray()) }
override fun show(s: Output<Char>, value: Int?) { if (value == null) return;
if (value in 1..9) super.show(s, value) else hanShow(s, value) }
}
val hanUnit = KeywordPattern<Int>().apply {
mergeStrings("" to 1, "十" to 10, "百" to 100)
mergeStrings("千" to 1000, "万" to 10000)
}
val k=NumUnitTrie(hanDigit, hanUnit, IntOps)
hanShow = k::show
/tmp/duangsuse.sock
我说说绝句里的情况吧。除了负数和小数,刚才我提到的 pattern 都是支持的。 特殊处理大概就三种: + 零..九 + 十一..十九 + 一千零一
我没支持到“亿”,因为那个数太大了
至于几百万的,在 NumUnitPattern 里,这很难实现,于是我避重就轻选择了特化支持 百万、千万这种单位,

但是一千二百又百 (此时的“又”等价“零”)是支持的。
……算了,这情况也不好说
/tmp/duangsuse.sock
我没支持到“亿”,因为那个数太大了 至于几百万的,在 NumUnitPattern 里,这很难实现,于是我避重就轻选择了特化支持 百万、千万这种单位, 但是一千二百又百 (此时的“又”等价“零”)是支持的。 ……算了,这情况也不好说
……“百万”的特例化支持,我也觉得是停止的好,因为它扰乱 show 的运作了
还是 三百又万 吧,严谨不少。
listOf("十", "百", "千").forEach { val k = this[it]!!*10000; this[it+"万"] = k; this[it+"万零"] = -k } 删了。

k < 0 -> op.times(abs(k), i).also { s.error("零 form cannot be used in initial part") } 又删除了个
Forwarded from Deleted Account
我把那个能够辅助读写汉字数值的 Pattern 弄出来了,然后在上面实现了个能读写汉字数的 Pattern [commit]
Forwarded from Deleted Account
/tmp/duangsuse.sock
改天得拿这个把 那个文档 更新下
敬绝句一杯 🍻,折腾了这么久,总算是又进一步!
https://zhuanlan.zhihu.com/p/106578320
我就说说这个『橙式』吧。ParserKt 的复用性可以做到直接处理。(ParserKt 的复用性厉害吧?能写 lexer 能写各种 parser 能处理双向转换,连单位进制换算都能做)

val 不翻译 = Convert(stringSurroundBy('¥' to '¥', anyChar), { "-" + it }, { it.drop(1) })
val 翻译器 = KeywordPattern<String>().apply {
mergeStrings("函数" to "fun", "量" to "val", "变" to "var")
mergeStrings("若" to "if", "否则" to "else", "判" to "when")
mergeStrings("当" to "while", "对" to "for", "在" to "in")
}
val 翻译 = Piped(翻译器) { "+" + (it ?: takeWhile { c -> c !in 翻译器.routes }.joinToString("")) }
val 橙式构词 = Decide(不翻译, 翻译).mergeFirst { if (it[0] == '+') 1 else 0 }
val 橙式 = Repeat(asList(), 橙式构词).Many()
Forwarded from Deleted Account
想问下各位大佬 这么写的错误在哪里(list2有值 但输出acty1的时候报了空指针)
Forwarded from Deleted Account
其实这样不能全怪我吧…… 毕竟这个
List<TTeam> list1 = hadJoinTeam(2, user.getId());
List<TActivity> activities = List.of();
for (int i=0; i<list2.size(); i++) { TTeam it = list2.get(i);
Activity activity = checkActivity(it).getId();
activities.add(activity);
out.println(String.format("下标为%i的值为%s", i, activity/*==activities.get(i)*/.getName() ));
}

你写得可谓是优雅…… 几乎把 Java 写成 C 了,那个命名风格我是看不太懂,有点超乎时代和传统,绝世而独立……

当然在 Kotlin 里这个程序就三行。
val team1 = users.filterInTeam(1)
val team2 = users.filterInTeam(2)
val activities = team2.map { it.checkActivity().id }
activities.withIndex().forEach { println("下标为${it.index}的值为${it.value}") }

至于 service 数据依赖怎么办,继承抽象类就可以用里面的扩展方法了。
当然如果觉得那太魔法(因为引入了一个隐式的 Service 的 this)
val teams = listOf(1, 2).map { service.filterInTeam(it, users) }
val activities = teams[1].map(service::checkActivity).map(Activity::id)

最后一行还可以提出来成 fun <T> Iterable<T>.debugPrintln(),有重复代码就直接调用了。
Forwarded from Deleted Account
直白点说吧,这种命名风格,抛弃现在 Java 一般的 TypeName, methodName, variable_name, argument_name 和与 stdlib 的风格兼容不提,
用 tb_typevariablename, methodname, getTypeGettername, variablename, argumentname)
如果 tb_team 是一个 type argument,那么 tb_team team1; 这种形式如何? tb_team getTeam_heading(); 呢?这样的名字重复了多少次?

算了,命名分词风格明确性的问题如果熟悉了其实也不重要,重要的是,不管是英语母语还是非英语母语,这样一堆 lowercase naming 和 underscore _ 的代码,在 Java 里是没人看得懂。
camelCased 的流行不是没有原因的,对 alllower 这种让人半懂不懂的风格的滥用基本已经随那个连多态都没有的 C (ver89) 离去了,现在即便是 C++ 和 Python 都有不少人不用或尽可能少用 alllower。

而且明明知道 acty1 是 List<Activity> 并且上面的 get(int) 返回 Activity,还要写叫 getActivity_name 的 getter,理论上好像是很没毛病(因为 class field 的 naming 是 snake_cased、getter 的前缀必须是 get、TypeName 是 Capitalized),这强迫症……
Forwarded from Deleted Account
如果一个程序员对语言都不够熟悉,经常语法错误
抑或是维护项目的过程中对命名这种东西都一头雾水

那些代码,看着再“高级”都只是累赘,没意义的表达结构会给日后的修改维护造成很大的困难。
编程重在逻辑和范式,不是重在对逻辑的文本表达,更不是重在毫无分析评测的“高性能”、开发用什么 IDE、文本编辑器、操作系统、甚至读一本技术书有多“快”上。

要写那种一行比十行的代码,这样日后修改和阅读也是读一行、改一行,十倍效率。
明明自己写出来的东西就是三四行的级别,在明知有更好的方法后还偏偏弄成十几二十行的话,受累的只有现在的自己和以后的自己,甚至连累上自己的队友一起迷糊。

如果你连对定义/控制结构的记忆和维护都有点作难(虽然很多人不愿意承认,他们觉得自己很聪明),那如何进行进一步的逻辑抽提和重构,甚至架构升级?

这也就注定了这种程序是被堆砌的,不是被设计的。 如果你去问它的“设计”者,设计者也总结不出到底有什么模型、依赖了什么操作、数据的流动和程序流程里的依赖,甚至于使用到的范式以及依赖实现语言特性的定义,因为他只可能看着原有的代码随手加上简单即得的新代码。稍微复杂点的算法如果也以这种方式加进去,画面太美我不敢看。

随着这样的项目的代码行数所增长的,不是作者对代码本身的理解,甚至也不一定是作者对代码使用的熟练度,往往只是维护的复杂度,偶尔顺带导致性能和安全性、健壮性的下降而已。

我真的不是很理解,为什么一些非常明显的 pattern(不是说类似 Kotlin 里 withIndex 那种复杂点的 pattern)许多人也都允许模板程序一遍遍出现,还觉得那么做性能“很高”。
既然写应用,就写好看点,难道应用也不容易写好看么…… #statement
哈哈哈哈笑死我了
This media is not supported in your browser
VIEW IN TELEGRAM
ParserKt 我觉得它可以考虑下,是不是要允许有一个 StatedFeed…… 我注意到 检查闭括号的程序的错误提示,好像需要开括号的位置……