Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ANNOUNCEMENT] (Experimental) Macros #440

Open
LingDong- opened this issue Dec 30, 2019 · 7 comments
Open

[ANNOUNCEMENT] (Experimental) Macros #440

LingDong- opened this issue Dec 30, 2019 · 7 comments
Labels
announcement Announcement from maintainers

Comments

@LingDong-
Copy link
Member

LingDong- commented Dec 30, 2019

As you might (not) have noticed, wenyan-lang strives to be more readable (for ancient Chinese people). Macros provide syntactic sugars to bring the 文采 of your code to the next level.

E.g. Now you can patch wenyan-lang's notorius print function like so:

或云「「書「甲」焉」」。
蓋謂「「吾有一言。曰「甲」。書之」」。

書「「問天地好在」」焉。

Since we're beating JavaScript to macros, here is a rough C equivalence:

#define   書(甲)焉   吾有一言。曰甲。書之
書("問天地好在")焉。

See ./examples/macro.wy for detailed usage!

How it works

In the 或云 statement, you specify the alternative syntax, using 「甲」,「乙」,「丙」etc. (十天干) to denote arguments, and in the 蓋謂 statement you specify what that statment should be replaced by, referencing the arguments using the same 天干. (more than 10 arugments is considered too hideous and therefore not possible).

It's just like regex.

Macros potentially solve other problems such as using 爲 instead of 為 etc. Currently, stdlib 列經 uses a couple of macros to make Higher-order functions such as map filter and reduce look prettier.

So instead of

施「遍施」於「加一」於「某列」。書之。

you can also do

凡「某列」皆「加一」其上者。書之。

where the syntax is defined by this macro in 列經:

或云「「凡「甲」皆「乙」其上者」」。
蓋謂「「施「遍施」於「乙」於「甲」」」

Cautions

Your macros cannot start or end with identifier/arguments (e.g. 或云「「書「甲」」」 or 或云「「「甲」焉」」 are BAD. It has to be 或云「「書「甲」焉」」). Otherwise the preprocesser cannot find out where it starts/ends and might not work as expected.

Implementation details

The preprocessing is done before tokenization, and it searches all imported modules and gather all the macros and do the finding and replacing. (It might not be the most efficient way to do it, so if you have a better idea please let me know!). See src/macro.js for details.

Your opinion

As you can see the macros are very powerful (maybe too powerful). And the downside is that it opens the door to a new dimension of hacks (probably wilder than I can imagine :)

Please let me know what you think! Thanks!

@LingDong- LingDong- added the announcement Announcement from maintainers label Dec 30, 2019
@antfu antfu mentioned this issue Dec 31, 2019
@antfu
Copy link
Member

antfu commented Dec 31, 2019

This looks so cool! Trying to find out what hacks we can do from this 😄

I also dumped this issue to the document.

Thanks for the great work!

@cuixiping
Copy link
Contributor

cuixiping commented Dec 31, 2019

Cool!

或云「「有術「甲」。已知「乙」。遂
    「丙」。
此術人称「甲」也。」」。

蓋謂「「吾有一術。名之曰「甲」。欲行是術。必先得「乙」。是術曰。「丙」。是謂「甲」之術也。」」


有術「平方」。已知一數曰「甲」。遂
    乘「甲」以「甲」。乃得矣。
此術人称「平方」也。

@lymslive
Copy link

Good if you can implement as much as the #define macro of C language.
来测试召唤术!

@kaiyuan01
Copy link
Contributor

The same macro above but with 元杂剧 flavor:

或云「「(冲末扮「甲」同外扮「乙」上)(「甲」诗云)坐守寒窗二十春,虀盐乐道不知贫。腹中晓尽古今事,命里不如天下人。小生「甲」便是。这一个是我同堂学业八拜交的弟兄,是「乙」。今有術「甲」。已知「乙」。遂
「丙」
此術人称「甲」也。」」。

蓋謂「「吾有一術。名之曰「甲」。欲行是術。必先得「乙」。是術曰。「丙」。是謂「甲」之術也。」」

@lymslive
Copy link

lymslive commented Jan 1, 2020

宏机制果然可以玩出很多花样。
不过我想到更重要的一点,这有望将 wenyan-lang 往实用化方向推进一步。
现在的语法常被外人诟病太啰嗦,略失文言精简之美。这无可否认,我也从欣赏的诵读角度称之为“骈赋体”。
但有了宏,就可以写出更精炼的语句。而且在后续(较大)版本进化中,应该将最简洁的语法植入语言核心,尽可能使用单字关键字,这是对编译器友好的,有可能大幅提升性能。而把当前的啰嗦版骈赋体做成宏归入 stdlib ,保持向前兼容,让后续用户按需选择使用。

仍以最基本的变量定义为例。它应包含类型、名字与值三段信息,所以理论上只要三个关键字就可以。

有数,名甲,曰三。
有数名甲曰三。
// var i = new int(3)
// int i = 3

关键字“有”用于创建变量,相当于 new ,“名曰”相当于初始化等号 = 两侧部分(变量重新赋值其实是略有不同的语义)。当然“吾”作为词法范围(变量作用域)限定词算是另一个独立关键字,不一定只与“有”联用,在简单脚本中可省略,在复杂程序中作用域管理才至关重要。

这种极简语法我们或可称之为“诗经体”或“易经体”。以此为根本,加以宏机制,应该也易定制出像如今的“骈赋体”变体,不过多加一句导入模块语句,例如:

观《骈赋体》矣。
吾有一数,名之曰甲,其值曰三。

所以 wenyan-lang 的下一步(也许是长远)重要目标,就是制定最小集,原则上以单词关键字与繁体字为宜。

路漫漫其修远兮。

Happy New Year @LingDong-

@lymslive
Copy link

@LingDong-
有计划加个引号转义功能吗,在宏定义的”或云“与”蓋謂“子句,想表达引号本身怎么办呢?

@LingDong-
Copy link
Member Author

@lymslive
It is already possible, the key is that 「」 needs to be matched at all times, so you can do the following:

或云「「“「甲」”」」
蓋謂「「「「甲」」」」

吾有一物。名之曰“馬”。

Compiles to:

var ={};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
announcement Announcement from maintainers
Projects
None yet
Development

No branches or pull requests

5 participants