Интересная зависимость от порядка аргументов
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.09.09 13:19
Оценка:
Такой код компилируется:
module Program
{
  Main() : void
  {
    Foo(Bar2, Bar1);
  }
  
  Foo[S](_x : void -> S, _y : void -> S) : void { }
  
  Bar1() : string { "" }
  Bar2() : object { "" }
}


а такой — нет:

module Program
{
  Main() : void
  {
    Foo(Bar1, Bar2);
  }
  
  Foo[S](_x : void -> S, _y : void -> S) : void { }
  
  Bar1() : string { "" }
  Bar2() : object { "" }
}

Error: in argument #2 (_y) of Program.Foo.[string], needed a void -> string, got void -> System.Object: the types string and System.Object are not compatible [simple unify]
Re: Интересная зависимость от порядка аргументов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.09.09 14:22
Оценка:
Здравствуйте, nikov, Вы писали:

N>Такой код компилируется:

N>
N>module Program
N>{
N>  Main() : void
N>  {
N>    Foo(Bar2, Bar1);
N>  }
  
N>  Foo[S](_x : void -> S, _y : void -> S) : void { }
  
N>  Bar1() : string { "" }
N>  Bar2() : object { "" }
N>}
N>


N>а такой — нет:


N>
N>module Program
N>{
N>  Main() : void
N>  {
N>    Foo(Bar1, Bar2);
N>  }
  
N>  Foo[S](_x : void -> S, _y : void -> S) : void { }
  
N>  Bar1() : string { "" }
N>  Bar2() : object { "" }
N>}
N>

N>
N>Error: in argument #2 (_y) of Program.Foo.[string], needed a void -> string, got void -> System.Object: the types string and System.Object are not compatible [simple unify]
N>


Это особенности вывода типов. В первом случае ты первым параметром указываешь, что S надо трактовать как object.
Когда же ты в первый параметр подставляешь Bar1, то это приводит к тому, что компилятор вывадит тип S как string и естественно, что при этом не проходит проверка совместимости типа для object.

Тоже самое можно наблюдать если попытаться проинициализировать коллекцию разными значениями:
def seq = array['a', 1];

Проблема решается или явным указанием типа, или уточнением типа первого элемента:
def seq = array['a' : object, 1];

Кстати, в Немерле введена одна эвристика. Хотя object является базовым типом для всех объектов, но при при унификации он не рассматривается как базовый класс. Считается, что если ты хочешь получить object, то стоит указать это явно.

С другими типами — это не так. Так что если у типов будет общий базовый тип, то компиляция пройдет.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Интересная зависимость от порядка аргументов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.09.09 14:37
Оценка:
Здравствуйте, nikov, Вы писали:

Да, для твоего примера можно поступить так:

module Program
{
  Main() : void
  {
    Foo(Bar1 : void -> object, Bar2); // 1
    Foo.[object](Bar1, Bar2);         // 2
  }
  
  Foo[S](_x : void -> S, _y : void -> S) : void { }
  
  Bar1() : string { "" }
  Bar2() : object { "" }
}
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Интересная зависимость от порядка аргументов
От: VoidEx  
Дата: 11.09.09 20:57
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это особенности вывода типов. В первом случае ты первым параметром указываешь, что S надо трактовать как object.

VD>Когда же ты в первый параметр подставляешь Bar1, то это приводит к тому, что компилятор вывадит тип S как string и естественно, что при этом не проходит проверка совместимости типа для object.

А почему именно первый, а не любой? Это, по-моему, не особенность, а кривое решение.
Re[3]: Интересная зависимость от порядка аргументов
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.09.09 14:59
Оценка:
Здравствуйте, VoidEx, Вы писали:

VD>>Это особенности вывода типов. В первом случае ты первым параметром указываешь, что S надо трактовать как object.

VD>>Когда же ты в первый параметр подставляешь Bar1, то это приводит к тому, что компилятор вывадит тип S как string и естественно, что при этом не проходит проверка совместимости типа для object.

VE>А почему именно первый, а не любой? Это, по-моему, не особенность, а кривое решение.


Потому что анализ производится слева направо, сверху вниз (т.е. в привычном человеку порядке). Об этом сказано на странице посвященной выводу типов.

Если бы в данном примере использовались бы типы имеющие общий базовый тип отличный от object, то был бы выведен именно он. А object обрабатывается особым образом, чтобы предотвратить случайные ошибки..
Проблем (на практике) это не вызывает.
http://nemerle.org/Banners/?g=dark
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.