Embracing Languages Inside Languages

Jeff,

I think Jon Galloway makes good points. If I’m not mistaken, in the .NET world, SQL is best handled by leaving the queries on your SQL Server and using parameter calls to prevent injection for best security and performance. In the land of Java, Hibernate uses HQL (a bastard version of SQL) that is server agnostic and currently the defacto standard.

As for fluent languages, I’ve read a bit of Fowler and I think he pushes for Domain Specific Languages as a whole and his argument generally points toward the business (or domain) that your computer language isn’t made for. If you’re handling invoicing, you don’t have a language command for ‘invoice.generate()’ or GENERATE INVOICE or whatever. Martin has been playing lately with products like ANTLR and some other compiler-compilers to add domain specific (or business specific) keywords to the language that makes a ‘language within a language’ for an application. He argues that it makes the development of the application fit the model and development much more rapid. If one doesn’t customize the actual structure of the language, then you can develop the API set. But his point is about the nomenclature that is used amongst developers, customers, consultants and analysts that must be specific to the domain and that there are no languages (regular expressions, SQL, Java, C#, Ruby) that speak Mining, Accounts Payable, NASA, or whatever.

I don’t know if I’m sold on his ideas, but for the moment, I’ll evangelize for Mr. Fowler. More on his blog…
http://martinfowler.com/bliki/DomainSpecificLanguage.html
http://martinfowler.com/articles/languageWorkbench.html
http://en.wikipedia.org/wiki/Domain-specific_programming_language

I really don’t think its fair to offer up my experimental (I’ve never used it in production code) ReadableRegex as a representative of fluent interfaces as whole. I was attempting to solve a well-acknowledged problem of regexes being hard to read. If I did not succeed in this instance, it is no reason to dismiss fluent interfaces for other applications.

Try looking at the Rhino Mocks tool which I refer to in my post. Compare its fluent interface to what the calling code would look like if it did not use a fluent interface.

I’m surprised that no one has talked about the fact that SQL itself is just another abstraction. Databases don’t naturally “speak SQL”. SQL was designed as an abstraction on top of what used to be proprietary libraries for getting at data. It is a “non-standard standard” of sorts. For example, Progress has its own proprietary language for getting at data and only supports SQL as an afterthought in my opinion.

So it is possible that some day LINQ may be considered the most common way to get at database data and some blogger will be ranting about how the technologies after LINQ are just embedding the LINQ “language inside a language”.

Maybe it’s just a phase wanting to use the massively-long-object-oriented stuff, I certainly went through something similar. Also, regarding regular expressions, I’ve found so many people to be so unimaginably fearful of parsing in general that it doesn’t surprise me they’d want something with a little more cush.

Wow! You use a Perl example.

I do most of my programming in Perl and have heard all the arguments against it. This includes “It’s not object oriented.” and “It’s unreadable.”

Some of its reputation of unreadability comes from contests where people purposefully write obfuscated code (my favorite example is http://99-bottles-of-beer.net/language-perl-737.html). However, most of Perl’s reputation for unreadability comes from handling regular expressions.

However, Perl’s ability to handle regular expressions is unsurpassed. I’ve switched to Ruby and PHP recently, and I find their regex syntax handling almost impossible to read. The example you gave is even worse.

People also complain that Perl is not a “real” object oriented programming language, but merely pastes object oriented techniques on a functional oriented language. So what? OOP is a technique and can be used in almost any programming language (I think APL is probably the lone exception). Some languages have built in support for OOP, but that doesn’t mean you can’t write good OOP style code in a language that doesn’t include OOP syntax.

The other thing I have to point out is that OOP is not a religion, but a tool. If writing OOP code makes your code more readable and more easily maintainable (as it usually does), then go for it. However, if you’re just wrapping everything in object classes just to make it OOP, then you are probably making the program harder to maintain, slower, and harder to read.

I worked on one project where the developers spent almost 2 years designing all the objects that the program would use. The project became obsolete and was canceled before a single line of usable code was written.

Jeff,

If you take the specific syntax out, it sounds like you’re advocating Lisp. :slight_smile: The trouble with Lisp, though, is its total lack of syntactic cues.

A language with conventional syntactic cues that allowed you to write mini-languages within it - and those with their own syntactic cues - would be a very cool thing. Does anybody know of one?

Your post implies that Fluent Interfaces and APIs to abstract out interfaces to other systems are the same thing. Your real beef seems to be against APIs that are more complicated than the complication they are supposedly abstracting which really doesn’t have anything to do with Fluent interfaces.

Fluent interfaces are just an API design methodology and could be applied to any API not just those that happen to already have a Domain Specific Language written for them. A good example that was mentioned above is much of the stuff in Rhino Mocks.

I think it should surprise no one that a Domain Specific Language that was designed to address a particular domain(Relational Databases or String Matching) are easier to use and more expressive than an interface that was built on top of and with in the constraints of a general purpose programing language.

I understand the sentiment behind your statements, but in practice, I totally disagree. As far as I can see, your main point is something along the lines that programming should be as simple as possible and that we are just overcomplicating things with all of this object model / code generation stuff. Why should we use all of these objects when we can just read the data into a simple table-like structure (a DataReader) and go at it from there?

The problem is that “going at it from there” is the most difficult part of all. In your SQL example, you totally left that out. The Subsonic example feeds the data into a strongly typed collection that can be easily manipluated via the object model. This means you can do things like traverse tables, rows and fields by simply iterating through collections of objects. In many cases, you can make one initial call for data, and then get to all related data (in related tables) just by traversing the object graph. Try to do that with simple select statements and a DataReader.

I have been using an ORM consitently for over 2 years, and I cannot live with out it anymore. I use LLBLGen, which I personally like a lot, but any good ORM will do. Here’s one simple example of why an ORM can be so much better than hand crafted SQL and DataReaders:

int customerId = 123;
CustomerEntity customer = new CustomerEntity(customerId);
Console.WriteLine(customer.Name);

foreach (OrderEntity order in customer.Orders)
{
Console.WriteLine(order.OrderNum);
}

In just that small amount of code, I was able to pull up a customer record and print their order info. Hand crafted SQL would make all of that take SOOOO much longer. Sure, ORM’s have their limitations, but working around them is well worth it. The biggest issue is that learning an ORM to begin with is kinda hard (like learning regex’s), so people tend to dismiss them as being “too complicated”. Sure, they can be, but not always, and the ones that are well written make programming way easier, not more difficult.

Jeremy

Jeff,

I agree with your example on regular expressions. The regex explosion is just hideous, although as one commenter noted it is quite easy to figure out what is going on for the non-regex fluent. On the other hand, I am a fan of ORM.

In either case, I don’t think these two indict fluent interfaces as a whole.

I’m perpetually disappointed (read: irritated) by all these fluffy abstraction layers that seem particularly dominant in the Free Software / Open Source worlds. We have gobs of processing horsepower at our disposal, yet we keep creating more work for the developer rather than the machine. I already know a couple dozen languages, why should I be learning a hundred different DB interfaces ?

What I like to see is “invisible magic”, the kind of function/object that will take generic input and do whatever it takes to make it work on the platform. Say the app is designed on MySQL, but some unfortunate chap tries to run it on SQL Server (or PG), why can’t there be some nice glue code that adapts the SQL string and/or return values to be consistent on any backend ? We have DB abstraction libs, but they all present their own slightly different interface; well if someone went through the hassle of designing a new interface, surely they could have had the time to write an SQL parser that handles legacy queries with a smile.

I think the root of the problem is that many people do OOP, but very few people actually think in high-level constructs, they just use OO everywhere without the slightest iota of applied logic. Me, I like a program that acts like a good assistant: you give it a simple job, and it comes back with the result without having to teach it every stupid little thing. That’s why my apps have imperative-style funcs like “GetList(‘employees’)”. I don’t even want to see “select * from employees” unless I’m explicitly writing that utility function, and I should have to do that only once.

In the end, almost all business apps do more or less the same thing, the entities have different names and relationships, but the bird’s eye view is the same: Get data, get related records, sort and print, with an update thrown in once in a while. That sort of thing shouldn’t need a half-dozen mini-languages to get the job done.

I’ve tried abstracting my SQL data into some self-made classes. It turned out to be more pain than it’s worth.

If you’re going to abstract SQL, it should be for portability or DRY reasons, not because you don’t know how to write SQL. If you can’t write an SQL statement then you need to go back to whatever 2-year IT school pumped you out and ask for your money back.

Interesting post, but I disagree in many respects. I like the idea of combining the languages into one clean coherent statement structure, but I think it’s ridiculous to say everyone should know all these other languages. Ideally it’s nice but not exactly practical. This argument reminds me of the old cliche instance of some programmer saying “real programmers use vi/notepad and don’t need those fancy editors”. Just because I want to write an application that talks to a database, should not require me to know the inner workings of that database or how it communicates. This is exactly the point of object wrappers, to abstract such details. The point another poster made about differences in SQL is especially relevant. I will agree that it is good practice to know how all these different things work, but realistically that is not most programmers out there, and as systems become more complex it will become more and more rare. As far as regexps go, you are one of the few people I know that think these things are simple. They are powerful and I love them for that, but I also hate them. For what they accomplish they are a pain in the butt and very much a voodoo art that those familiar with them will often describe as “simple”, however, there are many developers out there that look at regexps and think “wtf?”. I’m glad to have regexps at my disposal and they are useful but they could stand to be significantly improved. Just because you are familiar and comfortable with a cryptic syntax, does not make it a good one.

“If only someone could fluently resolve the mess of PHP, CSS, HTML and Javascript (cringe) that form a webpage…”

It’s been done … Curl http://www.curl.com/products_platform.php
…But it wasn’t adopted because no-one supported it

I guess they don’t teach lex and yacc anymore.
When was the last time you saw a cs grad that was able to write a parser, or a compiler?
Personally, I’ve written a bunch of parsers, some based on lex and yacc, some not…

I think that a thorough understanding of this subject should be a REQUIREMENT for every cs degree.

Maybe then we can get rid of this silly attempt to dumb-down code for things like SQL or hypertext…

All the arguments about regex I have no problems with, use regex’s the way they were meant to I see very little argument for abstracting them.

However I am really stuck on an abstracted db layer because without you cannot develop a truely agile application. SQL can and should be broken down into its simpler concepts so that the code can be reused, also you should not under estimate the benefits of projects like sql alchemy (python), qcodo (php), propel(php). They save developers a significant amount of time and as far as I have seen sometimes evenn write better SQL than most people because thats what is was made to do.

“I was attempting to solve a well-acknowledged problem of regexes being hard to read.” – Joshua Flanagan

That’s a “well-acknowledged” problem? Not by me. Here’s a “well-acknowledged” problem:

Working with something you don’t understand is hard.

Having trouble reading a reg-ex? Here’s a tip: learn reg-ex syntax. Problem solved.

LINQ? not sure I am a fan of the idea of it. I started with old asp and embedded SQL into it; i found out about the pitfalls of this then I moved to .Net. NTier development followed shortly after.

When SQL is embedded into an app (be it at the business object layer or higher) you couple the tiers too tightly, what if someone changes the database schema? is it feasible to expect a recompile of the application? if you were relying on the stored procs then you just release a new stored proc and the app still works.

Yep, that’s true. I believe that metaprogramming and DSL will make the future of the programming languages, since these technologies allow to integrate the SQL/Regex in the natural way

Steve - if your point is “I’m a better programmer than you because I can instantly grok a regex string”, then you win.
My point was never that I do not understand regexes or how to read them. Don’t you think I would have had to learn reg-ex syntax as a pre-requisite to writing the fluent interface wrapper? It was never intended as a wrapper to make it easier for “lesser” programmers to create and read regular expressions without having to learn regex syntax first. I agree - everyone should learn it.
My goal was trying to make it easier to read. I can read any regex you throw at me, given enough time. I do not have the ability to instantly translate all of the 1/2 character symbols into the language that I think in. If you can, this library was never intended for you.

Maybe I’m missing something listening to Jeff up on his soap box again, but isn’t the entire purpose behind using Objects/APIs the downline portability of it?

One of the things I personally have recently noticed going from SQL 2000 to SQL 2005, is that not all of my queries work the same way. If I have hard coded my SQL all over the place I have many points of potential failure. However, if I utlize an object based API then I should be able to update the API to ensure it works with SQL 2005 and not have to change all my SQL statements throughout my code.

Isn’t that the entire purpose of OO programming?