12 ms·
It's pretty common to call a DSL "internal" when it works within the syntax of an existing language, as opposed to an external DSL that is a separate language.
by hyperpape 11y ago
It's pretty common to call a DSL "internal" when it works within the syntax of an existing language, as opposed to an external DSL that is a separate language. I'm not sure saying "but it's not really a language" helps us stay clear on what's going on.
- dozzie 11y agoYes, it's pretty common to call it that. Mainly because it's pretty common for programmers to be undereducated, so they misapply terms or unnecessarily reinvent terminology. Let's call the "smart interface with domain-specific verbs" a domain-specific interface, it would be just fine. But calling it a language is simply a term abuse.
- tel 11y agoBefore you start throwing insults, what exactly is a language to you? I'm pretty confident that determining the difference between a language and an API is not so easy a thing to do.
- dragonwriter 11y agoA language has syntax and semantics; the combination of domain specific semantics with general purpose syntax is a domain-specific language. Of course, with host languages that support user-defined syntax rules, an internal DSL may also have specialized syntax. The cumbersome term you invented is not an accurate replacement for internal DSL.
- Dewie3 11y agoI've seen the distinction between internal and external DSL in academia as well.
- kenbellows 11y ago> it's pretty common for programmers to be undereducated... [citation needed]
- moron4hire 11y agoNot that I think it's an adequate citation, but there is an essay from Dijkstra on the front page of HN right now where he says essentially the same thing: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/EWD648.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/E...
- moron4hire 11y agoI'm not sure calling it a language does, either.
- chrisseaton 11y agoSo what's the difference between an internal DSL and any other library?
- kenbellows 11y agoUsually you call something an internal DSL when it reads like its own language. The reason that Ruby lends itself to internal DSLs is how optional a lot of its punctuation is, especially parens around method parameters, making it easier to write code that looks like a variant of English. A good example of this is Rake.
- chrisseaton 11y agoI still don't get what 'reads like its own language' really means though. Rake is still Ruby syntax and semantics. Rake just adds new methods - they're still Ruby methods and calling them reads like any other Ruby method using the same parsing rules. I'm playing the fool here - I do know what an internal DSL is but I think the term is entirely meaningless when you really think about it.
- drakecoffeecake 11y agoLisps let you define the semantics and syntax of a form with macros. I would consider the loop macro in CL to have an internal DSL. --edited
- draegtun 11y agoAnd another example of this, but not using macros, would be Rebol's parse which is a top-down parsing dialect (internal DSL) within Rebol. ref: http://en.wikipedia.org/wiki/Rebol#parse http://en.wikipedia.org/wiki/Rebol#parse
- moron4hire 11y agoI think the difference becomes clear when you consider that a language syntax is not just source code. Raw, text source code is just the means by which humans express utilizing the syntax of the language. Once that source code file is tokenized and parsed, it's no longer tied to whatever that text was. It becomes an abstract object in memory that either represents a process (a series of machine instructions) or is fed to a process to be manipulated and processed (i.e. interpreted scripting languages). For example, this blog post walks through McCarthy's original specification for Scheme: http://programmingpraxis.com/2011/11/01/rip-john-mccarthy/ http://programmingpraxis.com/2011/11/01/rip-john-mccarthy/ apply[fn;x;a] = [atom[fn] → [eq[fn;CAR] → caar[x]; eq[fn;CDR] → cdar[x]; eq[fn;CONS] → cons[car[x];cadr[x]]; eq[fn;ATOM] → atom[car[x]]; eq[fn;EQ] → eq[car[x];cadr[x]]; T → apply[eval[fn;a];x;a]]; eq[car[fn];LAMBDA] → eval[caddr[fn]; pairlis[cadr[fn];x;a]]; eq[car[fn];LABEL] → apply[caddr[fn];x;cons[cons[cadr[fn];caddr[fn]];a]]] This is a type of source code. Notice it even includes non-ASCII characters. But this code isn't executable as it is. It has to first be translated into a program, somehow. See the first reply at the original link, which I will not reproduce here, for brevity. It is a Scheme interpreter. The call to `evaluate` at the end of each test function is where the program gets interpreted. No, it is not a Scheme source file, but it is Scheme syntax, written in Python. Similarly, LINQ to SQL is a SQL syntax written in C#. Your LINQ expressions are C# code that construct objects that will be interpreted in a SQL context. LINQ to Objects, on the other hand, is NOT a SQL syntax, it's just a library. Even though the function calls look exactly the same, because the C# code you write defines objects that then execute in a C# context. Of course, that's not to say most "DSL"s haven't misused the term "language". I see it applied a lot to interfaces of chainable method calls. It isn't a new language, it's an exploitation of the existing language. The code still executes in the host language's context, it does not define its own contexts or semantics in any way. Look at Emscripten. Is it C because that was what the code was written as, or is it JavaScript because that is what the code gets translated to? It's C, because it creates an execution context within the JavaScript code to recreate C semantics. Look at this toy language I once wrote (https://github.com/capnmidnight/betty-boop/blob/master/loosp.js https://github.com/capnmidnight/betty-boop/blob/master/loosp...) and a Pong game that uses it (https://github.com/capnmidnight/betty-boop/blob/master/pong.html https://github.com/capnmidnight/betty-boop/blob/master/pong....). Is the Pong game Scheme because that's what it was written as, or is it JavaScript? It's JavaScript, because though the code looks like Scheme, it executes like JavaScript, it's just a different syntax that gets translated away.