<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Aphelion</title>
        <link>https://rynco.me/</link>
        <description>Rynco Maekawa's Personal Blog</description>
        <lastBuildDate>Thu, 12 Mar 2026 12:06:07 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>(c) CC-BY 4.0, by Rynco</copyright>
        <item>
            <title><![CDATA[林子的 2025 年终总结]]></title>
            <link>https://rynco.me/posts/wrapping-up-2025/</link>
            <guid isPermaLink="false">https://rynco.me/posts/wrapping-up-2025/</guid>
            <pubDate>Thu, 12 Mar 2026 11:58:51 GMT</pubDate>
            <description><![CDATA[三月了！！！！这个人才开始写年终总结！！！！
]]></description>
            <content:encoded><![CDATA[<p>2025 年的自己猜得没错：时间确实过得越来越快了。
这篇年终总结竟然已经是到了三月才开始写的。</p>
<p>闲话少说，来看下林子的 2025 年吧！</p>
<h1 id="工作" tabindex="-1">工作 <a class="header-anchor" href="#工作" aria-label="Permalink to “工作”">&#8203;</a></h1>
<p>在 MoonBit 的日子不能算差，至少在还有自由度的时候是这样的。</p>
<p>年初我给 <code>moonc</code>（MoonBit 编译器）做了一个完整的、带 debuginfo 生成的 LLVM 后端。
再上次写 LLVM IR 生成还是在研究生实验室打工的时候，
所以实际上算是重新熟悉了一遍 LLVM。</p>
<p>这个过程中比起倒腾 LLVM 本身，让我学到更多的其实是打包的过程。
当时的项目要求最早要能在 Ubuntu 16.04 上跑起来——但是 LLVM 18 的编译要求 C++ 17 的支持。
经过无数次 CI 爆炸之后，
最终让项目跑起来的配置是用系统自带的 GCC 5 bootstrap 一份 GCC 9.5，
再用 GCC 9.5 编译 LLVM 18 来拿到需要的兼容性和版本。</p>
<p>另外，LLVM OCaml binding 本身也很年久失修了
——当时修改的时候目之所及都是 10 年以上的老登代码。
想在这个环境下给它加功能加测试，
甚至同时还<a href="https://github.com/llvm/llvm-project/pull/131583" target="_blank" rel="noreferrer">交了一个 PR</a>，现在想想还是有点佩服自己的。
不过有点遗憾的是其实还有一些其他的对 LLVM OCaml binding 的翻新修改，
因为当时时间比较紧还没有交到上游，
但是现在也没有机会交了。</p>
<p>四五月份的时候离职了两位同事。
我到现在也不知道他们的离职原因到底是什么，虽然我觉得我能猜到。
总之，这两位同事的项目就都落到了我的身上。
于是情况就急转直下了。
自由度？什么自由度。</p>
<p>五月一整个月都被用来更新包管理平台的后端。
从六月开始，我就在着手构建系统的重构工作了。</p>
<p>我不想说前同事坏话。
大家都是打工人，在这么紧的期限内写出来的东西能跑就很不错了。
相比之下，就当是我的工作记忆没有一般人那么大好了。
对于构建系统的行为，当时的我实在是难以在短时间内理解透彻。</p>
<p>总之，接手构建系统之后光研究行为我就研究了一个多月，
才总算把一般情况下的构建行为写成文档。
之后就是磨人的语义对齐工作。
从七月到十二月，我的工作基本上就是 实现功能——对比测试——修 bug 的循环。
没办法，各种 edge case 的行为太难搞了。这还没到 1.0 呢。</p>
<p>然后在新年之前我就跑路了。</p>
<p>关于离职的细节我不想说太多，总之算是某种程度上的方向不和导致的和平分手吧。
前同事们人都很好，我对他们没有任何负面评价。
实在对相关的事情和感想感兴趣的话，也可以找我偷偷问，大概？</p>
<p>离职之后就离开了深圳，回到了北京，gap 了一个月，然后到了现在的公司。
至少目前感觉还不错，祝我好运。</p>
<h1 id="摄影" tabindex="-1">摄影 <a class="header-anchor" href="#摄影" aria-label="Permalink to “摄影”">&#8203;</a></h1>
<p>可能有些人发现我开始发修过的照片了。</p>
<p>我对摄影其实一直都有点兴趣。
我喜欢拍城市的楼，拍天空和云，当然也有路边的花花草草。
反倒是人好像拍的很少的样子。
但是对我来说，手机摄影在有些时候不是最好方案：</p>
<ul>
<li>
<p>一是手机相机的调色一般都很……高对比度。锐化过度。
还有 HDR 压进 JPEG 导致的各种神秘局部对比度问题。
总之拍出来总觉得修的有点过头。</p>
</li>
<li>
<p>二是没有长焦。
我尤其喜欢选取视野中很小的一块作为拍摄主体，
而当时使用的红米 Note 12 Turbo 的长焦端只能到 50mm（而且清晰度还很差），
导致很多时候我只能用 50mm 去凑合拍，后期再裁剪。
想拍 70mm 以上的视角基本上就是在做梦。</p>
</li>
</ul>
<p>于是到了年底我忍不住了，趁着还有国补买了一台 Sony A7C2 全画幅微单，
配了<a href="https://www.tamron.com/global/consumer/lenses/a075/" target="_blank" rel="noreferrer">腾龙的 25-200mm f/2.8-5.6 天涯头</a>。</p>
<p>简而言之：爽。</p>
<p>是真的，200mm 带来的爽感是 50mm 完全比不了的。
我终于可以把河堤上的人群装满取景框，
或者只截取高楼的一段或一片窗户作为拍摄主体，
或者只关注夕阳下远处的雾霭而不用拍成经典风景照了。
相机的调色和极端情况下的宽容度也比手机好太多了。毕竟底大一级压死人。</p>
<p>算了，不如去看看<a href="https://unsplash.com/@lynzrand" target="_blank" rel="noreferrer">我的 Unsplash</a> 吧。
还有免费下载喵！</p>
<p><img src="https://rynco.me/assets/shenzhen-haze.DxfjXFW-.jpg" alt="深圳夕阳下的雾霭"></p>
<h1 id="植物" tabindex="-1">植物 <a class="header-anchor" href="#植物" aria-label="Permalink to “植物”">&#8203;</a></h1>
<p>我开始养花了。</p>
<p>对，这个上学的时候连吊兰都能养死的人竟然开始养花了。</p>
<p>说来话长，但是长话短说：
五月的时候，我和朋友在一个叫 “很久以前” 的烤串店吃饭的时候，
被店员送了一盒 “呼伦贝尔的草籽”。
现在想想估计就是易拉罐分装的牧草草籽之类的东西吧。
不管怎么说，反正朋友说她已经有过一盒了，所以让我拿回家种着玩，于是我的窗台上就有了一盆青草。</p>
<p>光养青草有什么意思，对吧？</p>
<p>彼时我刚买了 3D 打印机，手里是锤子到处都是钉子，
于是我就开始给自己的青草建模并打印各种<a href="https://www.printables.com/model/1334044-minimalist-rectangle-flower-pot" target="_blank" rel="noreferrer">小花盆</a>。</p>
<p>然后就成了正反馈循环。
建模花盆本身就是一种享受（神奇吧 ADHD），
于是我每次建得差不多就去把它打出来。
打出来的花盆也不能空着，于是我就开始找更多的种子来种。
就这样直到我的窗台已经塞满了，没有地方放新的花盆为止才停手。</p>
<p>我从深圳的出租屋搬走的时候，
窗台上已经有了青草、三角酢浆草、吊兰、量天尺、欧芹、大花马齿苋和科西嘉薄荷，
一共七种植物，占据了厨房和卫生间的所有窗台空间。</p>
<p><img src="https://rynco.me/assets/windowsill.Xc01unGn.jpg" alt="草和打印机"></p>
<p>搬家的时候只有酢浆草、马齿苋和科西嘉薄荷被带回了北京。其他的都留给下一任租客了。
不过我已经开始在北京的家里种植新的猫薄荷、鼠尾草和葱了！</p>
<h1 id="精神" tabindex="-1">精神 <a class="header-anchor" href="#精神" aria-label="Permalink to “精神”">&#8203;</a></h1>
<p>我在<a href="./../2025-01-05-wrapping-up-2024/">去年的年终总结</a>里曾经怀疑自己有 ADHD。
这一猜想在春节前的最后几个工作日中不幸得到了证实。
不过老实说，确诊的信息其实对我也没啥影响：
专注达和托莫西汀的副作用对我来说都有点大，
所以现在依然是靠自觉维持一个差不多能像正常人一样工作的状态。</p>
<p>顺便一提，ASD 的诊断则因为深圳康宁医院没有条件作罢。
不过即使诊断了也没什么用就是了。</p>
<p>我怀疑去年下半年工作的压力越来越大的时候我就有了一些抑郁倾向，
毕竟工作最后一段时间的精神状态实在说不上健康。
随着今年年初确诊了一点点轻度抑郁，也是吃上 SSRI 了。
好在是轻度的。——还是因为我没有动力写项目才发现的。所以应该比较好解决吧。</p>
<p>工作真的会改变人，我去年最后一部正经看完的动画还是《Ave Mujica》。
只到今年年初才又看完了《超辉夜姬》。
哎工作怎么这么坏啊。</p>
<blockquote>
<p>一点也不感到寂寞哦<br>
因为我有好好习惯寂寞</p>
</blockquote>
<p>此乃谎言。</p>
<p>早就习惯寂寞了，但是偶尔也还是会想要一些让人安心的关系的吧。<sup class="footnote-ref"><a href="#footnote1">[1]</a><a class="footnote-anchor" id="footnote-ref1" /></sup></p>
<h1 id="杂谈" tabindex="-1">杂谈 <a class="header-anchor" href="#杂谈" aria-label="Permalink to “杂谈”">&#8203;</a></h1>
<ul>
<li>
<p>如前文所说，去年买了 3D 打印机。
目前已经成功沦为我的花盆工厂和我妈的手办工厂。
不过还是打印了一些收纳盒、吉他支架、相机包隔板之类的有用的东西的。</p>
</li>
<li>
<p>2024 年提到的延迟已经达到了奥尔特云级别的朋友，在 2025 年完全没有反馈。</p>
</li>
<li>
<p>不过好消息是 2025 年交到了不少新朋友！而且也有新的感兴趣的人了，大概！</p>
</li>
<li>
<p>2025 年 3 月开坑做了一个字体，<a href="https://github.com/pangpang-studio/monoxide" target="_blank" rel="noreferrer">Monoxide</a>。感兴趣的话可以看看。</p>
</li>
<li>
<p>离职之后的 gap 期间我去香港和澳门旅游了一趟。</p>
</li>
<li>
<p>我现在对于 AI 编码在工作中的用途依然持怀疑态度。</p>
</li>
</ul>
<h1 id="结语" tabindex="-1">结语 <a class="header-anchor" href="#结语" aria-label="Permalink to “结语”">&#8203;</a></h1>
<p>人呐就不知道，自己不可以预料。
2024 年年底写下 “10/10 would recommend” 的自己大概也不会想到一年后会这么坚定地离职吧。</p>
<blockquote>
<p>快乐一点当然更好<br>
还是假装开朗强颜欢笑吧</p>
</blockquote>
<p>今天的未来又会是什么样子的呢？</p>
<p><img src="https://rynco.me/assets/evening-birds.D0_k2GCx.jpg" alt=""></p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="footnote1" class="footnote-item"><p>虽然本意并非如此，但是也不是不能把这条当作求偶…… <a href="#footnote-ref1" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
            <enclosure url="https://rynco.me/assets/shenzhen-haze.DxfjXFW-.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Please don't make your compile unit the same size as your namespace.]]></title>
            <link>https://rynco.me/posts/compile-unit-neq-namespace/</link>
            <guid isPermaLink="false">https://rynco.me/posts/compile-unit-neq-namespace/</guid>
            <pubDate>Sun, 16 Mar 2025 15:24:23 GMT</pubDate>
            <description><![CDATA[A brief research about the relationship between compile unit and namespaces, and why you shouldn't copy Go on that.
]]></description>
            <content:encoded><![CDATA[<p>Before we start,
allow me to specify the terminology used in this article.
Terms like &quot;package&quot; and &quot;module&quot; tend to differ from language to language,
so it's good to settle on one interpretation so we avoid mimatches.</p>
<ul>
<li>
<p>A <strong>package</strong> is the unit of code that usually gets distributed atomically.
Examples are NPM and Python packages, Java JARs, Rust crates, Go modules.</p>
<p>When mentioning Go packages (namespaces), it is always next to &quot;Go.&quot;</p>
</li>
<li>
<p>A <strong>compile unit</strong> is the collection of code that gets compiled
in one call to the compiler.
Think whatever files you feed into <code>gcc</code> or <code>javac</code>.
Usually, cyclic dependency can only exist within one compilation unit,
unless the language contains features like forward declaration.</p>
</li>
<li>
<p>A <strong>namespace</strong> is an organization of code symbols that is logically grouped together.
Referencing to symbols (functions, vars, types) within the same namespace
is usually easier than referencing those outside.
Symbols can have the same name in different namespaces,
but usually can't within the same namespace (except overloading).</p>
<p>Examples are C++ and C# namespaces, Java and Go packages, Rust and OCaml modules.
Low-level languages like C don't have namespaces.</p>
</li>
</ul>
<hr>
<Chat :avatar=rynco :flip=true>
  <p>
    Yeah I'm not a Go expert.
  </p>
  <p>
    I have <em>read</em> a couple of Go code before for researching and debugging,
    but almost never <em>written</em> them.
    Take my statements with a grain of salt if you like.
  </p>
</Chat>
<p>I have been researching about module systems between programming languages recently,
because I'm troubled constantly by one specific design decision.</p>
<p>You see, compiled programming languages with namespaces
often fall into one of two categories:</p>
<ul>
<li>
<p>Some <strong>have compile units spanning multiple namespaces</strong>.
An entire package is usually compiled with only one compiler invocation.</p>
<p>Examples of this are: C#, Java, Dart, Rust, etc.</p>
</li>
<li>
<p>Some others <strong>have namespaces spanning multiple compile units</strong>,
usually using one compiler invocation per file.
Some of them can also declare smaller namespaces within them.</p>
<p>Examples of this are: C++, OCaml (with wrapped modules).</p>
</li>
</ul>
<p>Either way (or for some language both ways),
the size of a namespace is usually different from the size of a compile unit.
The compiler leaves you some room to logically groups parts of your code into smaller units,
so you may maintain cleanness while writing namespaces that reference each other.</p>
<p><strong>But there's one language that's a big exception of that -- Go</strong>.</p>
<p>In Go, <strong>a single folder within the source code repository simultaneously respresent
<em>one compile unit</em> and <em>one namespace</em></strong>, which Go calls a &quot;package&quot;.
Go packages cannot have dependency cycles,
and neither does it have any smaller internal structures.
All symbols declared within it must reside in one flat namespace,
which spans all source code files within it.</p>
<p><strong>But why is Go so special?</strong>
Can we study Go's implementation and use it in our own ones?</p>
<Chat :avatar=nene>
  Isn't it because Go's philosophy is to simplify the <em>compiler</em> at every turn,
  while happily forcing complexity onto the <em>users?</em>
</Chat>
<Chat>
  QED. End of article.
</Chat>
<Chat :avatar=rynco flip>
  <em>(chuckles)</em> Can't you just shut up and let me explain first?
</Chat>
<h2 id="when-go-s-solution-worked" tabindex="-1">When Go's solution worked <a class="header-anchor" href="#when-go-s-solution-worked" aria-label="Permalink to “When Go's solution worked”">&#8203;</a></h2>
<p>The structure of Go's package should look familiar to many C and C++ programmers.
Simply speaking,
it's the common C/C++ project structure,
sans header files and forward declaration.</p>
<p>In fact, I would suspect that such design directly comes from C projects --
the three main designers of it are all famous senior C/C++ engineers,
who have worked large, <em>very</em> large C and C++ projects.</p>
<p>Needless to say, Go's package system works.
<strong>But it works not because it's <em>good</em>.
Rather, it's because it is <em>aligned and deeply coupled</em> with the other design aspects of Go.</strong></p>
<Chat :avatar=nene>
  Well at least it's better than writing <code>CMakeLists.txt</code>s I guess?
</Chat>
<p>And I want to put my argument upfront.
Go's package system works now because the following 4 features of Go
forms a reasoning cycle that self-supports.
When some of them change,
the rationale that makes Go packages what they are now no longer holds rigidly.</p>
<ol>
<li>A namespace contains every file in a folder, nothing more or less.</li>
<li>Go's interfaces are structural, decoupling it from implementation.</li>
<li><code>go generate</code> generates new files instead of macros modifying existing files.</li>
<li>Each file gets to specify its list of imported namespaces.</li>
</ol>
<h3 id="namespaces" tabindex="-1">Namespaces <a class="header-anchor" href="#namespaces" aria-label="Permalink to “Namespaces”">&#8203;</a></h3>
<blockquote>
<p>A namespace contains every file in a folder, nothing more or less.</p>
</blockquote>
<p>It's direct derivation of classic C projects' structures.
A somewhat common pitfall in C is forgetting to implement a forward declaration,
so banning them altogether is a valid move (like all other modern languages).</p>
<p>But without forward declaration, how do we handle dependency cycles?
Right, we can allow dependency cycles in one (CMake-style C) &quot;library&quot;
by considering all symbols declared within it at once.
The compile unit gets a little larger than the original C structure,
but it's still within control.</p>
<p>From here, to avoid the other common pitfall in C -- name clashing,
we make each &quot;library&quot; here its own namespace,
so symbols within it won't clash with those outside.</p>
<p>And bam! We get a Go package.</p>
<Chat :avatar=nene>
  So, a Go package is basically a C library isolated in its own namespace,
  with forward declaration replaced with cyclic references within the library,
  and compiled in one unit.
</Chat>
<p>Doing so comes with costs. We'll see how Go's design deals with it.</p>
<h3 id="interfaces" tabindex="-1">Interfaces <a class="header-anchor" href="#interfaces" aria-label="Permalink to “Interfaces”">&#8203;</a></h3>
<blockquote>
<p>Go's interfaces are structural, decoupling it from implementation.</p>
</blockquote>
<p>So, although we can remove cyclic dependencies between Go packages,
there's one more pattern we need to handle
if we want people to write applications on it -- interfaces.</p>
<p>It's a <em>very common</em> pattern to declare interfaces and methods that use implementations together.
Take this for an example:</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre><!--::markdown-it-async::a2h0u98hs0tgkugyanbur6::--><code>package pkg.services:
  interface IService
  class Factory:
    method createA() uses ServiceA
    method createB() uses ServiceB

package pkg.services.a:
  class ServiceA impl IService

package pkg.services.b:
  class ServiceB impl IService</code></pre>
</div><p>Such pattern is very common in applications --
defining high-level interfaces in one namespaces,
defining the implementations in the descendants of it.</p>
<p>But sadly, if you're still using nominal interfaces
<em>while</em> having everything else behave like Go packages,
this won't work.
You get a cyclic dependency:
<code>pkg.services.Factory</code> -&gt; <code>pkg.services.a.ServiceA</code> -&gt; <code>pkg.services.IService</code>.</p>
<Chat :avatar=nene>
  I can put <code>IService</code> into a separate Go package,
  and let all other packages depend on that, I guess?
</Chat>
<Chat :avatar=rynco flip>
  Yeah, why not.
</Chat>
<Chat flip>
  Now you have to create <em>a new package</em> 
  for each common dependency of 
  <em>two packages</em> you don't want to merge.
  Enjoy your packages!
</Chat>
<Chat :avatar=nene>
  <em>*staring at dependency graph*</em>
  Oh man.
</Chat>
<p>So technically you <em>can</em> solve it,
but at the cost of creating a lot more Go packages than you want.
If each file were their own &quot;package&quot; (like OCaml or TypeScript),
you might be able to pull that off (although still quite dirty),
but now you're working with folders,
which are mentally heavier than files...</p>
<p>Go developers obviously went to the other route:
What if our implementation <em>does not</em> depend on the interface?</p>
<p>This takes us to the land of structural interfaces.
The implementation <code>ServiceA impl IService</code> is now implicit and hidden to the compiler.
Such relationship checked only when you actually perform the cast on the type.
In this way, we can now remove the dependency <code>pkg.services.a</code> -&gt; <code>pkg.services</code>.</p>
<p>So, the original downside of Go's package design is now somewhat fixed using structural interfaces,
and structural interfaces (not nominal) are justified by the package design.
Reasoning cycle 1, complete.</p>
<h3 id="go-generate" tabindex="-1"><code>go generate</code> <a class="header-anchor" href="#go-generate" aria-label="Permalink to “go generate”">&#8203;</a></h3>
<blockquote>
<p><code>go generate</code> generates new files instead of macros modifying existing files.</p>
</blockquote>
<p>Macros. The part of C that programmer hate and love the most.
They are powerful enough to save programmers from writing repetitive code,
even generating generic data structures at compile time.
However (as what they are in C), they are notoriously hard to maintain.</p>
<p>This makes it a clear no-go for Go. (Haha, unintentional wordplay.)
So, nothing can modify existing source files now.</p>
<Chat :avatar=nene>
  Can't they use procedural macros?
</Chat>
<Chat :avatar=rynco flip>
  You know Go people will decline compile-time code execution ideas
  like this at first glance.
</Chat>
<p>But programmers still need <em>something</em> to generate code for them.
The thing will need to be able to read and parse existing code,
and then inject definitions that interact with existing code.
Since Go doesn't permit dependency cycles,
they will need to directly inject the code into the current Go package,
but without touching existing files.</p>
<p><em>But wait!</em>
In Go packages, every file within a package already share the same namespace,
so you can just put generated code into the current folder and call it a day!</p>
<p>This is what Go designers settled on.
A <code>go generate</code> command that invokes custom generator executables
(that can parse and generate Go ASTs),
which then generates needed code in <em>new files</em>
that gets <em>automagically included</em> into the current package.</p>
<Chat :avatar=nene>
  But with this definition, 
  they <em>are</em> procedural macros, 
  just manually invoked and generate into another file!
</Chat>
<Chat :avatar=rynco flip>
  Then every code generator is a procedural macro.
</Chat>
<Chat flip>
  <em>*inhales*</em>
  Oh wait they are.
</Chat>
<p>So in short,
the Go package design makes generating code in other files painless,
and such code generation fixes the issue of not having macros to modify files,
making Go's package design necessary.
Reasoning cycle 2, complete.</p>
<h3 id="import-list" tabindex="-1">Import list <a class="header-anchor" href="#import-list" aria-label="Permalink to “Import list”">&#8203;</a></h3>
<blockquote>
<p>Each file gets to specify its list of imported namespace.</p>
</blockquote>
<p>Nobody likes managing dependency,
increasingly so when the unit of dependency gets smaller and smaller.</p>
<p>You might be able to manage the dependency list of a NPM <code>package.json</code> with ease.
But managing dependencies of libraries in a large project
where some of its code are even generated?
That's another story.</p>
<p>Not only will you face a dependency graph
much more detailed than the package-(not Go packages)-level,
but in generated code you <em>will not know what namespaces the generated files depend on</em>,
until the compiler complains!
-- And it might change from time to time!</p>
<p>This is actually quite common in C/C++ project management --
dependencies are hard --
and it's why many C/C++ libraries are dependency-free and/or header-only.</p>
<Chat :avatar=nene>
  Since we usually explicitly import namespaces in code,
  and namespaces <em>are exactly</em> packages in Go,
  does that mean...
</Chat>
<p>Go takes a clever way to solve that.
Instead of the C way of having a <code>CMakeLists.txt</code>-like file
in each Go package specifying its dependencies,
it just uses an import statement like any other modern languages,
and calculates dependencies from those statements.</p>
<p>Because each namespace in Go directly corresponds to a Go package,
the union of all import statements <em>are</em> the dependency of the package.
This also solves the problem of not knowing the dependencies of generated code --
it's specified in that file, so you don't need to even think about managing them.</p>
<p>So, the design of code generation and Go packages can be justified
by gathering dependencies directly from import lists,
and using import list as dependency list can only work when packages is equal to namespaces.
Reasoning cycle 3, complete.</p>
<h3 id="what-do-we-get-now" tabindex="-1">What do we get now? <a class="header-anchor" href="#what-do-we-get-now" aria-label="Permalink to “What do we get now?”">&#8203;</a></h3>
<p>As can be seen in this dependency graph of features in Go,
these features are clearly tightly coupled.
In its heart, the feature &quot;a namespace is exactly one compile unit&quot;
has its downside solved by other features,
and justifies the existence of them.</p>
<p><img src="https://rynco.me/assets/dependencies.BUaoUWq4.svg" alt="Dependencies of Go packages and features"></p>
<Chat :avatar=nene>
  Wondering if I can change some of them...
</Chat>
<h2 id="when-go-s-solution-doesn-t-work" tabindex="-1">When Go's solution doesn't work <a class="header-anchor" href="#when-go-s-solution-doesn-t-work" aria-label="Permalink to “When Go's solution doesn't work”">&#8203;</a></h2>
<p>Say you're designing something of your own.
Your personal weekend programming language project or something like that.
Can you use Go's solution on the trinity of namespaces, compile units, folder?</p>
<p>As you might have guessed from the graph above --
<strong>No. Absolutely no, unless you're making some carbon copy of Go itself.</strong>
Even then, unless you're absolutely sure it will work in your scenario, just don't.</p>
<p>Let's try doing an experiment.
What if we change some of the features above?</p>
<p>Beginning with the structural interface feature.
If we replace that with nominal interfaces
(which means you need to explicitly implement them), what will happen?</p>
<Chat :avatar=nene>
  Umm, I will create a new namespace (i.e. "Go" package) for the interface type,
  so that it can be imported by both its implementors and users?
</Chat>
<Chat>
  And because each namespace spans a whole folder,
  I will end up with many folders with only one file in each!
</Chat>
<p>Might not be <em>that</em> disastrous as you might think,
but many small folders would still be pretty annoying to work with.
In that case you might better off just use file-scoped namespaces,
larger compile units or forward declaration.</p>
<p>Okay. Next up, <code>go generate</code>.
What if we remove it?</p>
<Chat :avatar=nene>
  I will lose the ability to procedurally generate code.
</Chat>
<Chat>
  Okay maybe not,
  but the ecosystem will definitely become more divided.
  Everybody will have their own version of <code>go generate</code>.
</Chat>
<p>Right, metaprogramming is required for compiled languages like this,
or people will find the 100 other workarounds to do metaprogramming without official support for it.</p>
<p>On the other side, if you think of replacing it with <em>real</em> procedural macros...
That's a pure boost,
but it also means you won't need the generated code
to be <em>automagically</em> included in the same namespace as your source code,
so the namespace design is useless again.</p>
<p>Finally, what if we remove the import list?</p>
<Chat :avatar=nene>
  <em>I DON'T WANT TO WRITE <code>CMakeLists.txt</code> AGAIN!!!!!!</em>
</Chat>
<p>That tells.
Micromanaging dependencies is never a good idea,
so in this way you'll prefer the two mainstream designs again.</p>
<p>And let's not forget the elephant in the room -- <strong>large dependency cycles</strong>.
If you happen to be writing something that has a large inherent complexity,
like compilers or large applications,
you'll probably encounter one or two very large dependency cycles
that <em>just can't</em> be easily reduced without increasing maintenance difficulty.</p>
<p>With Go's namespace design,
the tool you have to manage complexity --
smaller namespaces that can be cyclically referenced and partially exported --
does not exist <em>at all</em>.
You're forced to put <em>everything</em> in your reference cycle
into <strong>one big f_cking flat namespace</strong>.
It'd be nightmare maintaining code like this.</p>
<h2 id="conclusion" tabindex="-1">Conclusion <a class="header-anchor" href="#conclusion" aria-label="Permalink to “Conclusion”">&#8203;</a></h2>
<Chat :avatar=rynco flip>
  Do I need to state this <em>again?!</em>
</Chat>
<p><strong>Go's solution works, but <em>it's because it's Go</em>. Go is special.</strong></p>
<p>Go has its very specific set of trade-offs it made,
so that making compile units precisely equal to namespace is possible.</p>
<p><strong>If you're designing something on your own,
you're very likely not using the same set of trade-offs as Go does.
So, just. Please. DO NOT COPY GO'S NAMESPACE DESIGN.</strong></p>
<p>Take a walk outside. Get some fresh air. Touch the grass.
Use anything sane from scripting language's per-file scope,
to modern languages' package-level compile units.
Caching will always be your friend.
Even C/C++'s forward declaration and separated compilation has some merits.
But you're not Go, so just don't copy Go.</p>
]]></content:encoded>
            <enclosure url="https://rynco.me/assets/dependencies.BUaoUWq4.svg" length="0" type="image/svg"/>
        </item>
        <item>
            <title><![CDATA[接纳距离：林子的 2024 年终总结]]></title>
            <link>https://rynco.me/posts/wrapping-up-2024/</link>
            <guid isPermaLink="false">https://rynco.me/posts/wrapping-up-2024/</guid>
            <pubDate>Sat, 11 Jan 2025 02:29:54 GMT</pubDate>
            <description><![CDATA[距离近日点还有很久；在此之前：认同这个距离。接纳这个距离。享受这个距离。
]]></description>
            <content:encoded><![CDATA[<p>2024 年很长，长得甚至有点过头了。
不、并不是说我主观感觉上它很长。只是它确实很长。
我不记得有之前的哪一年经历的事情有今年一年多
——虽然我觉得这应该是我对过去本来就没多少记忆的问题。</p>
<p>但是在我的主观感受里，它很短，就像我对之前的年份的感受一样。
甚至可能还要更短一些。
都说人工作之后时间过的会飞快，这么想来这种说法大概是有一定道理的。
未来的日子大概会过的比刚刚过去的 2024 年还要再快一点吧。</p>
<p>这篇文章其实可以算是临时起意写的。
我想着先定一个标题给全文定下基调，想了半天只好用回 2025 新年贺图的那一句：
<em>Embrace the distance. 接纳距离。</em>
写下来之后发现这句话还意外地挺符合 2024 年的基调的，
就决定这么用了吧。</p>
<h1 id="毕业班的挣扎" tabindex="-1">毕业班的挣扎 <a class="header-anchor" href="#毕业班的挣扎" aria-label="Permalink to “毕业班的挣扎”">&#8203;</a></h1>
<p>根据我的 Git 提交记录，
毕业论文是 1 月 20 日开始写的。
这个时间比我记忆里以为的还要晚一些：我以为是 2023 年 12 月就开始写了。
但是总之，
我毕业前的两个学期可以算是在高等教育的七年里最噩梦的两个学期了。
作为一个学习计算机的学生，
我在这一整年里工作时间干的事情基本上只有写论文、写论文，还是 TMD 写论文。
投会议的项目论文（坏消息：直到现在没投出去），改会议论文，写毕业论文，
改会议论文，写毕业论文，改毕业论文。</p>
<p>写论文可以算是我最不擅长的事情之一了。</p>
<p>感谢写论文，我在放寒假前的那个月底，
由于睡眠问题和精神压力，
成功在校医院精神卫生科拿到了轻度抑郁和焦虑的诊断，
吃了接近两个月的氟哌噻吨美利曲辛。
一天三次，一次一片。
也算是体会过抑郁症病人都会经历什么样的感觉了。
当然，还有一盒我尽可能少去吃的安眠药。</p>
<p>毕业论文写作从一月一直持续到五月中旬，
期间一直以一天不到一千字的水平推进着——我说过，我真的不擅长写论文。
说不上烦躁或者累，只是感觉自己一定要这么做罢了。</p>
<p>三月，我开始了在 <a href="https://moonbitlang.com/" target="_blank" rel="noreferrer">MoonBit</a> 的实习。
老实说，mbt 的工作氛围我确实很喜欢。
工作压力不大，而且所有人都能做到准时下班。
工作内容也都是我熟悉并感兴趣的、编译器和工具链相关的实现和优化。
总的来说，实习体验非常好，这也是为什么我后面决定去那里工作的原因。</p>
<p>比起这个，更大的问题可能是我直到研三写毕业论文的时候才开始实习，
于是我的作息就变成了白天上班、晚上写论文。
这样的安排占去了我所有的自由时间，
所有的 side project 也全部停工了。
我没有多花时间去想这意味着什么。
<strong>我需要干的事情太多了。</strong></p>
<p>于是日子就在这样的规律里一天一天地过去。
在 MoonBit 的现场实习在两周后结束，我回到了宿舍继续进行了三个半月的远程实习，
期间贡献了编译器的一个子模块的实现，还对工具链的某个模块进行了一次完全重写。
毕业论文在我不情愿又坚持的编写下也逐渐涨到了快要可以交差的程度。
大概是心理压力的问题，我还一直有喉咽反流的症状
——只不过因为症状轻微，直到毕业之前都一直没有去看。</p>
<p>我本以为毕业答辩是一切的终点。
不知道是导师换了学院被针对了<sup class="footnote-ref"><a href="#footnote1">[1]</a><a class="footnote-anchor" id="footnote-ref1" /></sup>，或者什么其他原因，
我的毕业论文被提了多条修改意见，并且被要求进行二次答辩。</p>
<p>我向 mbt 请了一周的假。
我认为自己不是一个爱请假的人；在这之前，我每周只会在实验室开组会的那个下午请半天假。
但是总之在那一周，我对照着评委的每条意见认真修改了论文，
包括各种挑刺的格式问题。</p>
<p>然后在第二次答辩之后，
我接到了对论文的大改通知。</p>
<p>端午假期？没有什么端午假期了。
在三天的时间里，论文的第三、四、五章被我全部撕碎，
然后将剩下的尸块用呕吐式写作产生的胶水文字重新拼接成新的章节。
我不是很愿意去回忆这段时间到底发生了什么，现在也想不起来什么东西，
只能从 Git 提交记录里找到一些巨大 diff 的残片。
毕竟毕业证在人家手里……别的事情也干不了什么了。</p>
<p>好在那群评委并没有再次刁难人。
大修之后的论文终于得到了通过，我也再也没有打开过它。</p>
<p>离开读了七年的北航之前，
我回到了我在大一大二时学习和生活的沙河校区转了一圈，
发现里面没有变过的大概也只有教学楼、操场和正门前的草坪了。
被嘲笑了六年的沙河图书馆终于从郁郁葱葱变成了钢筋水泥，
西北角的大片草皮也变成了一片新的教学和宿舍楼。
旧宿舍楼和食堂全部经过了重新装修和粉刷，
我怀念的一楼牛肉饭、三楼铁板饭和麻辣烫全都不见了。
到头来，我只能在自己还认得的几个地方拍点照片怀念一下过去，
在新的食堂匆匆吃过晚饭（顺便一提，西区食堂很好吃）之后离开。</p>
<p><img src="https://rynco.me/assets/buaa-shahe-building.CuLf13pV.jpg" alt="沙河教学楼和图书馆的吊车"></p>
<p><img src="https://rynco.me/assets/buaa-shahe-grass.zQx4-1tk.jpg" alt="沙河正门的草皮"></p>
<p>然后我就毕业了。</p>
<p>没有留恋，仿佛这件事情就该这么发生一样，因为它本来就该这么发生。</p>
<h1 id="_1960-千米与工作" tabindex="-1">1960 千米与工作 <a class="header-anchor" href="#_1960-千米与工作" aria-label="Permalink to “1960 千米与工作”">&#8203;</a></h1>
<p>我的七月是睡过去的。</p>
<p>很好理解。
在那之前的至少半年里我已经过劳了，
于是等到七月毕业之后，我能干的事情只有整天地睡觉了。
失眠和喉咽反流也在这个时间达到了最高峰。
整个七月，我唯三坚持下来的事情就是吃安眠药
（我在很努力地只借助褪黑素入睡）、吃抗酸药和刷多邻国。
我很庆幸这半年没有给我再整出来个什么抑郁之类的——那样的话我的药罐子又要增大一倍了。
毕业论文的余波直到三个月后的九月中旬才基本消解。那是后话。</p>
<p>不管怎样，反正时间是不等人的。
7 月 26 号在 D901 次列车上睡了一个不安稳的觉之后，
我就这样离开了生活了 24 年的地方，
到了距离它 1960 千米以外的那个属于打工人的城市，
成为南海边这个圈里又一名光荣的打工人。</p>
<p>我大概该说我适应的很快。
自己一个人住并没有为我带来什么困扰。
不如说，我就是冲着一个人住来的。
只要有电脑、能吃上饭，我并不怎么在乎自己与别人还有没有联系（吗？）。
家里人？
我过得很好——谢谢关心——不不不我什么都不需要我自己都买了——这就足够了。
因为我一个人真的过的很好。</p>
<p>我甚至开始在周末自己做饭。
以往只有暑假偶尔能锻炼的厨艺，
在有自己的厨房和充足的预制菜来源之后得到了较大的提升。
虽然这里的炉子是个功率小的可怜的电陶炉（甚至不是电磁炉），
但是不管怎样我还是可以用有限的厨具搞出一些自己喜欢吃的东西来，
某种程度上也可以算是生活中的小小幸福吧。
（中间因为工作内容的原因停过一阵子，不过现在又开始了）</p>
<p>上班之后我做过的某些任务还是可以说一说的。
MoonBit <a href="https://mp.weixin.qq.com/s/TqUNsOZPVKCKl_CuBdsdCQ" target="_blank" rel="noreferrer">在前段时间举办了一个编程比赛</a>，
而我在它编译赛道两个月的比赛阶段中承担了绝大部分工作。
改进空间还有很多，我承认。但是我尽力了。
参考实现？后端是我写的，调试是我做的。
测试样例？我写的。
评测机？还是我写的。这甚至是我写的第一个大型 Python 项目。
评测机在我这里的代号是 Kitakogawa——北小河。
我没跟同事说过为什么要起这个名字——他们甚至不知道有这么一个代号
——它其实是在致敬我写过的第一个评测机 <a href="https://github.com/buaa-se-compiling/rurikawa" target="_blank" rel="noreferrer">Rurikawa 琉璃河</a>。
或许以后还会有高碑店、小红门、永丰、槐房或者清河吧。</p>
<p>至于剩下的工作任务，可能等相关的功能公开发出来之后再说还是更好一些。</p>
<p>讲道理，低压力的、规律的生活确实有利于身体健康。
在吃了两个多月之后，我于 9 月中旬正式停掉了抗酸药。
入睡时间也在相近的时间点不再需要依赖褪黑素或者安眠药来维持。
后面虽然有的时候因为工作比较忙或者什么样的原因临时用过一点药物修正入睡时间，
但是确实没有过上半年那样连着几个月吃褪黑素的情况了。</p>
<p>总的来说在 MoonBit 的工作是很开心的。
虽然因为语法设计的问题和同事争论过好几次
（以及至今依然对某些设计细节有保留意见），
但是这个工作内容和条件真的没话说。
10/10 will recommend.
（张老师好像还在<a href="https://x.com/bobzhang1988/status/1872536092634964017" target="_blank" rel="noreferrer">招人</a>，如果你有做 AI 或者编程语言的经验可以投简历试试）</p>
<p><img src="https://rynco.me/assets/the-sky-was-pink.DFdFr-CR.jpg" alt="粉色的天空"></p>
<h1 id="人与人的连接-或者-at-力场" tabindex="-1">人与人的连接，或者 AT 力场 <a class="header-anchor" href="#人与人的连接-或者-at-力场" aria-label="Permalink to “人与人的连接，或者 AT 力场”">&#8203;</a></h1>
<p>熟悉我的人大概都知道，我应该说是一个非常孤僻的人<sup class="footnote-ref"><a href="#footnote2">[2]</a><a class="footnote-anchor" id="footnote-ref2" /></sup>。
那种如果你不戳的话半年都不会给你发消息，
但是依然会把你当朋友的人。</p>
<p>所以当我发现我今年、尤其是今年下半年一直在努力寻找建立人与人之间新的联系的话，
包括我自己在内应该会有很多人感到惊讶吧。
这大概与去年与前女友的分手不无关系，但显然这不是唯一的原因。</p>
<h2 id="在奥尔特云迷失" tabindex="-1">在奥尔特云迷失 <a class="header-anchor" href="#在奥尔特云迷失" aria-label="Permalink to “在奥尔特云迷失”">&#8203;</a></h2>
<p>今年年初，我认识了一位网友。
我第一次读到她（对的，至少我没有找到相反的证据）的知乎回答时就被吸引住了：
在当时的我看来，这简直就是我自己的性转。
科幻。动漫。极客。写编译器。甚至一样都会时不时的搞点小玩具出来。
What can go wrong anyway?</p>
<p>于是在自我纠结了多半个月之后，我给她发了知乎私信，
后来又要到了她的即时通讯软件账号。
虽然她回消息的频率很低（和四五年前的我一样），但是我很享受聊天的过程，
哪怕很多时候是单纯的单方面 pebbling。
她也很享受这样的聊天，至少她是这样说的。</p>
<p>然后就没了。</p>
<p>她说她没有讨厌我，
但是她回消息的频率越来越低。
从最初的每天，
到后来的一周上线一次，
再到中间连续一整个月没有上线。
7 月 1 日她发送了最后一次消息，从此之后再无音讯。
有时还会看到她的账号上线，但是再也没有看到过我发出的消息的任何一次已读。
我不知道发生了什么。
可能她在准备闭关考研。可能她家里发生了一些变故。可能她只是单纯的不愿意找我。</p>
<p>我不知道。我之前尝试寻找这次不辞而别的蛛丝马迹，却一无所获。
我现在已经不再想努力寻找了。</p>
<p>——虽然，如果她想起来还曾经有过我这么一位朋友的话，
我想我并不会因为中间的空档对她有任何其他的、不良的看法。
我可能会问问到底发生了什么，但是仅此而已。</p>
<p>就像我对我曾经和现在的每一位朋友一样。</p>
<p><img src="https://rynco.me/assets/flock-of-birds.d-m6Lmkv.jpg" alt="A flock of birds, hovering above"></p>
<h2 id="新朋友" tabindex="-1">新朋友 <a class="header-anchor" href="#新朋友" aria-label="Permalink to “新朋友”">&#8203;</a></h2>
<p>如果你关注了我的 Telegram 频道，
你可能会发现从今年八九月份开始情绪化的输出频率出现了一次大幅提升。
我不好说这是不是针对之前的失败的一些补偿机制。</p>
<p>不管怎样，今年我认识了很多新朋友。
有些是以前只闻其声不见其人的大佬，有的是曾经一面之交的网友，
也有的是新认识的。
反正都是网友。</p>
<p>感谢你们。
虽然林子可能不会很经常地发消息。</p>
<p>本想在这里列一个具体名单的，想了想还是算了。</p>
<blockquote>
<p>我不愿意把这称作征友，但是如果你觉得你想认识一下林子，欢迎到任意平台给林子发消息。
你知道能在哪里看到我的账号的。</p>
</blockquote>
<h2 id="老朋友" tabindex="-1">老朋友 <a class="header-anchor" href="#老朋友" aria-label="Permalink to “老朋友”">&#8203;</a></h2>
<p>群里今年成了两对。好可怕。
<s>明明是我的后宫群。</s></p>
<p>今年 Rami3L 也来深圳上班了。
在公司有熟悉的人的感觉很不错，
有时候想炫耀点什么也有人可以炫耀（笑）。
我们俩住的很近，回家路上可以一起聊天，他有时候也会来我家蹭饭。</p>
<p>来到深圳之后，常驻珠三角的朋友们也对我提供了很大的帮助。</p>
<p>感谢一直陪伴林子的老朋友们。</p>
<h1 id="文字" tabindex="-1">文字 <a class="header-anchor" href="#文字" aria-label="Permalink to “文字”">&#8203;</a></h1>
<p>11 月中旬，我用自己挣到的钱买了一本电纸书。
不、它并没有成为泡面盖子。
除去我其实不怎么吃泡面的原因以外，
我是真的在用它读书。</p>
<p>除去在上班时间用它读了《The Garbage Collection Handbook》和好多篇论文以外，
我也开始读一些更文学的东西，感觉找回了当年看科幻小说一看一整天的感觉。
在这一个月里，我读完了 Andy Weir 的《火星救援》、《挽救计划》，
还有阿西莫夫的《银河帝国》系列的 1 – 8 部。
《银河帝国》后面机器人的部分不太能引起我的兴趣了，所以到这里就不看了。
我目前在看 Ayn Rand 的《阿特拉斯耸耸肩》，估计再有一周就能看完了。</p>
<p>除去这些文学作品以外，我还看了一些可能有用的非文学作品。
Phillip Dettmer 的《战斗细胞》（Immune）是一部很生动地讲免疫系统的作品，
和他运营的 Kurzgesagt 频道一脉相承。推荐。
我还看了讲工业党的《大目标》和讲经济的《小岛经济学》。
都只看了一半。
倒不是说我认同他们的观点，只不过我觉得读一读的话大概会有帮助罢了。</p>
<p>我开始自己写故事了。
虽然写得很慢，而且受到了 Andy Weir 的巨大影响，
而且是非常 nerd 风格的第一人称故事，
但是至少比起过去那些在达到 1000 字之前就烂尾的东西要好多了。
我不知道到时候会不会发布给不特定人群看，或许应该发一发，但是大概也不会是在这里。</p>
<h1 id="结语" tabindex="-1">结语 <a class="header-anchor" href="#结语" aria-label="Permalink to “结语”">&#8203;</a></h1>
<p>他从不知道持续了多久的睡梦中醒来，
发现自己身处一个不认识的空间站之内。
室内照着昏黄的灯光，
舷窗外是点点繁星和银河。
辨不清方向的他四处张望，
终于找到一颗比其他恒星更亮的星，在黯淡地照耀着自己。</p>
<p>这时他才发现舷窗边贴着一张便签。</p>
<blockquote>
<p>欢迎来到远日点基地。</p>
<p>即使是光，也要花上几十小时才能到达内太阳系。
距离近日点还有很久；
在此之前：认同这个距离。接纳这个距离。享受这个距离。</p>
</blockquote>
<p>他转身回到自己的卧室。</p>
<p><img src="https://rynco.me/assets/aphelion.Dr3hxJzq.jpg" alt="远日点基地"></p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="footnote1" class="footnote-item"><p>和我同一个导师的舍友也遭到了如此待遇，所以我严重怀疑真的是导师被针对了。 <a href="#footnote-ref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="footnote2" class="footnote-item"><p>我之前做过很多自测量表，结论是可能有 ADHD 和高功能自闭症谱系倾向。
我目前没有找过正规医疗机构确诊或者否定这一观点，
不过如果是真的的话确实可以解释我的很多现象，所以姑且认为是一个较大概率存在的事情。 <a href="#footnote-ref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
            <enclosure url="https://rynco.me/assets/buaa-shahe-building.CuLf13pV.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Markdown Extension Examples]]></title>
            <link>https://rynco.me/markdown-examples.html</link>
            <guid isPermaLink="false">https://rynco.me/markdown-examples.html</guid>
            <pubDate>Mon, 30 Dec 2024 15:14:27 GMT</pubDate>
            <description><![CDATA[This page demonstrates some of the built-in markdown extensions provided by VitePress.
 Syntax Highl]]></description>
            <content:encoded><![CDATA[<h1 id="markdown-extension-examples" tabindex="-1">Markdown Extension Examples <a class="header-anchor" href="#markdown-extension-examples" aria-label="Permalink to “Markdown Extension Examples”">&#8203;</a></h1>
<p>This page demonstrates some of the built-in markdown extensions provided by VitePress.</p>
<h2 id="syntax-highlighting" tabindex="-1">Syntax Highlighting <a class="header-anchor" href="#syntax-highlighting" aria-label="Permalink to “Syntax Highlighting”">&#8203;</a></h2>
<p>VitePress provides Syntax Highlighting powered by <a href="https://github.com/shikijs/shiki" target="_blank" rel="noreferrer">Shiki</a>, with additional features like line-highlighting:</p>
<p><strong>Input</strong></p>
<div class="language-md"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre><!--::markdown-it-async::o4yj3oulydcmumdgnu6bc::--><code>```js{4}
export default {
  data () {
    return {
      msg: &#039;Highlighted!&#039;
    }
  }
}
```</code></pre>
</div><p><strong>Output</strong></p>
<div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre><!--::markdown-it-async::3ydii0htjp82vf0ty1d1dq::--><code>export default {
  data () {
    return {
      msg: &#039;Highlighted!&#039;
    }
  }
}</code></pre>
</div><h2 id="custom-containers" tabindex="-1">Custom Containers <a class="header-anchor" href="#custom-containers" aria-label="Permalink to “Custom Containers”">&#8203;</a></h2>
<p><strong>Input</strong></p>
<div class="language-md"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre><!--::markdown-it-async::him3oe7mbxdof3gr5dpmk::--><code>::: info
This is an info box.
:::

::: tip
This is a tip.
:::

::: warning
This is a warning.
:::

::: danger
This is a dangerous warning.
:::

::: details
This is a details block.
:::</code></pre>
</div><p><strong>Output</strong></p>
<div  class="info custom-block"><p class="custom-block-title custom-block-title-default">INFO</p>
<p>This is an info box.</p>
</div>
<div  class="tip custom-block"><p class="custom-block-title custom-block-title-default">TIP</p>
<p>This is a tip.</p>
</div>
<div  class="warning custom-block"><p class="custom-block-title custom-block-title-default">WARNING</p>
<p>This is a warning.</p>
</div>
<div  class="danger custom-block"><p class="custom-block-title custom-block-title-default">DANGER</p>
<p>This is a dangerous warning.</p>
</div>
<details  class="details custom-block"><summary>Details</summary>
<p>This is a details block.</p>
</details>
<h2 id="more" tabindex="-1">More <a class="header-anchor" href="#more" aria-label="Permalink to “More”">&#8203;</a></h2>
<p>Check out the documentation for the <a href="https://vitepress.dev/guide/markdown" target="_blank" rel="noreferrer">full list of markdown extensions</a>.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[又一个新的开始]]></title>
            <link>https://rynco.me/posts/a-new-start.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/a-new-start.html</guid>
            <pubDate>Mon, 07 Oct 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[咦我为什么要说又。

好吧，我又换博客引擎了。
]]></description>
            <content:encoded><![CDATA[<p><em>咦我为什么要说又。</em></p>
<p>OK，确实这又是一个新的开始。
上一个博客已经死掉了<s>，就像 Crychic 一样死得透透的</s>。</p>
<p>事实证明，<a href="https://ghost.org" target="_blank" rel="noreferrer">Ghost 博客引擎</a> 虽然带了个网页编辑器，但是完全没有起到让人想写东西的效果。
而且那玩意还要占一个服务器，之前升级还把 SQLite 支持取消了
（虽然咱当时按照讨论区里面说的方式 workaround 掉了继续用，但终归没有官方支持了），
根本没有好用到哪里去。</p>
<blockquote>
<p>这就是你两年没有更新博客的理由吗？</p>
</blockquote>
<p>好吧。就是咱懒行了吧。</p>
<hr>
<p>总而言之言而总之，我换博客引擎了。</p>
<p>这回用的是 <a href="https://getzola.org" target="_blank" rel="noreferrer">Zola</a>，一个静态网站引擎。
顺便仿照自己以前在 Ghost 上的主题 Dres <a href="https://github.com/lynzrand/ghost-theme-dres" target="_blank" rel="noreferrer">（你现在还可以在咱的 GitHub 上找到它）</a>
的样子写了一个新的主题。
中性灰，极简，正合我意。
名字嘛，上一个主题叫 <a href="https://wiki.kerbalspaceprogram.com/wiki/Dres" target="_blank" rel="noreferrer">Dres</a>，这个就叫 <a href="https://wiki.kerbalspaceprogram.com/wiki/Ike" target="_blank" rel="noreferrer">Ike</a> 好了。
有机会的话咱会考虑把主题开源出来的。</p>
<p>博客的名字被我改成了 Aphelion，远日点。原因？</p>
<p><em><strong>这里超级冷的。</strong></em></p>
<p>咱真诚地希望未来的自己可以在这里多写一点东西。<br>
当然只是希望而已。</p>
<p>倒是已经有几篇博客在酝酿中了。
在不远的将来大概会有一篇讲编程语言的模块系统的，敬请期待。</p>
<h2 id="关于旧博客的内容" tabindex="-1">关于旧博客的内容…… <a class="header-anchor" href="#关于旧博客的内容" aria-label="Permalink to “关于旧博客的内容……”">&#8203;</a></h2>
<p>都搬过来了！而且加了跳转，原来的链接也可以跳转到它们现在的位置！
所以你并没有丢什么东西 XD</p>
<p>Ghost 虽然可以一下子导出所有内容，但是那个 JSON 看着好难受。
总之旧内容是直接把他渲染好的 HTML 搬过来的，希望不会有什么大问题。</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[高级祭祖 Bluespec 现代工具链简单食用指南]]></title>
            <link>https://rynco.me/posts/legacy/high-arch-bluespec-toolchain.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/high-arch-bluespec-toolchain.html</guid>
            <pubDate>Fri, 13 May 2022 18:33:02 GMT</pubDate>
            <description><![CDATA[给在 RHEL、Git 1.8 和 X11 转发中挣扎的 6 系学子们]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>本文的目标阅读群体是还在上北航 6 系高级计组，但是看着 RHEL、Git 1.8 和还需要 X11 转发 GUI 的 Bluespec 工具链不爽的同学们。</p>
</blockquote>
<blockquote>
<p>本文作者强烈要求以后的实验全部用 <a href="https://github.com/chipsalliance/chisel3">Chisel</a> 做。</p>
</blockquote>
<hr>
<p>前情提要：你或许不知道，但是 Bluespec 工具链已经开源了。地址在这里：<a href="https://github.com/B-Lang-org/bsc/releases/tag/2022.01">https://github.com/B-Lang-org/bsc/</a>。开源版本的 Bluespec 跟闭源版本存在一点不兼容（主要是名称上的，详情见 <a href="https://github.com/B-Lang-org/bsc/blob/2021.07/release/ReleaseNotes.adoc#202107-release">2021.07 版本的发布日志</a>），但是基本一致。</p>
<p>如果你不想在本地安装 Bluespec，但是想直接用远程机的命令行进行编译，那么可以直接跳到 Step 1 阅读。</p>
<h1 id="step-0-%E5%AE%89%E8%A3%85-bluespec">Step 0. 安装 Bluespec</h1><p>要自己搭工具链那肯定不能再用老师提供的机器了。</p><p>Bluespec 工具链分为两个部分：提供基础功能的编译器 <code>bsc</code> 以及图形环境 <code>bdw</code> （在实验机器上的命令是 <code>bluespec</code> 那个）。要编译我们写的 Bluespec 程序，我们可以不用 <code>bdw</code> ，直接用 <code>bsc</code> ——缺点嘛，就是要对着命令行发呆喽。</p><p>Bluespec 在开源仓库里面为 bsc 提供了 MacOS、CentOS 和 Ubuntu 版本的预编译程序，其他操作系统的同学需要自己编译。此外，Arch Linux 的同学可以在 AUR 安装 <code>bluespec-git</code> 包，NixOS 的同学可以安装 <code>bluespec</code> 包，当然都需要自己编译（笑）。</p><p>本文作者截止本次更新时尚未尝试过安装或运行过 bdw，所以很抱歉这里还没有关于 bdw 的具体安装指南。应该一个 <code>make install</code> 就能解决了（吧？）。</p><p>用你喜欢的方式安装好 Bluespec 编译器工具链之后就可以编译运行 Bluespec 编译器编译 bsv 文件啦！</p><h1 id="step-1-%E8%BF%90%E8%A1%8C">Step 1. 运行</h1><blockquote>Bluespec 提供了完善的 <a href="https://github.com/B-Lang-org/bsc/releases/download/2022.01/bsc_user_guide.pdf">编译器操作指南</a> 和 <a href="https://github.com/B-Lang-org/bsc/releases/download/2022.01/bsc_libraries_ref_guide.pdf">程序库参考指南</a>，本文只介绍快速入门的用法（其实是因为作者也是初学）。</blockquote><p>按照课程 PPT 的要求下载和解压了 Lab1 的内容之后，差不多是这个情况：</p><pre><code>❯ ls -la
.rwxrwxrwx  330 rynco  6 Jan  2013 Gates.bsv
.rwxrwxrwx 3.2k rynco  7 Jan  2013 Lab1.bspec
.rwxrwxrwx   44 rynco  7 Jan  2013 Makefile
.rwxrwxrwx 1.2k rynco  2 May  2013 RightShifter.bsv
.rwxrwxrwx  341 rynco  6 Jan  2013 RightShifterTypes.bsv
.rwxrwxrwx 1.5k rynco  7 Jan  2013 TestShifter.bsv</code></pre><p>下面我们编译一下我们的测试程序。Bluespec 的编译分为两步：</p><ol><li>把 Bluespec SystemVerilog <code>.bsv</code> 编译成 Bluesim Object <code>.bo</code> 文件；</li><li>把 <code>.bo</code> 文件编译到测试用的程序文件。</li></ol><p></p><p>两步都要用到 <code>bsc</code> ，但是使用的命令不一样。下面先进行第一步：</p><pre><code>❯ bsc -sim -u TestShifter.bsv
checking package dependencies
compiling ./RightShifterTypes.bsv
compiling ./Gates.bsv
compiling ./RightShifter.bsv
compiling TestShifter.bsv
code generation for mkTests starts
Elaborated module file created: mkTests.ba
All packages are up to date.</code></pre><p>解释一下命令行的参数：</p><ul><li><code>-sim</code> 参数指示编译器把源代码编译到 Bluesim Object 文件；</li><li><code>-u</code> 参数指示编译器递归编译文件的所有依赖；</li><li>最后一个参数是要编译的文件。这里我们想要的是测试程序，所以直接编译测试文件就可以。</li></ul><p>编译完成之后，我们的目录里就多了一大堆 <code>.bo</code> 文件，以及一个 <code>mkTests.ba</code> 。 <code>mkTests.ba</code> 是它为我们自动生成的用来测试的一个 module，下一步我们要从这里开始。</p><p></p><p>第二步就是生成 Bluesim 的测试程序。</p><pre><code>❯ bsc -sim -e mkTests
Bluesim object created: mkTests.{h,o}
Bluesim object created: model_mkTests.{h,o}
Simulation shared library created: a.out.so
Simulation executable created: a.out</code></pre><p>同样解释一下命令行参数：</p><ul><li><code>-sim</code> 的意义跟之前一样；</li><li><code>-e &lt;module&gt;</code> 指示编译器生成用于 <code>&lt;module&gt;</code> 参数的模拟器，这里是我们上一步生成的 <code>mkTests</code> 模块。</li></ul><p>进行完这一步之后，我们就有最终的测试程序 <code>a.out</code> 了。运行它就可以测试我们的硬件能不能正常工作了！</p>
<h1 id="step-2-%E6%B5%8B%E8%AF%95">Step 2. 测试</h1>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre><!--::markdown-it-async::jy9p6qtjoz9cjxrh4ces3r::--><code>❯ ./a.out
correct!
correct!
correct!
correct!
correct!
correct!</code></pre>
</div><p>如果你修改了源代码，你需要重新做一遍前两步才可以得到更新之后的测试程序。当然，你可以写点 makefile 来解决这个问题，比如</p>
<div class="language-make"><button title="Copy Code" class="copy"></button><span class="lang">make</span><pre><!--::markdown-it-async::1nwll11hvd4kqfbf7xoq1j::--><code>%.bo: %.bsv
    bsc -sim -u $*.bsv

mkTests.ba: TestShifter.bo # replace with the current testing file

test: mkTests.ba
bsc -sim -e mkTests
./a.out</code></pre>
</div><p>这样就可以一个 <code>make test</code> 走天下了（笑）</p><h1 id="%E5%90%8E%E8%AE%B0">后记</h1><p>本文作者也只是刚开始使用 Bluespec，所以文章内容可能会有疏漏。后续实验如果涉及到了更新的功能，我会在本文中更新。对文章内容有任何疑问或者补充都可以邮件联系。</p><p>用 VSCode 的同学可以在插件市场里找到 <a href="https://marketplace.visualstudio.com/items?itemName=mshr-h.VerilogHDL">Bluespec 的支持插件</a>。</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AOT Compiling JavaScript, Part 1]]></title>
            <link>https://rynco.me/posts/legacy/aot-compiling-javascript-pt-1.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/aot-compiling-javascript-pt-1.html</guid>
            <pubDate>Fri, 29 Apr 2022 18:23:00 GMT</pubDate>
            <description><![CDATA[We're building an AOT compiler for JavaScript. How did this project start, and how is the compiler designed?]]></description>
            <content:encoded><![CDATA[<p>So yeah. JavaScript. Your favorite language that's designed under 11 days and got patches all over its body, running in browsers and desktops and backends and scripts and everywhere with a <code>node_modules</code> folder as big as a supermassive black hole. Now we're building an AOT compiler for it.</p><blockquote>But what's the point of building an <strong>AOT</strong> compiler?</blockquote><p>Nice question. We don't know.</p><hr/><p>This project actually comes from the lab I'm in, where we were offered a contract from *some big phone company*. They'd like to use precompiled JavaScript in browsers to reduce loading  time, use JavaScript in phones for frontend without V8 and a browser, maybe also running JavaScript inside embedded devices or something like that. So they need us to compile JS into WebAssembly.</p><p>When I first heard of this project, I was like, "what did you just say?" There are literally <strong>tons</strong> of languages that's both better than JS and has AOT compiling ability. Just go to Dart or Java or Kotlin or C# or whatever and forget this JavaScript mess.</p><p>And they said, <em>"We want to reuse the full ecosystem created by NPM."</em></p><p>Reasonable. What's next?</p><p><em>"We also want it to beat V8 in speed."</em></p><p>WHAT?</p><hr/><p>The result of this is a year-long project (maybe even longer) under the codename "JWST," for "JavaScript to WebAssembly Static Translator" and <em>definitely nothing related to a telescope whose launch was postponed for 15 years</em>. We're currently a little more than a half year inside it, so expect stuff to change.</p><h1 id="v8-is-not-for-aot">V8 is not for AOT</h1><p>Speaking of beating V8 in speed, the best thing to beat V8 is V8 itself, right?</p><p>Wrong, because V8 is definitely not for AOT usage. We learned this after fiddling with V8 for about 1.5 months.</p><p>Let's first ignore the fact that a compiled version of V8 takes around 17 MiB of space for x86 code. Even its runtime only takes up half the size, it's 8 MiB, which is wayyyyyyyyy too large to be downloaded for accelerating webpages.
</p><p>Okay. Where do we start, V8 TurboFan compiler IR?</p><figure class="kg-card kg-image-card kg-card-hascaption"><img alt="" class="kg-image" height="900" loading="lazy" src="/posts/legacy/aot-compiling-javascript-pt-1-1.png" width="566"/><figcaption>Does anyone want to compile this? Not me =w=</figcaption></figure><p>Surprise! There's heap constants and JITter-facing checks everywhere, which we're too lazy to tackle with (with only 2 persons). We'd rather not change this whole pile of mess into an AOT compiler that generates stack-oriented code. No luck here.</p><p>What else, interpreter bytecode?</p><p>In this stage we're no longer using V8 to beat V8 of course (the speedup bits are mostly in the details of TurboFan). The bytecode is definitely much more readble, but we didn't spend a lot of time there.</p><p>We found a new prey!</p><h1 id="quickjs-to-the-rescue">QuickJS to the rescue</h1><p>When researching about AOT compiling JavaScript, we stumbled across multiple previous attempts. The most notable one is <a href="https://mp2.dk/techblog/chowjs/">ChowJS</a>.</p><p>ChowJS is a (unfortunately) closed source AOT compiler made for their game engine. They used QuickJS for frontend and built their own backend to do optimization passes and codegen. They do type guessing like Hopc (Serrano, 2018) did, which matches our previous researchs. Overall, their choices looks great and much more feasible than crushing V8 into WASM stuff. Prefect prey.</p><p>After exploring QuickJS for some time, we found it fits absolutely perfect into the project. Its bytecode is clean and built with portability in mind (woo-hoo, no more heap constants). Its types are simple without all the fancy optimization tricks used by V8. Its runtime functions are intuitive and easy to use. And it compiles to just over 800 KiB of WebAssembly (300 KiB gzipped, 250 KiB brotli) - even less if we ditch the codegen part and only leave the runtime (which is totally fine. Who uses <code>eval</code> anyway?). I can talk about this all day.</p><p>So yeah. QuickJS rocks. How do we AOT from that?</p><p>We designed JWST roughly based on stuff we learned from ChowJS and Hopc. It uses QuickJS as the frontend, has a custom-built variable type guesser, and compiles into LLVM IR (!) from QJS bytecode and type information. Further optimization passes (if any) are preformed on LLVM IR.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img alt="" class="kg-image" height="1700" loading="lazy" src="/posts/legacy/aot-compiling-javascript-pt-1-2.png" width="1288"/><figcaption>How JWST is designed to work</figcaption></figure><p>The whole thing seems pretty trivial to implement – every compiler does more or less the same thing. We just build a mimic stack and translate every QuickJS bytecode into their LLVM IR counterpart and call it a day, right?</p><p>Sort of? Every issue I met so far is something I haven't thought of, instead of something that is <em>really</em> challenging and requires researching. But I'm just working on the codegen part, not the typing part, which is harder and poses some interesting questions to solve.</p><hr/><p>I think that's enough for Part 1. Trying to add more stuff to it would probably make this blog inside the draft box forever like my other unfinished projects. In Part 2, I'd like to talk about the details inside this project, the interesting problems and bugs I tripped over on during this half-year journey, and stuff like that.</p><p>Stay tuned!</p><h1 id="references">References</h1><p>Serrano, M. (2018). JavaScript AOT compilation. <em>ACM SIGPLAN Notices</em>, <em>53</em>(8), 50-63.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[存档] 一百年后的世界会是什么样子 (1922)]]></title>
            <link>https://rynco.me/posts/legacy/1922-what-will-the-world-be-like-in-a-hundred-years.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/1922-what-will-the-world-be-like-in-a-hundred-years.html</guid>
            <pubDate>Tue, 08 Feb 2022 06:58:56 GMT</pubDate>
            <description><![CDATA[本文是对 W. L. George 于 1922 年发布的一篇文章的机器翻译，在此处仅供存档使用。]]></description>
            <content:encoded><![CDATA[<blockquote><a href="https://www.loc.gov/resource/sn83045774/1922-05-07/ed-1/?sp=87&amp;r=-0.201,-0.035,1.45,1.071,0">https://www.loc.gov/resource/sn83045774/1922-05-07/ed-1/?sp=87&amp;r=-0.201,-0.035,1.45,1.071,0</a></blockquote><blockquote>粗校过的英文版本 <a href="https://telegra.ph/What-will-the-world-be-like-in-a-hundred-years-02-08">https://telegra.ph/What-will-the-world-be-like-in-a-hundred-years-02-08</a></blockquote><blockquote>本文最初由 W. L. George 于 1922 年 5 月 7 日发表；本文由 Rynco 粗校并经过 DeepL 机器翻译。其余上下文参见 <a href="https://t.me/rynif/25569">https://t.me/rynif/25569</a>。</blockquote><p>有一条古老的规则，它要求我们在不知道的情况下永远不要预言，但是，同样的，当一个人不能预言的时候，他可以猜测，特别是如果他确信在预言到来时已不在人世时。因此，我不无忧虑地提出了一幅百年后的世界图景，并大胆猜测当时的世界对我们的一个鬼魂来说将是引人注目的，这不是因为它是如此不同，而是因为它是如此相似。</p><p>总的来说，我们所期待的变化必须由科学来实现。要实现像X射线这样的革命性的科学发现，比丝毫改变男人和女仆之间产生的情感质量要容易得多。2022年可能会有许多新的射线，但它们所照亮的人将大致相同。</p><p>由此，读者可能会得出结论，我并不期望在科学发现方面有什么惊人之举。事实并非如此；我相信在2022年，科学的进步将是惊人的，但它将不会像今天与一百年前相比那么惊人。我猜想，看到今天的世界会让杰斐逊总统感到惊讶的程度，将会比2022年的世界会让中央车站卖糖果的小女孩感到惊讶的程度大得多。因为杰斐逊对铁路、电报、电话、汽车、飞机、留声机、电影、镭等等一无所知；他甚至不知道冷热浴室。中央车站的小女孩是一个淡然的孩子；对她来说，这些东西都是司空见惯的；2022年必须产生一些非常惊人的东西才能引起她的幽灵的兴趣。关于发现的可悲之处在于，它正朝着自己的灭亡方向努力，而且我们发现的越多，剩下的越少。</p><p>这并不意味着，在科学上，2022年不应该是惊人的。我猜想，商业飞行将完全成为普遍现象。客运汽船将在沿海地区生存，但它将在主要航线上消失，并将被飞行船队所取代，它们应该在大约12小时内完成伦敦和纽约之间的距离。由于我希望读者不要把我看作是一个空想家，我想指出，在最近发生的一次飞机碰撞事件中，一架英国客机以每小时180英里的速度飞行，这个速度将使它在18个小时内横跨大西洋。因此，可以想象，美国与欧洲的距离可能只有八个小时。这个问题主要是人工加热和通风的问题，以使飞行员能够生存。</p><p>同样的原因将影响到铁路，届时，除了郊区交通外，铁路可能已经停止载客。铁路可能会继续处理货运，但甚至可能会被公路交通夺走，因为汽车不必承担轨道的巨大开销。当然，食品、邮件和所有轻型货物都将由公路卡车从铁路上接管。至于马，它可能将不再在白人国家饲养。</p><p>2022年的人们可能永远不会看到天空中的电线：几乎可以肯定的是，在本世纪结束之前，无线电报和无线电话就已经粉碎了电缆系统。也有可能，当找到防止巨大的电压突然在错误的地方放电的方法时，电力可能会通过空气传播。</p><p>煤炭不会被耗尽，但我们的储备将被严重耗尽，石油的储备也会被耗尽。一个世纪后的世界危险之一将是燃料的短缺，但到那时很可能会从潮汐、太阳、可能从镭和其他形式的辐射能中获得大量的能量，同时也可能会利用原子能。如果物质是由被称为电子的力量保持在一起是真的，那么我们就有可能知道如何利用电子。我们有可能知道如何处理物质，以释放电子作为一种力量。这种力量将与物质一样持久，因此与地球本身一样持久。</p><p>电影将更有吸引力，因为早在2022年之前，它们就会被现在只存在于实验室的Kinephone所取代。也就是说，屏幕上的人物不仅会移动，而且会有他们的自然色彩，并以普通的声音说话。因此，我们今天所知道的舞台可能会完全消失，这并不意味着艺术的灭亡，因为2022年的电影演员不仅不需要知道如何微笑，也不需要知道如何说话。</p><p>我们可以无限地延伸应该存在和将要存在的发明的数量，但读者可以自己想一想，更有趣的是问问我们自己，100年后我们的城市会是什么样子。在我看来，它们将提供一个混合的前景，因为人类从来没有完全拆毁任何东西来建立其他东西；它在建立新的同时保留了旧的；因此，现在的许多建筑将被保留下来。可以想象，华盛顿的国会大厦、许多大学和教堂在一百年后仍将屹立不倒，而且它们将几乎不加改动地被传统所保留。</p><p>此外，许多私人住宅也将幸存下来，并将由个人家庭居住。我认为，他们将经历合作阶段，预计在五六十年后，当仆人问题变得完全无法处理时，私人住宅将自行组织起来，雇用员工为团体做饭、打扫和修补。这个合作阶段将是那些想在自己家里保留某种奴隶的私人女主人的最后一击。在2022年，她将被环境所屈服，但她将恢复她的私人住所，由一个勤务员每天服务七个小时。成为勤务员的妇女将获得与速记员一样的报酬，穿自己的衣服，被称为 "小姐"，属于她的工会并在工会规则下工作。</p><p>自然，日渐减少的家务劳动，在2022年将会大大减轻。我相信，今天家里所需的大部分清洁工作都将被取消。首先，由于煤炭在所有没有电的地方消失，将不再有烟，也许连烟草的烟也没有了。其次，我看到墙壁、家具和挂件或多或少是由压缩的纸浆制成的，用黄铜或胶带沿边缘捆扎。因此，2022年将不再擦洗它的地板，而是拧开铜边或解开胶带，剥去地板或窗帘的肮脏表面。然后每年都会铺设新的地板板。人们可以希望，标准的椅子、桌子、地毯，也将以同样的方式被剥掉。</p><p>类似的改革也适用于烹饪，大量的烹饪将在老式的人中生存，但更多的烹饪可能会因为使用合成食品而被避免。可以想象，尽管不确定，在2022年，一餐完整的食物可能会以四颗药丸的形式服用。这并不完全是远见卓识；我相信玉米牛肉杂碎和南瓜派仍将存在，但药片午餐——也会出现在它们的身旁。</p><p>但是在那个时候，将很少有私人住宅被建造：取而代之的是社区住宅，人类的大多数人将在那里生活。它们可能会位于花园空间，并上升到40或50层，轻松容纳四千或五千户家庭。这并不夸张，因为今天在纽约的一家旅馆里，每天晚上有三千人睡觉。这也意味着每个街区都会有一个自己的地方当局。我想象这些住宅将为每个家庭的成年人提供一个房间，还有一个房间供大家使用。当时的烹饪工作将由街区的地方当局负责，它还将负责洗衣、补衣、清洁，并为租户的孩子们提供一个完整的托儿所。</p><p>也许到那时，我们将实现一个我经常怀有的梦想，即用玻璃做屋顶的城市。那个城市将是一个完整的单元，有房屋、办公室、工厂和空地的住宿，所有这些都是精心分配的。根基将完全消除天气，并将保持一个均匀的温度，由当时的口味来决定。人工通风可以抑制风。至于空地，如果温度是温暖的，它们就会不断地展示出花朵，这将使它们摆脱冬天和夏天；换句话说，无论哈钦森先生的后人等待多久，冬天都不会到来。</p><p>这个家族仍然会存在，尽管它今天做得不是很好。难以想象，父母和子女之间的某种感情不应该持续下去，尽管我当然无法判断这种感情会是什么。我想，这种联系会比今天更细，因为孩子很可能被国家接管，不仅要上学，还要吃饱穿暖，在训练结束后，还要被安排到适合其能力的岗位。</p><p>这可能会受到生育控制的影响，在2022年，生育控制将在全世界合法化。这将分为几个阶段：控制生育的第一个结果是降低出生率；然后国家会介入，就像在法国那样，让人们值得拥有更多的孩子；然后国家会发现，它让事情变得太容易了，人们正在不顾一切地生孩子；最后，在国家对孩子的需求和国家供应之间会建立某种平衡。</p><p>在很大程度上，家庭的状况将由妇女的地位来决定，因为妇女就是家庭，而男人只是家庭的支持者。几乎可以肯定的是，在2022年，几乎所有的妇女都将抛弃她们主要是 "男人的制造者" 这一想法。届时，大多数合适的女性将从事个人职业。2022年可能会看到大量妇女在国会任职，许多人在司法机构任职，许多人在公务员岗位任职，也许有些人在总统的内阁任职。</p><p>但是，妇女不太可能实现与男性的平等。像我这样谨慎的女权主义者认识到，事情进展缓慢，短暂的一百年不会消除三万年的奴隶制对妇女的影响。妇女将工作，部分是因为她们想工作，部分是因为她们能够工作。因此，妇女将支付她们在维护家庭和家族方面的份额。上述关于社区建筑的建议，即所有的家务劳动将由专业人员完成，将解放普通的妻子，使她能够从她的工资中支付她不喜欢的家务劳动的份额。</p><p>婚姻仍将像今天一样存在，因为人类对这种制度有着顽固的兴趣，但离婚可能会像在内华达州一样容易。然而，鉴于妇女地位的提高和她的挣钱能力，她不仅将不再有权获得赡养费，而且在离婚后，她将被期望支付她的孩子的那部分抚养费。</p><p>至于2022年的政治，我希望国家的形式会基本相同。在自决的基础上可能会有一些重新安排；例如，奥地利可能已经与德国联合，南美各共和国可能已经组成联邦，等等，但我不认为会有一个超级国家。可能在2022年，西班牙、意大利、荷兰和挪威的国王可能已经倒台，但由于各种原因，无论是缺乏进步还是实际方便，我们可能期望在瑞典、南斯拉夫、希腊、罗马尼亚和英国仍能找到国王。</p><p>在内部，这些国家可能略有变化，因为普遍存在着一种与社会主义无关的社会化趋势。大多数欧洲国家的政府正在无意识地将一些产业国有化，而且这种情况将继续下去。因此，我们可以推测，在2022年，大多数国家将把铁路、电报、电话、运河、码头、供水、天然气（如果有的话）和电力国有化。其他行业将像今天一样存在，但国家可能会倾向于控制它们，限制它们的利润，并在它们和工人之间进行仲裁。我们在美国的反托拉斯法案中发现了这种暗示；一百年后，这种趋势将更加强烈。值得注意的是，作为一个国际因素，到那时纯粹的国家工业将几乎消失，世界的工作将掌握在受控制的联合体手中，管理从中国到秘鲁的商品供应。</p><p>不幸的是，这些通过贸易建立的国际关系不可能影响到政治条件。仍然会有战争。那一时期的战争可能会比今天少一点，并受到诸如太平洋协议、加拿大和美国之间关于不设防边界的协议等安排的限制，但它仍然会存在。我怀疑未来的那些战争将因新的毒气、不灭的火焰和防光的烟云而变得超乎我的想象的可怕。在那些战争中，飞机炸弹将像今天的斧头一样显得过时了。战争最终可能会消失，但这超出了这篇文章的范围，甚至超出了我的思想范围。</p><p>特别是在美国，这个国家很可能已经达成了完全稳定，人口达到约 240,000,000 人。南方和北方、东方和西方的概念将几乎消失；到那时，美国的种族将形成一个明确的形式，移民将不会影响它。来自基韦斯特的美国人和来自西雅图的美国人将是同一类人。</p><p>上面讨论的是种族问题，而我觉得2022年的美国人在精神上将发生巨大的变化。今天，他是世界上最有进取心的生物，并被一种持续的上升和赚钱的冲动所驱使。这是因为现代美国人生活在一个仅有部分发展的国家，那里的巨大财富仍在等着他去获取。在2022年，这将像今天的英国一样完成。到那时，美国的财富要么被开发，要么为人所知，而所有的财富都将属于某个人。在美国不会有比今天在英国更多的机会。那些美国人将知道，实际上可以肯定的是，他们将在与他们出生时相同的位置上死去。因此，这些美国人的进取心会减少，而更喜欢享受。他们将反抗长时间的工作：在2022年，很少有人会每天工作超过7小时，甚至更多。</p><p>我相信这对我的许多读者来说听起来是令人遗憾的，但在我看来，其效果将是好的。如果美国人要发展其广阔的国家，就必须有强烈的劳动能力和强烈的野心，但一个结果是匆忙、过度劳累、噪音，所有这些都对神经不利。2022年，美国将取得她的财富，并将尽其所能地享受它。</p><p>我认为，她将是一个比今天更幸福的国家。财富的吸引力将减少，因为财富将难以获得，所以那些即将到来的美国人在艺术和文学方面的创作将比他们今天的创作多得多。今天，在小说方面，美国以真诚、信仰和无畏领导着世界，但美国的重要小说是一部反抗金钱、惯例和清规戒律的小说。2022年，美国文学将成为一种文化的文学，战斗将结束，枪口也将关闭。毫无疑问，2022年将会有一些人像1922年甚至更早的时候那样思考问题，但一种伟大的思想自由主义将占上风。</p><p>祝贺未来不是我的事，我也不想这样做，因为不可能说一件事是好是坏；人们只能说它存在。但是，如果我的一些读者在考虑我的午餐药丸或我的国有化铁路时感到厌恶，我想对他们说，他们也许是过分焦虑了。世界会自己照顾自己；它已经这样做了几百个世纪，而且还在旋转；世界将在2022年照顾自己：这是它的主要职业。不仅如此，我相信，尽管世界可能会失去一些恩惠，但它会发展出其他的恩惠，总的来说，随着时间的推移，人类会变得更加聪明，更加和蔼可亲，更加诚实。</p><p>未来会有困难；这有什么关系呢？过去也很困难；困难并不妨碍它变成一个可以容忍的现在。</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[嗨，2022]]></title>
            <link>https://rynco.me/posts/legacy/hi-2022.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/hi-2022.html</guid>
            <pubDate>Thu, 23 Dec 2021 21:11:30 GMT</pubDate>
            <description><![CDATA[在没有月光的夜里，雾气将远方的灯火化作一片朦胧。]]></description>
            <content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img alt="" class="kg-image" height="3000" loading="lazy" src="/posts/legacy/hi-2022-1.png" width="2000"/></figure><p>在没有月光的夜里，雾气将远方的灯火化作一片朦胧。</p><p>2022 来了。这个世界会好吗？</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[一个词法分析器的 Bug]]></title>
            <link>https://rynco.me/posts/legacy/logos-lexer-dfa-bug.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/logos-lexer-dfa-bug.html</guid>
            <pubDate>Fri, 24 Sep 2021 07:31:36 GMT</pubDate>
            <description><![CDATA[明明只是一个空白符 token 凭什么匹配 begin（]]></description>
            <content:encoded><![CDATA[<p>写程序设计语言原理课的大作业（嗯……早做准备早放心）的时候遇到了一个奇怪的问题：本来应该只匹配不换行空白符的 <code>WS</code> token 竟然匹配了四个空格<strong>加一个 begin</strong>！这非常不对劲。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img alt="" class="kg-image" height="1128" loading="lazy" src="/posts/legacy/logos-lexer-dfa-bug-1.png" width="726"/><figcaption>肇事代码，注意 diff 里面右边的 BeginKw 在左边不存在</figcaption></figure><p>咱在这里用的 lexer 用的是 <a href="https://github.com/maciejhirsz/logos">Logos</a> 自动生成的（声明一下，Logos 还是非常好用的），于是咱去 issues 区找了一下，发现其他人也遇到了这个问题，比如</p><ul><li><a href="https://github.com/maciejhirsz/logos/issues/181">#181</a> Bad matches for grammars that require backtracking（这个是主 issue）</li><li><a href="https://github.com/maciejhirsz/logos/issues/200">#200</a> Regex and token prefix causes error match</li><li><a href="https://github.com/maciejhirsz/logos/issues/160">#160</a> Strange behaviour when matching 'else' / 'else if'</li></ul><p>等等。</p><h1 id="%E9%97%AE%E9%A2%98">问题</h1><p>这些问题都有一个共性：在自动机的两个接受状态中间夹了一个不接受状态。我们可以用一个简单的例子说明这个问题：</p><p>假设我们现在有一个超级简单的 lexer，只接受两个 Token:</p><ul><li>TB -&gt; <code>ac</code></li><li>TD -&gt; <code>accc</code></li></ul><p>其他所有输入都是错误。比如理想状态下 <code>acacacccac</code> 会被解析成 <code>[TB, TB, TD, TB]</code>， <code>acaccacaccc</code> 会被解析成 <code>[TB, TB, Error, TB, TD]</code>。</p><p>我们希望用一个 DFA 来解决这个问题，于是我们写了个非常简单的自动机：</p>
<div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre><!--::markdown-it-async::3oot99whjaei7xfzw20sb::--><code>Start: S
Accepts: B (TB), D (TD)

-&amp;gt; S

S -[a]-&amp;gt; A

A -[c]-&amp;gt; B

B -[c]-&amp;gt; C

C -[c]-&amp;gt; D</code></pre>
</div><p>然后当我们在接受状态且继续输入不能引起有效状态变化的时候，我们输出相应的 token 并退回到 S 状态，再接受刚刚的输入。</p><p>对于正确的输入没有什么问题，比如它可以完全正确地解析 <code>acacacccac</code>。</p><p>然后当我们输入 <code>accd</code> 的时候，它进行了 <code>S -&gt; A -&gt; B -&gt; C</code> 的状态转换之后卡住了。</p><p>理想情况下，他应该回退一个状态，从 B 输出 Token TB <code>acc</code> ，然后输出一个 Error token <code>d</code> 。</p><p>但是这个作者没有实现 backtrack，于是它在 \万策尽きた/ 之后随便挑了一个 token 丢了出去。</p><p>当然在咱这个情况下，TB 对应的是空白符 Token <code>WS</code> -&gt; <code>[ \t]+</code>, 然后 <code>TD</code> 对应的是（因为没有 contextual lexing 所以在任何时刻都会输出的）字符串插值中段 Token <code>InterpolatedStringMiddle</code> -&gt; <code>[^\r\n'"]\*$</code> 。不过 anyway，跟之前的简化模型一样，这两个接受一个共同的开头，然后其中一个匹配不了的时候另一个必须回溯才能匹配上。</p><p>¯\_(ツ)\_/¯</p><h1 id="%E8%A7%A3%E5%86%B3">解决</h1><h2 id="workaround">Workaround</h2><p>那我只能先把字符串插值去掉以后再说啦。</p><h2 id="%E7%9C%9F%E6%AD%A3%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95">真正的解决方法</h2><p>大概是加入一个输出并转移到下一个可以匹配的最长输入的转换函数。</p><p>不过还没有实际写代码。</p><p><em>TODO: 能不能解决这个问题啊</em></p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Overflow]]></title>
            <link>https://rynco.me/posts/legacy/drawing-overflow.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/drawing-overflow.html</guid>
            <pubDate>Mon, 12 Jul 2021 06:41:24 GMT</pubDate>
            <description><![CDATA[新画]]></description>
            <content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-width-wide"><img alt="" class="kg-image" height="2000" loading="lazy" src="/posts/legacy/drawing-overflow-1.jpg" width="2000"/></figure><figure class="kg-card kg-embed-card"><iframe frameborder="0" height="315" src="https://embed.pixiv.net/oembed_iframe.php?type=illust&amp;id=91184881" width="600"></iframe></figure>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[看，新主题！]]></title>
            <link>https://rynco.me/posts/legacy/wow-new-theme.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/wow-new-theme.html</guid>
            <pubDate>Sat, 03 Jul 2021 18:35:11 GMT</pubDate>
            <description><![CDATA[名字是 KSP 里面来的。]]></description>
            <content:encoded><![CDATA[<p><s>拜拜，<a href="https://github.com/zutrinken/attila">Attila</a></s></p><p>总之把自己做的主题换上来了。东西还不是很全，不过好歹能看了。</p><hr/><p>这个主题的名字叫 Dres，似乎是做的时候想到主题是深灰色的就起了这么个名字。（记得 Dres 反照率还挺高的来着？这么黑的应该叫 Mun 或者 Ike）</p><p>总之先在 GitHub 上开源了。欢迎来锤。</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/lynzrand/ghost-theme-dres"><div class="kg-bookmark-content"><div class="kg-bookmark-title">lynzrand/ghost-theme-dres</div><div class="kg-bookmark-description">Contribute to lynzrand/ghost-theme-dres development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img alt="" class="kg-bookmark-icon" src="https://github.githubassets.com/favicons/favicon.svg"/><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">lynzrand</span></div></div><div class="kg-bookmark-thumbnail"><img alt="" src="https://opengraph.githubassets.com/14435f584e4a170a84e8fc51fb9c704beca72e03ac93151a82d5820cecb2efb1/lynzrand/ghost-theme-dres"/></div></a></figure><hr/><h1 id="%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF%E5%95%A5%E7%9A%84">设计思路啥的</h1><figure class="kg-card kg-embed-card"><iframe height="450" src="https://www.figma.com/embed?embed_host=oembed&amp;url=https://www.figma.com/file/ngfLKec9rVcWE19AGX6ERY/rynco.me?node-id=0:1" style="border: none;" width="800"></iframe></figure><p>这个是主题的设计稿。咱最初的想法是搞一个比较有特点的主题，于是选择了在页面上切几个斜角。不过后来被几个朋友预览之后感觉斜角还是太前卫了，于是就砍掉了。</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hello World, the third time.]]></title>
            <link>https://rynco.me/posts/legacy/hello-world.html</link>
            <guid isPermaLink="false">https://rynco.me/posts/legacy/hello-world.html</guid>
            <pubDate>Fri, 18 Jun 2021 00:45:12 GMT</pubDate>
            <description><![CDATA[这是这个博客的第一条消息。]]></description>
            <content:encoded><![CDATA[<p>嗨。我终于想起来部署博客了。</p><p>我也不知道这里能写什么东西，可能写代码写累了会来这里散散心吧。</p><p>找个时间<a href="https://www.figma.com/file/ngfLKec9rVcWE19AGX6ERY/rynco.me?node-id=0%3A1">把主题从 Attila 换走</a>，我要用 Inter 做主字体！</p><p>就这样。下了。</p><hr/><p>p.s. Uptime Robot 你来的正是时候</p><figure class="kg-card kg-image-card kg-card-hascaption"><img alt="Monitor is UP: rynco.me ( https://rynco.me ). It was down for 20270 hours and 40 minutes." class="kg-image" height="143" loading="lazy" src="/posts/legacy/hello-world-1.png" width="423"/><figcaption>要是没有这条消息我都忘了我还注册 Uptime Robot 了</figcaption></figure>
]]></content:encoded>
        </item>
    </channel>
</rss>