The languages that truly let you do anything you want flexibly invariably lead to incomprehensible ivory towers. It is why managers hate Lisp, it's why Perl is joked as write-once read-never.
The issue with the "DSL" is the third letter in the abbreviation: LANGUAGE. A language isn't just a specification of syntax. A language is a collective shared understanding between a sufficiently large number of people. Without that, it is a dead language.
Socially in programming, programming languages need to align to real-world concepts, because that is what enables the language to be understood by new adopters. And converging on those shared meanings is hard, because designers and lingo makers can't anticipate all the variations of understanding people will have.
Learning a language is hard. So every DSL I've encountered invariably forces me to be the compiler: what is this being translated into language-wise and what does it convert to. That is a big load, so your DSL better provide power and convenience to deserve it.
DSLs also run headlong into NIH/creator's advantage. The people/person that make the DSL and implement it will know it FAR better than any adopter will. And documentation is always lacking. So what is blindingly obvious to the core practitioners is very much not so to the noob.
You are limited by the average intelligence of the programmer at a cultural level. The lone mad scientist may produce amazing ideas, but all the groundbreaking technology happens because an army of people can be coordinated to implement something.
Lisp is basically a DSL factory, and everything is done via DSL. Can Perl7 do that better than Lisp? Is that a good or bad thing?
Well, it doesn't matter. Perl5 is what it is. Perl6 was a social failure. I doubt Perl7 will change anything.
> The languages that truly let you do anything you want flexibly invariably lead to incomprehensible ivory towers. It is why managers hate Lisp, it's why Perl is joked as write-once read-never.
I've yet to see that happen in a Lisp project. On the other hand, inflexible languages like Java lead to abominations like the Spring framework, where tons metaprogramming happens at runtime via reflection.
The thing about compile-time macros (e.g. Lisp macros) is that they can be debugged at compile time. For example, if you see a macro invocation, and you don't know what it does, you can just expand that macro right in your editor, and look at what code was generated.
People are always worried about DSLs, but most projects end up with their own DSLs. They're just often built out of functions, methods, objects, etc.
I think the real issue with understanding a project is learning the concepts, architecture, and abstractions they use. Knowing e.g. Go really well doesn't save you from having to wade through the giant pile of code used to express the program's intent. Abstraction is a way to get that complexity filtered down as close to the problem's inherent complexity as possible. Yes, you'll have to learn the abstractions, but if done reasonably well, that will still be much easier than trying to understand the non-abstracted version.
> People are always worried about DSLs, but most projects end up with their own DSLs. They're just often built out of functions, methods, objects, etc.
I wish there was a kind of super-upvoting that added one to the font-size of the comment you're upvoting, because I would absolutely super-upvote this comment.
> Abstraction is a way to get that complexity filtered down as close to the problem's inherent complexity as possible. Yes, you'll have to learn the abstractions, but if done reasonably well, that will still be much easier than trying to understand the non-abstracted version.
Absolutely. It's possible (arguably, too easy) to build a bad DSL, but the point of a DSL is to surface the inherent complexity of your domain so you can grapple with it on its own terms. Not using a DSL doesn't mean that complexity goes away; it just means you have to grapple with that complexity using coarser tools. You usually end up with a DSL-lite of types and functions that work in your domain, often with warts due to poor interactions with the host language's feature set.
For a lot of reasons, I'm a big fan of eDSLs, which aren't too much different from the DSLs-lite we usually end up with. But overcoming that impedance mismatch with the host is not easy. (That's one of the benefits of Lisp, I think -- very low impedance mismatch to overcome!)
I've gotten somewhat good at doing eDSLs in Java(!), where you want to keep things mostly idiomatic, unconstrained Java while still adding the novel behaviors you need for your domain solutions. But you're always going to have to wrangle the complexity of your domain, whether or not you involve a DSL in that effort.
when i first heard that lisp was supposed to be good for making DSLs, my first thought was 'gross, i'll just stick to writing plain lisp thankyouverymuch'
but i think that's a misunderstanding- it's not a suggestion to make a mess with reader macros or whatever, its an observation that common lisp _naturally_ builds up to form the language constructs needed in your domain, simply by virtue of providing the tools and syntactic flexibility needed to construct them
another thing that seems to put off newcomers to cl is the parallax between the promise of a smooth, polished dev environment, vs the nuts-and-bolts-exposed nature of the core language itself (eg the infamous eq/eql/equal/equalp situation)- but i think this can be explained as how cl is _not_ a scripting language, and you are expected to paper over these edges as you define the system
cl gives you the best tools in the business to turn itself into a dev interface so clean it might as well be a DSL
The issue with the "DSL" is the third letter in the abbreviation: LANGUAGE. A language isn't just a specification of syntax. A language is a collective shared understanding between a sufficiently large number of people. Without that, it is a dead language.
Socially in programming, programming languages need to align to real-world concepts, because that is what enables the language to be understood by new adopters. And converging on those shared meanings is hard, because designers and lingo makers can't anticipate all the variations of understanding people will have.
Learning a language is hard. So every DSL I've encountered invariably forces me to be the compiler: what is this being translated into language-wise and what does it convert to. That is a big load, so your DSL better provide power and convenience to deserve it.
DSLs also run headlong into NIH/creator's advantage. The people/person that make the DSL and implement it will know it FAR better than any adopter will. And documentation is always lacking. So what is blindingly obvious to the core practitioners is very much not so to the noob.
You are limited by the average intelligence of the programmer at a cultural level. The lone mad scientist may produce amazing ideas, but all the groundbreaking technology happens because an army of people can be coordinated to implement something.
Lisp is basically a DSL factory, and everything is done via DSL. Can Perl7 do that better than Lisp? Is that a good or bad thing?
Well, it doesn't matter. Perl5 is what it is. Perl6 was a social failure. I doubt Perl7 will change anything.