Здравствуйте, rudzuk, Вы писали:
R>Здравствуйте, swame, Вы писали:
s>> тут жопа только в бестолковом примере, писанном кем — то не знающим языка. s>> Нужно применять адекватные классы, в данном случае есть класс TStringList, любимый формоклепателями. s>> Там сортировка вызывается 1 строчкой.
R>Неа. Речь шла о пользовательском критерие сортировки, а он может быть любым. Со стринглистом такое не прокатит, если метод сравнения не перекрыть.
За 40 лет программирования мне понадобилось ровно 2 вида сортировки строк:
1. по алфавиту
2. по числовым, там где строки имеют одинаковое начало и сисловые части, типа 10 должно следовать после 9.
Второй вариант лежит у меня в виде единственной библиотечной функции, которая подключается 1 строчкой везде, где нужна.
Так что нытье про сложную и уродливую реализацию сортировки в Delphi не катит.
R>...
s>> 5. перегружает компилятор.
R>Проблема компилятора, если корректный код его перегружает Справедливости ради.
Это не-из за того, что компилятор плохой, а потому что такой код в принципе требуют намного более сложных структур при компиляции,
это время компиляции и память.
код который я привел генерирует 4-5 уровней вложенностей дженерики, и занимает на два порядка больше памяти в мап- файле по сравнению с обычным.
Здравствуйте, swame, Вы писали:
s> R>Неа. Речь шла о пользовательском критерие сортировки, а он может быть любым. Со стринглистом такое не прокатит, если метод сравнения не перекрыть.
s> За 40 лет программирования мне понадобилось ровно 2 вида сортировки строк: s> 1. по алфавиту s> 2. по числовым, там где строки имеют одинаковое начало и сисловые части, типа 10 должно следовать после 9. s> Второй вариант лежит у меня в виде единственной библиотечной функции, которая подключается 1 строчкой везде, где нужна.
Это говорит только о твоем опыте. Можно всю жизнь пилить круды и считать, что кроме грида людям ничего другого не нужно Ну и для твоего второго примера стринглист придется, таки, наследовать и вот это вот все.
s> Так что нытье про сложную и уродливую реализацию сортировки в Delphi не катит.
Я и не говорил, что она уродливая или сложная (однако, было бы лучше, если бы по дефолту использовался стабильный алгоритм). Я сказал, что стринглист хреновый пример.
s> R>Проблема компилятора, если корректный код его перегружает Справедливости ради.
s> Это не-из за того, что компилятор плохой, а потому что такие структуры в принципе требуют намного более сложных структур при компиляции, s> это время компиляции и память.
Если компилятор падает с out of memory, ему, таки, пора бы уже стать 64-битным. Так, мысли вслух.
s> код который я привел генерирует 4-5 уровней вложенностей дженерики, и занимает на два порядка больше памяти в мап- файле по сравнению с обычным.
В сто раз? Ну ок. В чем проблема, если код компилируется? Ну подольше, ничего страшного.
Здравствуйте, rudzuk, Вы писали:
R>Здравствуйте, swame, Вы писали:
s>> R>Неа. Речь шла о пользовательском критерие сортировки, а он может быть любым. Со стринглистом такое не прокатит, если метод сравнения не перекрыть.
s>> За 40 лет программирования мне понадобилось ровно 2 вида сортировки строк: s>> 1. по алфавиту s>> 2. по числовым, там где строки имеют одинаковое начало и сисловые части, типа 10 должно следовать после 9. s>> Второй вариант лежит у меня в виде единственной библиотечной функции, которая подключается 1 строчкой везде, где нужна.
R>Это говорит только о твоем опыте. Можно всю жизнь пилить круды и считать, что кроме грида людям ничего другого не нужно Ну и для твоего второго примера стринглист придется, таки, наследовать и вот это вот все.
И какой же ты сделал вывод о моем опыте?
А тебе какие еще сортировки строк приходилось делать?
s>> Так что нытье про сложную и уродливую реализацию сортировки в Delphi не катит.
R>Я и не говорил, что она уродливая или сложная (однако, было бы лучше, если бы по дефолту использовался стабильный алгоритм). Я сказал, что стринглист хреновый пример.
Это не ты говорил. И он же начал про сортировку строк. Не я.
s>> R>Проблема компилятора, если корректный код его перегружает Справедливости ради.
s>> Это не-из за того, что компилятор плохой, а потому что такие структуры в принципе требуют намного более сложных структур при компиляции, s>> это время компиляции и память.
R>Если компилятор падает с out of memory, ему, таки, пора бы уже стать 64-битным. Так, мысли вслух.
Согласен. НО я свои программы пытаюсь обуздывать в расходе памяти и продолжаю держать 32-битную версию основной, хотя там часто идет работа с десятками миллионов объектов.
Компилятор дельфи 32-битного кода мне как-то больше нравится, работает лучше и быстрей.
s>> код который я привел генерирует 4-5 уровней вложенностей дженерики, и занимает на два порядка больше памяти в мап- файле по сравнению с обычным.
R>В сто раз? Ну ок. В чем проблема, если код компилируется? Ну подольше, ничего страшного.
код такого стиля как я привел занимает едва ли 1%, но тратит процентов 30 времени компиляции, а память занимаемая при компиляции растет взрывообразно, под delphi 10 у нас уже не компилится, под delphi 11 на пределе — он чуть экономичней. В общем ничего хорошего. Так что я такой стиль запретил.
Здравствуйте, swame, Вы писали:
s> И какой же ты сделал вывод о моем опыте?
А какой вывод я могу сделать, кроме того, что тебе больше ничего не требовалось? Такой и сделал.
s> А тебе какие еще сортировки строк приходилось делать?
Например, сортировать игнорируя несколько первых или последних символов, по подстроке, короче.
s> Это не ты говорил. И он же начал про сортировку строк. Не я.
Sinclair говорил о сортировке по пользовательскому критерию, а не про сортировку строк. Если на пример посмотришь, то увидишь, что сортируются там не строки, хоть и по строкам
Здравствуйте, rudzuk, Вы писали:
R>Здравствуйте, swame, Вы писали:
s>> И какой же ты сделал вывод о моем опыте?
R>А какой вывод я могу сделать, кроме того, что тебе больше ничего не требовалось? Такой и сделал.
s>> А тебе какие еще сортировки строк приходилось делать?
R>Например, сортировать игнорируя несколько первых или последних символов, по подстроке, короче.
ТО, где такое может понадобиться, как я себе представляю, я бы скорее распарсил эти строки в какие-то структуры по смыслу,
и сортировал бы уже структуры по нужным критериям. а это уже не сортировка строк.
Случай, где нужно сортировать такие строки в чистом виде, не представляю.
s>> Это не ты говорил. И он же начал про сортировку строк. Не я.
R>Sinclair говорил о сортировке по пользовательскому критерию, а не про сортировку строк. Если на пример посмотришь, то увидишь, что сортируются там не строки, хоть и по строкам
Обвинять язык на основе какого-то говнокода, который показывает как не надо делать, при том что есть несколько способов сделать это правильно, как-то странно.
Здравствуйте, swame, Вы писали:
s> Случай, где нужно сортировать такие строки в чистом виде, не представляю.
Представь себе... Имена файлов с расширениями, например.
s> R>Sinclair говорил о сортировке по пользовательскому критерию, а не про сортировку строк. Если на пример посмотришь, то увидишь, что сортируются там не строки, хоть и по строкам
s> Обвинять язык на основе какого-то говнокода, который показывает как не надо делать, при том что есть несколько способов сделать это правильно, как-то странно.
Пардон муа, но этот "какой-то говнокод", это официальная дока. И это хорошее решение, если не рассматривать дженерики.
Здравствуйте, swame, Вы писали: S>За 40 лет программирования мне понадобилось ровно 2 вида сортировки строк:
Повторюсь: сортировать бывает нужно не только строки. S>1. по алфавиту S>2. по числовым, там где строки имеют одинаковое начало и сисловые части, типа 10 должно следовать после 9.
Вам повезло — попались непридирчивые заказчики. А как насчёт отсортировать строки по "похожести" на заданный образец (дистанция Левенштейна)?
Как насчёт case-sensitive vs case-insensitive? Как насчёт понизить приоритет whitespace, чтобы при сортировке "Иванов А.А." шёл рядом с "Иванов А. А." и с " Иванов А."?
Что будем делать с альтернативными представлениями Unicode? Ну, то есть вы же в курсе, что буква "ё" может быть как одним code point, так и двумя — и крайне желательно, чтобы оба варианта шли в выводе сортировки рядом друг с другом. S>Второй вариант лежит у меня в виде единственной библиотечной функции, которая подключается 1 строчкой везде, где нужна. S>Так что нытье про сложную и уродливую реализацию сортировки в Delphi не катит.
Давайте посмотрим на сигнатуру вашей библиотечной функции. Ну, чтобы понять, насколько она проста и неуродлива в использовании. Она же, наверное, подходит для всего — для TStringList, для array of string,
а также для любой массивоподобной коллекции элементов произвольного типа (object там или class), у которого есть произвольное строковое свойство, по которому и будем сортировать, да?
S>Это не-из за того, что компилятор плохой, а потому что такой код в принципе требуют намного более сложных структур при компиляции, S>это время компиляции и память. S>код который я привел генерирует 4-5 уровней вложенностей дженерики, и занимает на два порядка больше памяти в мап- файле по сравнению с обычным.
Стоимость памяти пренебрежимо мала по сравнению с зарплатой программистов. Так что пока компилятор пережёвывает такие структуры достаточно быстро, чтобы не нарушать цикл разработки, на потребление памяти можно смело забить.
Из строготипизированных языков с поддержкой таких штук я имел опыт с C#. Так вот — такой примитив его вообще не напрягает. Проект среднего размера собирается единицы секунд (и это на вполне себе средненькой машине разработчика, а не на выделенном сборочном сервере). Если Delphi делает это заметно медленнее (что было бы странно), то это как раз и порождает вопросы к языку, а не к подходу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, akasoft, Вы писали: A>Это почему же? Для каких-таких "алгоритмов" не предназначен?
Ровно для обобщённых. Обобщённые алгоритмы можно писать либо без типов (все языки с динамикой, плюс языки с дырками в системе типов вроде Pointer или void *), либо на генериках, либо никак.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, akasoft, Вы писали: A>Это называется "библиотечная поддержка".
Чтобы она появилась, потребовалась для начала поддержка в языке.
На K&R С вы не напишете ничего подобного filter/map/reduce никаким библиотечным способом. A>За этими filter/map/reduce кто-то попердолился и скрываются кучи кода.
Хороший язык предоставляет пологую кривую трудозатрат/выигрыша. Простейшая реализация filter/map/reduce на более-менее любом современном языке никакой кучи кода не требует:
public static IEnumerable<T> Where<T>(IEnumerable<T> source, Predicate<T> predicate)
{
foreach(var item in source)
if(predicate(item))
yield return item
}
public static IEnumerable<R> Select<T, R>(IEnumerable<T> source, Func<T, R> selector)
{
foreach(var item in source)
yield return selector(item)
}
public static A Reduce<T, A>(IEnumerable<T> source, Func<A, T, A> aggregate, A startValue)
{
foreach(var item in source)
startValue = aggregate(startValue, item);
return startValue;
}
И только если нас не устраивает производительность вот такой универсальной реализации, мы захотим делать её специализации. И, опять же, хороший язык даст нам это сделать не ломая прикладной код.
То есть на том конце, где библиотека потребляется, код так и останется таким, как был:
var a = [4, 8, 15, 16, 23, 42];
var b = a.Where(e => e % 2 == 0).Select(e => e * 3).Reduce((a, e) => a * e % 13);
A>А уж написать это в строку или в столбик значения не имеет.
Значение имеет то, насколько легко пишется и читается такой код. Пример на Delphi читается ужасно, не правда ли?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S> Обобщённые алгоритмы можно писать либо без типов (все языки с динамикой, плюс языки с дырками в системе типов вроде Pointer или void *), либо на генериках, либо никак.
Здравствуйте, rudzuk, Вы писали:
s>> Случай, где нужно сортировать такие строки в чистом виде, не представляю.
R>Представь себе... Имена файлов с расширениями, например.
Таки это лучше сначала на компоненты разобрать, а потом сортировать. Если при каждом сравнении извлекать часть, и потом её сравнивать, результат к пенсии получишь
Здравствуйте, пффф, Вы писали:
п> R>Представь себе... Имена файлов с расширениями, например.
п> Таки это лучше сначала на компоненты разобрать, а потом сортировать.
Не нужно мне ничего разбирать, ни на какие компоненты
п> Если при каждом сравнении извлекать часть, и потом её сравнивать, результат к пенсии получишь
Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
Здравствуйте, rudzuk, Вы писали: R>Давал уже ссылку: https://wiki.freepascal.org/Templates R>Можно писать обобщенно, типобезопасно и без дженериков. Эта возможность была даже турбо-паскале.
Я думал, вы шутите.
Во-первых, там в коде — явный косяк в секции inheritance. TAdvancedListInteger не содержит метода Add.
Во-вторых, обобщённый код — это совсем не то же самое, что и шаблоны препроцессора. В частности, вся инстанциация делается руками. Это — крайне неудобно по сравнению со штатными генериками, где достаточно передать значение нужного типа туда, где оно ожидается.
Грубо говоря там, где у меня будет функция вида List<T> WrapByList<T>(T item), позволяющая писать WrapByLisT(42), WrapByList("hello") и т.п., в "кодогенерённом" коде придётся писать IntList.Create(42), StringList.Create(42). Невозможно написать обобщённую функцию L Sort<L, K, T>(L list, Func<T, K> keySelector) where L: IList<T>, where K: IComparable<K> и передавать в неё произвольную коллекцию — придётся её специализировать для каждой комбинации типов.
Ну, то есть это лучше, чем совсем ничего, но всё ещё существенно хуже, чем существующий уровень техники.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, rudzuk, Вы писали:
п>> Таки это лучше сначала на компоненты разобрать, а потом сортировать.
R>Не нужно мне ничего разбирать, ни на какие компоненты
п>> Если при каждом сравнении извлекать часть, и потом её сравнивать, результат к пенсии получишь
R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
Здравствуйте, Sinclair, Вы писали:
S> Во-первых, там в коде — явный косяк в секции inheritance. TAdvancedListInteger не содержит метода Add.
Просто пропустили наследование в TGAdvancedList. В комментарии оно есть, а в декларации пропущено.
S> Во-вторых, обобщённый код — это совсем не то же самое, что и шаблоны препроцессора. В частности, вся инстанциация делается руками. Это — крайне неудобно по сравнению со штатными генериками, где достаточно передать значение нужного типа туда, где оно ожидается.
Здравствуйте, пффф, Вы писали:
п> п>> Если при каждом сравнении извлекать часть, и потом её сравнивать, результат к пенсии получишь
п> R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
Ты же знаешь, что у строк есть индексный доступ? Ну?
Здравствуйте, rudzuk, Вы писали:
п>> R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
R>Ты же знаешь, что у строк есть индексный доступ? Ну?
Здравствуйте, пффф, Вы писали:
п> п>> R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
п> R>Ты же знаешь, что у строк есть индексный доступ? Ну?
п> И?
Здравствуйте, rudzuk, Вы писали:
п>> п>> R>Поэтому не нужно так делать Можно сравнивать ничего не извлекая.
п>> R>Ты же знаешь, что у строк есть индексный доступ? Ну?
п>> И?
R>Чего и? Напряги мозгу.
Хочу от тебя узнать правильный ответ, самому не додуматься