Hi Sandro,
Thanks for the explanation.
On 28 Mar 2010, at 01:56, Sandro Magi wrote:
> On 27/03/2010 4:03 AM, Bruno Oliveira wrote:
>> I have seen things like IComparer before. From the documentation
>> links
>> that you sent me, I could not see the exact definition. Am I correct
>> that it is defined as:
>>
>> interface IComparer<T> {
>> Bool compare(T x);
>> }
>>
>> class MyClass extends IComparer<MyClass> {...
>> }
>
> Sorry, forgot msdn docs aren't the easiest to navigate. I've included
> more direct links at the bottom. IComparable<T> is the interface you
> identified above. IComparer<T> is:
>
> interface IComparer<T>
> {
> int Compare(T x, T y);
> }
>
> This is the type class pattern you are discussing in the paper. The
> same
> breakdown applies to IEquatable<T> and IEqualityComparer<T>.
>
>>> However, while reading this paper I remembered that C# 4.0 is
>>> getting
>>> named and optional parameters with default values. Assuming default
>>> values could be specified using general static terms, ie. access
>>> static
>>> fields/properties or invoke static methods, we get some of the power
>>> of
>>> implicits. Only one overload would then be needed, with the default
>>> value being the term: EqualityComparer<T>.Default
>>
>> How does Default work? Does it use reflection to try an get an
>> appropriate comparison operation for the particular type T in use?
>
> Yes, reflection on the runtime type (the CLR does not erase types).
> This
> would be a simple definition:
>
> static class EqualityComparer<T>
> {
> // static constructor, run once at first access for each
> // unique type T
> static EqualityComparer()
> {
> Default = typeof(IEquatable<T>).IsAssignableFrom(typeof(T))
> ? new EqByEquatable()
> : new EqByObjectEquals();
> }
> // accessor for a hidden private field
> public static IEqualityComparer<T> { get; private set; }
>
> class EqByEquatable
> {
> public bool Equals(T x, T y)
> {
> // use strongly typed IEquatable<T>.Equals(T,T)
> returns (x as IEquatable<T>).Equals(y);
> }
> }
> class EqByObjectEquals
> {
> public bool Equals(T x, T y)
> {
> // use untyped object.Equals() overload
> returns x.Equals(y);
> }
> }
> }
>
> There is also a Comparer<T>.Default static property using a similar
> computation for IComparer<T>.
>
>> I think in general default parameters are quite useful to have (Scala
>> will have them too in 2.8). (Not sure if I follow the idea you
>> propose, maybe a concrete example would help?)
>
> Here's a signature for a extension methods using default values that
> obviates the need for overloads:
>
> public static int Sort<T>(
> this IEnumerable<T> source,
> IComparer<T> compare = Comparer<T>.Default);
>
> public static bool Contains<T>(
> this IEnumerable<T> source,
> IEqualityComparer<T> compare = EqualityComparer<T>.Default);
>
> So I was suggesting a default argument could specify static expression
> term instead of just constant values. This essentially injects a small
> code fragment at any call site where no explicit param is provided.
>
Ok. I think I follow your idea. However, if I understand it correctly,
"instances"
would be looked up at run-time, right? I think this is ok ... if you
like that kind
of dynamic language feel. However, from my statically typed languages
perspective, I would be upset that my missing instances errors would now
become run-time errors.
>> But they have different use-cases from implicits:
>>
>> Default arguments are very handy for handling constant default values
>> at *definition* site.
>
> Yes, this was one way to possibly unify implicits and default
> arguments.
> It's less principled than implicits due to the possibility of
> side-effects from the code injection, but it was an interesting
> thought.
>
Bruno
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev