Live data from Hacker News

I Don't Want to Teach My Garbage DSL, Either

github.com

31–40 of 54 posts

Re: I Don't Want to Teach My Garbage DSL, Either

#31

If your API is so complicated that it becomes a DSL, then perhaps there should be better communication between frontend and backend teams. Setting up a lean API contract makes more sense than creating an internal DSL or exposing internal data stores directly to users.

Some things are irreducibly complicated. You can't set up a lean API contract for a complicated thing without giving up power. The example of SQL is pertinent. Any attempt to set up a lean API contract for a relational database is doomed to be weak and painful to use. Without knowing the specific problem domain the blogger was dealing with, you can't know whether that was the situation. But if we assume they are comp…

complexity != complicated

Re: I Don't Want to Teach My Garbage DSL, Either

#32
At the end of the day, most reports/dashboard UI's are a DSL over SQL. It may not be language in the traditional sense - more of a Visual or Interactive language. However, it is a language where the primitives (drop down, text boxes, etc) are understood by many, even more so than the language it is abstracting (SQL).

Re: I Don't Want to Teach My Garbage DSL, Either

#33
post #13

A DSL can be immensely useful in terms of useability. But it is not trivial to be done right. You need to define a consistent grammar, make sure it's intuitive to your users and free of all sorts of fun bugs that happen when odd constructs are put together.

I think you're describing what Fowler[1] calls an "external" dsl ie separate lexer, parser, and code generator. The alternative being "internal" dsl, something that uses a languages own constructs to create stuff; ie like how Ruby is is used in several well known frameworks. [1] https://www.goodreads.com/book/show/8082269-domain-specific-...

I think this is still applicable advice for embedded DSLs too, since the grammar of the DSL will be made up of the ways in which you can compose the operations you provide, whether they are parsed by the host language's parser or your own.

Overall, I agree that it's important to think about how to make sure that operations compose in an unintuitive, expected way. I find this hard to figure out without thinking of it in terms of a grammar and semantics, whether it's embedded or not.

Re: I Don't Want to Teach My Garbage DSL, Either

#34
post #13

A DSL can be immensely useful in terms of useability. But it is not trivial to be done right. You need to define a consistent grammar, make sure it's intuitive to your users and free of all sorts of fun bugs that happen when odd constructs are put together.

Also if you don’t write a debugger and report line numbers on errors, you have not fully understood your problem domain.

Re: I Don't Want to Teach My Garbage DSL, Either

#35
post #13

A DSL can be immensely useful in terms of useability. But it is not trivial to be done right. You need to define a consistent grammar, make sure it's intuitive to your users and free of all sorts of fun bugs that happen when odd constructs are put together.

I inadvertently created a scripting language recently. It started out as simple commands like "thing param" (kinda like TCL, I guess), but it slowly evolved (needed conditional commands, state, etc) and after a while I wanted proper expression parsing because my ad-hoc command parser was way too brittle. So I wrote an EBNF grammar and used Clojures Instaparse to parse it into an AST and then I added functions, loops and other more traditional programming constructs because why not. I've cleaned up the grammar a few times and now its a simple but relatively full featured scripting language (with some domain-specific features). There are basically three parts: the text parser (EBNF grammar and instaparse), AST transformation that takes the AST that the grammar created and cleans it up (removing or simplifying intermediary nodes, turning string numbers into numbers, extracting function definitions, etc) and the evaluator (which, I'm quite proud of: its a pure function of the scripts inputs + mutable state and it generates a collection of "actions" and new mutable state).

Now onto why I mention this:

> free of all sorts of fun bugs that happen when odd constructs are put together

I actually had an interesting experience with this, but in a good way. As I said above, I hoist the code for functions out of the AST (the final AST is basically a map of function to function body AST, where one of these is the main script code) and the declarations are replaced by the transformation step with a local variable binding that gets set to some data describing how to call the function (key into the map, list of parameters, other stuff), so when you do 'f()', it looks up 'f' in local state, gets this data and figures out how to call the function from that. What this meant was that I could pass functions around. And so I got higher order functions almost for free, without having planned for it, just because I thought "hmm, what if I do this?" (the current version did add some special logic to capture state, for closures, but I did that after when I decided why not support it for real).

As an aside, my little language is a synchronous language[1], which acts as if its runtime is instantaneous (ie, the world does not change until it completes), which makes a lot of things easier (both for me and for users) and makes sense in the domain, since its basically commands that get triggered when certain conditions are met. This almost makes it worth writing a custom language over using an existing one, but if I were to start again, I'd probably just use Lua or Javascript and save some time, even if the final language isn't so easy for my target audience.

[1] https://en.wikipedia.org/wiki/Synchronous_programming_langua...

Re: I Don't Want to Teach My Garbage DSL, Either

#36
post #26

I don't understand why writing an ORM requires creating a new query language. The point of an ORM, as I understood it, was to think about objects, not query languages. When I wrote my garbage ORM ( https://hrorm.org ) I just ignored everything that's hard (you can write your own SQL for that) but the easy things (basic CRUD) don't require a query language at all. They are just provided by an object-based interface.

The trouble with SQL is that its foundation is old and hasn't been given much love with regards to modern language theory, and any attempts to talk about how the language could be improved are shot down on the basis of confusing the language with the application of the language. The trouble with SQL is that it doesn't easily allow for basic building blocks that ORMs benefit from, like composability. This leads many O…

SQL is a great language. It's for querying records from a database. Trying to wrap stateful objects around SQL is where the industry went wrong, IMO. It does make some code more portable across datastores, but for me the price is too high. When you know how to write efficient SQL statements, ORM feels like having a hand tied behind your back.

Re: I Don't Want to Teach My Garbage DSL, Either

#37
post #26

I don't understand why writing an ORM requires creating a new query language. The point of an ORM, as I understood it, was to think about objects, not query languages. When I wrote my garbage ORM ( https://hrorm.org ) I just ignored everything that's hard (you can write your own SQL for that) but the easy things (basic CRUD) don't require a query language at all. They are just provided by an object-based interface.

The trouble with SQL is that its foundation is old and hasn't been given much love with regards to modern language theory, and any attempts to talk about how the language could be improved are shot down on the basis of confusing the language with the application of the language. The trouble with SQL is that it doesn't easily allow for basic building blocks that ORMs benefit from, like composability. This leads many O…

I agree that SQL as the lingua franca for talking to relational data stores is not ideal, and that in various ways it could be improved. I personally would start out with some of the issues of cosmetic syntax orthogonality, though I realize there are bigger fish to fry.

But two things come to mind on reading your comment. 1. For the problem of Object-Relational-Mapping (ORM) which query language is used is not that important. If one accepts that there is one general purpose language for application development and another for managing persistent data, you will be left with a situation where there is a bunch of redundant code to write in whatever query language and application language you have available, and it would be nice to not have to write all that by hand. 2. Over the years, I have encountered many projects (languages) that attempt to address various deficiencies in SQL. I feel like a lot of these projects make life too hard on themselves. Rather than building extensions to existing database engines, they want you to adopt not just their new language, but their whole persistence stack. If I was smarter, and I had a design for a "better SQL", I would try to integrate it into Postgres or some other existing database engine. I guess that's what some of the ORM authors are trying to do, but by compiling their language to SQL supporting all databases at once. But returning to point 1, that seems pretty separate from the issue of Object-Relational-Mapping.

Re: I Don't Want to Teach My Garbage DSL, Either

#38
post #10

I agree to an extent. But, I disagree that learning ORMs are a waste of time. For example, I'm on Phoenix, using Ecto. I find `Repo.all` much more convenient that "SELECT * FROM .." etc. I don't know if it's better or worse - the original blog post asking governments to regulate data formats/code!

Well, Ecto is not an ORM. It's a Data Mapper[0]. Rails' ActiveRecord is ORM.

I agree that some DSLs make SQL better and easier to reason about -- and that Ecto is one of them.

[0] https://en.wikipedia.org/wiki/Data_mapper_pattern

Re: I Don't Want to Teach My Garbage DSL, Either

#39
post #10

I agree to an extent. But, I disagree that learning ORMs are a waste of time. For example, I'm on Phoenix, using Ecto. I find `Repo.all` much more convenient that "SELECT * FROM .." etc. I don't know if it's better or worse - the original blog post asking governments to regulate data formats/code!

Well, Ecto is not an ORM. It's a Data Mapper[0]. Rails' ActiveRecord is ORM. I agree that some DSLs make SQL better and easier to reason about -- and that Ecto is one of them. [0] https://en.wikipedia.org/wiki/Data_mapper_pattern

Aren't data mappers generally referred to as ORMs?

Re: I Don't Want to Teach My Garbage DSL, Either

#40
As a broader point, the general message of this post is not said often enough and it should be.

People get attached to their creations and especially if the thing starts as a hobby project, the author can get carried away pretty far. When they eventually want to share their creation with the world they might get a really cold shower.

IMO us the programmers started becoming less practical and more tinker-y. Which is not a bad thing; it's healthy for the psyche. But when it comes to pieces of tech that can end up getting used on vast scales, we should be more responsible.

In this lane of thought, DSLs should be reserved to niche business domains and not as the first tool you reach for when you can't quite describe a problem with your programming language of choice.

Post reply on HN