В данном коде вывод типов не сработал.
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
Здравствуйте, _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>>
Здравствуйте, _nn_, Вы писали:
__>В данном коде вывод типов не сработал.
Засабмитил
репорт на bugs.nemerle.org. По-моему к выводу типов этот баг имеет лишь косвенное отношение. Это скорее глюк механизма разрешения перегрузки, причем весьма редкий и специфический. Я думаю это легко будет выловить и исправить.
Здравствуйте, 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>>
Здравствуйте, 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);
Здравствуйте, _nn_, Вы писали:
__>А в Nemerle нет:
В этом случае он "не может выбрать", потому что это просто неверный код. Для локальных функций нет перегрузки. Новое определение функции с тем же названием перекрывает старую, это так задуманно.
Почитай мой баг-репорт, этот баг(я все таки настаиваю, что это баг) проявляется только когда мы в качестве параметра функции используем результат локальной функции с выводом типов(и то далеко не во всех случаях, тривиальные случаи работают нормально).
Равнозначный твоему примеру на C# код должен выглядеть так(и в данном случае он прекрасно выбирает нужную перегрузку):
module Program
{
z(_ : string, _ : object) : void
{
}
z(_ : string, _ : array[object]) : void
{
}
Main() : void
{
z("{0}", 1);
}
}
Здравствуйте, 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>
Здравствуйте, _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>>