and then the compiler inserts the applier—in this case, invoke.

If you look under the hood, the difference between object-oriented programming and functional programming is not that big. It’s not some weird Frankenstein monster. It really blends very nicely, and that is because under the hood it just fits. TC You’ve both been talking about layers of abstraction and the fact that there are these new layers in the software. This is often challenging for programmers when they try to performance-tune or debug systems, because now there are these perhaps quite complex layers of software sitting underneath their code, and what those layers of software are doing can matter to them from a debugging or performance-tuning perspective.

We use NHibernate where I work, and we’ve found that even though we can see what the plans for the queries are, sometimes it’s difficult for us to understand how what we did at the level of NHibernate turned into this series of queries that we now see coming out the bottom. From a tuning perspective, we can say, “OK, I can see that I want to change this, but what do I do in the programming language to actually make that happen, because there’s a layer in between now and we’re not sure what it’s doing?” Is that a concern for you? Are you doing anything in particular in the context of LINQ and the Entity Framework to help make those layers more transparent or to enable the developer to inspect them? JB One of the problems in NHibernate is that the mapping and the programming binding are all bundled together. The specific algorithm that is used, for example, to map a particular expression to inheritance is known only by somebody who deeply understands the way in which Hibernate has been implemented. That is not the case in the Entity Framework, where the mapping between tables and high-level concepts, entities, and relationships is defined declaratively through mapping view expressions. It’s a view layer, so every single semantic concept—entities, relationships, inheritance hierarchies— is defined formally in terms of database views so there is always a declarative mapping layer that the developer has full control of. As you’re developing your entity data model and the mapping to the underlying relational model, the actual mapping is described openly in terms of views. There is much more transparency in the way in which the mapping operation is happening. That helps the user in case there are problems.

For example, if your system supports inheritance, some application developers may define very deep inheritance hierarchies. Mapping very deep hierarchies becomes

very complex, so when developers see the kind of view expressions that are generated to map that deep hierarchy, they may realize that they should review the depth of the hierarchy and use a different kind of mapping. TC I understand that having the mapping materialized as views certainly adds a layer of transparency to it, but even so, as a programmer you would have to have a reasonable knowledge of what is going on with that. For example, if you have a deep inheritance hierarchy, that’s typically going to show up as a deep set of joins to pull together the data from the multiple tables in order to create that finalized entity. But unless you understand that, unless you have a sophisticated understanding of the fact that inheritance and joining are related to one another, it’s going to be difficult for you to improve the performance of those things. Is it possible to create tools that help the programmer more directly understand the connections?

It would be nice to have something that would tell you that this portion of the LINQ query is associated with this portion of the SQL that’s coming out the bottom. The programmers don’t have to deduce it because the system is actually telling them what’s going on there. EM Let me give you a two-part answer. People probably will now say, “Oh, Erik is just an academic.” But the thing is, if you look historically, the kind of concerns that you raise have always been there whenever a new level of abstraction is introduced. When we moved from assembler to higher-level programming, people said, “I don’t have all the control that I have on the assembly language level and I don’t trust the compiler to do it, so I want to look at the assembly.” How often now when you’re writing in high-level languages do you look at the assembler code that the compiler is generating?

Over time, as the mapping from the abstraction to the next layer down gets better, this concern will go away and the tools will get better and people will get a better feeling of what’s happening. The points you raise are valid, but I think it shows that we are very early in this game. We’re just introducing this level of abstraction and people are not used to it, and the tools maybe are not very mature. That’s where these concerns come from. TC Where are developers going to get tripped up in LINQ and the Entity Framework? We have some new technologies here, and they’re introducing relatively sophisticated layers of abstraction. When developers start working with these things and maybe haven’t had a lot of experience with persistence or with databases or other things like that, what should they be careful of? Where should they be looking to avoid falling into problems? EM I can give you a concrete example. When you’re

References:

http://www.acmqueue.com

Archives