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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
全貌。 就这么一点逻辑还加一句一注释演技真是浮夸啊…… 很多 if 其实都只有一个语句,它偏偏要加缩进 而且还在那句上加个无关紧要的注释,真是把我以前在 Java 见过最烂的注释方式移植到 Kotlin 上了,一句一注释,而不是把这些破烂集合到内联文档垃圾场去,的确是很 Kotlin way 啊。 😠
看着这种优化的「注释」方式,我想起了那句“:shi味咖喱饭,还是咖喱饭味的:shi”…… (和谐
不管你怎么改,也只是从外表难看变成内部难看而已……

还有那个 if (treatAsOption && ..) if (!treatAsOption) 又是什么鬼啊……
还有 if (treateAsOption) { if (!p) // Argument is found } 这个注释又是什么鬼逻辑…… 难道这个开发者不懂 found 是什么意思?
This media is not supported in your browser
VIEW IN TELEGRAM
学到了学到了,不过这样的代码我是不会再以非重构目的阅读了就是。
乍一看非常厉害,其实也没啥算法,而且都是在无用的地方下篇幅,死板的机器 formatting 我也会写那种 reformater 呢,何必呢。

从根本上设计就有问题,过于复杂,看起来再难以理解也只是给自己添麻烦而已,能做出什么呢? 支持的太多,最后反而一个也用不到,自己也弃坑了,简直是暴殄天物。 Kotlin 这样融合OOP和函数式优点的语言拿来写这种烂代码、虚浮的内部建模,没有多大意义
混乱的代码就不多发了…… 这个拿来充当反面教材都太重口了。 隔壁的 CliKT 代码质量比它高到不知哪里去了,我从那抄 multiplatform 的无趣味代码抄得谈笑风生,而且都不需要重构。
duangsuse::Echo
混乱的代码就不多发了…… 这个拿来充当反面教材都太重口了。 隔壁的 CliKT 代码质量比它高到不知哪里去了,我从那抄 multiplatform 的无趣味代码抄得谈笑风生,而且都不需要重构。
仔细解读下这个反面教材哈, #Kotlin
1. optionFullFormPrefix 太长了(别告诉我没法短,不能短也得想办法变成 Pair 之类的弄短!)
2. 顺序虽然是统一的出现/依赖顺序而非重要性顺序,但和 prefix, delimiter, deprecatedWarning 放一起实在太草了,何况也并非严格按建模对象的出现顺序, full/short prefix 其实是并列的。
3. textDescription: String get() = 没有问题,但是后面还有一个 formatHelp: String get() {} 就实在是太糟心了
4. TResult ? 难道你不用 R 吗? 而且 T: Any 的 constraint 真的有意义吗? 很多时候在有 null T? 成员时根本不必显式指出的
5. 排版问题。 T? 和 T ?
6. ArgType<T> 和 TResult 的关系存疑,理论上只应有一个。 要知道 ArgType 是包含 convert 方法的。
7. Nullable 的东西太多了,设计建模可能有误会没消除
🤔 #zhihu 上看了 #Cplusplus 的一个 stream lcm 最小公倍数:
#include <iterator>
#include <numeric>
int main() {
int[] xs = {2,3,4,5,6};
cout << reduce(begin(xs), end(xs), 1, lcm<int,int>);
cout << endl; //^ 60
return 0;
}
https://coolshell.cn/articles/21003.html #web #security 草,原来字符串比较算法的耗时也可以被用来猜密码, str.zip(str1).fold(true) { (a, b) -> a xor b == 0 } 而不是 str.zip(str1).firstOrNull { (a,b) -> a!=b }
我艹受不鸟了,这是啥玩意啊『前端』……
#Cplusplus 这个 template 技巧收下了!
C/C++ 函数返回值可以不确定吗? - IceBear的回答 - 知乎
https://www.zhihu.com/question/414206269/answer/1408101568

template<> int f<int>() { return 1; }
template<> bool f<bool>() { return true; }
or:

variant<int, bool> produce(string &type) {
return true; //有时需先声明作局部变量 不然类型错误
}

auto visitor = [](auto &&arg) {
using T = decay_t<decltype(arg)>;
(is_same_v<T, int>)? f_int()
:(is_same_v<T, bool>)? f_bool()
:nullptr;
}
std::visit(visitor, value);
🤔 老实说我现在最看得起的「设计模式」只有 Delegate, Observer, Visitor, Kotlin 的 scope function let/run/apply/also 和 null/elvis chain 以及 OOP 原生的 嵌套式构造器调用、字段初始化、方法解析 。
This media is not supported in your browser
VIEW IN TELEGRAM
玩得再花,不能解决实际问题也是废物。还不如实在点、自然点,在合适的层次解决真正的问题。
所以说设计模式什么的都滚蛋吧…… 只有数据模型和程序的共鸣最重要

最近我设计的 ArgParser 和 ParserKt 也都只用了 Delegate/Visitor ,没有其它古古怪怪的 Adapter,Provider,Builder,Factory,Command 这样的东西,无脑的复制 pattern 显然是不好的,乱用各种 -er 对象更是不可取的操作……

所以说把函数式拿来修复面向对象的设计模式里各种奇奇怪怪的名词是最好的选择,而且也解决了函数式不明确、太隐晦的问题。
动态规划和递归算法有什么不同呢? #Algorithm #zhihu

动态规划是递归的子集,它解决的问题包含子问题有重复的情况。

比如说 factorial: 1 -> 1 ; n = (factorial n-1)*n , f(9) 和 f(10) 最终都会调用到 f(2) ,如果不缓存的话开销比较大,而且不能把俩子问题放一起平行比较。
在算 fib(n) = 1 -> 1 ; 2 -> 2 ; n -> fib(n-1)+fib(n-2) 的时候就更明显了,递推调用栈会变成长长的一串,所以递归也不是万能的,主要是用来写 DFS(深度优先搜索)
……有时候感觉 C++ 的设计还蛮一致的:
+ auto 在 C 里是和 register 一类的 storage classifier ,默认是栈上分配, 而 C++ 只是添加了自动类型的特性
+ template<> void op<>()lambda 的 []() 参数顺序有异曲同工的感觉, 都是上下文性质的形参放前面、参数放后面
duangsuse::Echo
🤔 老实说我现在最看得起的「设计模式」只有 Delegate, Observer, Visitor, Kotlin 的 scope function let/run/apply/also 和 null/elvis chain 以及 OOP 原生的 嵌套式构造器调用、字段初始化、方法解析 。
刚才没把 Observer 加进去,其实 ParserKt 的两个版本里都用了类似 Observer 的东西 —— Reducer<T, R> ,类似 java stream 的 collector ,它可以分配一个新对象,在流上运行 onAccept 方法并 finish() 出结果。
Observer 就比我私自造的 Reducer 多一个可选的 onError 方法,所以它是一个完整的设计模式,和 Promise 一样同时定义基于 Exception 的异常处理。 (术语当然是有区别的, Observer 的是 onNext, onDone, onError ; 我用 accept 是为了和 Consumer 的动词保持一致以及强调语义)

onAccept 是被动侧,处于调用栈的上方,无法捕获调用侧的异常,所以就把捕获逻辑做到栈下方的主动侧,再把异常传到 onError 那里
哇原来我之前在 #Haskell 里看到的就是这种…… 这个大佬很厉害
https://teek.readthedocs.io/en/latest/_modules/teek/_tcl_calls.html#init_threads
def _pairs(sequence):
assert len(sequence) % 2 == 0, "cannot divide %r into pairs" % (sequence,)
return zip(sequence[0::2], sequence[1::2])

#Python
_pairs xs = zipWith (\a b -> (a, b) ) xs (drop 1 xs)

*注:Haskell里\a b = lambda a,b: ,而且它的xs::(List a)是纯流式的
Python的slice with step xs[start:stop:step] 这样写了,默认可以省略的 ( [0:len(self):1] )