Mai*_*tor 2 hash dsl lambda language-design function
我想用一个非常短的语法编写一个DSL,我注意到两个对编程,函数和散列非常重要的东西.这是我的设计:
创建哈希:
(a:1 b:2 c:3)
Same as JavaScript's: {a:1,b:2,c:3}
Run Code Online (Sandbox Code Playgroud)
创建有序哈希,省略键:
(x y 5)
Same as JavaScript's: {0:'x', 1:'y', 2:5}
Run Code Online (Sandbox Code Playgroud)
创建一个匿名函数:
(a?)
Same as JavaScript's: (function(x){ return x.a; })
Example application:
((test a? b?) (a:1 b:2 c:3))
>> Outputs (test 1 2)
Run Code Online (Sandbox Code Playgroud)
嵌套函数:
(a? a?')
Same as JavaScript's: (function(obj1){ return function(obj2) { return [obj1.a,obj2.a]; }; })
Example double-application:
(((a? a?') (a:1)) (a:2))
Is reduced to: ((1 a?) (a:2))
Then outputs: (1 2)
Run Code Online (Sandbox Code Playgroud)
什么语言适合这种DSL的实现?
这听起来很像你喜欢一种具有强大宏系统的语言,比如某种Scheme.宏允许这种语法扩展,其中来自原始语言的代码片段可以嵌入到您建议的新表单中(我假设您希望能够说(a:1+1 b:2*2),等等).此外,宏系统不会像构建外部预处理器那样使构建过程复杂化或破坏错误消息位置.
但是有一个坏消息,就是没有任何(非深奥的)语言我知道它们的语法有足够的空间来提供你指定的确切语法.
这是我提出的语法:
哈希:
(: a 1 b 2 c 3)
; or, more clearly
(: (a 1) (b 2) (c 3))
Run Code Online (Sandbox Code Playgroud)
索引键控哈希:
(:lst 'x 'y 5)
Run Code Online (Sandbox Code Playgroud)
(如果你在哈希的RHS上允许使用裸字,那么你将很难引用变量,所以我假设你不想这样做)
匿名属性访问功能:
(anon. a)
Run Code Online (Sandbox Code Playgroud)
像前者一样,但是通过讨论它们然后返回一个列表来获取多个参数:
(anon. a a)
Run Code Online (Sandbox Code Playgroud)
好消息是你不需要编写词法分析器或解析器,也不需要使用构建系统来将这种语法添加到Scheme中; 它只是几行代码,导入语法就像导入函数一样.
第一个宏(命名:)很简单:
(define-syntax-rule (: (k v) ...)
(make-hash `((k ,v) ...)))
Run Code Online (Sandbox Code Playgroud)
第二个(命名:lst)更难,因为你需要生成索引.它可能不到十行代码,但我懒得写它们......
第三个宏(anon.)有点不平凡,但有点乐趣,所以这里是:
(define-syntax anon.
(syntax-rules ()
((anon. attr attrs ...)
(lambda (x) (cons (hash-ref x 'attr) (anon. attrs ...) )))
((anon.)
empty)))
Run Code Online (Sandbox Code Playgroud)
(请注意,为了保持一致性,我假设您anon.总是要返回一个列表;否则需要syntax-rules为特殊情况添加一个额外的子句.)我不确定这anon.是否真的是一个有用的宏,但这是你和你的代码库之间的关系.
如果你想破解宏,我建议你尝试我最喜欢的Scheme风格,Racket.它有一个特别宏观的世界观(参见这篇博文,当Racket被称为"PLT计划"时写回).
| 归档时间: |
|
| 查看次数: |
275 次 |
| 最近记录: |