This blog is rated 🔞, viewer discretion is advised

SPA+SSR 前后端混合渲染的 “Hydration” 问题

标题里的 "hydration" 应该来自 React 里 hydrateRoot 这个对象,其本意是如果说服务端模板输出的 html 是静态的,noscript的,干瘪的,那么 js 的引入就可以让页面变得 “湿润”,“充水”,“流动”,“顺滑” 起来。国内Web社区把这玩意翻译成 “水合”。

作为一个后端仔,这几天小搓了下页面,发现javascript工程化的一个大坑,说说我对 “hydration” 的理解。

以这个vue官方教程为例:

const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<ul>
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

看上去人畜无害很容易

但是加上 SSR 就复杂了。比如这个 TodoMVC 已经在服务端输出两条了

<ul>
  <li>A</li>
  <li>B</li>
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

现在如果 items 更新需要重绘,怎么让 v-for 知道前面两个 <li> 的存在呢?

假如这个问题你能解决,浏览器端OK,那么服务端怎么写呢?

<ul>
  {% for item in ["A", "B"] %}
  <li>{{ item }}</li>
  {% endfor %}
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

这样?是不是觉得太丑了,最好把两个逻辑合并呢?

这就是我理解的 hydration 问题。上面只是一个简单例子,复杂的SSR,理论上应该可以精确渲染到页面特定路由的特定状态的精确那一帧。

要达到这个目的,目前普遍做法是在服务端多一个 编译(compile) 过程,其核心无非是在服务器内存里山寨一个 DOM 的层级结构。

感觉应该有更好的做法,但是我没找到。现有的 Vue Vite React Next 都有解,但是我觉得都太重了。在一个 .html 里写几条 directive 修修改改就能把这事儿搞定的办法,目前看来几乎不可能。

累了,毁灭吧。

Posted

stdout

搓了个在线词典(半成品)

看到网上很多人都在用AI干大活儿了,我也开始搓了,vibe coding对我这种人菜瘾大的人很友好,自己懒得写就交给AI写。

13年前就有一个想法,做一个在线词典。那个时候还打算白嫖 RedHat 免费的OpenShift。

为什么要做在线词典呢?当时是眼红 Google Dictionary 觉得它什么都好。但就是需要翻墙,而且有一定几率查不出来,所以想做个镜像把它常用词都拉下来存起来。

当然这个想法无可争议的烂尾了。

一直到2023年,ChatGPT出来之后,发现大语言模型这玩意外语天才啊,用来写词典再好不过了。

说起来,英语的 Dictionary 实际出现时间很晚,比《永乐大典》都晚了它妈的至少200多年,因为英语作为一个拼音语言书写统一(正字法)都是很近代的时候才被行政力量推行的。英语在大部分时间里都是被日耳曼蛮子和高卢蛮子看不起的一个小岛口音。

英语词典的发明,是作为乡绅和学者随手一查拿来装逼的,并不是给初学者、外语学习者、特别是中文背景的ESL学生设计的

词典被当成「语法翻译法」的核心工具,其根本原因是印欧语系的语法、词源都能找到共通的联系。而这一套工具本来是贵族用来训练自己的继承子女去学习古希腊语和拉丁语用的。

当讲汉话写中文背景的家长、老师给娃讲英语的时候,就会遇到各种困难或者犯各种啼笑皆非的笑话。

所以想起来通过 ChatGPT 和类似技术做一套「英语」。当时我列举的愿景有:

  • 这个词语用得多不多,是不是很偏门、冷门还是常用词、热词、必背词、高频词
  • 最典型的场景下,具体放在句子的哪个地方
  • 什么时候出现的这个词语,最早什么意思,又因为什么渊源演变成了现在的别的意思
  • 是不是用这个词汇是骂人的、得罪某个群体的,是否需要忌讳
  • 完整列举出所有 conjugation 和 declension 并且阐述和说明,突出的就是一个屈折语的诘屈聱牙。
  • 不拘泥于单个「词」,固定搭配组合也直接当成单词收录用于记忆。

特别是第五点,过去的词典因为印刷和编辑成本很少这样做,现在电子产品完全有能力生成和遍历所有排列组合。

突破「词典」的固有形态,做一个「英语」的说明书

开始搓这个词典,我也看了下其他在线词典的问题:

  • Oxford English Dictionary 收费。滚
  • merriam-webster 用高级词汇解释简单词汇。需要thesaurus和dictionary合并到一个界面
  • cambridge 可以,就是排版字体略乱
  • collins 最适合
  • onelook 需要点两下
  • websters1913 最美。适合凭感觉学习。抛开一切语法和构词造句,纯粹体会词义之妙以及如何运用
  • wordreference 最简单明了。比如 inspire [sb] == awaken [sb]'s creative ideas 比一个 [T] (transitive) 符号更容易理解得多

搓的时候也陆陆续续解决了一些始料未及的问题:

  1. LLM中转站选哪家?openrouter 其实贵和卡
  2. 很多LLM中转站连 CORS 问题都懒得处理。每次请求其实都要 preflight 一下。你明明加一个 Access-Control-Allow-Origin 就解决大问题

本来想一个静态页面 .html 放在 Github Pages 万事,结果搓了一套mini后端。

最后成果放在 https://def.est.im/ 。还有很多待完善。当前版本我满意的就是在单独的释义下面放了 同义词 反义词,比混在一起方便清晰得多。

以前纸质的词典把大段意思混杂在一起排版,各种缩写代码人看了都头大,Web时代就应该有更清晰的排版。(虽然我现在的排版也很欠缺)

Posted

stdout

再也不愁 favicon 了,直接 inline SVG

每次在一个网页里, F12 或 Cmd+Opt+I 最痛苦的是什么?

/favicon.ico:1 GET favicon.ico 404 (Not Found)

简直逼死强迫症~前段时间折腾SVG,觉得用 xml 写一组 favicon.svg 或许不错。今天撸AI它丫的直接给我个最粗暴简单的:

<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://w3.org/2000/svg' viewBox='0 0 19 19'><text y=16>🤣</text></svg>">

预览一下这个SVG:

🤣

精简的地方:
1. www.w3.org 去掉 www
2. y=16去掉引号
3. viewBox 为19而 y=16 是因为该死的拉丁字母显示有个 baseline 问题。随便调整下懒得管了。
4. 节约了 font-size="16" 因为 默认就16px

直接用 emoji 作为 favicon。我贴这个版本应该是全网最精简最易读的,挑战有没有大神能进一步缩短这个 favicon 写法。

Posted

stdout

Hinton 一句话总结了教育的本质

回家路上听了个 1小时30分的 podcast ,采访 Hinton 的:

Godfather of AI: They Keep Silencing Me But I’m Trying to Warn Them!

有些亮点,通过这个该死的 transcript API www.youtube.com/youtubei/v1/get_transcript 把JSON搞了下来,然后通过这个恶心的脚本解析成 全文 文本:

with open('stdin-10-01.txt','w') as f: f.write('\n'.join([t['text'] for x in a['actions'][0]['updateEngagementPanelAction']['content']['transcriptRenderer']['content']['transcriptSearchPanelRenderer']['body']['transcriptSegmentListRenderer']['initialSegments'] if (v := x.get('transcriptSegmentRenderer')) for t in v['snippet']['runs']]))

他提到 “AI的危险” 分为两个层面

  • 有人拿AI来干坏事,比如诈骗,做武器,做病毒等
  • AI本身作为 superintelligence 把人类比下去了

他说这个 超级智能 是他在Google工作10年间发现的,Google曾经一度尝试制造“模拟电路”代替数字电路来更加逼真拟合人脑,但是他发现 数字 AI更具有竞争力。因为同样的算法和权重,你换一套硬件,也能复现它的能力。你换一个时间、换一个国家,也能差不多复制这个能力。数字化带来一个很恐怖的能力就是低成本迁移学习。一个模型吃掉另一个模型,近乎等于把权重拷贝过来然后求平均一下。要强化某一方面能力,就针对那部分权重做SFT。

数字模型的这一特点直接秒杀了人类。人类就算科技再发达,你能不能把另一个脑袋劈开,看看它神经元怎么连接的,然后复制到自己的大脑里呢?

When you and I transfer information, we're limited to the amount of information in a sentence. And the amount of information in a sentence is maybe a 100 bits. It's very little information. We're lucky if we're transferring like 10 bits a second.
These things are transferring trillions of bits a second. So, they're billions of times better than us at sharing information. And that's because they're digital. And you can have two bits of hardware using the connection strengths in exactly the same way.
We're analog and you can't do that. Your brain's different from my brain. And if I could see the connection strengths between all your neurons, it wouldn't do me any good because my neurons work slightly differently and they're connected up slightly differently. So when you die, all your knowledge dies with you.

他进而得到一个推论,因为模型和模型之间相互学习,相互蒸馏没,那就是数字AI几乎是永生的。。。。

我尼玛。。。这。。。洞大开啊。

他接着又说,为啥 superintelligence 肯定比人类更聪明,他举的例子是,在 gpt4 不能联网的时候,他问, 增肥堆(compost heap)和原子弹有啥相似之处?

答案我就不贴了。有兴趣的可以看原视频 59:00 或者 Ctr+F 我摘的原文。但是注意力结构天生就可以把各种事物的相似之处,转换成类似的 analogy,这样才能压缩信息,才能计算。AI 学习的材料比人类多得多,肯定懂得更多,交叉学科最能创新,所以AI肯定特别能创新

这个访谈又说到 Ilya 在做的 super alignment ,超级对齐,我倒是觉得吧,做模型安全只是一个幌子,Ilya 多半是发现了 AI很容易胡诌“you are absolutely right”,但是如果人类知识本来就是自相矛盾的怎么办?它这个 align 的恐怕不是AI,而是从 metaphysics 对全人类智慧进行归一、一致性的梳理。类似集合论,公理系统和希尔伯特那种地基类的工作。这样的AI训练出来恐怕非常无敌。如果拿来反人类岂不是更可怕?从法统和道统上碳基已死,硅基当立了。。人类怕不是减碳把自己给减没了。2333

回到标题,教育的本质是什么?

教育可以从很多人文,历史,社会等太多方面分析,甚至我见过最天方夜谭的理由是,孩子接受教育是因为工业革命之后,双亲被迫投入全职劳动,不得不设立k12公共教育来集体训练孩子。哈哈哈

Hinton 自称唯物主义(materialism)者,给了我一个晴天霹雳,所谓的教育,就是属于不同肉体长得完全不同的大脑,通过10bit/s 的带宽同步数据 😂

一切都豁然开朗了。那种 “醍醐灌顶” 是不是就是高压缩 .7z 给你当头棒喝?

从唯物的角度来说,谁能高带宽不丢包把数据同步好,谁就是最好的教育。

Posted

stdin

gzip 炸弹检测

国内很多人说两句话就能检测 gzip 炸弹,我翻了一下大概是这样

import gzip
import io
import requests
resp = requests.get(url, stream=True)

decompressed = resp.raw.read()
with gzip.open(io.BytesIO(decompressed), 'rb') as g:
    g.seek(0, 2)
    origin_size = g.tell()
    print(origin_size)

gzip -l xxx.gz 类似,原理是gzip格式在尾部8字节保存了 [CRC32][ISIZE],其中 ISIZE = uncompressed_length % 2³²

要反制这个检测很easy嘛,直接返回 Content-Encoding: deflate 不就行了?

况且,我搜了下,ISIZE是可以改的。。。所以更好的办法是:

import zlib

MAX_OUTPUT = 50 * 1024 * 1024  # 50 MB cap

def safe_decompress_gzip_stream(compressed_iterable):
    # compressed_iterable yields bytes chunks from incoming request body
    d = zlib.decompressobj(16 + zlib.MAX_WBITS)  # 16+ for gzip wrapper
    total_out = 0
    for chunk in compressed_iterable:
        out = d.decompress(chunk, 64*1024)  # limit per-call output
        total_out += len(out)
        if total_out > MAX_OUTPUT:
            raise ValueError("Exceeded decompression limit")
        yield out
    # flush remaining
    out = d.flush()
    total_out += len(out)
    if total_out > MAX_OUTPUT:
        raise ValueError("Exceeded decompression limit")
    if out:
        yield out

终归来说,gzip炸的都是内存。我在想,能不能利用LZ77反复横跳,做一个CPU炸弹呢?

比如解压个半天,发现结果是个 1KB 的小文件?压缩率高达 114514% ?

ChatGPT 居然拒绝回答了。但是指了个路:

Many tiny dynamic-Huffman blocks so the decoder rebuilds trees repeatedly (parsing overhead per block).
Constructing distance/length sequences that cause a lot of back-reference copying (expensive repeated copies, especially with overlapping distances).
Interleaving short literal runs with copies to create branch-heavy decode work.
Using many concatenated members/streams (or nested archives) to multiply cost.

OpenAI 真猥琐啊。

Posted

stdout

OKR 🔪 了 Google Reader

最近又刷到 RSS的一些讨论,然后又说起 Google Reader 这个陈年往事。

Google Reader是谁杀死的呢?准确的说是个三哥 Vic Gundotra。默许这件事的是女高管 Marissa Mayer。(Mayer 后来去 Yahoo 当了CEO,干得最牛逼的事儿就是收购了 Tumblr,后来还有更抽象的从 teen 手上买了一套 Summly)

Mayer这名字让我想起之前看有本讲netflix的书提到过,是OKR推崇者。所以杀死Google Reader的凶器是 不是OKR或者launch culture呢?

我决定探究一下 OKR 的由来。这玩意的鼓吹群体,最后都指向 Intel出身的风投 John Doerr,他写了一本书叫 《Measure What Matters》,书其实不用看了,直接去他家官网,3分钟就能了解OKR的核心理念:

https://www.whatmatters.com/resources/a-typical-okr-cycle

A Typical OKR Cycle

我之前也经历过OKR,再次看这个东西有一些不同的感触:

  • 管理层是不会全体公开自己的OKR的。因为管理层不用担责,也不想担责,也不敢担责。有一些 DAU 之类的指标能公开说吗?所以图里的第二步就是没有的,全靠下属去猜,猜错了才好挨板子嘛。
  • 部门OKR或许可以公开,但是跨部门呢?保护得更严实了。子部门和小组之间就有样学样,最后OKR成了村骗乡,乡骗县,一级一级往上骗,一直骗到国务院。OKR里强调的跨部门整合,冲突协调,我没太见着,可能是level太低了。但是人性者东西嘛,既然都分部门了,井水不犯河水,为啥我部门有牺牲收益顺着你部门的指标走?有啥好处啊?你几个人几条枪,凭啥我就不能更少的人更小的代价完成同样的事?
  • key result 强调客观指标,但是可观测性很多时候就是个取悦上级的play。记得有一次帮别的团队算“周均”指标,感觉基础数据查起来很麻烦,结果对方团队说,直接把日均加起来除以七就好了。而且必须得这么做,因为都是这么算的。后来咨询了下做SaaS的师兄,结果业界大概三七分,一大半都是拿日均直接套。给我吓尿了。
  • Google的OKR实践开头就说一句话,不能直接套用,要按实际情况调整,你能套上去说明你做错了
  • OKR里很强调 contributor 这个概念。啥意思?牛马就是执行者,不要多想。不要把自己当公司 partner 了
  • committed 类型的OKR得分为1,必须达到1。aspirational的平均分应该是 0.7。但是实践中这挂靠很多待遇福利,使得如何设 OKR 成了一门花活儿
  • Doerr 这名字起的好啊,行者。哈哈。
  • 反对 Business-as-usual OKRs。万事万物都必须从用户需求侧推导。我觉得这一点很好
  • 胆小aspirational OKR问题:愿景性OKR会倾向保守,出发点是,如果尚有余力,加一点运气,完成blah。实际有一个简单衡量标准(The litmus test),如果你完成这项OKR,会不会大幅度超出用户预期?多年以后用户会不会因为这项OKR受益?
  • Sandbagging。正如前面提到的和薪资福利挂钩,很多人会消减 committed OKR 目标。按照 Doerr 的说法,承诺性OKR是需要几乎耗光团队所有人力财力时间的目标才对。承诺+愿景 加起来应该超过团队能支配的资源。OKR这一工具是用来摸索团队执行力边界的。Doerr甚至说到如果每次OKR都能漂亮完成那说明团队在 hoarding resources or not pushing。我寻思,这也太资本主义了。哈哈哈。
  • Low Value Objectives (LVOs) 不要追求“把CPU尖峰降低3%”。而是要反推,如果你这指标 1.0 完成,对 enduser 或公司效益有什么直接的促进作用吗
  • 所有的KR合起来,需要构成对O的充分条件。如果所有 KR 都 1.0 分完成,那么 O 必将实现。这一点很要害啊,实践中很多KR也就是一些对自己有利的必要条件而已。估计很多团队也是对 硬骨头 避而不谈。OKR 这一工具的目的就是发现公司层面缺乏对“房间里的大象”的关注和投入的
  • committed OKR以达到1.0为宗旨。如果团队达不到,那么需要尽早升级。升级不仅是常见的,还是必须的。无论是你对OKR不认同,优先级问题,还是有冲突,还是资源不够,管理层的义务是尽可能在OKR周期内发现问题并投入解决。
  • 达不到 1.0 的committed OKR需要postmortem。Doerr说这样做不是为了惩罚团队,而是看到底是计划环节,还是执行过程中出了问题。但往往OKR更多的被用成敲打的工具?哈哈
  • Aspirational OKR 可以长期保留,成为下一个周期的基础。如果没有进展就丢弃,说明要么你这目标设定有问题,要么优先级设定有问题,要么资源调度有问题,要么对事物的认知出了根本问题。
  • Aspirational OKR在团队之间平移是OK的。manager不应该假设它们得到的支持永远是非常充足的。
  • 简单衡量(The litmus test):如果每个KR都是季度末最后一天完成,那么说明压根没计划。
  • 如果重要团队职能没能在OKR里体现,就添加更多的OKR

OKR这一套的的祖师爷 是Intel 老总,匈牙利Holocaust难民 Andy Grove 。我看了下其实老爷子没把这一套说得那么玄乎,就是 8085 处理器当年需要每个季度出货,就搞了一套分摊生产的机制。这也解释了为啥OKR往往都是年度、季度为单位的。因为财报也是这个节奏嘛。他举例说,O是Intel芯片占领中端市场,那么KR就是8085 处理器 10个 新设计。我寻思这也不能必然支撑“占领”这一目标啊?万一市场不认帐怎么办?老爷子又说了,KR可以是 milestone,这一波不行下一波继续加码不就行了🤣 主要是“占领”这一说法是可以argue的,但是10个就是10个,结果只会是达成是否yes/no,可以 measure 的。

这篇讲OKR渊源的文章里,有一句话说得特别好

OKRs overturned the top-down management system. Suddenly, workers were valued by what they accomplished, not by their background, degree, or title. With OKRs, execution is more important than mere ideas,
OKR改变了人们马首是瞻的管理模式。员工的价值衡量以完成目标为准,而不再是背景、学历、职衔。OKR体系下,执行比畅想更重要。

那么话说回来,为啥OKR 杀死了 Google Reader?

因为 Larry Page 给全公司定的 O 是:亿级用户用户,越多越好。要做 google-scale 的产品

Google Reader受众是一小撮核心用户,虽然 engage 很高频,但是小众爱好的增长就是慢。当年 Google+ 势头被三哥吹上天,显然更有前途。Marissa Mayer是G家老人了(工号#20) 做 OKR 有一手,Google Reader显然是一个 business-as-usual 成熟产品了,所以开发团队都被挪用了,人都跑光了,据说它代码还不能跑在新款Google软件架构上(borg之类的),所以越来越没人关心。因为没人能靠Google Reader升职加薪,所以成了弃子。

说 OKR 🔪 了 Google Reader ,不是说 OKR不好,而是OKR作为一个框架,一套工具,它是中立的。

OKRs help you hit every target — except the one that matters.
OKR确保你命中目标,至于是不是重要目标就不得而知了

或许Google Reader真的对于Google不重要。但是反过来,没有 Google Reader 真的对Google那么重要吗?G家还做了那么多 arts project 怎么就不砍掉呢?

所以我琢磨下来,OKR这套工具,在蓝海市场,销售向的行业里是非常有用的。它能聚焦业务,保持各团队对齐,排查执行环节问题是非常有效的

但前提是,你只缺执行吗?

另一个方面,对于 SRE 安全这类部门来说,它们的成功不在于本部门 执行有多好,而是在于其他部门的「下限」有多烂。有哪个敢给自己定一个全年100%不出漏洞不出问题的O?

这类 support, maintanence 和 backoffice 部门,本来就就是降低负收益,处理烂摊子的,它们存在的意义,就是把公司的潜在损失尽可能降低到最小

这个出发点来说,是不是应该把OKR设置成默认 -1.0 分,然后擦屁股得越干净越好?

胡思乱想又水了一篇,大家别当真

Posted

stderr

Fix WestData SN550/SN570 SSD slow read problem

I had a painful slow game load experience during the past few days. In the beginning, I tried everything I can to tweak the Win10 system, cleanup the PC box, but the disk IO was always pegging at 2MB/s to 5MB/s at taskmgr.exe.

The real culprit? The WD ssd I bought some years ago. Turns out if the data was old enough, the firmware had real trouble recognizing the volatile bits and throttles the throughput.

The fix? read the file again and write them back. Since my disk is almost full (another reason here), a inline replace would be prefered.

I spent next few hours vibe coding an HTML5 utility

https://lab.est.im/ssd-warmup/

The code works as intended, however the File System API in Javascript writes a .crswap file instead of the original.
It's a Chromium thing thus makes the JS method completely useless.

I wrote a Python version instead.

https://github.com/est/snippets/blob/master/ssd-warmup/ssd_warmup.py

The AI wrote code using os.path.walk and I changed it with pathlib.Path, which was more pleasant with its rglob method.

You can try it:

python ssd_warmup.py /path/to/fix/

The lesson learned: Don't buy Sandick or WestData. At least the low-end ones.

Posted

stdout

CBOR 和 MsgPack 是一回事

翻旧账的时候无意中发现的。MessagePack的实现者 mdhb 说:

Disclaimer: I wrote and maintain a MessagePack implementation.
CBOR is MessagePack. The story is that Carsten Bormann wanted to create an IETF standardized MP version, the creators asked him not to (after he acted in pretty bad faith), he forked off a version, added some very ill-advised tweaks, named it after himself, and submitted it anyway.
I wrote this up years ago (https://news.ycombinator.com/item?id=14072598), and since then the only thing they've addressed is undefined behavior when a decoder encounters an unknown simple value.

以及

There's no reason an MP implementation has to be slower than a CBOR implementation. If a given library wanted to be very fast it could be. If anything, the fact that CBOR more or less requires you to allocate should put a ceiling on how fast it can really be. Or, put another way, benchmarks of dynamic language implementations of a serialization format aren't a high signal indication of its speed ceiling. If you use a dynamic language and speed is a concern to this degree, you'd write an adapter yourself, probably building on one of the low level implementations.
That said, people are usually disappointed by MP's speed over JSON. A lot of engineering hours have gone into making JSON fast, to the point where I don't think it ever made sense to choose MP over it for speed reasons (there are other good reasons). Other posters here have pointed out that your metrics are usually dominated by something else.
But finally, CBOR is fine! The implementations are good and it's widely used. Users of CBOR and MP alike will probably have very similar experiences unless you have a niche use case (on an embedded device that can't allocate, you really need bignums, etc).

看它又翻了一堆旧帐。。hmmmm。。。好吧。

最近在看 ATProto 发现它既可以 CBOR 也可以 JSON

Posted

stdin

大集团,小组织和原子个体

来自 Terence TaoHN上讨论很热烈

Some loosely organized thoughts on the current Zeitgeist. They were inspired by the response to my recent meta-project mentioned in my previous post https://mathstodon.xyz/@tao/115254145226514817, where within 24 hours I became aware of a large number of ongoing small-scale collaborative math projects with their own modest but active community (now listed at https://mathoverflow.net/questions/500720/list-of-crowdsourced-math-projects-actively-seeking-participants ); but they are from the perspective of a human rather than a mathematician.

As a crude first approximation, one can think of human society as the interaction between entities at four different scales:

  1. Individual humans

  2. Small organized groups of humans (e.g., close or extended family; friends; local social or religious organizations; informal sports clubs; small businesses and non-profits; ad hoc collaborations on small projects; small online communities)

  3. Large organized groups of humans (e.g., large companies; governments; global institutions; professional sports clubs; large political parties or movements; large social media sites)

  4. Large complex systems (e.g., the global economy; the environment; the geopolitical climate; popular culture and "viral" topics; the collective state of science and technology).

An individual human without any of the support provided by larger organized groups is only able to exist at quite primitive levels, as any number of pieces of post-apocalyptic fiction can portray. Both small and large organized groups offer significant economies of scale and division of labor that provide most of the material conveniences that we take for granted in the modern world: abundant food, access to power, clean water, internet; cheap, safe and affordable long distance travel; and so forth. It is also only through such groups that one can meaningfully interact with (and even influence) the largest scale systems that humans are part of.

But the benefits and dynamics of small and large groups are quite different. Small organized groups offer some economy of scale, but - being essentially below Dunbar's number https://en.wikipedia.org/wiki/Dunbar%27s_number in size - also fill social and emotional needs, and the average participant in such groups can feel connected to such groups and able to have real influence on their direction. Their dynamics can range anywhere from extremely healthy to extremely dysfunctional and toxic, or anything in between; but in the latter cases there is real possibility of individuals able to effect change in the organization (or at least to escape it and leave it to fail on its own).

Large organized groups can offer substantially more economies of scale, and so can outcompete small organizations based on the economic goods they offer. They also have more significant impact on global systems than either average individuals or small organizations. But the social and emotional services they provide are significantly less satisfying and authentic. And unless an individual is extremely wealthy, well-connected, or popular, they are unlikely to have any influence on the direction of such a large organization, except possibly through small organizations acting as intermediaries. In particular, when a large organization becomes dysfunctional, it can be an extremely frustrating task to try to correct its course (and if it is extremely large, other options such as escaping it or leaving it to fail are also highly problematic).

My tentative theory is that the systems, incentives, and technologies in modern world have managed to slightly empower the individual, and massively empower large organizations, but at the significant expense of small organizations, whose role in the human societal ecosystem has thus shrunk significantly, with many small organizations either weakening in influence or transitioning to (or absorbed by) large organizations. While this imbalanced system does provide significant material comforts (albeit distributed rather unequally) and some limited feeling of agency, it has led at the level of the individual to feelings of disconnection, alienation, loneliness, and cynicism or pessimism about the ability to influence future events or meet major challenges, except perhaps through the often ruthless competition to become wealthy or influential enough to gain, as an individual, a status comparable to a small or even large organization. And larger organizations have begun to imperfectly step in the void formed by the absence of small communities, providing synthetic social or emotional goods that are, roughly speaking, to more authentic such products as highly processed "junk" food is to more nutritious fare, due to the inherently impersonal nature of such organizations (particularly in the modern era of advanced algorithms and AI, which when left to their own devices tend to exacerbate the trends listed above).

Much of the current debate on societal issues is then framed as conflicts between large organizations (e.g., opposing political parties, or extremely powerful or wealthy individuals with a status comparable to such organizations), conflicts between large organizations and average individuals, or a yearning for a return to a more traditional era where legacy small organizations recovered their former role. While these are valid framings, I think one aspect we could highlight more is the valuable (though usually non-economic) roles played by emerging grassroots organizations, both in providing "softer" benefits to individuals (such as a sense of purpose, and belonging) and as a way to meaningfully connect with larger organizations and systems; and be more aware of what the tradeoffs are when converting such an organization to a larger one (or component of a larger organization).

读完之后很惆怅。双亲+子女组成核心家庭 里Michelle Obama说的那句话犹在耳畔。

人存在的意义和价值是什么?大多数时候,是由TA所在社会群体里的(某种形式的)地位决定的。

大集团往往是纯粹的经济价值来源和利益机器

小组织给人归属感

个体的结局只有一个——孤单

想到这里,突然又手痒想键政了。秦汉公民兵的崩坏,被世家大族吸收消化;六镇府兵制的隋唐,不过是回光返照,最后不得不换成雇佣兵和藩镇。到了大怂国感觉汉人是完全不会打仗了,这也跟山河四省彻底原子化,科举这个上升通道沦为「个体」刷分机器有莫大的干系。小组织(户)和大集团(族)都完蛋,加上打压工商业,无法形成新的行会 - 商团 乃至财富汇集托举的 文艺 - 科学 团体,整个社会结构要么是男耕女织的这种极端原子化的小农家庭,要么是皇权这种巨无霸;文官集团彻底被以个体利益出发的党争玩坏。整体民心是个什么状态呢?一个民族,一个国家里的每个个体,既无法从组织里得到利益,也无法得到归属感,反正生活都是苦和累,今朝有酒今朝醉,天子换谁来当都一个屌样,那么结论很容易得出:整个汉地的「自然组织度」约等于0 。朱88的军户制度,也是行政和官僚手段强行拉高组织度一种无奈,但是最后还是被更高组织度的八旗吊打。

不得不说老外的 civil society 这一套说法 还是很有道理的

要说这一切的罪恶之源是什么呢?先来想去,铁犁+纺车,从井田制崩坏就开始了?

为啥孔老二崇周礼?因为当年的农业生产是纯纯人力,得分工和群体劳动才能生存,国君祭天是一件严肃的生产分配大会,而不是后来流于礼节形式。为啥游牧部落总是能找到机会在某一个点突破防线?因为轮牧制度是根本,只要部落之间平息仇杀一致对外,就可以凭借天生的高组织度完成更复杂的战术和战略目标。

所以21世纪的铁犁是什么呢?AI?

不敢想不敢想。看着孩子现在 pad 上安装了豆包、千问、deepseek等众多app,我寻思,可能人类社会连父母和后代的养育联系,可能在未来某一个时刻都要断掉了吧。

呃,网上其实现在已经是这个风气了,原生家庭的“罪”罄竹难书,老登只有爆金币一个用途了。

Posted

stdin

xHTML5

有 ChatGPT学姿势就是快

<!DOCTYPE html [
  <!ENTITY myEntity "Hello World">
  <!ENTITY wow "alert('hi')">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  &myEntity;
  <script>
    &wow;
  </script>

</body>
</html>

保存到本地 1.xhtml,双击浏览器打开。谁能想到这也行?xml entity 还可以这样玩?

只要MIME为 application/xhtml+xml 就可以把HTML5当XML渲染。

部署了个在线demo: https://lab.est.im/svg/entity.xhtml

不敢相信自己眼睛,确认下是HTML5:

  • document.compatMode 返回 CSS1Compat 没问题
  • ocument.doctype 返回 <!DOCTYPE html> 没毛病

如果是老的兼容模式:

  • document.compatModeBackCompat
  • document.doctype.publicId-//W3C//DTD HTML 4.01//EN
  • document.doctype.systemIdhttp://www.w3.org/TR/html4/strict.dtd

思路打开了。哈哈

Posted

stdout

disqus已卸载,手搓了套blog评论系统 - req4cmt

一直用 disqus 主要是觉得方便(懒)。但是自从被墙了就很不方便了。加上近期开始强制插入广告,就更讨厌了

想找个替代品,很多基于 github 的,在 issue 盖楼,我觉得不方便备份,希望是能直接写入 repo的。这样一个 git clone 就搬家了。更不用说几乎都是基于 OAuth 的 github 登录实际上能拿到你所有 repo 的 scope,也就是能读写你所有公开(甚至私有)仓库内容。我一般都不点

于是决定手搓一个。

首先考虑的就是如何把内容写入 git repo。这个在做 gitweets 已经调研尝试过了。

本着在 cloudflare worker 白嫖的心态,这种 serverless 的环境肯定不允许装 git 命令行或者 libgit 这种 .so,所以考虑 pure python 的 dulwich。折腾了一下 python binding 发现CF居然是个WASM转译。那还不如js。还好nodejs生态也很丰富,有个纯js的实现 isomorphic-git

然后手搓了一下发现需要个 memfs 在内存里模拟文件IO。

其次是如何读取内容,评论列表以 域名/路径.jsonl 格式保存为纯文本,一行一条评论JSON,方便diff。将来可以做成 pull request 当成 moderation

本来想通过 git-http 来读文件,发现太慢了。干脆走捷径直接反代 https://raw.githubusercontent.com/ 就行。本来也不用反代,一是这个域名被DNS屏蔽,二是加一个该死的CORS头才能跨域。

跑通之后接着就模仿disqus实现页面一段.js嵌入,渲染表单,展示评论列表等等,我的 js/css 实在捉急就搓了套最基础的。

能用就行!

防止spam这方面也没多想,看很多人说做 hidden input 就能拦住绝大部分,那就先这样跑着。除了评论框这个 textarea 甚至名字都是选填

尽可能做兼容,让在没有 .js 的情况下也能提交表单。当然得在嵌入页面的时候弄 <noscript>

该项目严重依赖 cloudflare 和 github 两位赛博菩萨的免费额度,所以请求过多会被控频。实在不行弄个KV队列之类的。但是我这博客这么冷清,多虑了?

最后,把 disqus 老的评论都导出来了。毕竟是多年的回忆。

项目放在 https://github.com/est/req4cmt 欢迎点评。

Posted

stdout

抗日

看完阅兵式直播,记录一些最近几年才了解到的抗战细节:

  • 1941年4月13日,苏联承认伪满洲国
  • 1945年2月08日,雅尔塔会议,罗斯福同意斯大林,保障大连港、中东铁路、南满铁路的利益,以及恢复俄罗斯海军在旅顺口的租赁
    Yalta Conference
    -1945年6月24日,苏联在莫斯科红场举行「伟大的卫国战争」胜利阅兵仪式,🇯🇵帝国陆军武官矢部忠太,帝国海军武官 臼井淑郎作为嘉宾受邀列席检阅红军。


- 1945年8月06日,美军用「Little Boy」核平广岛
- 1945年8月08日,苏联撕毁 《苏日中立条约》向🇯🇵宣战
- 1945年8月09日,美军用「Fat Man」核平长崎
- 1945年9月02日,🇯🇵在东京湾「USS Missouri」战列舰上向盟军投降
- 1955年5月26日,12万苏军的最后一批撤离旅顺、大连。至此大陆外国驻军清零。

东北就是东亚的波兰?

Posted

stdout

gitweets:单html实现独立微博,拿git历史当feed流发推

twitter争议不断持续多年,先是各种 cancel culture 闹得动静很大,被一龙马买了之后更甚,社区分裂到 mstdn nostr bsky支流,各种话题炒上天,在众多替代品里,2022年看到个最别具一格的:

拿 git 当微博使

  • 发推: git commit --allow-empty
  • 加关注: git remote add <alias> <their fork url>
  • 转发: git cherry-pick <their "tweet">

脑洞大开。而且git基于merkle tree的,p2p 历史不可篡改,有web3那味了。

当时就饶有兴趣,挖了个坑准备搓个web界面。但是限于涣散的注意力,以及对css这种抽象排版玩不转,一直拖沓没做好。

周末心血来潮,外带 AI 工具加持,进展神速。目前已经基本可用。

项目叫 gitweets ,意思是用 git 发 tweets,网址在 https://f.est.im/ 。二级域名 ffeedf.est 也就是 fest 表示。。。 盛会的意思。

feature list

  1. 把任意 github repo 渲染成微博
  2. 给任意 github repo 发推。其原理是,通过REST API新增一条 commit 。
  3. 发图!如果 commit message 以冒号结尾,而且恰好也在本次新增加了位于 static 下面的图片文件 那么会尝试去加载图片作为附件渲染
  4. 写 commit 基于 OAuth app 实现。浏览器记录 access_token 到 cookie,理论上可用 8个小时。过期重登
  5. 如果你的 commit 有是通过 -S 参数提交带签名 ,那么展示为蓝色表示verified

记录一些坑

  1. OAuth app vs Github App。前者是代客做事;后者是独立主体单独账号,类人行为,多用于 CI/CD
  2. OAuth app 的 scope 如果是 repo 可以读写你所有仓库代码,包括私有仓库!网上的很多基于 github 的第三方评论系统有这个隐患!
  3. 我这里用的是 public_repo,读写所有公开仓库。毕竟 github是个开源社区,拿公开git来当feed使,要安全一些。
  4. 更安全的办法是只能读写单个指定的repo。要实现API读写git,在github有下列几种方法:
    • REST API。可以用 fine grained PAT 读写一个repo
    • GraphQL API。
    • git 协议。走 github.com:22 端口。可以采用 deploy key 或者私人账号 ssh key
    • git-http。走 https://github.com:443
  5. Private Access Token (缩写 PAT) 可以完全控制个人或者团队账号,fine grained PAT 可以只控制指定的几个仓库
  6. deploy key默认只读,可以改成读写,一库一用,不能复用
  7. REST API 列举 commits 不能获得当前 commit 改了哪些文件。需要额外N+1每个commit再次查询详情。背后的原因估计是 git 内部 ref 和 blob 是严格区分的。甚至可能是分开存的数据库表
  8. 网站是跑在赛博菩萨 cloudflare worker 上的。这种所谓“serverless”平台很强大了。功能齐全没啥缺的。甚至可以发起 tcp 连接。
  9. 本来计划走 git-ssh 或者 git-http 协议,想了下js操作binary太复杂了,弄个 libgit2 之类的库估计很重。还是REST方便
  10. REST API 新增一个 empty commit 有多复杂? 1. 获得当前branch 的 sha 2. 获得该 sha 的 tree 3. 新增一个 sha+tree 的commit 4. 把 ref 指向第三步的 sha 。啊,就不能一步完成么。下次有机会看看GraphQL 能不能一次调用完成
  11. Github 的API 强制要求 User-Agent 。你可以乱写但是不能没有
  12. Github 虽然返回了 Access-Control-Allow-Origin: *,但是现代浏览器他妈的不认这个 * 。所以在浏览器只能匿名调用 GET ,如果 POSTPATCH 带了 credentials: "include" 直接拒绝。网站必须显式指定允许哪个具体的 origin
  13. cloudflare的 Response.redirect('/') 直接挂掉。原来是 3xx 跳转不允许相对路径。

why?

由于习惯,古法写web,一个html包含了 css js 。无二次加载,无第三方依赖库。除了不能写死的全部写死 🤣。无需build。

源码放在 https://github.com/est/gitweets/ 。该仓库的 commit 历史也作为feed展示在 https://f.est.im/

接下来准备用类似的思路实现网站评论系统,代替现在的 disqus ,虽然它是免费的,但是广告太多了。

可能有人要问:why ?闲的蛋痛?

我想,首先的确蛋痛,because we can。其次是不想在平台,处处受人限制。然后也是最重要的,self-host。所有数据资料都在一个repo打包带走,备份什么的很方便。比如以前wordpress受众多功能全,但是后来大家都 hexo 之类的静态blog了。

我心目中 gitweets 就是“静态”微博的一种。虽然它现在还是依赖 github API。等有空了可以试试生成纯静态页面。

ToDo

  1. 如何发视频 音频
  2. 如何转发
  3. 如何混合展示多个repo的feed。基于 pull request ?

欢迎评论或者提 issue

Posted

stdout

敬语和咒语

因为旅游瞎逛,才了解有这样一种东西:

字库塔又叫“惜字宫”、“敬字亭”、“惜字塔”、“焚字炉”等,它是收存和焚烧字纸的专用设施,沿自古人有“敬惜字纸”之风,“惜字得福”之说。而在我国传统文化中有一种独特习俗——“惜字如金”,“敬天惜字”。
于是,焚烧字纸就变得非常的郑重,不但有专门的礼仪,还建有专门的场所和设施,于是“字库塔”就应运而生,也就成了古人专门修建来焚烧字纸的小型建筑。据史料记载,字库塔始建于宋代,到元明清时已经相当普及了。
在古代,民间有种说法,糟蹋字纸会生疮害病、瞎眼睛,受到惩罚并祸及子孙等,因此字纸不可秽用,而应该“羽化成蝶”,而糟蹋字纸会得罪神灵,受到惩罚并祸及子孙。所有用过的字纸或废书,都要统一收集起来,放到一个地方集中焚化。

小时候,一直把语言和文字当成知识的载体,是语文和英语这样的学科,一种很客观的工具。没想到古人对待文字是如此的神圣,甚至达到需要单独做祭坛的程度。最近几年也一直有感触,语言和文字肯定以及必然在上古时期是有魔法的。

这个魔法怎么来的,比如人类最原始,最古老的语言词汇,肯定是 妈妈,爸爸。

一个孩子叫你一声父母,你身上就多出来一份悲怜和责任。据我观察,很多成年人和家庭,都是因为孩子,苦苦撑下去。没有软肋的中年人是无敌的。

所以我觉得,某种程度上,这个称谓是一种咒语。为什么是咒语?拿魔幻小说《哈利波特》为例,最入门的打架咒语就是 “除你武器” (Expelliarmus)。这是哈利的招牌咒语,作用是让对手手里的武器(通常是魔杖)飞出去,有时也会直接把人震退。如果你在网上或者现实中骂架,让对方直接破防的咒语是啥呢?

我是你爹!

对方要破除你这个咒语,那么多半会使出类似下面这样的咒语:

我今天非教训你这孙子不可

爹,孙子 这些人类最基础的代词,居然有如此调动情绪魔力。

又看到最近和长久以来一个被反复提起的话题:

媒体呼吁「同志」称呼重归主流

曾几何时,招呼人无须刻意措辞,一声“同志”便可,听者坦然、舒泰。后来,经济发展、文化多元,称呼也花样百出,“先生”“小姐”“老板”满天飞,开初尚觉新鲜,久之不免腻味,尤其是“小姐”这一称呼,常给人轻薄之感。如今,“小姐”似乎被“美女”取代,后者也逐渐失掉了赞美之意,变成了泛称。
称呼自有其潮流,随时代而动。譬如“同志”,在民风淳朴的年头,人们不论是在工作中,还是在生活里,都讲究人人平等,因而“同志”这种一视同仁的称呼也被长久使用,且“同志”也有志同道合之感。再如“师傅”,使用的时间也不短,于我个人而言倍觉亲切。我年轻时在机务段当过3年机车钳工学徒工,满师后又独立干了一年左右车辆修理活计。当时,早我几天入行的师兄师姐,我见了一律都得叫“师傅”。在技术为先的机车维修一线,学艺是头等大事,称呼关乎传道授业的礼仪,自然马虎不得。“师傅”之谓,是对有一技之长劳动者的尊称,也是对德厚者的敬重。几十年之后,虽然热火朝天的劳动场景已远去,但是这声“师傅”,我沿用至今。我想,只要对方形容不轻慢,精神不委琐,不论老少,皆可尊称一声“师傅”。

中年人应该对这个最有感触的。小时候以为所有人都叫 叔叔阿姨 就够了。直到有一天,你被别人叫了 叔叔阿姨。身份的转变带来一个困境:原来的叔叔和阿姨,你如何称呼?

能否避免让别人觉得太老?能否不区分职业、职级?能否不区分性别?

有没有一个通用敬语?想来想去,排除上面的“同志”,似乎只有 老师?

没有一个咒语拿来起手破冰,所以一旦脱离了乡土的熟人社会,陌生的人际交往在大城市就很难发生。

身份认同、权力关系、情感负担,这些都是心理学上焦虑和矛盾的根源

想起一个孙猴子那个经典笑话

“原来你就是那闹天宫的弼马温么”
行者道:“是你也认不得你老外公哩。你老外公乃大唐上国驾前御弟三藏法师之徒弟,姓孙,名悟空行者。若问老孙的手段,说出来,教你魂飞魄散,死在眼前。”那怪道:“我不曾会,你有甚么手段,说来我听。”行者笑道:“我儿子,你站稳著,仔细听之。我:

自小神通手段高,随风变化逞英豪。
养性修真熬日月,跳出轮回把命逃。
一点诚心曾访道,灵台山上采药苗。
那山有个老仙长,寿年十万八千高。
老孙拜他为师父,指我长生路一条。
他说身内有丹药,外边采取枉徒劳。
得传大品天仙诀,若无根本实难熬。
回光内照宁心坐,身中日月坎离交。
万事不思全寡欲,六根清净体坚牢。
返老还童容易得,超凡入圣路非遥。
三年无漏成仙体,不同俗辈受煎熬。
十洲三岛还游戏,海角天涯转一遭。
活该三百多馀岁,不得飞升上九霄。
下海降龙真宝贝,才有金箍棒一条。
花果山前为帅首,水帘洞里聚群妖。
玉皇大帝传宣诏,封我齐天极品高。
几番大闹灵霄殿,数次曾偷王母桃。
天兵十万来降我,层层密密布枪刀。
战退天王归上界,哪吒负痛领兵逃。
显圣真君能变化,老孙硬赌跌平交。
道祖观音同玉帝,南天门上看降妖。
却被老君助一阵,二郎擒我到天曹。
将身绑在降妖柱,即命神兵把首枭。
刀砍锤敲不得坏,又教雷打火来烧。
老孙其实有手段,全然不怕半分毫。
送在老君炉里炼,六丁神火慢煎熬。
日满开炉我跳出,手持铁棒绕天跑。
纵横到处无遮挡,三十三天闹一遭。
我佛如来施法力,五行山压老孙腰。
整整压该五百载,幸逢三藏出唐朝。
吾今皈正西方去,转上雷音见玉毫。
你去乾坤四海问一问,我是历代驰名第一妖。”

那怪闻言笑道:“你原来是那闹天宫的弼马温么?”

行者最恼的是人叫他弼马温,听见这一声,心中大怒

这一切也发生在职场。现在流行把同事叫 “同学”。我对此能接受,但是总感觉哪哪不对。

比如你求其他部门的人办事,你又没身份来安排别人,叫 “同学” 恐怕不行吧?的还是叫 “大佬”?你也不清楚对方职级,叫 “同事” 会不会太对等了?

对于我这种社交白痴,万分纠结。

职场混久了,感悟很多事儿其实是跟业务无关的。规章制度更多的都围绕一个核心:不信任成本。官场也一样,不要看什么AI 智慧城市 什么的,哪里有那么多 intelligence。全都是 diligence 不够。

为什么 diligence 不够?现代社会分工太细,你使唤不动别人。

很多事你是有心无力的。

或许,离开了原生家庭,这个世界没有魔法了。

Posted

stderr

原研哉《棍子和碗》

之前看到个 棍子和碗 的说法,印象很深,觉得很扯,总觉得哪里不对,但是没想明白。查了下居然是 原研哉 说的。也就是传说中200w给小米logo倒了个圆角的日本设计师。

日本设计家原研哉有一个说法,他说,这个世界上,我们用的所有东西只有两样,一个是碗,一个是棍子。什么意思?
碗,就是用它围合起来的那个内部空间。比如水缸、冰箱、液化气罐、汽车、房子、手机,本质上都是碗。它内部装了什么,决定它是什么。
而棍子呢?就是用它去作用于其他东西。比如弓箭、螺丝刀、枪炮、键盘,本质上都是棍子。它作用于什么,才决定它是什么。
其实,我们中国人在文化中也有类似的分类法。我们经常说一个词“器具”。所谓“器”,就是装东西的,就是原研哉说的“碗”;而“具”呢,就是作用于其他东西的,就是原研哉说的“棍子”。这两样东西合起来就是“器具”,也就是人类造出来的所有东西的统称了。
之所以提这个分类方法,是想说,我们观察任何东西,都有两个角度,一个是看它内部装的是什么,就是它作为一只“碗”的特质。还有一个,就是看它作用于什么,就是它作为一支“棍子”的特质。
比如说,我们了解一个人,当然可以把它看成一只碗,看他身体内部的状况,给他做体检,和他谈心,看他的所思所想,这是了解一个人的方法。但是我们也可以把他看成是一根棍子,在他周边的社会关系中进行访谈,看他干了什么,成就了谁,又祸害了谁,他在自己的社交网络里面填补了什么空白,他的每一个行动是在应对什么挑战。

刚中午小憩的时候,突然想通了,这个二元论分类太内涵,太隐晦了。我不妨帮日本人把这个分类说得更直白一些:

  • 棍子就是 JJ
  • 碗就是 子宫

Posted

stdin

A single Python function for both async/sync

Scenario: I often need to write Python functions like:

  1. take some parameters and format them
  2. call an API with the formatted parameters
  3. parse the result and return chosen values

There's a huge problem in step #2.

In today's Python world, troubles arise because async/await are "infectious", In practice this function is splitted - like in Python stdlib, where a vanilla method and its async counterpart amethod often come in pairs. Package authors scramble to provide sync transport and another async transport. I discovered this ugly fact while reading the source code ofredis-py, httpx and elasticsearch-py. Duplicate and lookalike code was always written twice. All it takes is some random async IOs in one place and your code would be forced to change forever.

Is there a way to write the function in one place, but callable both with async and without?

I pondered this question for ages, and today I stumbled upon something interesting:


  def s1():
    return asyncio.sleep(1)

  async def s2():
    return await async.sleep(1)

There's virtually no difference when calling await s1() and await s2()

I vaguely remembered how Python’s coroutines were designed, and after some tinkering, I came up with this snippet:


import asyncio, types, functools

def aa(f):
    """
    make a function both awaitable and sync
    idk how to property name this. anti-asyncio (aa) maybe?
    """
    @functools.wraps(f)
    def wrapper(func, *args, **kwargs):
        if asyncio.iscoroutinefunction(func):
            return types.coroutine(f)(func, *args, **kwargs)
        else:
            async def afunc(*a, **kw):
                return func(*a, **kw)
            g = types.coroutine(f)(afunc, *args, **kwargs)
            try:
                while True: next(g)
            except StopIteration as ex:
                return ex.value
    return wrapper


@aa
def my_func(func, *args, **kwargs):
    # prepare args, kwargs here
    # add a prefix `yield from` everywhere, for either sync/async
    result = yield from func(*args, **kwargs)
    # handle the result here
    return result


import httpx

# async
async def main():
    # the same as `await httpx.AsyncClient(timeout=3).get('https://est.im')`
    print(await my_func(httpx.AsyncClient(timeout=3).get, 'https://est.im/'))
asyncio.run(main())


# sync
print(my_func(httpx.get, 'https://est.im'))
# works the same as httpx.get('https://est.im')

The above shows a single function called my_func, dependency injection of an HTTP get call of either sync/async, allows for customizable pre- and post-processing logic, and returns the result with clean syntax.

The only mental tax: inside my_func, you have to replace all await keyword with `yield from.

Update 2025-05-16: The only mental tax: add a yield from prefix for every funccalls for IO or API, either sync or async.

It solves all problems for my scenario and I’ve yet to find a simpler solution. If you have a good name for the @aa decorator please comment!

A sidenote, I am not sure if this method affects async schedulers and blocks something maybe? Like the while True might be a new kind of GIL. Also i haven't looked at problems with contextvars.

Posted

stdout

听 彭罗斯 吹了90分钟波函数的坍塌

https://www.youtube.com/watch?v=sGm505TFMbU

Roger Penrose: I don't believe it is consciousness that collapses the wave function, instead it's the collapse of the wave functions that produces consciousness

这句话很美妙啊。一下子把唯物和唯心给联系起来了。

我一直觉得,人的意识,就是因果律的推演。这个推演明显是一个离散的,有清晰步骤的,quantized 的和决定论的。

人的潜意识和直觉可能是概率的。

看完这个 90分钟的访谈,我大概明白为啥 量子力学 和 神棍 经常联系在一起了。一切都源于这个薛定谔方程 和 “观察者”

观察者不是一个真实存在的定义。你甚至无法严格定义 观察。欧美神棍一般喜欢往三位一体,意识,灵性上面靠。感觉物理世界是混沌的,一下子有了光,状态就坍缩了。哈哈哈。

国内的话 遇事不决,量子力学。民科重灾区。甚至还有量子佛学这种离谱的。

他还写了一本书,Fashion , Faith and Fantacy,fashion就是弦论,faith 就是量子力学。fantacy是宇宙膨胀理论。哈!

Posted

stdin

光 的本质是什么?

来自 Curt Jaimungal

Guy:什么是光?
Chap:嗯,光是使物体可见的东西……
Bloke:其实,光也可以是不可见光谱的一部分,比如紫外线和红外线……
Lass:其实,光是光子,是电磁场中的一种波动……
Dude:其实,光子是电磁场中量子化的波动……
Fellow:其实,光子是与狄拉克方程的 U(1) 对称性相关的规范玻色子……
Guy:其实,光子是与狄拉克方程的局域 U(1) 对称性相关联的规范玻色子……
Fellow:其实,光子场来源于 SU(2)ʟ × U(1)ʏ 的一个子群——该子群保持希格斯真空态不变……
Chap:其实,光子一种导数……
Guy:其实,光子是为了使导数具有规范不变性而进行的修改,和刚才那位说的一样……
Lass:其实,光子是庞加莱群的一个表示……
Dude:其实,光子是庞加莱群的一个不可约表示……
Fellow:其实,光子是庞加莱群不可约表示的一个基底元素……
Guy:其实,光子是一个四维时空中无质量、自旋为 1 的粒子……
Chap:其实,庞加莱群本来就在四维时空中,所以这是多余的细节……
Bloke:其实,庞加莱群可以推广为任意维度 d 下的 ISO(1,d−1) 群……
Lass:其实,d 必须大于 2,否则系统会出现简并结构……
Dude:你才简并呢……哦不好意思……我是说,其实,光子是从超图的底层更新规则中涌现出来的一种现象……
Fellow:其实,光子是统一规范势 ϖ 中与结构群 Spin(4) 子群相关的一个特定分量,而这些规范分量是通过观测嵌入被拉回到我们 4D 时空中的……
Guy:其实,我们原本是在谈“光“这个词,它源自古英语 lēoht,意思是“亮度“……
Chap:其实,它是原始日耳曼语 leuhtam,也表示亮度——所以你这次总算说对一件事……
Dude:其实,词源更早是原始印欧语 leuk-,意为“光、亮“,同源词有拉丁语 lux、希腊语 leukos(意为“明亮、白“)……
Lass:其实,还可以追溯到梵语 rochis,意思也是“亮度“……
Dude:其实,你不该说“其实“,你破坏了节奏……
Fellow:其实,词源顺序是:古英语 → 拉丁语 → 原始日耳曼语 → 希腊语 → 梵语 → 原始印欧语……
Guy:其实,光是黑暗的缺失,而黑暗的定义是邪恶……
Chap:其实,“邪恶“可以在扭量空间中建模为全纯对象……
Bloke:其实,我们回到光子的问题,它在弦论中是 H¹(T, O(−2)) 的一个上同调类,其中 T 是扭量空间,O(−2) 是一个全纯线丛,用于编码自旋为 1 的无质量场的螺旋度……
Lass:其实,光子是共形场论中的边界激发……
Dude:其实,光子是电子-正电子对自纠缠形成的涡旋结构,可能包含 T4G 框架下的虫洞子结构……
Bloke:其实,光子是由弦局域场表示的,属于庞加莱群下零质量、无限自旋的表示……
Fellow:其实,光子是一个沿零测地线传播的无质量粒子……
Guy:其实,引力子和其他假设粒子也可以是无质量的,并沿零测地线传播,所以……
Chap:其实,光子是光中微子的超对称伴粒子……
Bloke:其实,在弦论中,光子是开放弦的第一个激发态,通常出现在 Neveu–Schwarz 扇区……
Lass:其实,你们已经这样说了五十年……
Dude:其实,我没说五十年,不然我一直在呼气早就不能呼吸了……
Fellow:其实,你太咬文嚼字了……
Dude:其实,我只是在追求表达的精确性……
Chap:其实,你表现出对“其实”准确性的过度执着,并在越来越细微的细节上纠缠,以至于忽视了整体,这正是咬文嚼字的体现……
Bloke:其实,你的指责本身是主观观点,而不是“其实”判断……
Dude:好吧,这有点失控了。
Chap:其实没有,一切都在掌控之中。
Fellow:你是个傻子。
Guy:而你没有动用你整个大脑。
Fellow:这没关系,因为人类本来也只使用了 10% 的大脑……
Bloke:……
(众人互望)
(沉默十秒)
Fellow:……
Guy:(看着 Dude)还是别说这个了——
Dude:其实……

Curt Jaimungal 的视频看着真过瘾。我是从他 youtube 频道 Theories of Everything 最近一期喷真理元素 (Veritasium) 了解这个人物的。北美何教授。

Posted

stdin

Windows 自动设置开机锁屏壁纸 V3

之前也写过,Windows下自动设置墙纸 V1V2,今天发现两种方法都失效了。

于是一气之下搞了个 Bing Image of the Day 版本的。

保存为 change_wallpaper.bat 双击执行。加入自启动或者定时触发。

@if (@X)==(@Y) @end /* set Win10 wallpaper to Bing Image of The Day. By est.im
@echo off
cscript //Nologo //U //E:JScript "%~F0"
exit /b %errorlevel%
*/

function http_get(url){
  var xhr = new ActiveXObject("MSXML2.XMLHTTP")
  xhr.open("GET", url, false)
  xhr.setRequestHeader("Accept-Encoding", "identity")
  xhr.send()
  return xhr
}

var rss_req = http_get('https://www.bing.com/HPImageArchive.aspx?format=rss&idx=0&n=1&mkt=en-US')
// WScript.Echo(rss_req.getAllResponseHeaders())
var img_url = 'https://www.bing.com' + rss_req.responseXML.selectSingleNode("//rss/channel/item/link").text
WScript.echo(img_url)
var fso = new ActiveXObject("Scripting.FileSystemObject")  // shit cant handle binary data
var stream = new ActiveXObject("ADODB.Stream")
var img_path = fso.GetSpecialFolder(2)+"\\bing_iotd.jpg"
WScript.echo(img_path)
stream.Open()
stream.Type = 1
var img_req = http_get(img_url)
stream.Write(img_req.responseBody)
stream.SaveToFile(img_path, 2)
stream.Close()

var WshShell = new ActiveXObject("WScript.Shell")  
WshShell.RegWrite("HKEY_CURRENT_USER\\Control Panel\\Desktop\\Wallpaper", img_path, "REG_SZ")
WshShell.Run("RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters")

其中 format=rss 可以改成 =js 或者 =xml 本来想解析 json 但是发现老的 IE6 引擎不能支持双引号这种JSON,而且只能用 eval() 就放弃了。还好有 xpath 还挺方便。

要用 .bat 套一层是因为 win10 貌似禁止 .js 或者 .vbs 双击执行了。病毒木马太多了。这种一份源码同时被两种语言解析还有点技巧可以参考下。

很久没写 .jscript 了用了 ChatGPT 这个 vibe coding 真爽。

Posted

stdout

语言,逆差

又睡不着,琢磨一段话

多戲超人 @DoubleFakeCute: 文字很容易传播仇恨,但很难传递感动。
@yetone: 是的,换句话说文字传播感动是需要功底的,但是传播仇恨不用上完九年义务教育就可以

这句话背后揭示了一个道理:表达愤怒、抱怨、不满,似乎是语言最原始、最本能的用途。人类还未掌握完整的语法与修辞,就已学会了哭泣。

新生婴儿落地的第一声啼哭,正是一种天赋的语言——一种对环境提出抗议的表达。哲学家维特根斯坦说过:“语言的边界就是世界的边界。”在生命伊始,我们的语言边界,即是对苦痛的感知;我们最早学会的,是如何说“我不喜欢”。

相较之下,笑,是后天习得的,是在社会化过程中逐渐学会的回应。但当笑成为一种礼貌、成为一种职场的面具,它也就褪去了它的真实。于是我们在笑中疏离,在沉默中彼此冷漠,脸上浮现的,是长久训练出的 poker face,那张扑克脸仿佛是一种文明社会强加的伪装。

最近 realDonaldTrump 把🇨🇳进口关税从10%,20%,54%,104% 一路干到154%。 仿佛数字本身也在喊叫。一个长期生活在中国的美国人 王渊源John 打趣地说 trump 的支持者之所以对“涨关税”拍手叫好,是因为“trade deficit”(贸易逆差)这个词在英语里带有天然的负面含义——“deficit”意味着赤字、亏空,仿佛国家正在负债累累。而在中文语境中,“逆差”这个词更像是一种经济现象,而非道德沦丧,无需过度反应。

这让我想起另一个语言误会的悲剧——美国的“war on drugs”(禁毒战争)之所以久攻不下,很大程度上,也可能是败在语言上。在英语中,“drug”一词含义,既可以指药品(medicine),也可以指毒品(narcotics)。这导致在大众语感中,毒品并没有一种“邪恶之物”的鲜明面孔。相比之下,中文中“毒品”与“药品”泾渭分明,一个是治病,一个是害命,“吸毒”这个词本身就带着罪与恶的意味。而英文中的“drug overdose”,只不过是一场“药物使用过度”的中性描述,仿佛只是剂量出了问题,而非价值观的崩塌。

语言之毒,在于其无形;它不像刀剑那样可见、可防,而是悄无声息地改变我们的感知。孔子曾说:“巧言令色,鲜矣仁。”。庄子又言:“言者所以在意,得意而忘言。”。语言虽巧,往往意在蛊惑;修辞的闪光点,也可能是陷阱的倒影。语言的本质是媒介,而非终点。

古代巫师、祭司、先知,其实都是语言的炼金术士。他们并非真正能预见未来,而是能以一字一句为符咒,将人的心智引向他们想要的方向。如《盗梦空间》中,那个悠悠旋转的陀螺,不断将人困于梦与醒之间,真假难辨。

语言即现实的建构者,它能唤醒你,也能奴役你。它是文明的基石,也是误解的温床。传播仇恨,只需几句粗陋的标语;而传递感动,却如雕刻光影,需要时间、技艺与赤诚。


15:12 根据ChatGPT润色了文章。太他妈吊了。

Posted

stderr