A Fronteira do DSL
Posted on September 27, 2006
Quando lemos alguma descrição de Ruby frequentemente vemos a sigla DSL (Domain Specific Language). Quando lemos uma descrição de Rails também vemos a definição que “Rails é uma DSL para aplicativos Web”.
Mas o que é uma DSL? Martin Fowler, um renomado escritor de livros de engenharia de software, especialmente no assunto de Design Patterns, nos dá uma definição para DSL em seu Bliki. Vejamos a tradução:
Quando o tópico DomainSpecificLanguage aparece, um dos quebra-cabeças comum é definir o que exatamente é ou não é um DSL. O problema é que não existe uma definição precisa para DSL além de uma grande área cinzenta entre DSLs e outras coisas.
Para mim, um elemento-chave é que DSLs são limitados tanto em escopo (eles se referem a um domínio em particular) e capacidade (eles não têm funcionalidades básicas para linguagens de propósito genérico). Como resultado, bons DSLs são normalmente pequenos e simples: daí termos como “pequenas linguagens” e “mini linguagens”.
Para DSLs internas, a fronteira estranha é o que é uma API e o que é uma DSL. Fundamentalmente não existe diferença: uma DSL interna é apenas uma API com um nome interessante (como diria a velha Bell labs: “design de biblioteca é design de linguagem”). Apesar disso, entretanto, acho que existe uma sensação diferente quando se está trabalhando com uma API que é escrita como uma DSL. Coisas como uma InterfaceFluente podem tornar o trabalho com uma API uma experiência qualitativamente diferente. Pensar em termos de DSL faz pensar sobre facilidade de leitura de uma maneira diferente, explorando a sintaxe da linguagem hospedeira para criar alguma coisa que parece ser independente – rake é um grande exemplo disso.
Quando falamos de DSLs externas a questão, às vezes, vem na forma de qual a diferença entre uma DSL e uma linguagem de propósito geral (General Purpose Language ou GPL – não confundir com a licença GNU). Normalmente um sinal claro é quando a DSL não é Turing-complete ou não tem facilidades de abstração. Regexps (Expressões Regulares) são um bom exemplo dessa limitação de capacidade. SQL é um candidato mais interessante. É uma linguagem complexa e capaz, mas falta ser Turing complete e a habilidade de construir novas abstrações.
Pode uma linguagem ser Turing complete e ainda ser uma DSL? A linguagem de script Ploticus é Turing complete, mas seu foco claro de produzir grafos faz dela uma DSL. Mas então e XSLT? Ele também tem um foco limitado de transformar documentos XML, mas ganhou tantas capacidades que gradualmente as pessoas pensam nela como uma GPL.
O exemplo de Ploticus levanta questões se linguagens embarcadas são DSLs. A linguagem de macro Excel é uma DSL quando é virtualmente o mesmo que Visual Basic? O que acontece quando embarcamos uma linguagem de propósito geral em um aplicativo?
Como na questão de DSL interna VS API, acho que a intenção é a chave aqui, tanto do criador da linguagem quanto do usuário. Se eu usar XSLT apenas para transformar um documento XML então a estou tratando como uma DSL – mesmo que eu faça alguma chamada para fora para embutir algum valor no documento de saída. Entretanto, se eu a usar para resolver o problema do quebra-cabeça das oito rainhas, a estou usando como uma GPL. Se os designers do XSLT a vêem como transformações de XML então estão pensando nela como uma DSL, mesmo que pessoas espertas façam coisas não-naturais com ela.
Essa é uma daquelas discussões de barzinho mas que não deve desviar a atenção das boas idéias em usar DSLs. Elas devem ser desenhadas como sempre, como linguagens limitadas altamente focadas em um problema singular. Se você entrar no design e usar essa idéia como base, elas serão úteis. Afinal, é a usabilidade que realmente conta.
blog comments powered by Disqus
Archives
- February 12(2)
- December 11(1)
- November 11(4)
- October 11(6)
- September 11(5)
- August 11(1)
- July 11(5)
- May 11(4)
- April 11(11)
- March 11(4)
- February 11(3)
- January 11(4)
- December 10(9)
- November 10(2)
- October 10(10)
- September 10(4)
- August 10(6)
- July 10(14)
- June 10(16)
- May 10(8)
- April 10(14)
- March 10(9)
- February 10(6)
- January 10(14)
- December 09(10)
- November 09(10)
- October 09(7)
- September 09(19)
- August 09(4)
- July 09(12)
- June 09(7)
- May 09(12)
- April 09(11)
- March 09(9)
- February 09(9)
- January 09(12)
- December 08(14)
- November 08(20)
- October 08(15)
- September 08(18)
- August 08(25)
- July 08(13)
- June 08(21)
- May 08(29)
- April 08(27)
- March 08(12)
- February 08(32)
- January 08(31)
- December 07(27)
- November 07(30)
- October 07(25)
- September 07(28)
- August 07(16)
- July 07(15)
- June 07(16)
- May 07(7)
- April 07(13)
- March 07(8)
- February 07(9)
- January 07(24)
- December 06(17)
- November 06(17)
- October 06(15)
- September 06(38)




