Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
DSL (Domain Specific Language) @Mark 2020.10.26 特定领域语⾔
Slide 2
Slide 2 text
DSL 特定领域(Domain)所专⻔是合计的词汇和语法,简化程序设计过程,提⾼ ⽣产效率的技术,同时也让⾮编程领域专家的⼈直接描述逻辑成为可能。
Slide 3
Slide 3 text
• 优点: 集中描述 『想要做什么』(What)的部 分,⽽不必对『如何做到』(How)进⾏描述
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
• ⽐如⼀个名为 rake的编译⼯具,功 能和 make差不多会分析⽂件依赖关 系,⾃动执⾏程序编译、链接等操作 • 例⼦表达了: • 1) 默认任务为test • 2) test的内容是执⾏ node, python,ruby三个任务 • 启动rake 是 : rake 任务
Slide 6
Slide 6 text
• DSL是对特定⼩规模语⾔的称呼,是⼀个新叫法,但是这个东⻄并不是稀 罕东⻄,尤其是Unix社区中诞⽣了很多『专⽤语⾔』⼯具 • ⽐如 awk(⽂本处理), make(构建) ,sed(数据流编辑) • Unix中还提供语法分析⽣成⼯具 yacc,以及词法分析器⽣存⼯具 lex • Yacc,lex本身也有⾃⼰的迷你语⾔
Slide 7
Slide 7 text
• 迷你语⾔都是专⽤于特定⽤途,⼤多数情况下⽆法完成复杂⼯作。 • 因此本质上和DSL都是⼀样的。 迷你语⾔
Slide 8
Slide 8 text
外部DSL
Slide 9
Slide 9 text
外部DSL 以迷你语⾔为代表的,专⻔语⾔引擎实现的DSL,统称为外 部DSL。
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
• Java程序中⼤量使⽤了可拓展标记语⾔(XML)编写配置⽂件。这种 XML配置⽂件也是⼀种外部DSL 外部DSL例⼦ • 数据库访问所使⽤的 结构化查询语⾔(SQL)也是⼀种典型的外部DSL
Slide 12
Slide 12 text
• 独⽴于程序语⾔,对某个领域操作程序,不⼀定是同⼀个语⾔。 外部DSL优点 • 外部DSL是独⽴于程序语⾔开发,因此可以实现跨语⾔共享。 • 学会SQL可以在不同语⾔中使⽤SQL操作 • 例如正则表达式也是⼀种DSL,在Ruby,Perl,PHP,Python中都可以使 ⽤
Slide 13
Slide 13 text
内部DSL
Slide 14
Slide 14 text
内部DSL 外部DSL是从Unix中发展⽽来,内部DSL则是发源于Lisp和 Smalltalk的⽂化中。
Slide 15
Slide 15 text
内部DSL并不是创在⼀种新的语⾔,⽽是在现有语⾔中实现 DSL。⽽作为DSL的基础,这种语⾔称为宿主语⾔。 Lisp,Smalltalk,Ruby这些语⾔适合作为宿主语⾔,因此这 些语⾔的社区中经常使⽤内部DSL。
Slide 16
Slide 16 text
内部DSL优缺点 • 优缺点和外部DSL正好相反。 • ⽆需学习新语⾔,宿主语⾔的尝试依然有效。 • 甚⾄可以借助宿主语⾔,实现复杂逻辑的书写。 • 『寄⽣』在宿主语⾔上,使得可以轻松实现功能。即使『迷你语⾔』在拓 展线上都⽢拜下⻛。
Slide 17
Slide 17 text
DSL优势
Slide 18
Slide 18 text
DSL优势 • 更简洁的表达 • 减少与程序员交流成本 • 实现⽣产效率提⾼ • 不涉及内部细节,⽽是在⾼级层⾯上描述——抽象化 • # 不断抽象化其实是编程语⾔的未来发展⽅向之⼀
Slide 19
Slide 19 text
DSL的定义
Slide 20
Slide 20 text
DSL的定义 • 如何才算是 DSL呢?
Slide 21
Slide 21 text
DSL定义 • 观点1 像 『是否具备禁⽤于特认定⽤途的功能』、『(设计者)⾃⼰是 否将其命名为⼀种DSL』 这种标准,今天逐渐变得模棱两可
Slide 22
Slide 22 text
• ⻉尔实验室名⾔: • 库设计就是语⾔设计(Library design is language design). 我们在思考编程语⾔的时候,⼤多仅强调语法,但如果脱离了相当于词汇的 库、类和⽅法,语⾔也就⽆法思考。 也就是说 API也是构成编程语⾔的⼀个要素。
Slide 23
Slide 23 text
• Programming is a process of designing DSL for your own application. (编程就是为⾃⼰的应⽤程序设计DSL的过程) —— ⼤卫·托⻢斯
Slide 24
Slide 24 text
DSL定义 • 考虑到DSL实际上是编程语⾔抽象化得延伸,那么问题就不应该是什么是 DSL,什么不是DSL => DSL应该是将⾯向特定领域的API设计成优秀的 DSL这样⼀个设计的过程。
Slide 25
Slide 25 text
• DSL不仅仅是⼀种技术,⽽是程序开发的重要设计原理和原则之⼀,适⽤ 于任何软件的开发。
Slide 26
Slide 26 text
适合内部DSL的语⾔
Slide 27
Slide 27 text
• 虽然任何语⾔都可以成为宿主语⾔,但像Lisp,Smalltalk,Ruby这样的被认 为适合DSL的语⾔,都有⼀些共同的特征
Slide 28
Slide 28 text
• 简洁 DSL本来就是为了针对特定⽬的处理⽤的,⾼级的、简洁的⽅式进⾏描述。 因此简洁的描述⽅式才是最本质的。 简洁是作为DSL宿主语⾔不可或缺的要素。 Lisp、Ruby等于眼中,⽆需声明数据类型,编译器『规矩』也少,因此可 以变得简洁。
Slide 29
Slide 29 text
• 灵活 开发者通过⾼度抽象化代码集中描述 WHAT ⽽不是HOW。因此作为对抽象 化得⽀持,元编程等功能最好⽐较充实。 ⽐如Lisp具备宏(Macro)功能,只要遵循『⽤括号进⾏表达』的S表达式, 就可以实现⾃由表达。因此可以说Lisp语⾔本身就是⼀种可被编程的语⾔。 Ruby中的代码块(Block)功能可以实现控制结构,虽然不像Lisp那样万能, 但是⽤来实现内部DSL也⾜够了。
Slide 30
Slide 30 text
• 灵活 开发者通过⾼度抽象化代码集中描述 WHAT ⽽不是HOW。因此作为对抽象 化得⽀持,元编程等功能最好⽐较充实。 ⽐如Lisp具备宏(Macro)功能,只要遵循『⽤括号进⾏表达』的S表达式, 就可以实现⾃由表达。因此可以说Lisp语⾔本身就是⼀种可被编程的语⾔。 Ruby中的代码块(Block)功能可以实现控制结构,虽然不像Lisp那样万能, 但是⽤来实现内部DSL也⾜够了。
Slide 31
Slide 31 text
No content
Slide 32
Slide 32 text
No content
Slide 33
Slide 33 text
外部DSL实例
Slide 34
Slide 34 text
• 外部DSL就是拥有专⽤引擎的⼀种独⽴特定领语⾔。外部DSL也有各⾃不 同的实现⽔平。 最简单的莫过于配置⽂件,例如 YAML、JSON 更复杂⼀点DSL,虽然也是为特殊⽬的设计,但是可以编写出描述任何算法 的程序。例如 ⽂本处理的 awk。 再⽐如 ⾯向打印机的描述⻚⾯语⾔ PostScript 是⼀个基于逆波兰的图灵完 备语⾔。
Slide 35
Slide 35 text
还有⼀些⽐较特殊,虽然本身也是通⽤语⾔。叫做DSL并不合适,但是却与 特定计算机模型有很强关联性,也就具备了类似DSL的性质。 例如 Prolog 以⼀阶谓词逻辑为基础的语⾔。 统⼀,⽤于并⾏计算的Actor模型密切相关的 Erlang 虽然也是通⽤语⾔,但 是也具备了『⾯向并发编程领域的DSL』这个性质。
Slide 36
Slide 36 text
对于Java中: Java中 XML。由于Java中默认内置了解析XML的库,因此⽤XML写DSL很 容易被读取。这样可以省略为DSL开发语⾔引擎的步骤。 但是XML不论是阅读还是编写都⼗分冗⻓,并不是很友好。
Slide 37
Slide 37 text
DSL设计的构成要素
Slide 38
Slide 38 text
上下⽂(context) 语句 (Sentence) 单位(Unit) 词汇(Vocabulary) 层次结构(Hierarchy)
Slide 39
Slide 39 text
上下⽂ 作⽤就是 定义上下⽂,表示这个测 试的⼀个⼤框架。 ⼀个测试框架例⼦: ⽐如 context “a User instance” do 就表示对 『a User instance』这个 上下⽂的测试进⾏定义的意思 Should⽅法定义了『需要满⾜某个 条件』这样⼀个测试。
Slide 40
Slide 40 text
这样与其说定义测试,不如说定义 了⾏为(Behavior) 有时候也称为规则(Spec)。 前置定义这种Spec就是 BDD ⾏为 驱动开发。
Slide 41
Slide 41 text
⼀个⼩作品,在Ruby的语 法范围内到底能设计出多 接近英语的DSL。 这是⼀个描述做⾯包的 DSL。
Slide 42
Slide 42 text
接近⾃然语⾔的利弊 外⾏⼈容易纠结到底在哪⼉要加上 标点符号。顺序是否可以调换。 COBOL就遇到了这样的设计问题。 由于Ruby可以⾃由增加⽅法,所以 利⽤这⼀点,实现了上⾯的DSL
Slide 43
Slide 43 text
Ruby on Rails 包含的ActiveSupport库中, 『现在时间的20⼩时之前』可以写出 『20.hours.ago』 Rails不仅是⼀种Web框架,也可以说是以 Ruby为基础的DSL
Slide 44
Slide 44 text
词汇、层次 Rails中如果数据库users表中包含name属性, 可以这样调⽤: User.find_by_name(“⻢克”) find_by_name 是⾃动⽣成的
Slide 45
Slide 45 text
层次可以理解为嵌套上 下⽂ ⽤Ruby作为DSL⽣成 XML 看起来可能要⽐XML简 洁
Slide 46
Slide 46 text
Sinatra是⼀个规模较⼩ 的Web框架。 通过特殊的 get语法, 以简洁的形式,应⽤了 上下⽂。
Slide 47
Slide 47 text
⼩结
Slide 48
Slide 48 text
DSL虽然是最近出现,但是实际上已经从数⼗年前就使⽤的技术。 就像给设计模式起个名字⼀样,可以提⾼其认知度。 今后DSL也可能作为判断设计优秀与否的重要指标,对软件开发产⽣巨⼤影 响。
Slide 49
Slide 49 text
Q&A
Slide 50
Slide 50 text
THANKS