Hi - not at all a "dumb question".
> Has there ever been a general discussion about how close NH's LINQ
> provider actually _wants_ to be to LINQ to objects?
I do not know whether such a discussion + results has been done.
My contribution are (few) conceptual texts about expected semantics / behavior
with examples - see the one I attached to the jira entry, where I argued that
one should in principle stick to Linq2Objects semantics. However, Patrick is
convinced that we should another semantics ("pure outer join semantics" or
(||-4)-semantics in my text), for which I have not yet written an explaining
text ... but I certainly will.
> In any case, 100% compatibility to LINQ 2 objects is an illusion. You'll
> never get there, so you might as well not try.
May I suggest that you read my text at the jira entry where I argue for
various, *defined" deviations from LINQ2Objects? The main idea I had is that
for all cases where LINQ2Objects does *not* throw an exception, the behaviors
are identical; and this *is* feasible at least for navigation and the &&, |, !,
and Any operators. It depends on what you mean by "illusion" - but as both SQL
and Linq(2Objects) semantics are precisely defined and strong enough, it is
certainly possible to have 100% compatibility at least under my (BEHAV-3) rule.
Still, especially performance arguments might make us agree that a differing
semantics is better for all practical purposes - which is why Patrick suggested
a different, deviating (also from Linq2Objects' non-exceptional behavior)
semantics, which I now try to implement for the logical operators (I'm almost
there ...).
> Consider the typical
> NullReference problem:
>
> a.b.c == x
>
> What's this code supposed to do if a.b is null? In C#, you'd get a
> NullReferenceException. Do you want the same in SQL? Why?
See (BEHAV-1) ... (BEHAV-4). Other possibilities are Patrick's "Copy EF
semantics" or your suggestion "Copy Linq2SQL semantics" ...
> My suggestion is to copy the behavior of LINQ to SQL and stay as close to
> SQL as you can, because that's easier to handle for the user, and less
> likely to bring surprises.
... but both these suggestions obviously have the problem that there is no
useful definition of these semantics and, especially, their design targets
(e.g., do they want to follow de'Morgan's laws everywhere - so if they don't,
it's a bug?).
Moreover, I would strongly argue that NHibernate should NOT duplicate one
behavior of Linq2SQL which I cannot qualify other than "very weird", namely the
null-constant vs. null-in-a-variable anomaly: (In some version - I did not look
recently) Linq2SQL creates SQL
P IS NULL
from Linq
...Where(x => x.P == null)...
but it creates
P = NULL --- which is never true
from
SomeType nullVar = null;
...Where(x => x.P == nullVar)...
And because I do not believe that the Linq2SQL semantics is consistent (i.e.,
not contradictory), we should also look at certain conditions, e.g. those with
!Any ("not any") - these are classical examples where OR mappings fail (because
some people assume erroneously that "Any" can always by evaluated with joins
and no sub-selects ...).
Also, AFAIK, Linq2SQL can only handle the "table per hierarchy" strategy for
inheritance - and we would certainly not want to duplicate *this* limitation in
NHibernate.Linq, wouldn't we?
So, it seems to me that some people ("you"? "we"?) still need to define (parts
of) NHibernate.Linq's semantics better so that it is clear
* what constitues a bug (a deviation from that defined semantics); and
* what is a feature (a designed deviation from Linq2Objects semantics).
And in the course of this discussion one would also establish design targets
(at least all the meta-rules from logics - like de'Morgan, neutrality of
contradictions for || and tautologies for &&, associativity etc.), as these are
fundamentally used by all programmers to argue about correctness of and find
bugs in their application code. Therefore, I completely agree with you on the
following:
> In any case, there needs to be a clear and concise documentation for
> translation results. It's just a language that you need to learn before you
> use
> it. If one has to look up everything in unit tests or try it out, or even
> memorize many inconsistent cases, LINQ becomes a burden. A wiki page will
> do. A reference to unit tests won't.
And I'm quite sure that such a definition needs
(a) (many...) examples
(b) but also a discussion of the "meta-rules" mentioned above - e.g., do we
want de'Morgan to hold (as it does in propositional logic, C#, and SQL) or not?
do we require that "false" (or any contradiction) is a neutral element for || -
i.e., that we always have P || false exactly if P? etc.etc.
[The problem with such rules is that they may have consequences that are not
immediately visible: contradict each other; or contradict the wanted behavior
of some examples ... but this is well known to all that work in logics. If you
are interested: try to invent all possible consistent 4-valued logics; and for
a "very meta" problem of that sort, read about "material implication" and
"strict conditional"].
Anyway, yes, you are right, such a discussion - certainly including
proofs/arguments of wanted / not wanted properties of the ensuing logic - plus
documentation is a good thing!
> Just my two cents.
Your text was, IMHO, more than that :-)
Regards
Harald
--
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl