Embracing Languages Inside Languages

Now if only MS would open up CSC so we could actually do this well…

Until then, an OO abstraction is the best we can do without serious effort (ie…ANTLR)

Fluent interfaces arguably have a place but I don’t think that place is necessarily for replacing database queries, nor regular expressions.

I think fluent interfaces do have a role to play in domain-driven design (see books by Evans and Nilsson) and the like. They talk about the need to derive a “ubiquitous language”. This language forms the model that is used:

  1. in analysis to aid in understanding by all parties in a development project
  2. for unambiguous communication between developers and users/BAs
  3. as the actual model that the code is built with

Now that’s all good in theory but the problem is that you often can’t express all the nuances of natural language required for the model to be used in point 2 (communication), in something like UML or object /state/etc diagrams, for use in point 3 (code). As a result you often lose model specifics when you try and code.

So to derive such a model and then still have it be expressive and useful in and for coding requires a coding language construct that is, likewise, expressive. This is where this whole idea of fluent interfaces comes from, or so I gather - I’m not saying I totally buy into it though.

So for example, when a (business logic) model says “the software should monitor a specific folder and all its sub-folders, and send an email to Mark if a new file is created” you could write:

string mark = "mark@email.com";
Notifier notifer = (new Notifier()).Monitors(specifiedFolder).IncludingSubFolders.On.NewFileCreation.Then.Email(mark);
notifier.Activate();

Two main prolems though:

  1. fluent interfaces don’t conform to common coding conventions at all (eg properties doing work and not just returning values, or often returning “this” instead of nulls) so are jarring to read for some developers
  2. they aren’t always easier to read anyway (see your regex example), particular if the fluent interfaces aren’t “phrased” as you personally would say them.

Clearly fluent syntax is more concise and readable for simple cases but (in the .Net sphere) with longer initialisation lists, I think the .Net 3.0 object initialisation stuff is arguably better. You also often have to go to a lot of effort with interfaces to make the “sub parts” of the fluent interface hold together.

Cheers,
Mark

I think LINQ is amazing. I particularly like the abstraction of “data”. It doesn’t matter if my data is rooted in an instance of Collection or in a DB table. It’s still just data, and I can query it efficiently with an SQL-like language.

I’m curious, what do you think about the System.Linq.Expressions? Give the post, I’d suspect that you wouldn’t like things like this:

var localCustomerNames = customersList.Where( c = c.City == “Montreal” ).Select( c = c.Name );

Which is equivalent to

var localCustomerNames = from c in customersList where c.City == “Montreal” select c.Name;

I really like the “Expressions” OO-like syntax. Maybe even because of its fluency. I like that “from” doesn’t need to be explicitly stated if I’m using someCollection.Where(…). They’re also nearly identical to the Array#select and Array#collect methods from Ruby, which I’ve grown pretty comfortable with.

IMO, that’s not languages inside languages, but foreign languages. Languages are born to equal.
SQL, RegEx, math operators, HTML, CSS, js, etc, are all foreign languages to Java or C# or whatever.
as well as JVM speaks java, DB speaks SQL, Strings speaks regex, numbers speaks math operators, IE/FF speaks HTMLjsCSS.
JVM, DB, IE are different countries speak different languages.

anyone got what I said?

While in general I agree with you, Jeff, you have to remember that it’s very unlikely that you actually have a line saying “SELECT * from Customers WHERE Country = “USA” ORDER BY CompanyName” in your program. It’s more likely to look something like this:

String sqlQuery = "SELECT " + selection + " FROM " + sourceString + " WHERE " + condition01;
if (condition02 != null) then sqlQuery += " AND " + condition02…

and so on. Your string only looks this obvious and understandable because it’s the RESULT of what are likely going to be plenty of lines of code tinkering it together.

Actually, writing code that reads like English isn’t that difficult:

if (input.is_valid_email() user.is_admin()) { … }

It’s simply a matter of choosing one’s wording carefully. And as Steve Jackson pointed out, chaining method calls is a good way to create a minilanguage when there’s no alternative. Look at jQuery. But again, this must be well thought-out.

Regarding punctuation: if you want it to really look like English, use Ruby. But punctuation is useful: it makes the various parts of an expression stand out. Why do you think the C syntax has been adopted by most programming languages invented after it? Familiarity is just part of the answer.

Regarding the issue of SQL abstraction, I know a better way: just put all your queries in a single module or package. When the time comes to switch databases, all the required changes (many as they might be) are localized. And then it’s your abstraction layer, lean, mean and under your control. Yeah, I know, I’ve been burned by PEAR DB once too many times…

…And no, a webpage doesn’t have to be a mess of PHP, CSS, HTML and Javascript. Not at all.

sorry but I have to say it’s the best post for weeks.

I would have read the whole article, except the straw man BS at the beginning somehow claiming that fluent APIs are considered a valid replacement for regular expressions was just too much of a put-off.

DSLs, ubiquitous language, SQL, regex, mathematical notation, are all useful tools. None of them replaces the other. Sheesh. Hopefully you finished the article up with a “Ha, ha, I was just joking about that dumb regex claim in order to make a point”. I’m not going to bother to look with this one though.

Good post, though I agree with Rob Conery’s comments. SubSonic pre-dates LINQ and utilizes C# as it existed at the time. It’s convenient now with C# 3.0 and LINQ to poke at the SubSonic query syntax especially using an example with four lines of code (when one could have sufficed) though wouldn’t have helped your argument.

SubSonic aside I’ll agree a good understanding of things like Regex and SQL is first and foremost allowing one to better/more fully understand the pitfalls of ORM frameworks.

I’d say take Rob up and do the deep dive here and see what turns up! I’ll be watching for that post. :slight_smile:

The problem with having languages embedded in your languages is that you need to train people to work in both. You’re just extending your feature set that much further. This is one of the problems with C#: it does SO MUCH with its libraries, you need to spend forever learning it. Then, because you have spent so much time learning it, you are tied to it forever.

A language undeniably better and more usable could come around, and the cost of the time you have sunk into learning one language becomes so great that learning another is unthinkable.

Bad idea.

SQL and Regular Expressions are in good spots for sub-languages. They both serve very important and broad-based needs… But if there were, say, twenty things like them (XML aims to be a third, Javascript [in some ways] another, TCP/IP Networking could be another, as could Cisco’s OS, etc etc etc…) that were all completely necessary, you would be unable to become skilled at actual production of code.

There seems to be a substantial amount of confusion around SQL. All of my web-apps have used “SQL” and I develop on MySQL, and many of my clients run PostgresSQL, and even MsSQL yet I have never had a complaint of the app not working. If you don’t use DBMS specific code then your SQL queries will run on most any SQL based server.

I’m so easily annoyed by small details. In:

a.valueOf(b.plus(1).times(a.pow(2))

you’re missing a “)” at the end. However this error only proves your point.

Ahhh. Remember Cobol:

Subtract X From Y Giving Z

So beautifully verbose, one line would take 10. Easy to read if you enjoy a 5,000 page novel.

So poorly optimized. It took forever to run.

Then there was APL

Z-Y-X

5 characters (That’s a left arrow). X, Y and Z can be any object type, including vectors, arrays and multi-dimensional objects. With it’s powerful yet succinct operations (e.g. Y+.*X is sumproduct) allowing those who have nothing better to do to write “any” program in one line (with a few tricks), albeit a very long line.

So beautifully condensed, getting that 5,000 page Cobol novel onto one page. Yet impossible to read.

Could only be interpreted and not compiled. It took forever to run.

Neat, I always like when I disagree with your blog posts, mostly because it happens so rarely and it reminds me that you really are just some guy with opinions :slight_smile: Usually good opinions but just opinions none the less.

I feel you missed a big point of Joshua’s blog post, that he is attempting to make code more readable and maintainable. Given the size and complexity of projects I’d rather see more lines of code if they make it easier to understand what’s going on. If I need to tell if I regex is bad his method is more discoverable while a pure regex sucks horribly if you’re not a regex guru. Now I happen to think simple regex aren’t that hard to read but I get his point and I agree with it, same as I agree with SubSonic’s Query object or the fluent testing API’s that are out there.

I will take maintainable and readable code that is expressing intent any day over saving a few lines of code. I will also take a discoverable interface over one that needs a seperate help document. There is nothing to jog my memory in the IDE when writing a regex expression, I have to go hunting in the tubes for the right syntax yet with Joshua’s interface I can quickly discover/remember my available options. No, it’s not perfect and I may or may not use it but his intent is spot on and I agree with anything the promotes it.

Jeff, come on! Are you jumping the shark as well?

First a disclaimer - I DO know SQL and regular expressions. I’ve used them a lot and I hate them from the bottom of my heart. I have cried almost on every encounter with them. End of disclaimer.

Fluent interfaces are pretty nifty IMHO. I wish there was no other way to program. The code gets a lot more readable and even sounds like English. Heck it even looks like SmallTalk :slight_smile:

Regular expressions are a big pile of mud when it comes to readability. No doubt they are your first choice for text processing but still their syntax sucks. Please don’t give regular expressions as a good example of integrating domain specific languages.

I don’t know why you prefer LINQ over SubSonic’s query language. LINQ is yet another abstraction on top of SQL. It just uses some syntax sugar to make it look like SQL (admit it, the syntax highlighting is the thing which turns you on). However LINQ only resembles SQL - for example the whole statement is spelled backwards “from abc select cde” where in SQL it is “select cde from abc”. LINQ however is helluva better than plain concatenated SQL strings hammered against the poor database.

Attacking Rob Conery (and SubSonic) was not a good move at all. Let alone politically correct. I’ve been aggregating his blog for a long time and have never seen a bad word in your direction. Why did you attack him, Jeff? jokeAre you being jealous that Microsoft will start paying Rob to work on his open source project?/joke

Your blog is really jumping the shark IMHO. Please make something to prevent this. One more “3 monitor rox0rz” post and I will ditch it for good. And I don’t want to do that - I’ve been a long time fan.

Another point Jeff,

Using domain-specific languages is always a good thing. This is the reason why we see languages like Erlang are touted more for concurrency programming than hacks like OpenMP.

The problem of domain-specific languages is trying to integrate them with core languages like Java, C/C++, etc. Which is always a pain.

I agree with the examples given, but I think Rails (and to some extent Ruby itself) definitely gets this fluency thing right.
It is much nicer to write:
if my_date 2.days_from_now
than it is to do the equivalent in Java.
Even little things like my_array.first and my_array.last are much more readable coming into a project than myArray[0] and myArray[myArray.size()-1]

Funny, I look at the examples given and come to the opposite conclusion.

First show a regex expression which is completely unreadable to anyone not versed in regex’s, compared it to a test interface that makes it into something readable by any competent programmer.

Then you show a trivial line of sql code (yet still so non portable that won’t work on any of the databases I use) and compare it to a more verbose interface that will at least work, and return data to the program.

If you want to argue against fluent interfaces, at least pick a good example. How about a sql example using user entered parameters running against an arbitrary database. Once you start doing that, your one line of sql starts becoming several lines of conditionals, parameters, and concatenations. And you are still embedding sql in the middle of your app.

Linq is nice, but it is .net only. Those of us who aren’t writing our own compilers can’t add Linq to our language de jour. We can however add fluent interfaces.

Your post has inspired me though, I am going to add a fluent interface to my favourite persistance layer.

Totally agreed.

and LINQ sure is beautiful!

Question: do you actually use any kind of ORM, at all?