From the options Fabian has listed here
> I've listed our options together with a more elaborate explanation
> here: http://www.re-motion.org/blogs/mix/archive/2009/10/16/vb.net-specific-text-comparison-in-linq-queries.aspx
I believe #3 would be a good solution for string comparison.
> 3. Define generic text comparison expression node types and replace
> the MethodCallExpressions with instances of those types.
There is a finite set of conditions on which the comparison-result can depend: null or empty, case, and culture.
This means we can define a StringComparisonExpression that should be to express anything a future language might come up with that's natively supported in the dotNET framework.
Stefan said:
> Since we don't want to mess with the perfectly fine C# expressions,
> every provider will have to handle two distinct types of expressions anyway.
I'm not convinced that we would have to do that. There is no reason _not_ to mess with the C# syntax if we can provide a complete StringComparisonExpression because the C# syntax provides no benefit when implementing a linq solution.
As for option #5:
> Implement support for language packages, i.e. plug-ins for re-linq
> that encapsulate language-subtleties and their processing.
To me, that's an orthogonal concept to string comparison. Yes, you can implement string compare individually for each language, but I don't believe that's necessary.
Michael
Yes, I'm also leaning towards that approach. We would leave the
"default" case (C#'s semantics) as is (BinaryExpression.Equals), and
add StringComparisonExpressions for specific comparisons. We'd use the
StringComparisonExpressions for both VB.NET and calls to the various
String.Compare overloads.
(BTW the set of conditions is not so small, see
System.Globalization.CompareOptions...)
Architecture-wise, I'd say we should introduce an additional
expression tree transformation step executed during the structural
parsing phase - after partial evaluation, but before the individual
top-level nodes such as Where or Select are parsed. That step will be
used to perform the substitution (and will be used to perform
additional substitutions in the future). We should also add a
VisitStringComparisonExpression method to ExpressionTreeVisitor and
ThrowingExpressionTreeVisitor.
Cheers,
Fabian
>
> Stefan said:
>
>> Since we don't want to mess with the perfectly fine C# expressions,
>> every provider will have to handle two distinct types of expressions anyway.
>
> I'm not convinced that we would have to do that. There is no reason _not_ to mess with the C# syntax if we can provide a complete StringComparisonExpression because the C# syntax provides no benefit when implementing a linq solution.
>
> As for option #5:
>> Implement support for language packages, i.e. plug-ins for re-linq
>> that encapsulate language-subtleties and their processing.
>
> To me, that's an orthogonal concept to string comparison. Yes, you can implement string compare individually for each language, but I don't believe that's necessary.
>
> Michael
>
> --
> You received this message because you are subscribed to the Google Groups "re-motion Developers" group.
> To post to this group, send email to re-mot...@googlegroups.com.
> To unsubscribe from this group, send email to re-motion-de...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/re-motion-dev?hl=en.
>
>
>
>
Is this even a decision we have to make? Who would be responsible for
triggering the comparison-replacing visitors? They could also decide
whether to trigger the C# replacers or not.
> > For more options, visit this group athttp://groups.google.com/group/re-motion-dev?hl=en.- Hide quoted text -
>
> - Show quoted text -
> Are you two sure you agree? I read that Michael wants to replace C#
> comparisions too, and Fabian doesn't.
No agreement. Yet.
> Is this even a decision we have to make? Who would be responsible for
> triggering the comparison-replacing visitors? They could also decide
> whether to trigger the C# replacers or not.
Possibly...
Fabian said:
> (BTW the set of conditions is not so small, see
> System.Globalization.CompareOptions...)
Right. On the plus-side, though, we can use the enum-type in the StringComparisonExpression and still have a stable interface until MS adds another option to the enum.
Michael
Sorry, I misread that. (Actually, I read a different e-mail, but whatever...)
Okay. I'm for keeping the C# comparisons because:
- It's standard: The C# compiler creates a BinaryExpressionNode with
NodeType Equals for all comparisons that invoke a custom equality
operator ("operator ==" in C#). The C# expression "s1 == s2" (s1 and
s2 being strings) results a custom equality operator
(string.op_Equality) being invoked, just like "dt1 == dt2" (dt1 and
dt2 being DateTimes) does. Therefore, the C# compiler creates the same
BinaryExpressionNode. That's logical. If we changed it, we'd violate
expectations (IMO) and we'd add an additional burden regarding
documentation. I'd like to keep the number of surprises as low as
possible.
- It's a non-breaking change.
I wrote that I was inclined to take option 3 rather than 4 because I
liked the idea of having a generic string comparison expression
allowing you to deal with VB.NET and String.Compare at the same time.
If there were a CompareOptions value with the same semantics as
defined by VB.NET, I'd immediately go that route.
OTOH, there isn't - String.Compare doesn't seem to allow you to mimic
VB's behavior (other than hand-coding the null/empty checks), so it's
really a VB-specific expression. And don't forget that there are other
VB-specific operators as well, the
Microsoft.VisualBasic.CompilerServices.Operators class has about 30 of
them. If those need to be retained as well because of their specific
semantics (and I fear they do), that would make option 4 the more
sensible option again.
(BTW, there's actually an option 6: replace it with a standard
expression tree that has the same semantics. But I'd rather not do
this by default in order to give the re-linq user as many choices as
possible.)
I think before making the decision, I'll have to check out some sample
expression trees generated by VB.NET. I'll do that as the first step
of adding VB support to re-linq when I schedule that feature. (Unless
somebody else volunteers for the feature, of course.)
>> Is this even a decision we have to make? Who would be responsible for
>> triggering the comparison-replacing visitors? They could also decide
>> whether to trigger the C# replacers or not.
>
> Possibly..
Yeah, we could also implement opt-in VB support; but actually, I'd
prefer if it worked out-of-the-box.
>> (BTW the set of conditions is not so small, see
>> System.Globalization.CompareOptions...)
>
> Right. On the plus-side, though, we can use the enum-type in the StringComparisonExpression and still have a stable interface until MS adds another option to the enum.
Too bad the CompareOptions enum doesn't include that "TreatNullAsEmpty" flag.
Regards,
Fabian
Good point, but how surprising would it be for the unsuspecting provider author that their provider just doesn't work for VB users? Some conscious decision needs to be made here by the provider author.
> >> Is this even a decision we have to make? Who would be responsible
> >> for
> >> triggering the comparison-replacing visitors? They could also decide
> >> whether to trigger the C# replacers or not.
> >
> > Possibly..
>
> Yeah, we could also implement opt-in VB support; but actually, I'd
> prefer if it worked out-of-the-box.
That's just a matter of defaults. I.e., the default setting could just leave C# expressions alone but replace VB expressions according to option 4 or anything else. If the provider overrides those defaults, it could either leave it all alone, replace everything (including C#) with generic operators in order to avoid double implementations, replace everything with standard operators (and just lose language semantics) or whatever.
There might even be different sets of language-specific visitors in order to provide a choice of semantics. E.g., one user might prefer operators to be translated to SQL literally, while others might want to keep the language semantics... without touching the provider. (Yes, dangerous, but we'd just provide the entry points.)
Also, users could trigger their own visitors in order to support languages that a specific provider was not even aware of.
As for the visitors we would provide out of the box, I tend towards generic operators that just have a language property. So "equals" would always be "equals", but a provider could just decide to generate different output for C# or VB. That's the easiest way to think about it for the provider author: What would a VB user expect? What would a C# user expect? Or just ignore the source language and translate literally...
And we could still extend this model to carry metadata (CompareOptions etc) along the language property in order to more easily support a whole range of languages.
Cheers
Stefan
Fabian