实现此DSL最适合的语言是什么?

时间:2012-09-04 19:37:54

标签: function hash lambda language-design dsl

我想用一个非常短的语法编写一个DSL,用于我注意到对编程,函数和散列非常重要的两件事。这是我的设计:

创建哈希:

(a:1 b:2 c:3)
Same as JavaScript's: {a:1,b:2,c:3}

创建有序哈希,省略键:

(x y 5) 
Same as JavaScript's: {0:'x', 1:'y', 2:5}

创建一个匿名函数:

(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)

嵌套函数:

(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)

哪种语言适合实施此类DSL?

1 个答案:

答案 0 :(得分:5)

这听起来很像你喜欢一种具有强大宏系统的语言,比如某种Scheme。宏允许这种语法扩展,其中原始语言的代码片段可以嵌入到您建议的新表单中(我假设您希望能够说(a:1+1 b:2*2)等)。此外,宏系统不会使构建过程复杂化或破坏错误消息位置,就像外部预处理器一样。

但是有一个坏消息,就是我所知道的没有任何(非深奥的)语言在语法上有足够的空间来提供你指定的确切语法。

以下是我提出的语法:

哈希:

(: a 1 b 2 c 3)
; or, more clearly
(: (a 1) (b 2) (c 3))

索引键控哈希:

(:lst 'x 'y 5)

(如果您在散列的RHS上允许使用裸字,那么您将很难引用变量,所以我假设您不希望这样做)

匿名属性访问功能:

(anon. a)

和前者一样,但是通过讨论它们然后返回一个列表来获取多个参数:

(anon. a a)

好消息是,您不需要编写词法分析器或解析器,也不需要使用构建系统来将此语法添加到Scheme中;它只是几行代码,导入语法就像导入函数一样。

第一个宏(名为:)很容易编写:

(define-syntax-rule (: (k v) ...)
  (make-hash `((k ,v) ...)))

第二个(名为:lst)更难,因为您需要生成索引。它可能不到十行代码,但我懒得写它们......

第三个宏(anon.)有点不平凡,但很有趣,所以这里是:

(define-syntax anon.
    (syntax-rules ()
      ((anon. attr attrs ...) 
       (lambda (x) (cons (hash-ref x 'attr) (anon. attrs ...) )))
      ((anon.)
        empty)))

(请注意,为了保持一致性,我假设您希望anon.始终返回一个列表;否则需要为特殊情况向syntax-rules添加额外的子句。 )我不确定anon.是否真的是一个有用的宏,但这是在你和你的代码库之间。

如果你想破解宏,我建议你尝试我最喜欢的Scheme风格,Racket。它有一个特别以宏观为导向的世界观(见this blog post,当Racket被称为“PLT计划”时写回。)