LINUX.ORG.RU

[вброс]Почему объектно-ориентированное программирование провалилось?


2

7

http://citforum.ru/gazeta/165/

по линку многабукаф, немного для Ъ:

факт остаётся фактом: сторона, представлявшая объектно-ориентированное программирование, во время открытой дискуссии с противниками под смех зала даже запуталась в своих же концепциях. Люди вспоминают, что у всех создалось стойкое впечатление, что аргументация Lisp’еров была куда убедительней и последовательней, чем сторонников ООП.

Другой крупный критик ООП – это известный специалист по программированию Александр Степанов, который, работая в Bell Labs, участвовал в создании C++ вместе c Бьерном Страуструпом (Bjarne Stroustrup), а впоследствии, уже после приглашения в HP Labs, написал Standard Template Library (STL). Александр Александрович полностью разочаровался в парадигме ООП; в частности, он пишет: “Я уверен, что парадигма ООП методологически неверна. Она начинает с построения классов. Это как если бы математики начинали бы с аксиом. Но реально никто не начинает с аксиом, все начинают с доказательств. Только когда найден набор подходящих доказательств, только тогда на этой основе выводится аксиома. Т.е. в математике вы заканчиваете аксиомой. Тоже самое и с программированием: сначала вы должны начинать развивать алгоритмы, и только в конце этой работы вы приходите к тому, что оказываетесь в состоянии сформулировать четкие и непротиворечивые интерфейсы. Именно из-за этой неразберихи в ООП так популярен рефакторинг – из-за ущербности парадигмы вы просто обречены на переписывание программы, уже в тот самый момент, когда только задумали её спроектировать в ООП-стиле”.

Ричард Столлман (Richard Stallman) также известен своим критическим отношением к ООП, особенно он любит шутить насчет того мифа объектников, что ООП “ускоряет разработку программ”: “Как только ты сказал слово «объект», можешь сразу забыть о модульности”.

Ричард Гэбриел неожиданно сравнивает нынешнюю ситуацию с ООП с провалом эфиродинамики в физике начала 20 века, когда, в сущности, произошла “тихая революция”.

Ответ на: комментарий от hibou

> Прална, шоб быть в теме, нада читать Waterlaz'a. )

Он прав, как и Степанов. Переставай быть наивным дяденькой. Наука отличается от школьных учебников.

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от jtootf

> и какое же отношение эта цитата имеет к правоте Степанова?

Очевидное. При выводе какого-то совсем дикого следствия из аксиомы выбора от нее вполне могут отказаться, или заменить на какой-то ограниченный вариант.

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от jtootf

> а для Real надклассом должен быть Complex - я правильно тебя понимаю?

да

и наследование реализации должно идти в противоположном направлении наследованию интерфейса?

тут уже я не уверен; я вел речь об ограниченности наследования

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от Waterlaz

> Проблема в том, что у нас не преподают философию математики.

Да, и я скажу *зачем* так делается.

Из детей воспитывают быдло, которое подчиняется пастухам — сначало родителям, затем правительству. А философия науки этому мешает — мешает править от лица и прикрываясь авторитетом «ученых».

Впрочем, не всем эта философия нужна. Скорее тем, кто сам станет ученым.

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

Блин да при чем тут аксиомы выбора? По ссылке аксиомы упомянуты лишь метафорично, никакой строгости там нет. Устроили, понимаешь, олимпиаду, кто моднее термин нагуглит (upd за исключением, пожалуй, www_linux_org_ru и jtootf - им гуглить явно не надо).

mclaudt ()
Ответ на: комментарий от www_linux_org_ru

Очевидное

кому как

При выводе какого-то совсем дикого следствия из аксиомы выбора от нее вполне могут отказаться, или заменить на какой-то ограниченный вариант

могут (правда, пока не получилось); но Степанов говорит выводится аксиома - так как же, по-твоему, должна выводится аксиома на замену аксиоме выбора?

jtootf ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> а для Real надклассом должен быть Complex - я правильно тебя понимаю?

да

просто интересно - а где в этой иерархии будут алгебраические числа? а кватернионы? а друг относительно друга? :)

jtootf ★★★★★ ()

>>“Ну и где мы теперь, с этой вашей красивой теорией относительности, кто-нибудь может мне назвать хоть какие-то реально-практические результаты её применения в вашей обыденной жизни после целого века её ковыряния и массового насаждения?” – как всегда язвительно вопрошает Гэбриел.

Гэбриела ждут новости, которые его не обрадуют.

mclaudt ()

Ещё нужно добавить, что ООП это немножко маркетологический термин (в большей степени чем что-то конкретное из теории или практики программирования). Просто есть языки с таким дизайном (C+, Java и прочие) в которых три выразительных степени свободы (наследование, полиморфизм, инкапсуляция) почему-то сводятся к одной (поведение объекта определённого (с помощью class) класса). Естественней ведь просто иметь эти три степени свободы - агрегация (вместо наследования), полиморфизм/перегрузка в виде паттерн-матчинга функций по их типам и модули/пакеты вместо инкапсуляции. Но, как всегда, наиболее гибкие решения не являются наиболее распространёнными (так и ноги можно сломать).

Например, у нас есть класс Integer, и мы хотим определить класс Real — так вот, Real должен быть надклассом.

Например, у нас есть класс

foo
  slots
  methods

=> множество:

foo = {slot-1 -> value-1, slot-2 -> value-2, ..., slot-n -> value-n,
       method-1(set-of-slots-1), method-2(set-of-slots-2), ..., method-m(set-of-slots-m)}

При наследовании мы получаем

bar(foo)
  slots
  methods

=>

bar = from-definition ∪ foo

Т.е. уже видно, что определение предка

(foo)baz
  slots
  methods

=>

baz = from-definition

foo ? <- baz
bar ? <- foo <- baz

потребует горячего обновления всех потомков (всего дерева потомков), то что мы давеча обсуждали :)

quasimoto ★★★★ ()
Ответ на: комментарий от jtootf

> но Степанов говорит выводится аксиома - так как же, по-твоему, должна выводится аксиома на замену аксиоме выбора?

кхм, это тоже не очевидно?

если кратко — то неформально; так, чтобы максимально сохранить полезные и необходимые результаты и избавиться от самых подозрительных

можно попробовать ограничить че-нить счетностью; кстати, не знаешь, как там обстоят дела с такими вариантами аксиомы выбора?

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

а для Real надклассом должен быть Complex - я правильно тебя понимаю?

да

Не, ну это ни в какие ворота :) Направление наследования (агрегации) это Natural -> Rational(num, den) -> Complex(real, imag). А Real это либо плавающее (представимо как Rational), либо его вообще нет, либо в виде генератора бесконечной последовательности.

quasimoto ★★★★ ()
Ответ на: комментарий от jtootf

> а где в этой иерархии будут алгебраические числа?

алгебраические числа над чем?

допустим, алгебраические числа вида а+bε+cε² (где ε³=1, а,b,c — целые) похоже должны быть субклассом Complex и надклассом Integer

я не сказал «прямым (над, суб)классом»

а кватернионы? а друг относительно друга? :)

я не думаю, что тут будут внутренние противоречия

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

алгебраические числа над чем?

над Q. множество всех возможных корней Z-многочленов

не знаешь, как там обстоят дела с такими вариантами аксиомы выбора?

не знаю. и я действительно не отказался бы от формального примера на ту же тему

jtootf ★★★★★ ()
Ответ на: комментарий от quasimoto

> Естественней ведь просто иметь эти три степени свободы - агрегация (вместо наследования)

Подумай над примером Integer & Real и поймешь, что тут явно наследование (наследование==LSP) без агрегации.

полиморфизм/перегрузка в виде паттерн-матчинга функций по их типам

ну допустим да

и модули/пакеты вместо инкапсуляции

а в чем разница?

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от jtootf

> и я действительно не отказался бы от формального примера на ту же тему

не совсем ясно про что ты, но сравни аксиоматику Вейля и Гильберта евклидовой геометрии — я об этом уже писал

там все ясно по-моему

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от anonymous

> Передай этим многим, что они идиоты :) Какое отношение private имеет к ООП?

прямое

private позволяет организовать и поддерживать инвариант у объекта, что в практическом приложении ООП наиболее ценно

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

Подумай над примером Integer & Real и поймешь, что тут явно наследование (наследование==LSP) без агрегации.

Что есть Real? Float? Или ∈ ℝ ? Во первых в любой системе ООП объект это множестов связей (имя-слота -> значение) и множество методов от наборов слотов. Я привёл пример - наследование это отчасти построение union для двух этих множеств. В то время как определение надкласса вовсе не очевидно (про горячее обновление кода) - так что нужно либо определить что это либо ввести альтернативное представление объектов в виде АТД.

и модули/пакеты вместо инкапсуляции

а в чем разница?

Например, я не занимаюсь тем что помечаю поля класса (public, private, protect), я имею пакет в котором я могу произвольные символы (классы, их поля, методы, обычные функции, переменные и т.д.) объявлять как внутренние/внешние/защищённые в пакете. Привязывание механизмов сокрытия именно к class (в смысле c++) это вполне искуственно.

quasimoto ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

private позволяет организовать и поддерживать инвариант у объекта, что в практическом приложении ООП наиболее ценно

Какого инварианта? В CLOS, например, нет аналогов private. Там есть возможность определить функцию чтения и/или записи для слота, либо не определять её, а доступ к слотам остаётся всегда. Ну и нужный символ либо экспортируется из пакета, либо нет.

quasimoto ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

не совсем ясно про что ты

я конкретно про аксиому выбора говорил. ладно, чёрт с ней с этой аксиомой, сам почитаю что там нынче и как; однако я определённо не Коэн, и мне идея выведения аксиомы совершенно не кажется очевидной и/или тривиальной

jtootf ★★★★★ ()
Ответ на: комментарий от jtootf

> однако я определённо не Коэн, и мне идея выведения аксиомы совершенно не кажется очевидной и/или тривиальной

я думаю, что идея «выбора подходящей аксиоматики из нескольких возможных», а в качестве примера — разные аксиоматики евклидовой геометрии, тебе вполне покажется очевидной

степанов явно не имел в виду *формальный* вывод аксиомы

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от quasimoto

> Привязывание механизмов сокрытия именно к class (в смысле c++) это вполне искуственно.

И чем это более искусственно, чем привязывание их к пакету?

Я привёл пример - наследование это отчасти построение union для двух этих множеств.

это наследование реализации, которое я лично иногда издевательски называю наследованием байтов

прочти про http://ru.wikipedia.org/wiki/Принцип_подстановки_Лисков

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от jtootf

> не торт. тред делает меня грустным и хотеть массовых расстрелов

я уже предлагал, и еще раз предлагаю — пусть школьники проорутся, а мы будем писать начиная ну допустим с 4-й страницы

если бы все серьезные люди так согласились, можно было бы такие темы с самого начала не читать :-)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от quasimoto

> а доступ к слотам остаётся всегда. Ну и нужный символ либо экспортируется из пакета, либо нет.

тоесть доступ к слоту извне пакета можно закрыть?

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

И чем это более искусственно, чем привязывание их к пакету?

Тем, что в модуле/пакете мы занимаемся этим отдельно - и не только для классов и их полей, но и вообще для чего угодно. В C++ же приходится одно делать в class, другое в namespace.

Как бы это точнее выразится - модульность/инкапсуляция/охрана символов это вещи которые независимы от наследования или полиморфизма, поэтому зачем заниматься из скрещиванием? Что касается вопросов «а что - могу я это поле у класса, прочитать/изменить?» то это называется аккессоры :) - либо RO (только читаем), либо RW (читаем-пишем) либо NA (неактивен, т.е. собственно скрытый слот).

это наследование реализации, которое я лично иногда издевательски называю наследованием байтов

Ну, классы это алгебраические структуры, т.е. множества с доп. свойствами. Наследование как раз и есть агрегация, агрегация это условно говоря операция пересечения множеств (∪). Ты наверно про субтипы говоришь, это уже производное отношение от принадлежности (⊂). Т.е. агрегация это конструирование нового множества на основе двух (синтез), а вот если ты определяешь супер тип, то, как я говорил, переопределяешь (что совсем не декларативно) отношения в дереве типов - т.е. нужно все его перестроить это уже смесь анализа и синтеза. Хотя, если определишь таки альтернативное ООП без агрегации, «логическое ООП» :) - тогда посмотрим.

LSP в виде:

q(x) = true, ∀ x ∈ T
 ⇓
q(y) = true, ∀ y ∈ (S ⊂ T)

Относится к отношениям типов, агрегация это отношение классов:

T ← S ⇒ T = {T*.slots ∪ S.slots, T*.methods ∪ S.methods}

В случае агрегации мы имеем не LSP а распространение-на/наследование метода потомком:

q(x) = true, ∀ x ∈ S
 ⇓
q(y) = true, ∀ y ∈ (T ← S)

Т.е. это ровным счётом противоположные вещи. И «пирамида чисел» везде где только можно (ок, где я видел - ну... C, Python (хотя в Python и в Ruby это тот же C - достаточно поглядеть в *.h файлы) CL, Haskell) строится в стиле агрегации от Number до Complex (или от Group до Field, к примеру).

quasimoto ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

а доступ к слотам остаётся всегда. Ну и нужный символ либо экспортируется из пакета, либо нет.

тоесть доступ к слоту извне пакета можно закрыть?

В смысле - можно ли в CL иметь внутри пакета символ который ну никак недоступен извне? Нельзя, если надо - можно изменить и read-only слот и внутреннюю переменную в пакете. Просто это делается специальным образом - в первом случае это аналогично использованию внутренних слотов в потрохах внутренних методов класса, во втором - доступ к внутреннему слоту отличается от доступа к экспортируемому. Но это хорошо :) потому что в здравом уме никто таки не дотянется до спрятанного слота класса или внутренней переменной пакета - это можно сделать только имея явное желание это сделать.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

тоесть доступ к слоту извне пакета можно закрыть?

А закрыть доступ к слоту класса (класс и слот принадлежат пакету) никак нельзя - можно только переопределить класс и слот в пространстве пакета - и то если эти символы не сделаны LOCK.

quasimoto ★★★★ ()
Ответ на: комментарий от annoynimous

>> объекты есть развитие идеи структур. к чему холивары не понятно

Объекты есть развитие системы типов, позволяющее выводить одни типы из других, а также задавать возможные операции над конкретным типом.

Это уже лучше, но ты забываешь про prototype based objects

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от quasimoto

ты бы мог не терять свое время и не писать формулы, все равно формулами ты ничего нового не сказал

Хотя, если определишь таки альтернативное ООП без агрегации, «логическое ООП» :) - тогда посмотрим.

Угу, на основе аксиом и интерфейсов.

Но оно не «альтернативное», а фактически используемое на практике.

Т.е. это ровным счётом противоположные вещи

Да, одно ковариантно, другое контравариантно... с чего я и начал свой разговор.

И «пирамида чисел» везде где только можно (ок, где я видел - ну... C, Python (хотя в Python и в Ruby это тот же C - достаточно поглядеть в *.h файлы) CL, Haskell) строится в стиле агрегации от Number до Complex (или от Group до Field, к примеру).

Бред какой-то. Приведи пример, где Real получается аггрегацией из Integer. Никто так делать не будет, т.к. есть для каждого из них свой удобный, диктуемый железом, формат.

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от quasimoto

> В смысле - можно ли в CL иметь внутри пакета символ который ну никак недоступен извне? Нельзя, если надо - можно изменить и read-only слот и внутреннюю переменную в пакете. Просто это делается специальным образом - в первом случае это аналогично использованию внутренних слотов в потрохах внутренних методов класса, во втором - доступ к внутреннему слоту отличается от доступа к экспортируемому.

И как это будет выглядеть? (пожалуста код минимального размера для обоих случаев)

Т.е. допустим программист захотел скрыть слот, а другой

1. пользуется открытым слотом

2. все-таки вопреки первому полез в скрытый слот

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

ты бы мог не терять свое время и не писать формулы, все равно формулами ты ничего нового не сказал

Я не писал формул ;)

Бред какой-то. Приведи пример, где Real получается аггрегацией из Integer. Никто так делать не будет, т.к. есть для каждого из них свой удобный, диктуемый железом, формат.

Уже приводил - http://hackage.haskell.org/trac/haskell-prime/wiki/NumericClasses как самый формальный. Т.е. Rational это агрегация по Natural, Complex - по Rational. А что ты подразумеваешь под Real, для меня Real это такой Rational который во-первых имеет процедуры чтения/печати в виде

[-|+]*[digit]*.[digit]*

В той или иной СИ. А также во время IR1 (в компиляторе) преобразуется в подходящий для данной архетектуры float.

quasimoto ★★★★ ()

Выскажусь пожалуй. Я быдлокодю почти 20 лет.
С топиком и Степановым - согласен.

А всё Минский со своими фреймами в 74ом, отодвинувший функциональный и реляционный вгляд на второй план и надеющийся - что кто-то взмахнёт волшебной палочкой, и мёртвые структуры оживут божественным промыс^Wвнешним скриптом. Да и Вирт туда же. А вот кто тот скрипт - самое главное - писать будет? А ведь алгоритмы не менее важны, чем локальность, а гораздо более. Где хранить контексты и как его защитить их от загрязнения - уже вопрос второй.

Когда начинаю очередной проект (будь то какая-нибудь регрессия или просто валидация-распихивание данных) - начинаю с основной функции, задействованных потоков (то-есть мыслю в терминах обработки потока большой тюринговой машиной), алгоритма, и только потом, по мере надобности делаю структуры, по-ходу. Но основная функция, потоки, данные на входе и выводе - первичны. Иногда надо реализовывать машину состояний, иногда - большой пайплайн, иногда - рул-энджин, иногда - большой цикл (почти как в игре). Но всегда всё идёт с главного процесса, функции (практически от main), которая постепенно обрастает.
Я уж не говорю про чисто алгоритмические вещи (умещающиеся в одну процедуру/функцию фортрана, паскаля, си, PL/SQL или джавы - какая разница? Главное - чистая функция) как то методы Ньютона, Эйлера, Рунге-Кутта, Симпсона, координатного спуска итд итп. Там всё знание - вовсе не в структурах, а в процессе. Это по рассчётным задачам и я уж не говорю про задачи CS. Упор на структурах и отодвигание алгоритмов на второй план - всё равно что говорить - что для работы архитектора/конструктора/удожника самое главное - заточка карандашей, выбор формата бумаги, а _процесс_ трорчества - вторичен.

И бизнес аналитиков, подкидывающим задачки - приучаю сразу сообщать мне требования в сжатом виде и просто: в виде определения области определения, области значений, набора правил трансформаций (а уж как я реализую оператор - моё дело). Кстати, юзкейсы - это фактически то-же самое.
(прошу заметить - что объекты в юз-кейсах - это не объекты ООП! Одна из ошибок начинающих программистов, получающих тормоза и взрыв сложности в процессе осознания и реализации задачи - это попытки склейки вышеупомянутого оператора из многочисленных кривых вызовов методов классов, из-за изначально тупо по-недоразумению выбранных объектов. Из-за каких-то глупых решений в выборе фреймвоков или дизайна «сверху-вниз», им одним понятным. Эффективное же и красивое решение может (по моему опыту) быть сделано только снизу-вверх, построением пилота, расширения его, раздвигания точности, числа размерностей итд из уже чего-то хорошо работающего на частностях, что ты уже хорошо контролируешь). Т.е. только agile метод и работает. Waterfall, SDLC и прочие - изобретены для эффективного распила, либо по недоразумению теоретиками от программирования из комитетов. (В «любви» к комитетчикам-теоретикам - также солидарен со Степановым. Но это уже из другого топика).

siberean ()
Ответ на: комментарий от www_linux_org_ru

> для сортировки нужна либо скала, либо с++0х

вот так прям категорично?

А я например люблю примерно так: «select blah-blah-blah order by » + N;

где сменой всего одной переменной - меняю поле сортировки. ЧЯДНТ? Как ещё можно сделать проще? (разве что «| sort»)

siberean ()
Ответ на: комментарий от quasimoto

или от Group до Field, к примеру

кстати, вот эта иерархия, вообще говоря, иерархией быть не должна; должен быть набор аксиом, набирая которые можно получить ту или иную алгебраическую структуру. такой подход позволил бы избежать проблем при задании структур вроде унитального группоида (без ассоциативности, но с единицей) или квазигруппы (группоид с единственностью решения a*x=b и x*a=b для любых a и b)

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

jtootf ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> не совсем ясно про что ты, но сравни аксиоматику Вейля и Гильберта евклидовой геометрии

спасибо за подталкивание меня взять с полки Германа Вейля «Математическое мышление». Там как раз Гильберт с 3й части. Пошёл читать.

siberean ()
Ответ на: комментарий от www_linux_org_ru

Ок, опуская детали:

;; класс
;;
class foo
  slot-1                   ;; внутренний слот
  slot-2 :reader   slot-2  ;; RO слот
  slot-3 :accessor slot-3  ;; RW слот

;; (1) пользуется слотами в методе класса:
;;
method baz (foo :: foo)
  print (slot-2 foo)   ;; печатаем слот - можно
  set   (slot-3 foo) 1 ;; меняем слот который можно
  print (slot-1 foo)   ;; ОШИБКА! нет такого аккессора
  set   (slot-1 foo) 2 ;; ОШИБКА! нет такого аккессора

;; (2) полез во внутренний слот в методе класса:
;;
method bar (foo :: foo)
  with-slots (slot-1) foo
    set slot-1 1 ;; жёстко поменяли слот

Далее, если к слотам приписать :type foo, то они будут статически типизированы. Что касается пакетов:

package for-foo
  export foo
         slot-2
         baz

Тогда извне можно получить доступ к экспортируемым так - for-foo:foo, for-foo:slot-2, for-foo:baz, а к внутренним - for-foo::bar, for-foo::slot-1, for-foo::slot-3.

grep по двоеточию и with-slots выясняет наличие таких мест.

quasimoto ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

мне жалко твое время, потраченное на формулы — ты бы мог его потратить на обсуждение идей

Считай что там лежат идеи (века этак с 17-ого :)

quasimoto ★★★★ ()
Ответ на: комментарий от siberean

> А я например люблю примерно так: «select object order by » + «field_to_order» (* тут я чуть изменил *)

ну это-то просто, как пареная репа

template<class T, class F> void sort(T* array, T::*F field_to_order)

а вот интересно, как ты отсортируешь записи, если отношение «меньше» на field_to_order задано как «одно число делит другое»?

(хотя PGSQL это позволяет, да)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от siberean

> вот так прям категорично?

я не сказал «только»

однако для статически безопасной и не избыточно многословной сортировки ява не годится

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от quasimoto

> grep по двоеточию и with-slots выясняет наличие таких мест.

из-за наличия в лиспе макросов grep-ание выглядит не очень убедительно

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

grep по двоеточию и with-slots выясняет наличие таких мест.

из-за наличия в лиспе макросов grep-ание выглядит не очень убедительно

with-slots это всегда with-slots (везде), а \s+::\s+ это всегда доступ к internal-symbol-in package. Что касается макросов - то макрос это просто функция.

quasimoto ★★★★ ()
Ответ на: комментарий от jtootf

Мне тут аналогия практически приснилась, да и упоминали уже про фундамент. Почему строительство начинают с фундамента? Ответов два - потому что привыкли и потому что фундамент наименее изменяемая часть здания. Мождо допустим представить ситуацию когда в каком-то племени мумба-юмба строительство начинают с крыши, из тростника так удобнее хижины вязать. И вот это племя мумба-юмба осваивает самостоятельно, без европейских инструктажей современные строительные материалы. И откуда они начинают строить? Правильно, как и привыкли, с крыши. Крыша, при постройке под ней стен естественно деформируется, при заливке фундамента также деформируются крыша и стены. И что делают мумба-юмба? Правильно! Постоянно ремонтируют деформирующуюся крышу, делают ее модульной, чтоб перестраивать ее удобнее было и тд. Частично это помогает, но дом все же остается рыхлым, вязким и нестабильным как и большинство компьютерных программ. Где-то на ЛОРе уже ссылка была про сравнение логики регуляции E. Coli и Линукс-ядра. Так вот, схема логики регуляторных генов кишечной палочки напоминает пирамиду. Логику ядра тоже можно представить в виде пирамиды, но с одним нюансом - пирамида стоит на острие вершины. Не стоит недооценивать консервативность человеческого мышления. И хорошо что иногда умные люди задаются вопросом «а правильно ли мы все делаем?». Важно не просто делать, а делать ПРАВИЛЬНО. Во избежание будущих проблем.

DNA_Seq ★★☆☆☆ ()
Ответ на: комментарий от quasimoto

>Не, ну это ни в какие ворота :) Направление наследования (агрегации) это Natural -> Rational(num, den) -> Complex(real, imag). А Real это либо плавающее (представимо как Rational), либо его вообще нет, либо в виде генератора бесконечной последовательности.

а слабо абстрагироваться от конкретной архитектуры? Хотя знаешь, в перле, руби и возможно других языках все числа внутренне представляются как вещественные

DNA_Seq ★★☆☆☆ ()
Ответ на: комментарий от DNA_Seq

а слабо абстрагироваться от конкретной архитектуры?

У большинства людей при попытке построить сложную систему, будь то годное абстрактное представления данных и способов их обработки, которое при этом имеет приемлемое представление в данной архитектуре, или ещё что-нибудь подобное, так вот у большинства людей случается конфуз мозгов :-/

Тут я утверждаю некоторую данность, которую можно опровергнуть только контр-примером.

Хотя знаешь, в перле, руби и возможно других языках все числа внутренне представляются как вещественные

Я знаю что в Python и Ruby это не так - можно почитать Python/Include/intobject.h, ruby/include/ruby/ruby.h, ruby/bignum.c.

А вообще - «настоящие мужчины не используют плавающие числа» (с), это даже разработчики ядра знают :)

Где эти перл с руби с их «абстрагированием? тут и тут. Кажется это уже мои любимые картинки :_)

quasimoto ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> template<class T, class F> void sort(T* array, T::*F field_to_order)
тоже подход, но я темплейты плохо знаю.
Мне кстати классический пример в K&R пойнтера на функцию компаратора не кажется более сложным чем приведённые выше темплейты.
А касаемо динамического каста - вы производитель фреймвоков или собираетесь мерить цвет апельсинов с размером яблок? Всегда же можно проверить - что на входе, а в большинстве случаев (особенно если данные из базы) - тип уже опредён базой. У меня обычно всё либо в базе либо в текстовых файлах, где данные однородны.


а вот интересно, как ты отсортируешь записи, если отношение «меньше» на field_to_order задано как «одно число делит другое»?


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


Я обхожусь обычно семью строками, если из жабы:
java.util.Collections.sort(context.sortedHirs, new Comparator(){
public int compare(Object o1, Object o2){
Something u1 = (Something)o1;
Something u2 = (Something)o2;
int metrics1=u1.getМetrics();
int metrics2=u2.getМetrics();
return (metrics1<metrics2 ? 1 : (metrics1==metrics2 ? 0 : -1));
}
});

но как сказано выше - предпочитаю операции над множествами делать внутри базы - там есть оптимизатор, поля скорее всего уже индексированы и прохождение по B-Tree будет очень дешёвым, т.е. пользуемся существующими индексами, да хоть внешней люциной.

siberean ()
Ответ на: комментарий от DNA_Seq

Тебе в школе на информатике не объяснили что корень всех зол - преждевременная оптимизация?

Скажешь ещё что-нибудь помимо заслюнявленных афоризмов? :-)

quasimoto ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.