Hacker News new | past | comments | ask | show | jobs | submit login

Out of curiosity (because this is what I was hoping from from the article), has anyone found a DSL in the wild that actually achieved its objectives?

That is, it either simplified the code necessary to write a program that there was a net savings for the project compared with developers just writing it in a language they were familiar with, or it simplified the business logic aspect to such a degree that even non-devs were able to be productive with it?

I admit this is partly determined by what we decide a DSL is, since it is, ultimately, at some level just an abstraction. But almost every instance I'd squarely say "that was an attempt at a DSL", it became just as complex as the underlying language, with additional gotchas, if it even 'worked' at all (i.e., allowed you to solve the domain specific problems it was intended to solve).




I can give Anvil as an example (https://github.com/zserge/anvil). It's a DSL for writing Android view layouts in Java and Kotlin. The DSL looks nicer than linear code of creating views and binding their properties, its look follows the hierarchy of the views, and the way it works results in a very fast rendering mechanism.


regular expressions work so well people have stopped thinking of them as a dsl and just see them as a language feature.


Character escapes and string formatting (printf, String.Format in .NET) fall into this category as well. They’re weird little domain-specific sublanguages that are entirely unlike their host languages, which people don’t even think of as DSLs because they’re so pervasive and (somewhat) consistent across languages.


I'd throw in pattern matching, which is becoming popular thanks to functional programming.


yeah, i pointed out racket's `match` in a sibling comment, where they added it to the language as a dsl. works beautifully.


Likewise, Common Lisp has a powerful matching DSL library too - Optima[0]. I also found a pretty new alternative, Trivia[1], which claims to be a drop-in replacement for Optima, but more extensible. --

[0] - https://github.com/m2ym/optima

[1] - https://github.com/guicho271828/trivia


Good example! And maybe that's what happens; extremely successful DSLs stop being thought of as DSLs, but as languages or features in their own right.


JuMP, in Julia: https://github.com/JuliaOpt/JuMP.jl/blob/master/examples/bas...

It's rapidly displacing proprietary DSL's like AMPL and GAMS in operations research. Neither of those happen to be embedded in a host language, they're special-purpose. Though there are comparable tools out there embedded in Python or Matlab, they don't perform as well as JuMP or the special-purpose tools.


One in particular that my team and I have used extensively is Spock, a unit testing Groovy DSL (see http://spockframework.org/spock/docs/1.0/index.html). In particular, we make heavy use of data tables and data pipes to generate sophisticated test data that would be a huge pain otherwise. And the accessible mocking syntax makes mocking so easy that devs end up writing more tests and testing more edge cases. The systems we have that use Spock the most have incredible test coverage and are very robust, because Spock makes it very easy and quick to test all your edge cases.


I second this. Spock is the best testing framework I've ever used. Same results on my team: much better test coverage just because writing tests is so much easier and fun.


You are two users each talking about your team to promote a framework. I'll take some actual time to look at some code from the sole link here, which is the website:

  class DataDriven extends Specification {
      def "maximum of two numbers"() {
          expect:
          Math.max(a, b) == c

          where:
          a | b || c
          3 | 5 || 5
          7 | 0 || 7
          0 | 0 || 0
      }
  }
I see here a DSL that

* defines blocks without curlies by overloading the C-style label syntax normally used for break targets

* overloads the | and || operators to build tables of data without quotes around it

* uses strings as function names instead of camelCase

The Apache Groovy DSL enables that by having a complex grammar and intercepting the AST during the compile. Clojure, also for the JVM, has a simple grammar and provides macros, which are convenient for eliminating syntax in repetitive tests. I switched from Groovy 1.x to Clojure years ago for testing on the JVM.


In a team/company using Java, Groovy is a relatively easy sell compared to Clojure.

(I love Clojure and would much rather use it than Groovy.)


Show me the code, please?


I wrote one once, a bastardized xpath that was used in a web crawler. I think it worked because it was extremely limited in what it could do and because normal code was a fallback in several places, it was never intended for non-developers. With it we could condense several hundred lines into < 10, with much lower error rates. Come to think of it, I'm not sure if the term "DSL" had been coined at the time, or I was unaware of it in any case, "creating a language" was not something I was attempting to do.

Since then I've encountered several in the wild that have been maintenance nightmares. Some were too simple that they were useless. Others were too complicated, so we ended up having to maintain a language and the code in that language.

There's one lying around here that was intended for support people to program in via an expression tree editor with a clunky UI. That was a disaster. We've got another one which is a terribly bastardized regex that was built because "support people don't understand regex". The don't understand this one any better, they would have been better off learning a life skill like regex.


JSX is similar, and I'd say it's a huge positive


This may partly be Stockholm syndrome, but I'm actually somewhat fond of Gradle (a Groovy DSL for configuring builds/managing dependencies for Java projects). It's certainly not perfect and I think it would be overkill for simple builds, but I find the DSL well suited to writing custom build tasks.

As an example, I wrote a Gradle plugin for a project I work on that lets you write:

  apply plugin: 'mycompany.service'
  
  mainClassName = 'mycompany.Main'
  service {
    id = 'serviceid'
    port = 1234
  }
This results in a `buildImage` task being added which builds a Docker image that runs `mycompany.Main` and exposes the specified port (and does some Docker tagging with the service id).

Implementing this plugin was straightforward, less than 50 lines of Groovy, most of which is invoking another DSL[1] for creating a Dockerfile.

[1] https://github.com/bmuschko/gradle-docker-plugin#creating-a-...


> Gradle (a Groovy DSL

Gradle is not a Groovy DSL. Gradle enables you to write its build files in either Kotlin or Apache Groovy, and perhaps there'll be more choices later on.

> Implementing this plugin was straightforward, less than 50 lines of Groovy

Did you know Gradleware now recommend using Kotlin for writing plugins for Gradle versions 3.0 and later?


Gradle may not claim to be a "Groovy DSL" anymore, but they certainly used to.

From the overview page at the time of the 1.0 release

At the heart of Gradle lies a rich extensible Domain Specific Language (DSL) based on Groovy. https://web.archive.org/web/20120724040152/http://www.gradle...

Now they just call it a "DSL" but also say that a build script is also a Groovy script https://docs.gradle.org/4.0/dsl/


Rebol/Red's VID (Visual Interface Dialect) is a DSL which did achieve it's objective - http://rebol.com/docs/easy-vid.html

And another success is the Parse dialect which I use daily and comes baked-in with Rebol / Red - http://www.rebol.com/docs/core23/rebolcore-15.html

Rebol / Red is an excellent language for creating DSL's (Dialects) and there are plenty of examples in the wild (I've seen Rebol dialects for creating PDF's, Excel spreadsheets, Scheduling tasks, etc)


> it simplified the business logic aspect to such a degree that even non-devs were able to be productive with it

* bash (or any shell) -- Might seem odd to call it a DSL, but it certainly embodies the abbreviation.

* Matlab/R/etc.

* Excel (and even VB depending on usage) -- This even plays into "business logic"

You're probably more talking about something along the lines of Gherkin (Cucumber) though. While I've certainly seen it make devs unproductive, I don't know that I've even heard of it achieving the converse unless you loosen the criteria to meaninglessness.


Yeah, I actually was thinking Excel, and then was like "but that kind of depends on your definition of DSL", hence in part the question. A shell is an interesting thought of one. I don't know that I'd consider Matlab/R/etc given they're full on programming languages, just ones with a math-y slant.


I don't know if it would be considered a DSL, but the Rails router API is pretty great. Then there's Rspec, which I find atrocious.


Spray is the best approach to HTTP routing I've ever used, though I suppose you could argue it's just a normal library and you just write normal Scala. I'm not sure how you'd really draw a line between that and a "DSL" - to my mind any good library lets you write what you're doing in a simple, declarative, domain-appropriate way.


Plenty of such project-specific microDSLs can be seen in Lisp world. They do a great job at reducing the boilerplate one would otherwise have to write, and they're relatively easy to inspect, if you need to know what's being done underneath.


Right, but that hinges on the definition of a DSL. It's not a complete language for solving a domain specific need; it's just a set of abstractions intended to reduce boilerplate. To me that's not that different than, say, a library in any programming language; it's a set of nouns and verbs to make certain problems easier, but it still requires the full knowledge of the underlying language to make useful.


racket's `match` is a very successful dsl in terms of simplifying code: https://docs.racket-lang.org/reference/match.html


Loop in Common Lisp is a good one.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: