Здравствуйте, Programmierer AG, Вы писали:
PA>Здравствуйте, Mystic, Вы писали:
PA>Не флейма ради, но не мог промолчать, уж простите.
M>>Декларативность имет как как плюсы, так и минусы... (вспоминаю язык SQL ). PA>А какие минусы у декларативного SQL? И на каком императивном языке удобнее писать запросы к БД?
Минус проявляется при ручной запросов. Если ты можешь предложить более оптимальную схему выполнения запроса (основываясь, например, на понимании смысла данных в таблицах) то объяснить это серверу БД не совсем тривиальная задача, зависящая от конкретной СУБД.
M>>К тому же я не вижу очень уж большой декларативности: последовательность вызовов более-менее жестко определена и довольно-таки избыточна. PA>Если думать о последовательности вызовов, то декларативности не увидишь .
С одной стороны согласен, с другой стороны нет. Будем говорить о "степени" декларативности. Скажем так, если брать Prolog и SQL, то там за декларативностью стоит еще некоторый объекм работ, которые вополняет движок. Тут же все можно свести к последовательности вызовов.
PA>Нет главного, что было в примере Влада — функции высшего порядка.
Зато задача решена и без этого В общем-то я хотел показать не сколько тот факт, что в Delphi есть такие возможности, сколько тот факт, что остутствие данных возможностей не сильно мешает. Даже в C# этим не все пользуются каждый день.
M>>А насчет читабельности... Читабельность данной конкретной строчки не самое страшное. Имхо гораздо важнее понимание сути в целом, общей идеи, лежащей в основе... PA>Так функции высшего порядка и позволяют закодировать эту идею раз и навсегда. Чем выше уровень абстракции, тем больше "сути и общих идей" видно из кода.
Я это понимаю. Но не вижу огромного выигрыша от этого. Да, программируя на Delphi иногда приходилось делать Copy+Paste чтобы перенести реализацию одного типа на другой. Но сказать, чтобы это было принципиально по трудозатратам при разработке ПО я бы не стал.
M>>Я знаю, что ужасно консервативен. PA>Так функциональному программировнию — 100 лет в обед
Я скорее против не функционального программирования, а винегрета.
Здравствуйте, DennisLiG, Вы писали:
DLG>2.Его перспективы на ваш взгляд.
Радужные Если серьезно, то, если тебя этот язык и жесткая связь с .Net устраивает — используй его. Ничего существенно плохого (т.е. не позволяющего его использовать) в нем нет, напротив, в наличии много приятных вещей, особенно, начиная с версий 2 и 3.
DLG>4.Есть ли альтернатива?
Для каких целей? "Вообще" — альтернатив очень много, начиная с Java и C++, и заканчивая Ruby, Python etc. Для .Net — VB.Net, C++/CLI и т.п.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Mystic, Вы писали:
M>А зачем именно так.
Чтобы было короче и понятнее. Вот надо тебе вывести список (или чего угодно) целых разделенных запятой и что делать? Бежать писать кучу непростого кода который еще и отладить нужно. А тут раз... и получил результат без напряга. Просто, быстро и понятно.
M> Это некоторый академический код, который демонстрирует возможности C#. Поскольку этих возможностей в Delphi нет, то для реализации именно этого фрагмента кода может понадобиться чуть больше кода, кое-что реализовать руками, либо чуть по другому спроектировать классы, и т. д. Но это не смертельно. Скажем приведенный ниже код делает в результате то же самое
M>
program Project1;
M>{$APPTYPE CONSOLE}
M>uses SysUtils;
M>procedure PrintArray(const Data: array of Integer);
M>var
M> I: Integer;
M>begin
M> if Length(Data) > 0 then
M> begin
M> I := Low(Data);
M> repeat
M> Write(Data[I]);
M> I := I + 1;
M> if I > High(Data) then Break;
M> Write(', ');
M> until False;
M> end;
M> WriteLn;
M>end;
M>begin
M> PrintArray([1, 3, 24, 6, 32, 7]);
M>end.
Ну, вот и сравни этот код. Понять, что делает твой код можно только разобравшись в каждой строчке. А мой просто очевиден. В нем нет ни одной императивной конструкции. Я просто описал что мне нужно сделать с массивом чтобы получить результат.
ЗЫ
Понимашь, Паскаль, даже в виде Дельфи, сильно отстал от современных языков. И вложенные функции тут явно его спасут. Они хоть и могут быть созданы чуть ближе, но не могут являться объектом с которым можно манипулировать. А это заставляет писать намного больше кода и выбирать куда более запутанные решения.
Например, что нужно тебе сделать на дельфи чтобы отсортировать неких массив объектов? На C# 3.0 это будет:
using System;
using System.Query;
class Person
{
public string Name;
public DateTime Birthday;
public override string ToString()
{
return"Имя: " + Name + new string(' ', 20 - Name.Length)
+ " День рождения: " + Birthday;
}
}
class Program
{
static void Main(string[] args)
{
var persons = new Person[]
{
{ Name="Иванов", Birthday=new DateTime(1971, 3, 18) },
{ Name="Яшин", Birthday=new DateTime(1973, 2, 12) },
{ Name="Сидоров", Birthday=new DateTime(1956, 5, 18) },
{ Name="Пертров", Birthday=new DateTime(1971, 1, 11) },
{ Name="Антовнов", Birthday=new DateTime(1981, 3, 25) },
};
var byName = persons.OrderBy(person => person.Name);
var byBirthday = persons.OrderBy(person => person.Birthday);
Console.WriteLine("Список отсортированный по датам:");
foreach (var person in byBirthday)
Console.WriteLine(person);
Console.WriteLine("-------------------------------");
Console.WriteLine("Список отсортированный по именам:");
foreach (var person in byName)
Console.WriteLine(new { person.Birthday, person.Name });
}
}
Этот код выведет:
Имя: Сидоров; День рождения: 18.05.1956 00:00:00
Имя: Пертров; День рождения: 11.01.1971 00:00:00
Имя: Иванов; День рождения: 18.03.1971 00:00:00
Имя: Яшин; День рождения: 12.02.1973 00:00:00
Имя: Антовнов; День рождения: 25.03.1981 00:00:00
-------------------------------
{Birthday=25.03.1981 00:00:00, Name=Антовнов}
{Birthday=18.03.1971 00:00:00, Name=Иванов}
{Birthday=11.01.1971 00:00:00, Name=Пертров}
{Birthday=18.05.1956 00:00:00, Name=Сидоров}
{Birthday=12.02.1973 00:00:00, Name=Яшин}
Выделенное жирным, это те самые анонимные функции, так называемые лямбды. Просто без всего лишнего. Типы параметров выводятся из выражений.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Mystic, Вы писали:
M>Декларативность имет как как плюсы, так и минусы...
Несомненно. Зачастую бывает так, что декларативная реализация проигрывает императивной. Но:
1. Прогресс не стоит на месте и оптимизация декларативных конструкций со временем будет все лучше и лучше.
2. Зачастую разницы в скорости или нет вообще, или она не значительна для конкретного случая.
Не забывай, что на C# в любой момент можно переключиться на императивный стиль и написать тот же код более эффективно. Только вот эффективность может понадобиться только в конкретных случаях. Вот их и имеет смысл заменить на оптимизированные версии. А большая часть кода будет намного более понятна и читабельна.
M>
WriteLn(Join(ArrayIntToStr([1, 2, 3]), ', '));
M>В этом случае мы, как я понял, аналогичным образом выдилили суть операции. И чем хуже более радикальная мера?
Кстати, обрати внимание, на то что ты не зная синтаксиса спокойно смог воспринять суть. Вот в этом и есть прелесть декларативности.
M>
WriteLn(IntArrayToStr([1, 2, 3]), ', '));
M>Конечно, перед глазами отсутствует код этих функций.
Не только. Ты еще вынужден будешь наклепать тучу кода который скорее всего понадобится только один раз. А это тебя подтакнет к тому чтобы отказаться от подобного подхода. Хотя его можно только приветсвовать. К тому же ты не сможешь написать маленький набор универсальных функций. Ты будешь вынужден каждый раз писать кучу специализированных функций.
Так что лучше надеяться, что хотя бы в следсвии совместимости со вторым фрэймворком в дельфи добавят вещи похожие на шарповские.
Но это еще не все вкусности. Как тебе такое?
using System;
using System.Collections.Generic;
using System.Query;
class Program
{
static void Main()
{
Func<int> Next = new Random().Next;
Func<int, List<int>> Generator = delegate(int count)
{
List<int> list = new List<int>();
for (int i = 0; i < count; i++)
list.Add(Next() % 200);
return list;
};
Console.WriteLine("Случайные числа больше 100:");
foreach (var i in Generator(10).Where(x => x > 100))
Console.Write(i + " ");
Console.WriteLine();
Console.WriteLine("Случайные числа меньше 100:");
foreach (var i in Generator(10).Where(x => x < 100))
Console.Write(i + " ");
Console.WriteLine();
}
}
Заметь, все в одной функции. Хотя казалось бы в C# нельзя делать всложенных функций.
M>Конечно, в библиотеке Delphi нет таких функций, но это относится более к наличию библиотек...
В дельфи нет поддержки анонимных методов, но есть вложенные функции. А лучше было бы наоборот.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Mystic, Вы писали:
M>С одной стороны согласен, с другой стороны нет. Будем говорить о "степени" декларативности. Скажем так, если брать Prolog и SQL, то там за декларативностью стоит еще некоторый объекм работ, которые вополняет движок. Тут же все можно свести к последовательности вызовов.
Э... не скажи. Последовательность вызовов и компилятор и есть тот самый движок. Именно от них зависит эффективность.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, WolfHound, Вы писали:
C>>*Тормоза вроде как, сужу по Янусу. WH>Сколько еще раз нужно повторить что в Янусе тормозит не .NET, а JET самый что ни на есть нативный компонент.
Похоже это бесполезно говорить. Дело в том, что им унжно найти фактов под заранее сделанные выводы. А при таком подходе, все что идет в разрез с их логикой не существенно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Programmierer AG, Вы писали:
E>>Наверное, проще уже было бы JET заменить на что-нибуть быстрое и управляемое. PA>Так вроде бы есть уже поддержка MS SQL в Янусе.
Ага. Но ведь в этой версии Янус работает куда быстрее, а это идет в разрез с тем что хочется доказать. По этому проще не смотреть на эту версию.
PA>А меня лично тормоза Януса с Jet'ом вполне устраивают, зато базу таскать проще.
Кстати, у MS SQL2005 вроде как БД тоже в отдельном файле и ее можно таскать.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Chiрset, Вы писали:
C>>*Тормоза вроде как, сужу по Янусу. WH>Сколько еще раз нужно повторить что в Янусе тормозит не .NET, а JET самый что ни на есть нативный компонент.
Ок, этот аргумент выкидываю, вроде как другие приложения на C# не тормозят.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Mystic, Вы писали:
M>>Декларативность имет как как плюсы, так и минусы... VD>Несомненно. Зачастую бывает так, что декларативная реализация проигрывает императивной. Но:
Я же говорю, есть плюсы и минусы.
VD>1. Прогресс не стоит на месте и оптимизация декларативных конструкций со временем будет все лучше и лучше.
Ты оптимист Решаемые задачи будут сложнее и сложнее и эта диалектика будет вечной.
VD>А большая часть кода будет намного более понятна и читабельна.
Кому как.
VD>Кстати, обрати внимание, на то что ты не зная синтаксиса спокойно смог воспринять суть. Вот в этом и есть прелесть декларативности.
О, тут целая история... Я первым делом я проконсультировался у знакомого программиста на C#. Он его запустил и сообщил мне великую новость, что этот же массив и напечатался. Мои подозрения подтвердились. После чего последовал коментарий:
>> 31.01.2006 12:54:41 K wrote:
>> да странная конструкция.
>> 31.01.2006 12:55:31 K wrote:
>> токо чего добивался аффтар....
>> крутизны мозга
>> зачем......
>> наверное ему жалко памяти на диске на несколько понятных лишних и читабельных строк кода
После этого я посще тщательного анализа исходника восстановил всю последовательность вызовов (как я понимаю).
VD>Не только. Ты еще вынужден будешь наклепать тучу кода который скорее всего понадобится только один раз.
Сам этот процесс доставляет мне удовольствие, близкое к половому
VD>А это тебя подтакнет к тому чтобы отказаться от подобного подхода. Хотя его можно только приветсвовать. К тому же ты не сможешь написать маленький набор универсальных функций. Ты будешь вынужден каждый раз писать кучу специализированных функций.
Да, такая потребность возникает в Delphi. Но я бы не назвал это смертельным. Мне не составляет труда быстро написть недостающий код, а также понять его в чужом исходнике. Конечно, если бы я только этим и занимался все время, то искал бы возможность, как это все исправить. Но то, что занимает менее 1% всех трудозатрат менять на что-то лучшее...
VD>Так что лучше надеяться, что хотя бы в следсвии совместимости со вторым фрэймворком в дельфи добавят вещи похожие на шарповские.
Я не пишу под .NET Точнее пытался, но у меня не получалось Большое чувство дискомфорта от того, что исчезли старые привычные провереные средства, а новые неизведаны... Я больше мыслю в терминах указателей, памяти и других подобных терминов. Абстрагироваться от этого получается слабо.
VD>Но это еще не все вкусности. Как тебе такое?
Фича как фича... До тех пор пока я не смогу оценить ее потенциальную полезность, до тех пор какого-ли положительного мнения о ней у меня не будет сформировано. Приведенный пример легко переписать без использования оной.
VD>Заметь, все в одной функции. Хотя казалось бы в C# нельзя делать всложенных функций.
И... в основном я использую вложеные функции для того, чтобы получить доступ к аргументам вызывающей функции. Либо для того, чтобы структурно выделить некий код.
VD>В дельфи нет поддержки анонимных методов, но есть вложенные функции. А лучше было бы наоборот.
Кто знает?
Здравствуйте, VladD2, Вы писали:
VD>Понимашь, Паскаль, даже в виде Дельфи, сильно отстал от современных языков.
Отстал, так отстал... Подивем --- увидим, к чему эти возможности приведут Лично мне возможностей Delphi в общем-то головой хватает, кроме разве только GC или weak pointers.
VD>Но это еще не все вкусности. Как тебе такое?
VD>
VD>using System;
VD>using System.Collections.Generic;
VD>using System.Query;
VD>class Program
VD>{
VD> static void Main()
VD> {
VD> Func<int> Next = new Random().Next;
VD> Func<int, List<int>> Generator = delegate(int count)
VD> {
VD> List<int> list = new List<int>();
VD> for (int i = 0; i < count; i++)
VD> list.Add(Next() % 200);
VD> return list;
VD> };
VD> Console.WriteLine("Случайные числа больше 100:");
VD> foreach (var i in Generator(10).Where(x => x > 100))
VD> Console.Write(i + " ");
VD> Console.WriteLine();
VD> Console.WriteLine("Случайные числа меньше 100:");
VD> foreach (var i in Generator(10).Where(x => x < 100))
VD> Console.Write(i + " ");
VD> Console.WriteLine();
VD> }
VD>}
VD>
надо еще вкуснее:
from random import randint
from sys import stdout
rprint = lambda gen, op : map(lambda x : stdout.write("%d " % x), [x for x in gen if op(x)])
generator = lambda n : [randint(0, 199) for x in range(n)]
print "Случайные числа больше 100:"
rprint(generator(10), lambda x : x > 100)
print "\nСлучайные числа меньше 100:"
rprint(generator(10), lambda x : x < 100)
print
Здравствуйте, FR, Вы писали:
FR>надо еще вкуснее:
...
Ну, да. Как всегда в ФЯ... идентификаторы по короче и по бредовее... длинна строк по больше... Зато на прау строк короче. Хотя смысл тот же но уже без привычки фиг поймешь. А это уже гарантирует, что найти тебе замену для поддержки твоего кода буден сложно. А что еще нужно для стабильности карьеры?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, FR, Вы писали:
FR>>надо еще вкуснее: VD>...
VD>Ну, да. Как всегда в ФЯ... идентификаторы по короче и по бредовее... длинна строк по больше... Зато на прау строк короче. Хотя смысл тот же но уже без привычки фиг поймешь. А это уже гарантирует, что найти тебе замену для поддержки твоего кода буден сложно. А что еще нужно для стабильности карьеры?
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, FR, Вы писали:
FR>>угу FR>>я имел в виду что C# туда же катится
VD>Не совсем. Все же названия куда более понятны непосвященным. И нет попытки засунуть в одну строку максимум LOC-ов.
Ну я тоже могу почти в один один как у тебя переписать, это уже просто вопрос стиля.