using System;
using System.Windows.Forms;
namespace Test
{
class Form1: Form
{
static void Main()
{
Application.Run(new Form1());
}
private Form1()
{
string[] strings = new string[]{"test1", "test2", "test3"};
ComboBox comboBox1 = new ComboBox();
comboBox1.Items.AddRange(strings);this.Controls.Add(comboBox1);
}
}
}
D:>csc test.cs
Версия компилятора Microsoft (R) Visual C# 20058.00.50727.42
для Microsoft (R) Windows (R) 2005 Framework версии2.0.50727
Авторские права (C) Microsoft Corporation 2001-2005. Все права защищены.
D:>
Код на Nemerle не компилируется:
using System;
using System.Windows.Forms;
namespace Test
{
class Form1: Form
{
static Main() : void
{
Application.Run( Form1());
}
private this()
{
def strings = array["test1", "test2", "test3"];
def comboBox1 = ComboBox();
comboBox1.Items.AddRange(strings);this.Controls.Add(comboBox1);
}
}
}
D:>ncc -r System.Windows.Forms test.n
test.n:17:1:17:25: <[01;31merror<[0m: in argument #1 (items) of comboBox1.Items.AddRange, needed a array [System.Object], got array [string]: the types System.Object and string are not compatible [simple unify]
D:>
Workaround:
using System;
using System.Windows.Forms;
namespace Test
{
class Form1: Form
{
static Main() : void
{
Application.Run( Form1());
}
private this()
{
def strings = array["test1", "test2", "test3"];
def arr = Array.ConvertAll(strings, Converter.[string, object](fun(from){from}));
def comboBox1 = ComboBox();
comboBox1.Items.AddRange(arr);
this.Controls.Add(comboBox1);
}
}
}
Кстати Nemerle приводит функции к делегатам автоматически, так что в данном случае никакого смысла создавать делегат по имени не было. Если это для того, чтобы указать тип функции, то можно было проще:
Array.ConvertAll(strings, fun(from) : object { from });
Re: Nemerle vs C#: array[object] and arrya[string] are not c
Протупил. Скопировал с MSDN даже не задумавшись, что это делегат. А про вывод функций к делегатам знал.
VK>Можно было написать так: VK>
VK>Array.ConvertAll(strings, x => x : object);
VK>
Здесь не очень понятно, почему можно так написать.
Правильно ли я рассуждаю, что можно вот так сократить:
1. Первоначальный максимальный вариант — конструктор делегата с анонимной функцией в качестве параметра:
Converter.[string, object](fun(from){from})
сокращается до
2. Только собственно функция с паттерн-матчингом:
fun(x: string): object {match(x){| x => x: object} }
сокращается до
3. Типы функции и параметров выводятся, единственный match в функции можно сократить:
fun(x) {| x => x: object}
сокращается до
4. Саму функцию сокращаем до просто ее тела (на каком основании сокращаем и куда исчезает токен "|"? С чего компилятор догадывается, что "x => x : object" — функция?).
Здравствуйте, Ilya10k, Вы писали:
I>Здесь не очень понятно, почему можно так написать. I>Правильно ли я рассуждаю, что можно вот так сократить:
Нет, не правильно. Паттерн-мэтчинг здесь не причем, просто внешне напоминает. x => y это нотация для анонимных функций, позаимствованная из C# 3.0. Во многих языках есть что-то похожее. Например в Haskell это \x -> y.
Если интересно, почему и как компилятор это понимает, то можно и пояснить.
В стандартной библиотеке макросов есть бинарный макро-оператор @=>. x => x он раскрывает в fun(x) { x } (x,y) => x + y в fun(x, y) { x + y }
В качестве списка параметров он(макрос) воспринимает только имена параметров(или _ если параметр игнорируется) с опциональной аннотацией типов. Это поведение кстати отличается от методов и локальный функций. Параметры методов можно еще помечать атрибутами. В параметрах локальных, анонимных функций и методов можно использовать паттерны. Например так:
def f = fun((a,b), (x::xs)) {}
Т.е. это просто сильно облегченный синтаксис для анонимных функций. Меньше функциональности, но зато и меньше "оверхеда".
Re: Nemerle vs C#: array[object] and arrya[string] are not c
Да, это извесный баг компилятора о котором известно разработчикам. Но у них никак не дойдут руки до этого дела. Я с ними как-то об этом говорил.
Как решить проблему тебе уже написали, я же для упрощения проблемы добавил Extention method с именем To.Base(). Так что моно писать так:
I>Код на Nemerle не компилируется:
Здравствуйте, Ilya10k, Вы писали:
VK>>Можно было написать так: VK>>
VK>>Array.ConvertAll(strings, x => x : object);
VK>>
Скажу больше использовать Array.ConvertAll() тоже смысла нет. Вместо него можно использовать метод-расширение NArray.ConvertAll(). Вот пример преобразования массива целых в массив строк:
using System.Console;
using Nemerle.Utility;
def ary1 = array[1, 2, 3, 4];
def ary2 = ary1.ConvertAll(elem => elem.ToString());
WriteLine(ary2.ToString(", "))
Можно даже еще короче:
def ary2 = ary1.ConvertAll(_.ToString());
"_.ToString()" — это так называемое частичное применение. Оно преобразовывается в анонимную функцию (лямбду) анлогичную "elem => elem.ToString()".
Кстати, в функциональном мире методы аналогичные ConvertAll() принято называть Map(). Правда Map
НО в твоем случае, вообщен не стоит вызвать ConvertAll(). Здесь требуется приведение типов (описанное ie
), вместо которого удобнее применять метод ToBase(). Метод ToBase обеспечивает так же и дополнительный контроль, так как на его параметры типов наложено ограничение. Так что пользоваться лучше именно им. Ну, а там глядишь и компилятор поправят.
I>Здесь не очень понятно, почему можно так написать. I>Правильно ли я рассуждаю, что можно вот так сократить:
Нет не правльно.
x => x : object
это описание анонимной функции. Просто другой синтаксис (реализованный в виде макроса). Этот код полностью аналогичен коду:
fun (x) { x : object }
В свою очередь "x : object" просто приказывает компилятору трактовать x как переменную типа object. С тем же умпехом можно было бы написать так:
fun (x) : object { x }
или так
(x) : object => x
Задание уточнения типа нужно только потому, что иначе компилятор выведет функцию как
(x) : string => x
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Nemerle vs C#: array[object] and arrya[string] are no
Здравствуйте, ie, Вы писали:
ie>Не совсем, это фитча ie>Если я не ошибаюсь, авторы столкнулись с какой-то проблемой связаной с парой: ковариантность массивов — вывод типов.
По-моему — это баг. Просто не учитывается ковариантность массивов. Причем на фоне того, что ковариантность реализована для интерфейсов — версия проблемы выглядит еще более сомнительной. Так что проблема тут тольк одна — промазали с логикой.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Nemerle vs C#: array[object] and arrya[string] are not c
Здравствуйте, VladD2, Вы писали:
VD>Подумалось... Есть смысл создать extension-методы вроде: VD>Тогда никакого "шума" не будет. Добавил файлик к проекту и живи спокойно. А то и вообще в библиотечку положить можно.
Ну уж коль разработчики признают баг и планируют его поправить, то в библиотечку класть ИМХО смысла не имеет. Тем более, что на все коллекции, экстеншенов не напасешься. А как воркараунд, отличное решение!
VD>Причем в этом случае мы получаем контроль времени компиляции, так как передать этому методу массив вэлью-типов уже не дастся.
Что-то не вкурил, а зачем нужна такая дескриминация вэлью-типов?
... << RSDN@Home 1.2.0 alpha rev. 655>>
Превратим окружающую нас среду в воскресенье.
Re[3]: Nemerle vs C#: array[object] and arrya[string] are no
Здравствуйте, ie, Вы писали:
ie>Ну уж коль разработчики признают баг и планируют его поправить, то в библиотечку класть ИМХО смысла не имеет. Тем более, что на все коллекции, экстеншенов не напасешься. А как воркараунд, отличное решение!
Исправят уберем. Да и если не уберем, то тоже проблем не будет.
ie>Что-то не вкурил, а зачем нужна такая дескриминация вэлью-типов?
Массмвы вэлью-типов не ковариантны. Их так приводить нельзя.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Nemerle vs C#: array[object] and arrya[string] are no
Здравствуйте, VladD2, Вы писали:
VD>Скажу больше использовать Array.ConvertAll() тоже смысла нет. Вместо него можно использовать метод-расширение NArray.ConvertAll().
NArray.ConvertTo()
VD>[/c#] VD>Можно даже еще короче: VD>
VD>def ary2 = ary1.ConvertAll(_.ToString());
VD>
VD>"_.ToString()" — это так называемое частичное применение. Оно преобразовывается в анонимную функцию (лямбду) анлогичную "elem => elem.ToString()".
А почему не работает "_:> Class1"? Пришлось писать "x => x:> Class1":
Здравствуйте, VladD2, Вы писали:
I>>А почему не работает "_:> Class1"? Пришлось писать "x => x:> Class1":
VD>Самому интересно. По уму хорошо бы чтобы работало. В общем, я лучше за багрепортю это дело, а там послушает что неперловцы скажут. А вось исправят.
Елы-палы. Я думал, чего-то недопонимаю. А тут опять баг-репорт... snks
P.S. Я нигде не указывал версию Nemerle. Но все и так понимают, что речь идет о последней официальной версии на день отправки сообщения (ждем, не дождемся первого релиза):
D:\>ncc -V
Nemerle Compiler (ncc) version 0.9.3.99 (SVN)
(c) 2003-2005 University of Wroclaw, All rights reserved.
P.P.S. Что я пытаюсь сейчас сделать — так это ради изучения переписать свой старый проект на новый язык. И создаю новые — на Nemerle. Эх, не смогу ж назад перейти...
Re[6]: Nemerle vs C#: array[object] and arrya[string] are no
Здравствуйте, Ilya10k, Вы писали:
I>Елы-палы. Я думал, чего-то недопонимаю. А тут опять баг-репорт... snks
Дык свежая голова со свежими паттернами вот баги и полезли. Каждый раз когда к языку приобщается кто-то дейятельный сразу вылезают некотоые проблемы. Радует, что все же они в последнее время не критичны и то что их довольно быстро фиксях. Как с МС ждать по три года не надо.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.