duangsuse::Echo
715 subscribers
4.25K photos
127 videos
583 files
6.46K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
https://segmentfault.com/a/1190000012641345 #Java #DontKnow #Stream
其实 ParserKt 里出现过的 Reducer 在 Java stream 里叫 Consumer, 动词都一样

这是个 Java8 StreamForker 实现,可以流一遍出多个结果,实质上和我的版本功能一致

简单说下, builder() 出一个 Consumer 然后会被拿去 sequential().forEach()
其中 m1.entries.reduce(new Map 的是 ... 啊不对, reduce(initial, op, op_finish={ m1.putAll(m2); m1 })
这实际相当于 forEach { (k,v) -> m1[k]=waitOperationTo(queues, v) }
其中 queues:List<BlockingQueue<T>>
m1=forks as Map<Object, Function<Stream<T>, ?>>

waitOperationTo 把 StreamSupport.stream(newSpliterator(addQueue()) ) 在 CompletableFuture.supplyAsync 里 apply 给 op

它返回 ForkingStreamConsumer(queues,actions=m1) , 这个里面定义一个 EndOf S(tream) 对象是“帮助”被 queue 的子 stream 鉴别的, finish() 时使用

accept() = queues.forEach(q -> q.add(item));
get(i) = ((Future<R>) actions[i]).get();
Forwarded from duangsuse::Echo (duangsuse)
fold.kt
1.1 KB
#Kotlin #OOP "小王 老猪 阿司马 某A君".split(" ").map(String::length).fold { reduceAll(::minMaxer, ::averager) } == arrayOf(2 to 3, 2)
Forwarded from dnaugsuz
Reducer 这个设计是我之前写那啥的时候搞出来的,有一段时间了但设计没变
想必工程界也有框架有类似的功能吧,但是语言自带的库一般都写得很垃圾,不能过一遍生成多个值……
Forwarded from PollutedHeck
看了下 Java8 实战,附录有提到用 StreamForker 并行用一个流出多个结果
有兴趣可以自己去看看,相当于一个 fork 的操作
看了以后我算是了解了下 Java 的流,和 Kotlin 的 Iterable/Collection operators ext funs 完全不是一个概念,这个流是 queue,async 的

但是上面实现的人明显不重视简洁性(甚至在 map.assignEach {v->op(a,v)} 时有拽技巧的嫌疑)

我感觉不是很优雅。(M<V>=Map<Object,V>) 理论上 forks: M<Function<Stream<T>, ?>> 不能说难看,应该说是错的,完全滥用了流窗口大小 (不对,本身没有窗口,应该说传参方式太奇怪了

forks: M<String, Consumer<T>> 才算正常,或者说这根本就应该实现为组合些许 Consumer 的 Consumer 才对

在 build() 里它把函数们默认参 ()->op.apply(queueStream) 再套了一层 future (supplyAsync) ,然后再在 consumer 里 apply(x) = queues.forEach { it.add(x) }
get(i)=actions[i].await() ?

实际上就是 workers: M<Pair<Queue<T>, /*supplyAsync(op.bind(queueStream))*/Future<R>>>
🌚?? 这么麻烦
Forwarded from dnaugsuz
https://t.me/dsuse/15727
总结了下,最后得出三行:
workers: Map<Object, Pair<Queue<T>, Future<R>>> = forks.entries.associate { (k,op) -> val q=BlockingQueue(); k to (q to Complet_Future.supplyAsync(op.bind(SSupport.stream(BQSpilterator(q)) ))) }

apply(x) = workers.forEach { it.first.add(x) }
get(k) = workers[k].second.get()/*await*/


queues 也可以不放在 Pair.first ,而独立成 List 或 Set 。
原版的其它函数:
finish() = apply((T)(Object)END_OF_STREAM) //unchecked cast

getResults() = sequential().forEach { accept(it) }.let { finish(); this }


Forker 类的 fork() 和 build() 感觉不至于用设计模式、命名失败,不作评。

Forker 可以用于归纳流至结果(如 1,2,3 => 6),但是默认带 async ,而且你的 op: Function<Stream<T>,?> 必须处理一个 (Object)END_OF_STREAM ,返回类型无泛型参数,需强转
看了我真的觉得一些 JavaEE 者必须学习一个,净搞些花里胡哨的,功能都没做好。
Forwarded from dnaugsuz
如果看的懂的话,可能我就没时间写它了🌝
想要提高技术水平,就必须压缩不重要的细节带来的时间开销,否则很难有精力走下去而不被表象蒙住眼睛。

其实原版也半通不通吧…… 看看以后能不能有改善
#essay #Java 想了下最近队列的代码坑 #js #python
#Java #serialize #parsing, [18.01.21 10:11]
chen leiothrix: json反序列化的时候,有key对应两种不同结构有什么办法能针对性读取吗

捏造的信仰: [In reply to chen leiothrix]
这种情况的原因是类型信息缺失。如果你用 Jackson 可以看这篇 https://segmentfault.com/a/1190000023218408

ヾ(^▽^*)))Sam: 这种你的分别处理
要根据value值去if else
没啥好办法

I lluZ: 是的,直接当 map 处理,没法反序列化成一个 List<POJO>

ヾ(^▽^*)))Sam: list不行,因为你的数组不属于同一个类型无法搞
https://github.com/ice1000/arend-language-server/blob/88dd2e94ea7ae564a743d349b93487dd5aa4b5f8/src/main/kotlin/server.kt 草,原来冰封那么厉害也没有写自己的 Argument Parser... 我还以为函数式爱好者都痛恨 (org.apache.commons.cli) 需要 (opt as Options).addOption(Option.builder("i").build()) 的代码呢
看来事情还是要一分为二的去辩证地看待 🤔

现在想来我几乎从不用第三方的库,凡事只要行数限制不大,能自己动手,决不允许任何可能的辣鸡代码掺进项目里,哪怕有也要自己先封一层。
可能这就是编程习惯的问题吧
This media is not supported in your browser
VIEW IN TELEGRAM
第一次知道原来大佬也有不重视代码质量的时候(话说我是有点强迫症吧……)
20 行要我就不会用 o.addXXX(cfg.build() )

opt.initArgs("""
c client-port language-
s server-port language-
a client-host ?language client hostname, default localhost
i interactive ?start the Arend REPL
""".trimPadding())


我对代码的追求,慢慢也从仅排版整齐上,变成了空格排版项目范围内语义一致、重视代码简洁性和可配置性;想想以前的我看见现在的代码,估计会觉得很难看吧 🤔

fun Options.initArgs(code: String, sep: String = "-") {
addOption("h", "help", false, "print this message")
code.split("\n").forEach { line ->
val (s, sLong, desc) = line.split(' ', limit = 3)
val opt = Option.builder(s).longOpt(sLong)
if (sep in sLong) opt.hasArg().argName(sLong.substringAfter(sep))
opt.desc(if (desc[0] == '?') { opt.optionalArg(true); desc.drop(1) } else { desc }.replace('-', sLong.replace(sep, ' ')) )
addOption(opt.build())
}
}

运行时开销又高了😂 不过总体看处理了 3种 case (normal+1param+optional, 交织的不算),还是挺清晰的
duangsuse::Echo
https://github.com/ice1000/arend-language-server/blob/88dd2e94ea7ae564a743d349b93487dd5aa4b5f8/src/main/kotlin/server.kt 草,原来冰封那么厉害也没有写自己的 Argument Parser... 我还以为函数式爱好者都痛恨 (org.apache.commons.cli) 需要 (opt as Options).addOption(Option.builder("i").build())…
#Java #Kotlin #GitHub #project #suggest 评论一下我之前开发的 ArgParser 😂
是个好东西,对命令行参数的建模也很好,就是 addHelpSubCommand() 这样的帮助函数,没有考虑到应用的需要,应为 addHelpVerCommand 不对,这个是显示子命令树结构的... 那个 -h -v 的也应该有,但可以另加
还有,生成命令行补全的代码也该加

存在的一些问题,包括强类型约束过于严苛(为此还有 ArgParser4~1 的泛型), 以及 subcommand&formatter 参数实现未测试的瑕疵("All tests passed" 但复杂了 我不敢保证) 😂
(Apache: 你敢和我比?🌚强大吗? 还有 "<!s #d"fmtstr...)
谈谈 "both [src...] [dst] and [dst] [src...] are supported" 是怎么实现的吧
我们的解析器是流式的(因为框架很重视不同甜度需求的复用性,它是一层层建起来的,其根基 SwitchParser 就是基于状态机构建输出数据结构的)

所以实践上 [src...] dst 里你怎么知道 srcs 不能把最后一个 dst 也解析了(看起来 dst 也可以理解为 src 的一项啊) 🤔? Py 的 argparse 也支持这样(但我不清楚它的架构细节),总之没有一些较 dirty 的 hack 是比较不容易的。

一个即得的技巧是,记住上一次读的 list ,然后读 dst 时从 vararg items 里“偷” 一个项目出来,末尾有 N 项就“偷” N 次。
另一个技巧是寻找 vararg items 的 position ,解析时直接就算 srcs 有多少项,取了跳过 (有点类似 Lua 虚拟机对不定长参函数的编码方法,但这种方法可以做成支持多个 vararg 的不知道有啥样用)

ArgParser 的解决方法比较骚,因为它支持 unparse (backRun) ,换句话说它可以先用无问题的 [dst] [src...] 解析(通过动态构造解析器),再把整个 items 拼了转过来
没有那么高级,其实只需要把参数输入和解析结果,共反转两次就够了 🌝(不过依然要用到 backRun 😂
这是为什么呢? 因为我们必须先检查参数是否合法,并且取得其中 item arg 部分…… 但如果你的代码没有用到 reverse, 相应 backRun 逻辑是不需要的(只是即便这样 progurad 等工具也不知道它可以 delete 掉 (x
#tencent #Haha 😂 想到华为之前挺的那个啥 Linux OS
Forwarded from 某10