[Nemerle] Вывод типов.
От: _nn_ www.nemerleweb.com
Дата: 29.09.06 18:08
Оценка:
В данном коде вывод типов не сработал.
using System.Console;

def y(i)
{
    i(1, 2)
}

def x(i, j)
{
    i + j
}

WriteLine("{0}", y(x));


А так работает:
using System.Console;

def y(i)
{
    i(1, 2)
}

def x(i, j)
{
    i + j
}

def z(_ : string, _ : object) : void
{
}

z("{0}", y(x));


Разъясните почему.
Спасибо.

P.S.
Версия 0.9.3.

30.01.07 18:11: Перенесено модератором из 'Декларативное программирование' — IT
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: [Nemerle] Вывод типов.
От: pagid Россия  
Дата: 29.09.06 19:52
Оценка:
Здравствуйте, _nn_, Вы писали:

__>В данном коде вывод типов не сработал.

__>
__>using System.Console;

__>def y(i)
__>{
__>    i(1, 2)
__>}

__>def x(i, j)
__>{
__>    i + j
__>}

__>WriteLine("{0}", y(x));
__>


Неопределенность во втором параметре object или object[]
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re: [Nemerle] Вывод типов.
От: Vermicious Knid  
Дата: 29.09.06 20:52
Оценка:
Здравствуйте, _nn_, Вы писали:

__>В данном коде вывод типов не сработал.

Засабмитил репорт на bugs.nemerle.org. По-моему к выводу типов этот баг имеет лишь косвенное отношение. Это скорее глюк механизма разрешения перегрузки, причем весьма редкий и специфический. Я думаю это легко будет выловить и исправить.
Re[2]: [Nemerle] Вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.06 22:10
Оценка:
Здравствуйте, Vermicious Knid, Вы писали:

VK>Здравствуйте, _nn_, Вы писали:


__>>В данном коде вывод типов не сработал.

VK>Засабмитил репорт на bugs.nemerle.org. По-моему к выводу типов этот баг имеет лишь косвенное отношение. Это скорее глюк механизма разрешения перегрузки, причем весьма редкий и специфический. Я думаю это легко будет выловить и исправить.

Мне кажется это не глюк. Попробую обяснить логику typer-а, как я ее понимаю.
using System.Console;

def y(i) // typer встретил функцию тип параметров и возвращаемого значения которых ему неизвестен.
{
    // здесь тайпер сделал четкое предположение что аргументы имеют тип int, 
    // но о возвращаемом значении однозначного предположение сделать нельзя. 
    // Ведь функция может возвращать что угодно!
  i(1, 2) 
}

def x(i, j) // для этой функции тайпер вообще предположений сделать не может.
{
    i + j
}

// Функция WriteLine имеет варианты перегрузки:
// public static void WriteLine(string format, params object[] arg);
// public static void WriteLine(string format, object arg0);
// Тайпер может вывести общий тип object, но срабатывает правило 
// по которому такой вывод скорее всего является ошибкой, так как
// все без исключения данные в .net приводятся к object.
// Компилятор выводит сообщение об ошибке.
WriteLine("{0}", y(x));


Проблема устраняется разными путями:
1
def y(i) { i(1, 2) }
def x(i, j) { i + j }
System.Console.WriteLine("{0}", y(x) : object);

2
def y(i) { i(1, 2) }
def x(i, j) : object { i + j }
System.Console.WriteLine("{0}", y(x));

3
def y(i) { i(1, 2) }
def x(i, j) { i + j : int }
System.Console.WriteLine("{0}", y(x));

4
def y(i) { i(1, 2) }
def x(i, j) : int { i + j }
System.Console.WriteLine("{0}", y(x));

5
def y(i) { i(1, 2) }
def x(i, j) { i + j }
System.Console.WriteLine("{0}", y(x) : object);

6
def y(i) { i(1, 2) }
def x(i, j) { (i + j)  : object }
System.Console.WriteLine("{0}", y(x));

...

Но что радует — это то что на Немерле так обычно не пишут. В нем редко понадобится использвать форматную строку, а уж такую вырожденную точно. Я бы написал так:
def y(i) { i(1, 2) }
def x(i, j) { i + j }
System.Console.WriteLine(y(x));

и проблема бы исчезла сама собой.
Если нужно форматирование, то так:
def y(i) { i(1, 2) }
def x(i, j) { i + j }
System.Console.WriteLine($"Result is: $(y(x))");
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Nemerle] Вывод типов.
От: _nn_ www.nemerleweb.com
Дата: 30.09.06 07:15
Оценка:
Здравствуйте, VladD2, Вы писали:

<skip>

Логику вывода типов я понимаю и решение проблемы нашел тоже.
Остается вопрос почему при выборе между
public static void WriteLine(string format, params object[] arg);
public static void WriteLine(string format, object arg0);

Компилятор не может выбрать 2-ю функцию.

Код в C# ведет себя правильно:
using System;

namespace ConsoleApplication2
{
    class Program
    {
        static void z(string a, object b)
        {
        }

        static void z(string a, object[] b)
        {
        }

        static void Main(string[] args)
        {
            z("{0}", 1);
        }
    }
}


А в Nemerle нет:
using System.Console;

def z(_ : string, _ : object)
{
}

def z(_ : string, _ : array[object])
{
}

z("{0}", 1);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: [Nemerle] Вывод типов.
От: Vermicious Knid  
Дата: 30.09.06 10:51
Оценка: 1 (1)
Здравствуйте, _nn_, Вы писали:

__>А в Nemerle нет:

В этом случае он "не может выбрать", потому что это просто неверный код. Для локальных функций нет перегрузки. Новое определение функции с тем же названием перекрывает старую, это так задуманно.

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

Равнозначный твоему примеру на C# код должен выглядеть так(и в данном случае он прекрасно выбирает нужную перегрузку):
module Program
{
    z(_ : string, _ : object) : void
    {
    }
    z(_ : string, _ : array[object]) : void
    {
    }
    Main() : void
    {
        z("{0}", 1);
    }
}
Re[5]: [Nemerle] Вывод типов.
От: _nn_ www.nemerleweb.com
Дата: 30.09.06 11:18
Оценка:
Здравствуйте, Vermicious Knid, Вы писали:

VK>Здравствуйте, _nn_, Вы писали:


__>>А в Nemerle нет:

VK>В этом случае он "не может выбрать", потому что это просто неверный код. Для локальных функций нет перегрузки. Новое определение функции с тем же названием перекрывает старую, это так задуманно.
Точно, я и забыл, что функции получаются локальными

VK>Почитай мой баг-репорт, этот баг(я все таки настаиваю, что это баг) проявляется только когда мы в качестве параметра функции используем результат локальной функции с выводом типов(и то далеко не во всех случаях, тривиальные случаи работают нормально).


Читал конечно.

VK>Равнозначный твоему примеру на C# код должен выглядеть так(и в данном случае он прекрасно выбирает нужную перегрузку):

VK>
VK>module Program
VK>{
VK>    z(_ : string, _ : object) : void
VK>    {
VK>    }
VK>    z(_ : string, _ : array[object]) : void
VK>    {
VK>    }
VK>    Main() : void
VK>    {
VK>        z("{0}", 1);
VK>    }
VK>}
VK>
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: [Nemerle] Вывод типов.
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.10.06 02:03
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Логику вывода типов я понимаю и решение проблемы нашел тоже.

__>Остается вопрос почему при выборе между
__>
__>public static void WriteLine(string format, params object[] arg);
__>public static void WriteLine(string format, object arg0);
__>

__>Компилятор не может выбрать 2-ю функцию.

Вообще-то я уже ответил "почему".
Есть правило по которому вывод object-а в качестве общего базового типа является ошибкой. Это правило отлично работает в общем случае, но в данном конкретном частном случае оно явно является перебором. Логично сделать спецобработку для таких случаев, но это требует время. Меж тем случая редкий. Баг (хотя технически это и не баг) Vermicious Knid уже отрапортовал. Так что будем надеяться что его пофиксят.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.