Skip to main content

变色龙代码

最近的新玩具: https://github.com/coolwanglu/quine-chameleon

受mame的100个语言的quine-relay的启发,我想可否做一个完全图,即多个语言互相转换。
这样的程序英文叫multiquines,Wikipedia上有介绍,程序运行时需要指定一个参数,比如输出语言,然后程序会输出自身代码的对应那种语言的版本。如果指定参数就是这个程序源代码所使用的语言,那就是quine了。

网上有一个5种语言的multiquines,我看了看,不是太优美。我一开始就是朝着multiquines的方向写。然而后来注意到,不指定任何参数的时候对multiquines来说是没定义的(或者什么都不应该输出),这个有点浪费,于是我做了ouroboros(就像quine-relay那样)和随机转换两种模式。

再后来我注意到反而是不指定参数这部分更有趣,而且为了同时支持带参数和不带参数,需要各种判断,造成代码臃肿。于是我就把这两部分拆开,目前在源码中分别叫chameleon.*和multiquines.*。分别进行优化。

写这个东西最大的乐趣当然是不断加入新的语言。我开始不久就把自己熟悉的语言放进去了,然后慢慢添加新语言,不会的就现学现卖。基本上需要的语言特性和函数有如下几个

- 支持双引号定义的字符串,支持反斜杠转义
- 将字符串按分隔符切成数组
- 生成随机数
- 支持命令行参数
- 数组查找
- 字符串转义,或者json输出,或者字符串/正则式替换
- 输出(不带换行)

按目前的设计,第一条决定了一个语言是否能很容易的加入。这里比quine-relay难的地方在于,任何两个语言都要互相输出,所以最好能有一个公共的转义和还原的标准。而quine-relay中每个语言只需要考虑下一个语言的转义就好了,更方便预处理,支持新语言(比如whitespace,brainfuck)以及其他特性(比如字符串压缩)

我在写这个玩具的过程中也很自然的学习了一些新语言。之前为了写dunnet.js而研究了emacs lisp,这里还加入了其他lisp系列比如clojure,racket,发现写写脚本也还挺顺手的。只可惜scheme由于标准库太小以及srfi实现不统一没能加入。另外就是接触了之前完全不想接触的perl和awk,发现不但没有想像中的可怕,反而挺好用的。

ruby出乎我的意料,一直是各个语言中最短的,尤其multiquines的原始代码(不包含数据)只有80个字节!然而一般python就够我用了,也没有太大动力学新的。coffeescirpt和javascript经过不断优化也冲到了前面,不错!

其他值得一提的是,即使是之前比较陌生的go,lua,vala,我都能很快上手,一方面说明了文档齐全,互联网时代获取知识非常容易,另一方面我也觉得现代编程语言比较类似,语言本身已经成为了工具,脑子里有一些大概念就可以畅行无阻了。当然具体细节还是要慢慢学习和熟悉。

至于C家族,你们就乖乖在最后好好歇着吧。。。

Comments

Popular posts from this blog

A Rocky Migration: Moving from docker-compose to Podman and gVisor

I've been running a few containers for several years. They were all running under rootless Docker with a single user. Initially, I planned to  migrate the containers to VMs , but I couldn't get a stable workflow after about two months of effort. Later,  gVisor caught my attention , and I decided to migrate to Podman with gVisor instead. The new plan is to run each container with  --userns=auto  and use Quadlet for systemd integration. This approach provides better isolation and makes writing firewall rules easier. I'm now close to migrating all my containers. Here are a couple of rough edges I'd like to share. Network Layout I compared  various networking options  and spent a few hours trying the one-interface-per-group approach before giving up. I settled on a single macvlan network and decided to use static IP addresses for my containers. To prevent a randomly assigned IP address from conflicting with a predefined one, I allocated a large IP range for my ...

Exploring Immutable Distros and Declarative Management

My current server setup, based on Debian Stable and Docker, has served me reliably for years. It's stable, familiar, and gets the job done. However, an intriguing article I revisited recently about Fedora CoreOS, rpm-ostree, and OSTree native containers sparked my curiosity and sent me down a rabbit hole exploring alternative approaches to system management. Could there be a better way? Core Goals & Requirements Before diving into new technologies, I wanted to define what "better" means for my use case: The base operating system must update automatically and reliably. Hosted services (applications) should be updatable either automatically or manually, depending on the service. Configuration and data files need to be easy to modify, and crucially, automatically tracked and backed up. Current Setup: Debian Stable + Docker My current infrastructure consists of several servers, all running Debian Stable. System Updates are andled automatically via unattended-upgrades. Se...

mkosi: First Impressions

I stumbled upon the Gentoo wiki page for systemd-nspawn , which in turn led me to nspawn.org , mkosi , and later systemd-sysupdate . mkosi quickly caught my eye because it's almost exactly what I wanted to build myself, as mentioned in a previous post . So, I decided to spend my "sysadmin fun quota" on it. Overview mkosi is similar to docker build or podman build , but it's designed for creating full OS images. It focuses on development and testing. For example, much like nix-shell , mkosi can quickly launch a sandboxed shell with a specific distribution and selected packages installed. The systemd project itself uses mkosi for testing across different distros. The re-introduction article  is a great read. Speed Note that this is by no means a rigid benchmark. My setup is an SSD with LUKS and an ext4 filesystem (without reflink support). Building Container Images mkosi is pretty fast. A simple mkosi command creates a fresh Debian image. I used the --incrementa...