Embracing Languages Inside Languages

Come on, tell me I’m not the only one who read that as “flatuant interfaces”? :slight_smile:

(I obviously can’t type either): flatulent

First of all, if you want to make an apples to apples comparision and you’re looking for terse code, you shouldn’t use the fluent interface:
IDataReader rdr=new Query(“Customer”).WHERE(“Country”, “USA”).OrderByAsc(“CompanyName”).ExecuteReader();

As Rob pointed out (and we talked about on Saturday), there’s a big difference between your simple SQL statement and what SubSonic’s doing. A big difference is database independence.

The point of multiple database support isn’t that you’ll be moving a single application between databases, but that once you get good at SubSonic, you can easily write robust data access code that works on SQL Server 2005, SQL Server 2000, Oracle, MySQL, SQLite, etc. Today on a biz-dev call, the client mentioned MySQL support and I didn’t flinch, because even though it’s been a few years since I wrote a SQL statement in MySQL, I know I can do anything I’d need with MySQL right now without worrying about how it handles paging, sorting, datatypes, etc. SubSonic’s MySQL provider was written by a member of the MySQL team and has been tested by thousands of users, while you’re writing new MySQL queries from scratch.

That’s a selling point for Linq, too - instead of using a different syntax (SQL or object) to query everything, we use standard Linq syntax which works everywhere.

A bigger issue is the use of untyped datareaders. I never use an untyped datareader in SubSonic. I use a strongly typed collection:
CustomerCollection col = CustomerCollection(“Country”, “USA”).OrderByAsc(“CompanyName”).Load();
Now I can use a strongly typed collection of Customer objects, while you’ve got a dumb, anonymous blob of data.

I see your point in a “blue sky / wouldn’t it be nice” academic argument, but it’s not useful beyond that. You can’t really be suggesting that we embed SQL statements in our code (SQL injection alone is a good enough counterargument there). It’s just not a systainable way to write real world applications. I’ve got plenty of battle scars from poorly written data access code built on embedded SQL.

So, then, we need to write some sort of data access utility. Once we’re doing that, does it make sense for every developer in the world to write their own, untested data access code - especially when you’ve established that a lot of developers have trouble with FizzBuzz? I’d prefer to work with a data access system written by some of the best developers I know.

And, really, recommending embedded SQL (in if it’s just to make an academic point) without some heavy disclaimers is kind of irresponsible. How many developers do you estimate will take this as best practice advice and move to (or stick with) embedded SQL? If it’s one, it’s too many, and my guess is that it’s a lot more than that.

Oh, and the Linq thing. It’s true that it looks prettier, but it’s only because of compiler magic. I could make SubSonic queries look really pretty if I owned the compiler, too.

Under the hood, you’re working with object which look a lot like SubSonic query objects:
IEnumerableCustomerTuple locals =
customers.Where(c = c.ZipCode == 91822)
.Select(c = new CustomerTuple(c.Name, c.Address));

The compiler and IDE allow you to express that as:
var locals = (from c in customers
where c.ZipCode == 91822
select new { c.Name, c.Address})

However, it’s important to not that you’re still calling through objects and fluent interfaces, it’s just hidden behind the scenes.

http://msdn.microsoft.com/msdnmag/issues/07/06/CSharp30/

“In The Land of Strings, we speak regular expressions. In The Land of Data, we speak SQL.”

Haha, I love this quote. Mind if I steal it?

LINQ is awesome. I’ve been all over that since the first CTP, and now that Orcas actually provides Intellisense for it, I can say pretty confidently that it blows every other ORM tool out of the water. I do wish it had slightly better support for the UD in CRUD, and it would be nice if XLinq was as clean in C# as it is in VB, but eh, nothing’s perfect.

And as Eric says, you can use these SQL-like operations on any IEnumerable. So if - for example - you’re getting data from a web service instead of a database, you can treat it almost exactly the same way. That is a true “fluent interface”, making PROPER use of object-orientation to make an actual abstraction rather than a useless wrapper. Although I suppose it’s a little easier to do this when you also make the compiler. :slight_smile:

Jeff,

Never forget that SQL itself is merely another example of what LINQ is doing - it embeds the Relational Calculus in a data management language. And Codd is on record that it does it badly.

I can see a need for abstraction of the database for some solutions as they will need to be database agnostic, but as as whole, the more abstractions the harder the code will be to debug and follow, even if it is in “API” like syntax. And, it will be slower. Plus it is very easy to implement different database versions with an interface and implementations of the interface.

Interface GenDB
Abstract GetCustomers()
Abstract GetSales()

SQLServer : GenDB
GetCustomers()
//SQL Server SQL to Get Customers

Oracle : GenDB
GetCustomers()
//Oracle SQL to Get Customers

Pretty simple. Add another DB, implement the interface.

If I use SQL, I can debug the code to where the SQL is being generated and cut and paste the SQL in to a query analyzer (toad, etc) type of tool and check to make sure the SQL is working as expected. LINQ, where’s the SQL? It’s in LINQ somewhere, so now another layer to figure out where the problem is. The problem will be that everyone will start using LINQ instead of just issueing a query to the database.

There definately seems to be an “abtraction movement” to generalize everything, but in my experience abstractions can lead to a very unclear picture to what is really going on in the code. Some of us would like to know what is going on rather than relying on faith of an API call.

The dumbing down of programmers continues. Programmers of the future will not be known as software engineers, thier titles will be “object abstraction monkeys”.

I realize this is a general post on how great it is to throw untyped strings into your code, but I it’s worth pointing out reason for the bias many people have against a data access layer: you tried one before and you didn’t like it. It didn’t add value, it got in the way, and you ended up wishing you could just get at your data instead of messing with some wacky wrapper. Your data access layer caused extra work, and didn’t really help.

Here’s something you might not have considered: it’s not data access layers, it’s you. You screwed up - you built or picked a dumb data access layer, then decided data access layers are bad. Nope, it’s you.

http://blog.wekeroad.com/2007/10/09/unleashing-elmer-fudd/

People seem to have missed one of the most used (and IMHO very useful) fluent interfaces… C++'s iostream . Who among us is not familiar with the code:

cout “Hello World.” endl;

Fluent interfaces have their place, as do embedded languages. Though I have to admit that I’ve seen some JSP code (and PHP for that matter) that would cause any programmer to run away screaming. It’s the constant switching between languages (HTML and Java) that can really get you.