Вывод типов всё ещё слабоват
От: nikov США http://www.linkedin.com/in/nikov
Дата: 26.05.11 21:52
Оценка: 7 (1)
Решил проверить, как в релизной версии Nemerle работает вывод типов по сравнению с C#.

Вот такой пример в C# работает на ура:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        Foo(Enumerable.Reverse, Enumerable.Reverse);
    }

    static void Foo<T>(Func<IEnumerable<List<int>>, T> x, Func<IEnumerable<IList<int>>, T> y) { }
}


Nemerle же, к сожалению, не справляется:

using System;
using System.Linq;
using System.Collections.Generic;

module Program
{
  Main() : void
  {
      // Error: in argument #2 (_y), needed a System.Collections.Generic.IEnumerable[System.Collections.Generic.IList[int]] ->
      // System.Collections.Generic.IEnumerable[System.Collections.Generic.List[int]], 
      // got System.Collections.Generic.IEnumerable[?] -> System.Collections.Generic.IEnumerable[?]:
      // the types System.Collections.Generic.IEnumerable[System.Collections.Generic.List[int]] and
      // System.Collections.Generic.IEnumerable[System.Collections.Generic.IList[int]] are not compatible [simple unify]
      Foo(Enumerable.Reverse, Enumerable.Reverse)
  }

  Foo[T](_x : IEnumerable[List[int]] -> T, _y : IEnumerable[IList[int]] -> T) : void { }
}


И даже явное указание типа-аргумента не спасает:

using System;
using System.Linq;
using System.Collections.Generic;

module Program
{
  Main() : void
  {
      // Error: in argument #1 (_x), needed a System.Collections.Generic.IEnumerable[System.Collections.Generic.List[int]] ->
      // System.Collections.Generic.IEnumerable[System.Collections.Generic.IList[int]], 
      // got System.Collections.Generic.IEnumerable[?] -> System.Collections.Generic.IEnumerable[?]: 
      // the types System.Collections.Generic.IEnumerable[System.Collections.Generic.IList[int]] and
      // System.Collections.Generic.IEnumerable[System.Collections.Generic.List[int]] are not compatible [simple unify]
      Foo.[IEnumerable[IList[int]]](Enumerable.Reverse, Enumerable.Reverse)
  }

  Foo[T](_x : IEnumerable[List[int]] -> T, _y : IEnumerable[IList[int]] -> T) : void { }
}
Re: Вывод типов всё ещё слабоват
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.05.11 01:29
Оценка:
Здравствуйте, nikov, Вы писали:

N>Решил проверить, как в релизной версии Nemerle работает вывод типов по сравнению с C#.


А, видимо это мой недосмотр! Nemerle ведь компилируется под .NET 3.5, где интерфейс IEnumerable<T> не был объявлен ковариантным. А C# код я проверял под .NET 4.0.

Можно как-то заставить Nemerle компилироваться с mscorlib из .NET 4.0?
Re[2]: Вывод типов всё ещё слабоват
От: Ziaw Россия  
Дата: 27.05.11 01:56
Оценка:
Здравствуйте, nikov, Вы писали:

N>А, видимо это мой недосмотр! Nemerle ведь компилируется под .NET 3.5, где интерфейс IEnumerable<T> не был объявлен ковариантным. А C# код я проверял под .NET 4.0.


N>Можно как-то заставить Nemerle компилироваться с mscorlib из .NET 4.0?


Надо положить в ProgramFiles/Nemerle вот эти бинарники. К сожалению, пока вместе 2 версии фреймоврка не работают, надо либо менять env var Nemerle, либо бинарники в Program Files.
Re[2]: Вывод типов всё ещё слабоват
От: Ziaw Россия  
Дата: 27.05.11 04:27
Оценка:
Здравствуйте, nikov, Вы писали:

N>А, видимо это мой недосмотр! Nemerle ведь компилируется под .NET 3.5, где интерфейс IEnumerable<T> не был объявлен ковариантным. А C# код я проверял под .NET 4.0.


Проверил под .net 4, воспроизводится.

N>Можно как-то заставить Nemerle компилироваться с mscorlib из .NET 4.0?


Build-4.0.cmd DevBuildFull

/ref:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll"
/ref:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll"
/ref:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll"
/ref:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Xml.dll"

/out:D:\Projects\lib\nemerle\obj\Debug\net-4.0\\Stage1\\Nemerle.dll

Re[3]: Вывод типов всё ещё слабоват
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.05.11 18:02
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Проверил под .net 4, воспроизводится.


Ага, я попробовал определить ковариантный интерфейс прямо в коде — ошибка осталась. Замена функциональных типов (которые, кажется, не поддерживают вариантность) на вариантный делегаты тоже не помогла.

using System;
using System.Collections.Generic;

module Program
{
  Main() : void
  {
      Foo(Reverse, Reverse)
  }
  
  Reverse[T](_ : IMyEnumerable[T]) : IMyEnumerable[T]
  {
      throw NotImplementedException()
  }

  Foo[T](_x : MyFunc[IMyEnumerable[List[int]], T], _y : MyFunc[IMyEnumerable[IList[int]], T]) : void { }
}

delegate MyFunc[-S, +T](_ : S) : T;
interface IMyEnumerable[+T] { }
Re[4]: Вывод типов всё ещё слабоват
От: Ziaw Россия  
Дата: 27.05.11 18:05
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ага, я попробовал определить ковариантный интерфейс прямо в коде — ошибка осталась. Замена функциональных типов (которые, кажется, не поддерживают вариантность) на вариантный делегаты тоже не помогла.


Жаль, я надеялся, что проблема в невосприятии родной ковариантности четверки.
Re: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 18:46
Оценка:
Здравствуйте, nikov, Вы писали:

N>Вот такой пример в C# работает на ура:

N>
N>using System;
N>using System.Collections.Generic;
N>using System.Linq;

N>class Program
N>{
N>    static void Main()
N>    {
N>        Foo(Enumerable.Reverse, Enumerable.Reverse);
N>    }

N>    static void Foo<T>(Func<IEnumerable<List<int>>, T> x, Func<IEnumerable<IList<int>>, T> y) { }
N>}
N>


Вообще-то:

error CS0411: The type arguments for method 'Program.Foo<T>(System.Func<System.Collections.Generic.IEnumerable<System.Collections.Generic.List<int>>,T>, System.Func<System.Collections.Generic.IEnumerable<System.Collections.Generic.IList<int>>,T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

если компилировать на 3.5-ом фрэймворке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 18:48
Оценка:
Здравствуйте, nikov, Вы писали:

N>Nemerle же, к сожалению, не справляется:...

N>И даже явное указание типа-аргумента не спасает:

Да, косяк. Надо разбираться. Добавь, плиз, в багтреккер.

ЗЫ

Интересно, в реальной жизни такое может встретиться? Подозреваю, что случайно такой код не пишут.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 19:00
Оценка:
Здравствуйте, nikov, Вы писали:


N> Foo.[IEnumerable[IList[int]]](Enumerable.Reverse, Enumerable.Reverse)

N> }

N> Foo[T](_x : IEnumerable[List[int]] -> T, _y : IEnumerable[IList[int]] -> T) : void { }


А это случаем не ковариантность?
Тут ведь выходит, что T одновременно должно унифицироваться как с List[int], так и с IList[int].
Хотя IList[int] подтип List[int]...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 19:01
Оценка:
Здравствуйте, nikov, Вы писали:

N>А, видимо это мой недосмотр! Nemerle ведь компилируется под .NET 3.5, где интерфейс IEnumerable<T> не был объявлен ковариантным. А C# код я проверял под .NET 4.0.


N>Можно как-то заставить Nemerle компилироваться с mscorlib из .NET 4.0?


Из командной строки — скачать бинарники, разархивировать их куда-то и компилировать из командной строки.

Только тормозить будет. Чтобы не тормозило можно ngen по бинарникам прогнать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 19:17
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ага, я попробовал определить ковариантный интерфейс прямо в коде — ошибка осталась. Замена функциональных типов (которые, кажется, не поддерживают вариантность) на вариантный делегаты тоже не помогла.


Боюсь, что с функциональным типом оно вообще не выйдет, так как он же в класс переписывается. А для них ковариантности нет.

А вот с делегатами наверно косяк. Надо смотреть.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Вывод типов всё ещё слабоват
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.11 19:22
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ага, я попробовал определить ковариантный интерфейс прямо в коде — ошибка осталась. Замена функциональных типов (которые, кажется, не поддерживают вариантность) на вариантный делегаты тоже не помогла.


Пример никак нельзя упростить? Сдается мне дело в ковариантности для делегатов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.