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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
http://passer-by.com/relationship/ 丈母娘=老婆的妈妈 #relation #functonal 对!要的就是这个 🌚
下次关系式实践就一定要弄这个,可以算过去可以推出来,非常实际,还能支持 ABCD 变量是最好的了

要是只支持一个方向多无聊, 父母儿女 兄弟姐妹 拿 Map fold 一下就解决了,可是关系式求解才有意思 🌝
好吧,为了证明这个问题(单向查称呼以及单层回溯)没意思我就举个 #Python #code

族谱关系只分长幼男女两种,究其根本也就是「亲孩 长幼(指同辈关系的)」四个字

relationCode = """
父 爸.; 母 妈.
儿 儿子; 女 女儿
兄 哥.; 弟 弟.
姐 姐.; 妹 妹.
妻 老婆; 夫 老公
妻父 岳父; 妻母 岳母
夫父 公.; 夫母 婆.
母母 姥姥; 母父 姥爷
父母 奶奶; 父父 爷爷
母姐 大姨; 母妹 小姨
母兄 大舅; 母弟 小舅
父兄 叔叔; 父弟 小叔叔
"""
def relativeData(code, sep=' '): op=lambda s:s.split(sep,maxsplit=1); return {kv[0]:re.sub('(.)\\.', "\\1\\1", kv[1]) for kv in map(op, re.split('''\s*[;\n]\s*''', code)) if len(kv)==2}

def mktrie(d, k_end=None):
def br(dd,kk): v=dd.get(kk); vd = v if isinstance(v,dict) else ({k_end:v} if v else {}); dd[kk]=vd; return vd
for kkz in (iter(k_:=k) for k in d if len(k) > 1):
v = d[k_]; d0 = d
for kk in kkz: d0 = br(d0, kk)
d0[k_end] = v

class bidir_map(dict):
def __init__(*arg): dict.__init__(*arg); o=arg[0];o._rev = {o[k]:k for k in o}
def keyOf(self, v): return self._rev.get(v)
def relDesc(s, use_short): # 父父=爸爸的爸爸(=爷爷)
if use_short: return sep.join(rels[k] for k in s)
path = rels; res = []
for i, ch in enumerate(s):
if ch not in path: raise ValueError(f"unknow {ch} in {repr(s[:i+1])} at {path}")
if (v:=path[ch][None]): res.append(v); path = rels
def rrelDesc(ss): return [rels.keyOf(s) or s for s in ss]
# ~女儿的妈=女母 (要检测自相等关系和有效性就必须明白性别什么的 很麻烦,但是机械执行就不需要算法


下面的部分是湖北本地的叫法,当然这都是配置文件,能随便切换的。 😋

这个东西稍微推广下,结果 list 化下,就能支持关系别名,或泛性别、泛长幼的查询 ,但是一点意思也没有 要做就做好玩又好学的😒
从一个拓扑图里导出任意两点的关系写出的应用最优雅,可惜我不会,有没有人能教会我…… 可是博文 hello declarative world 的大佬都没能教会我 😢 扶不起
duangsuse::Echo
我 DIO 败了😂,明明没好气的说自己用的是鬼画符,看来还是比不上各类前端大佬鬼画符。 要是我,可能选择把自体判断和 父妻=$母 这种东西给移到另一个“绝对准确”的模块里,而且数据要压缩就会选择脚本预处理,字符串内存优化就会选择加一层恒等替换字典,总之绝不会另外搞一套 notation... 😒 另外动苏非常清楚这个东西绝对不可能有批处理的应用场景,权衡利耗后我觉得完全没有压缩数据包或内存的价值,性能也绝对不重要(不能再快就是了) 断舍离就是这么干脆😋 毕竟写的东西多了,也明白性能这个东西是不可臆测或不可企及的…
#日常精神分裂 #relation #functional
A: 那个亲戚关系计算器,你还说人家做的不好,这不,你不也没做成了么
B: 是鸽后面了啦,今天又有一些新想法,可以改进特性而且保持程序接口一致
B: 首先是关系的,如果认为「父父子」(大爷的儿子)也是「父父」的话(兄弟的孩子也是一家的孩子),「姑姑」这样的称呼就跨单个的亲子关系了
A: 这还真是难以理解
B: 这个不重要,关键是反向称呼的本质其实应该要自动处理才对: 「父父」是爷爷,而「子子」就是反向「!父父」,「孙子」才对;对「我子」来说,「我子子」就是「子」这样。(有点 relative path 的意思了
B: 我还发现 notation 可以有更多变换, 父^5 和 长=哥|姐 外,还可以引入「姊」「娣」自动加「长幼」的前缀(不过,这样就要预处理过程 flatMap 展开缩写了
A: 最后这个被否决了,理由是「亲孩长幼」四个字组成的也不过几十条,复杂化算法不值得?毕竟代码是给人看的。
B: 我觉得可以考虑一下在查询语句里支持 姐|妹的儿子 这种……
A: 那子程序的返回类型就有点麻烦了,用途也小,还是不要麻烦了(孤立支持一下父&母 这种并称算了),支持 父^n 这样的缩写就够了吧。
B: 反向关系很重要,规则是 (父父 爷爷 !孙子) ,如果我用 !父父 能查到反向称谓,为什么更合理的 子子 就查不到了呢?其实反向不应该做在 妻父子 (=岳父的儿子) !_=(爸爸的女婿) 这样的称谓里,而应该做在 妻父子 !_=(父女夫) = (爸爸的女婿) 这种
A: 那么具体怎么操作呢?这种自动从数据构造反向关系的方法?
B: 我觉得应该定义 (反向 妻父) = (女夫) 这样的关系字典?
A: 首先,这么做是对反向称呼的扩展,因为数据里只有 (妻父=岳父) 的对应关系,当然可以利用别名系统增加反向称呼 (岳父 !女婿) ,问题是你要知道「如果以岳父视角看,我和他是什么关系」,答案是 (反向 妻父) = (女夫)
B: 那我给你「女夫」,如何答我「女婿」
A: 把反向称呼的数据填一下, 孩(子女)/亲(父母) 为相反关系,查询 (反向 女夫) = (!妻父) 就成了。
B: 你可真是个小天才 :P 那就这么愉快的决定了。
A: 对了,那你之前说的那个人是怎么实现的
B: 噢,看了一下,那个是同时定义了 (d,h=女婿)(w,f=岳父) ,对他们来说 ! 这个运算符反而是特别做的(不像现在 的安排应该是直接查询)。
我们之所以这么麻烦翻来翻去的就是因为数据结构格式不同(同时有正反向称谓 就避免重复定义关系链条了),其实目前的模式也就是它的模式,没做「对方称呼我」而已
B: 总结的说,就是一个先支持反向关系再支持反向查询,一个先支持反向查询后才能实现反向关系。
A: 这么看你的在方法思想上也没有什么更高的地方啊😒
B: 是呢,不过我的数据集比较简单,单字符切分(js的之所以必须留逗号就是因为作者没法支持不定长的并列单项,不会写 tokenizer),后期也可以加预处理替换来压缩什么的 功能能做到一样 可以试试🌝
#日常精神分裂 #Haskell #functional #relation 推荐不要看的胡言乱语。
A: 听见人说 Rank N Types 可以弄出 p(p==not) (: forall x. p(x)==not(x)) 的关系式
B: 不过这个你自己也不明白吧,说白就是 p(q) = not q 时 q ,正确答案 q 只有一个,但是 q=(forall x. px==notx) = True 时 p=False , p!=not.not.not.not q ... 还有一大堆 not ,就是这里没法得到答案吧
A: 为什么有一大堆 not 呢
B: 为了保证 p=not 的定义, p(p==not) 应该里 p 的定义是不一致的,第一次是 not True 但导致 p=not.not=itself ,第二次又变成 not False 而 p=not,我们想做的是用比较形式化的方法从某一面「判断」这个东西是无解的,但它到底是等式,还是关系式,还是别的什么?
A: 那还是看看 rankn type 是什么吧。
B: 最简单的说法,对 id :: a -> a 里 a 有 Int, String 等可能,但是如果有 f :: a -> (a -> a) -> a ,f 里 a 就只能是任意一个类型,而在括号里加 forall a. 那 f g = 后面就能同时 (g 1) (g "") 了,但这只是 Rank 2 type 。 Rank 是「重评估」的意思, R0 t 是单态 R1 就是正常多态,如果要更多 Rank , (forall c . (forall a b . a -> b) -> c) -> d 就是一个 Rank 3 。 我之前还说不可能 forall a. forall a. (a -> a) 呢(没意义 a 已经在类似上下文 绑定过了)
A: 话说 type 和程序体有什么关系啊。
B: 一个常见的误会是系统化的类型和程序是相互依存的,比如完整的程序带来了类型信息,其实除了 type inference ,程序的组织结构和类型标记是两个独立部分,类型只是限制程序 它自成体系,甚至可以说能检查程序只是它的副作用。
A: 说起来 haskell 的 a b c 到底是怎么检查的啊
B: 类型就是符号之间的关系,符号绑定了语法树的模式和其它关约束条件。 hs 里这很简单,只有一个性质—— consistence 一致性,比如有 (+) :: Int -> Int -> Int ,那 1+"1", 1+0.0 就是无效的, 1.0+1.0 也是无效的。作用域单一没有同名重载,只能约束 (t,t) -> t ,如果各处的 t 是一致的就没问题,否则就错了。 typeclass 也是类似 trait ,其实类似一个小插件,是 (Show t) 拿到实型去查对应 instance ,查到就能选择多态 找到的实现版本而已。
A: 真的不明白 RankN 和有什么关系呢,毕竟 rank 是 polymorphism ,作为 type constraint 为什么会陷入死循环呢🤔,要不谈谈 rev rev=id 吧
B: 那个就是把 0 和 iLast-0 对应吧…… 和 xs.rev()==xs.rev() 不一样,是要 xs.rev().rev()==xs ,怎么解构呢,我区分不出 foldl 和 foldr 啊,函数式分不出调用顺序 理论上不存在栈这东西呢, foldl f v xs = foldr (flip f) v (reverse xs) 啊
A: 问句题外话,为什么不能 add :: Int Int Int 啊,而且遇到 f not p 时中间也得加 $ 或 <$> 的
B: 一个是并列一个是 infix 了,编程语言可没你聪明不知道 not 不是一参数 要加括号
B: 你到底有没有见过正经的 Recursive Type 啊
A: 递归类型是什么,为什么要递归?层数有限制吗?是不是有限性?在无限序列上有限计算 算不算用了递归类型? Py typehint 里 -> "self" 算不算?
B: 肯定不是啦…… self 是 py 作用域设计的问题,3.7 lazy 勉强解决了,和 recursive type 是无关的,这个大概和 Kotlin inference 一碰到就要 workaround 的递归返回值有关吧。
A: 当然基于 car cdr 的 apply transform 我都会,C++ template<T, ...Rest> 嘛
B: 那还真是好普通啊
B: 别灰心嘛,还是需要你们这种布道者的

A: 有时候感觉我们这些做同级翻译或者 LLVM 前端的人写的编译器本质是元编程的一种表现形式,有时候觉得完整的编译原理课又是照本宣科,除了后端都是重复,到底怎么样是好啊。
B: 我看到一个有意思的视频,一排柱子一根根升起,给你一个 i 你能不能做出动画来
A: 动画师估计挺麻烦吧。 普通人可能要求 timerup 后移 单个动画 ,但这个应该建模成 [0, 0], [1,0], [2,0], [2,1] 这样的「逐列递增表」,实际依然靠 i ,但是可以拿到过程中的所有状态。
B: 最方便的大概是直接一个乘除法吧…… 批量计算好
A: 感觉还是做到 assembler 前比较好
B: 你是说 SSA Value 和寄存器分配吧。 分配是独立的算法,但我可以告诉里不分配,完全溢出到栈上也是能实现的。只是要生命期内所有引用,局部 unified 就可以。 作为 stack ptr 参数还是 opcode reg input/out 的区别而已,如果用栈,也无所谓有几个 operand 或有几个AST前层,唯一又能统一的输入输出地址而已。