LINUX.ORG.RU

Почему Go это плохо, и он вам, на самом деле, не нужен.

 ,


7

15

Давайте я вам поясню про язык Go, откуда у него растут корни, и почему его на самом деле не стоит использовать. То что напишу ниже, это взято как из инсайдерской информации, так и из материалов, доступных в интернетах.

Дело в том, что Go это, на самом деле, «решение» внутренних гугловских проблем. Но отнюдь не проблем горизонтального масштабирования серверного ПО, как многие почему-то думают. Он приспособлен специально для использования в гугле вот в каком контексте.

Гугл нанимает большое количество тупых студентов, только-только после вуза или ПТУ, и заставлять их писать хоть какой-то простой код. И делать минимум ошибок, при этом. Для этого Go сделан таким тупым и упрощенным. И выкинут в паблик он только для того, чтобы вероятность, что у такого студента, только пришедшего в гугл, было хоть какое-то знание Go, была выше нуля.

Но дело вот в чем. В гугле, на самом деле, над каждой командой гошников стоит тимлид, или целая группа, который/которая вот этим взаимозаменяемым роботам-гошникам расписывает всю систему, чуть ли не вплоть до состояния конечного автомата, до if-ов, и показывает куда и что писать. Поэтому же Go на корню режет всю креативность, поэтому там нет практически никаких средств абстракции, и поэтому он не дает делать вообще ничего сложного. Дабы программисты на нем вообще ничего лишнего не думали, а кодировали все чуть ли не побуквенно по указаниям умных людей.

Из гугла же идет маразматическая система управления зависимостями Го, которая заточена на монорепы.

Тут возникает вопрос - а почему этому тимлиду не дать в руки кодогенератор, вместо всей этой accidental complexity, возникающей из-за огромного количества строк кода, и из-за затрат на коммуникацию?

А тут надо понимать, как внутри устроены огромные корпорации типа гугла.

Их давно пожрал рак бюрократии. Там у менеджерских и околоменеджерских должностей один из главных критериев промоушнов, или вообще даже ассесмента(усидения на должности), это количество людей у тебя в подчинении. И количество говнокода в вакууме которая твоя команда написала. И вот все эти люди, сидящие на более-менее средне-высоких должностях, постоянно бодаются за эти промоушны и ассесменты. Это их главная и единственная цель. Поэтому, ни о какой эффективности тут речи не идет вообще от слова совсем. Тут главное - корпоративные игры, количество голов в твоем стаде и количество и размер высеров, которые это твое стадо произвело(причем буквально, важны SLOC).

Естественно, это все отражается на качестве продуктов, и это видно как по полному прекращению инноваций в гугле, так и по постоянно мелькающим и закрывающимся высерам этой компании - hangouts, duo, google plus, google wave, и прочее и прочее, можете еще вспомнить много чего.

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

Никакой мифической простоты в отладке и в понимании кода Go не приносит. Да и сложность программных систем растет совершенно не из-за понятности/непонятности какой-то отдельной взятой строчки кода или функции. Потому, что, во-первых, понятность это понятие субъективное, во-вторых потому, что, отдельно взятая фунцкия на 5 строк понятна любому опытному программисту, будь она написана хоть на Rust, хоть на Common Lisp.

Сложность программных систем возникает из-за их размера. И Go эту проблему значительно ухудшает. Человек не может удерживать в голове слишком много вещей, даже если каждая отдельная вещь - очень простая. Количество RAM в голове ограничено.

В случае если вы не хотите выкидывать кучу денег просто так, и скорее предпочли бы нанять немного, но более-менее опытных программистов, Go будет только вреден, потому что все вменяемые люди от него, на самом деле, плюются. Он реально отталкивает опытных людей, которые способны понять сложные требования и написать, и поддерживать, более-менее сложные системы уровнем хотя бы нескольких сервисов плюс БД и MQ.

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

Вот, придумал простой пример: есть класс Животное с двумя подклассами: Кошка и Корова, есть класс Еда с двумя подклассами: Мясо и Сено. Нужно написать метод Съедобное? для того чтобы понять, может ли данный зверь это кушать.

Подход с обобщёнными фукнциями прямой, простой и расширяемый

  1. Мы определяем обобщённую функцию (defgeneric Съедобное? (Животное Еда))

  2. Мы определяем методы для нужных случаев

(defmethod Съедобное? ((Животное Кошка) (Еда Мясо))
  Да)
(defmethod Съедобное? ((Животное Корова) (Еда Мясо))
  Нет)
(defmethod Съедобное? ((Животное Кошка) (Еда Сено))
  Нет)
(defmethod Съедобное? ((Животное Корова) (Еда Сено))
  Да)
  1. При этом мы можем в любой момент расширить систему, добавить другие животные и типы кормов и нам не нужно будет лезть в код ранее определённых методов.
ugoday ★★★★★
()
Ответ на: комментарий от ugoday

Всё, что можно в случае С++ подобного ООП — можно сделать и на обобщённых функциях.

Вот только в данном контексте упоминать C++ не самая лучшая идея. Т.к. она больше свидетельствует о незнании C++.

В C++ есть и перегрузка операторов, которые автоматически привязываются к типу. И ADL (argument dependent lookup), который позволяет выбрать для объекта внешнюю свободную функцию просто если она объявлена в том же пространстве имен, в котором определен тип объекта.

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

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

Выбор по списку параметров мощнее выбора по одному параметру.

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

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

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

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

Т.к. она больше свидетельствует о незнании C++.

Сознаюсь в собственном невежестве относительно С++. В данном случае же я использовал термин С++ подобное ООП, имея в виду не реализацию ООП в С++, а сам подход, который так нравится моему собеседнику, что он считает его синонимом ООП вообще. Можно назвать и Java подобное ООП или ещё как-нибудь, главное, чтобы понятно было о чём речь идёт.

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

добавить другие животные и типы кормов и нам не нужно будет лезть в код ранее определённых методов.

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

в вашем случае, каждые очумелые ручки могут расширить список методов моего класса,… и выкатить кому-то мой класс вовсе не в том виде, котоый я имел ввиду???

это совсем нехорошо,и полно опасностей. как минимум отвечать за такой класс неохота.

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

в ооп методы есть методы класса.

Нет, это только в убогоньких недоязычках такое.

и привязаны к классу.

В CLOS методы также привязаны к классам, только более чем к 1.

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

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

класс есть первичная сущность, обладающая внутренним состоянием и методами с ним ассоциированными.

В CLOS точно так же.

нельзя написать класс в одном месте с каким-то методами, а потом в другом месте понадписать ему еще методов просто так

Можно и нужно, потому что предугадать использование объекта невозможно. Это напрямую соответствует open–closed principle из SOLID.

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

И получается говно в виде наслоений AbstractProxySingletonFactoryStrategy

Более того, от int и float по понятным причинам не наследуются. В убогоньких недоязычках это вырождается в необходимость кучи if-ов, или же хешмапы с типами объектов, и прочий сракотан.

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

Обобщенные функции это и есть «интерфейсы». И интерфейсы - первичнее реализации, всегда, даже в кривом симуловском ООП.

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

а сам подход, который так нравится моему собеседнику, что он считает его синонимом ООП вообще

Из того, что пишет тов. @alysnix у меня сложилось впечатление, что он хардкорный ООП-шник. Причем приверженец того самого «классового ООП», которое было реализовано в Java и C# (правда, в C# со временем добавили extension methods). А вот в C++ этим самым «классовым ООП» изначально было не так просто, вот с момента добавления перегрузки операторов и добавления механизмов friend-ов.

Кстати, ваш пример в C++ должен элементарно записываться (вроде бы). Просто за счет ad-hoc полиморфизма в виде перегруженных функций.

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

Сознаюсь в собственном невежестве относительно С++.

В с++ вы полным образом определяете тип данных, он же класс, в одном месте. класс это как бы(в идеале) черный ящик с торчащими наружу методами, которые перечислены в его определении, и компилятор строго проверит, что вы там дергаете и как.

сломать правильно реализованный класс невозможно, приписать ему новые свойства где-то извне - тоже. хотите расширять класс - наследуйте в новый и расширяйте.

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

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

я закрыл возможность расширять

Это очень хорошо, что вы заранее знаете как ваш класс будет использоваться в других проектах и как требования будут меняться со временем и всё сделали правильно с самого начала. Храни вас Бог, побольше бы таких, как вы было.

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

Да я изначально ни на что особо и не рассчитывал. Ибо сказано:

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

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

eao197:

Кстати, ваш пример в C++ должен элементарно записываться

alysnix:

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

Мнения разделились.

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

Это очень хорошо, что вы заранее знаете как ваш класс будет использоваться

конечно знаю, это например написано в ТЗ. а если писать класс, что потом допишут в множестве мест, да еще и поломают… то это вообще не тип данных. а кисель какой-то. в одном модуле он одно, в другом другое, в третьем - пятое. контекстно-зависимый такой класс, поведение которого неясно.

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

Можно и нужно, потому что предугадать использование объекта невозможно. Это напрямую соответствует open–closed principle из SOLID.

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

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

При этом мы можем в любой момент расширить систему, добавить другие животные и типы кормов и нам не нужно будет лезть в код ранее определённых методов.

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

да. это круто расширяемо. только это неверно. ваша расширяемость породила ошибку, поскольку мышка в всех частях кода должна есть одно и тоже.

есть в языке средства проверки, что мышка есть одинково во всех местах вашей программы?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от ugoday

(defmethod f ((x integer) y) … )

Вот эта вот фигня мне, кстати, в классических лиспах не очень нравится — что всё подряд в одинаковых круглых скобках и надо морщить лоб, чтобы понять — код это, данные или ещё что.

Вот этот (x integer) — это вызов функции? кусок данных? что-то ещё? (что-то ещё). В кложе это могло бы быть (теоретически) что-то типа (defmethod f [{x :integer}] ... ) — код в круглых скобках, остальное данные — векторы (в том числе параметры функций) в квадратных скобках, мапы в фигурных. И всё понятно с первого взгляда.

Но нет, у нас есть график, и всё, что не по гра стандарт! 94го года! %)

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 3)
Ответ на: комментарий от alysnix

чихать на этот солид

Собственно, на этой ноте тёрки за расово верный ООП можно и заканчивать %)

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

поскольку мышка в всех частях кода должна есть одно и тоже

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

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

Вот этот (x integer) — это вызов функции?

это вроде указание типа параметра что он integer.

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

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

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

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

В лиспе всё возможно, а мои проблемы с моей мышкой — это мои проблемы, не ваши.

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

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

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

Вот эта вот фигня мне, кстати, в классических лиспах не очень нравится — что всё подряд в одинаковых круглых скобках и надо морщить лоб, чтобы понять — код это, данные или ещё что.

Это абсолютное непонимание сути лиспа вообще. Которое впрочем повально встречается в т.ч. у кложуристов, в которые как правило идут жопоскриптеры, бидонщики и прочие с травмированным мозгом. И дрочат там на эти разные скобки, нахрен не сдавшиеся в дефолтном синтаксисе(впрочем другого у Clojure нет, т.к. рич хики не осилил ридер-макросы сделать).

Это макрос. Это не конструкция языка, еще раз. Макрос. У макроса свой синтаксис, вот и всё. В стандартном синтаксисе CL нет сахара по той простой причине, что в нем нету смысла, т.к. лисп позволяет произвольно абстрагироваться синтаксически, и ты не так уж часто пишешь на «базовом» подмножестве лиспа(практически никогда), чтобы какие-то базовые вещи там подсахаривать. Это не бидон, где у тебя есть какой-то синтаксис, ты им можешь копать отсюда и до обеда, и за шаг вправо или влево - расстрел.

Плюс, какие части синтаксиса подсахаривать? Массивы и хеши? А почему их? Почему не какие-то произвольные объекты CLOS, для которых я захочу написать make-load-form и прочая, например для регексов кастомных?

Я уже выше скидывал пример нескольких вещей из своей библиотеки. Вот нахера там бы сдался этот вот сахарок, будь он в базовом языке? Куда его там влепливать? Зачем? Он бы только мешался. Когда ты используешь DSL - тебе детали нижележащего языка - нахер не сдались, вообще от слова совсем. И это касается и типизации нижележащего языка и его синтаксического сахара, и прочей хероты, включая AST нижележащего языка(поэтому в т.ч. всякие макросы rust, scala и template haskell это в общем и целом провал, который годится только для всякой мелочи, в этом плане они IRL не сильно практичнее чем сишный препроцессор)

Плюс, я могу наоборот, сказать:

public void Foo(int x);

^^ почему тут int x? что значит int? почему не сказано, от какого до какого значения этот int? можно ли туда передавать отрицательные числа? Почему все инты одинаково записываются? Непонятно, требуются ли тут числа фибоначчи или только нечетные целые?

Или даже хуже: Почему Foo стоит перед скобками, а не как первый элемент списка? Нутыпонел, да?

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

1.А корову и кошку можно как-то определить в плотоядные/травоядные, чтобы для каждой функции вот так не прописывать все мыслимые кейсы.
2.А анализ как можно провести, чтобы понять, что собачка у нас ничего не кушает?
3.Вот мы добавили собачку и у нас она сначала была плотоядная, а потом мы подумали по-лучше и сделали её всеядной. Сколько надо сделать изменений?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от ugoday

eao197:

Кстати, ваш пример в C++ должен элементарно записываться

Сами можете оценить:

#include <iostream>

struct Cat {};
struct Cow {};

struct Meat {};
struct Hay {};

struct Wood {};

bool can_eat(const Cat &, const Meat &) { return true; }
bool can_eat(const Cow &, const Meat &) { return false; }
bool can_eat(const Cat &, const Hay &) { return false; }
bool can_eat(const Cow &, const Hay &) { return true; }

template<typename A, typename B>
bool can_eat(const A &, const B &) { return false; }

int main() {
    std::cout << std::boolalpha;
    std::cout << "Cat&Meat: " << can_eat(Cat{}, Meat{}) << std::endl;
    std::cout << "Cow&Meat: " << can_eat(Cow{}, Meat{}) << std::endl;
    std::cout << "Cow&Hay: " << can_eat(Cow{}, Hay{}) << std::endl;
    std::cout << "Cow&Wood: " << can_eat(Cow{}, Wood{}) << std::endl;
    std::cout << "Wood&Cat: " << can_eat(Wood{}, Cat{}) << std::endl;
}

Поскольку я давно с C++, для меня это элементарно.

И, вообще-то говоря, к ООП это отношения не имеет.

Ключевой момент в том, что перегрузки can_eat не лезут вовнутрь классов Cat/Cow/Meat и пр. А если бы залезли, то это бы означало, что ООП пустили вдоль.

И вот с точки зрения того, может ли внешний код залезть в потроха произвольного класса, позиция !alysnix вполне себе понятна (и, скорее всего, правильна).

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

При добавлении новой еды правок будет по числу животных * 2?
При добавлении нового животного тоже?

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

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

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)

Шутка

С ЯП всё просто!
Если программист любит ЯП, то и ЯП «в долгу не останется».

Forum0888
()
Ответ на: комментарий от eao197

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

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

Ну к Lisp Curse тоже есть некоторые вопросы, но из того что я видел - да. С Хаскелем та же история в какой-то степени. Небольшая мотивированная команда на лиспе может сделать очень много и сильно быстрее чем на условных плюсах, но поддержание такой команды само по себе дело непростое. Плюс если по каким-то причинам такая команда разваливается(ну например продали стартап крупняку, а те начали строить патлачей под себя), то вот это вот всё перепишут на что-то более подобающее массовому программисту.

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

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

Дурень, ты как обычно нихера не понял вообще от слова совсем.

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

Костыльный аналог обобщенных функций для двух аругментов в симуловском ООП это паттерн visitor.

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

Ответ на этот и многие другие вопросы вы узнаете, прочтя замечательную книжку «Art of the Metaobject Protocol».

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

Ну к Lisp Curse

Идиоты в интернете какой-то хероты понаписали, а другие такие же - подхватили и теперь им тыкают повсюду.

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

Каким, блеать, образом, на лиспах писались целые операционные системы, да и другой огромный софт, и в Apple, и в Texas Instruments, и в Symbolics, и так далее, над которыми работала хренова туча человек одновременно? Херли им Lisp Curse не мешал? Может потому что нет никакого Lisp Curse, и это говномем, придуманный каким-то недоучкой?

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

чтобы понять — код это, данные или ещё что.

Ну, здрасьте, у нас тут лисп. Мы сами не знаем код это или данные. Зависит от фазы исполнения. Да и не такая уж меж ними и разница, если уж на то пошло.

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

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

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

Можно и нужно, потому что предугадать использование объекта невозможно. Это напрямую соответствует open–closed principle из SOLID.

Бертранд Мейер бы сильно удивился такой интерпретации принципа open-closed (цинк):

A class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its clients.

Но то ж Бертранд Мейер, куда ему до lovesan-а.

PS. Даже описанный там же ниже в Wiki принцип Polymorphic open–closed principle не означает, что интерфейсы (в виде абстрактных базовых классов) можно просто так левой пяткой взять и расширить.

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

ваш пример в C++ должен элементарно записываться (вроде бы). Просто за счет ad-hoc полиморфизма в виде перегруженных функций.

Такой примитивный пример да, оно и на java можно перегрузкой статичных методов. А в общем случае нет, понадобится визитор, когда появится иерархия посложнее. ADL и операторы тоже не помогут, это всё статичное, а тут динамический диспатчинг (если верно понимаю пример на CL).

PS А, ну ты дальше примерно то же и пишешь. Но плюсовый код - не аналог лисповому.

unsigned ★★★★
()
Последнее исправление: unsigned (всего исправлений: 1)
Ответ на: комментарий от alysnix

Оно никогда не ответит тебе на вопрос, что именно могут есть плотоядные. Когда возникают какие-то вопросы это говнище ничего не может.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от eao197

Не так страшен си, как то, что там всё подряд под undefined behaviour и компилятором может быть воспринято как заблагорассудится.Это очень сильно увеличивает сложность написания, приходится думать о слишком большой куче нюансов.

У плюсов, скажем честно, с этим всё ещё хуже. Новые стандарты в каких-то местах ситуацию улучшили, но принципиально всё та же огромная жопа.

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

Дурень, ты как обычно нихера не понял вообще от слова совсем.

C++ – это статически типизированный язык, выбор делается во время компиляции.

Костыльный аналог обобщенных функций для двух аругментов в симуловском ООП это паттерн visitor.

У вас, вероятно, какая-то своя терминология для термина «обобщенная функция».

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

Шутка (с долей правды)

У меня обобщённые функции акцентируют свойства объекта.

Если объект сено любит, то - корова.
То бишь обобщённая функция сможет правильно работать если у «коровы» и «ёжика» имеются общие свойства.

В мире, то человек как распознаёт образы?
Через анализ свойств объекта.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 2)
Ответ на: комментарий от crutch_master

1.А корову и кошку можно как-то определить в плотоядные/травоядные, чтобы для каждой функции вот так не прописывать все мыслимые кейсы.

Можно. Там вообще можно всякие клёвые штуки делать. Теперь ваша очередь. Как такой же трюк с расширением языка провернуть с императивным языком, например с Go, раз уж мы о нём тут толкуем. Только чуть к кодогенерации внешними средствами не прибегать!

2.А анализ как можно провести, чтобы понять, что собачка у нас ничего не кушает?

Методы классов и суперклассов могут быть скоординированы, так можно определить метод по умолчанию для класса Животные и если для Животные->Собака соответствующий метод не определён, то его вызов равнозначен утверждению «мы забыли про собаку».

Вот мы добавили собачку и у нас она сначала была плотоядная, а потом мы подумали по-лучше и сделали её всеядной. Сколько надо сделать изменений?

Убрать реализации

(defmethod Съедобное? ((Животное Собака) (Еда Сено))
  Нет)
(defmethod Съедобное? ((Животное Собака) (Еда Мясо))
  Да)

Добавить

(defmethod Съедобное? ((Животное Собака) (Еда))
  Да)

Только не спрашивайте меня, что потом будет, если попытаться накормить собаку сеном, хорошо?

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

Ну к Lisp Curse тоже есть некоторые вопросы, но из того что я видел - да. С Хаскелем та же история в какой-то степени. Небольшая мотивированная команда на лиспе может сделать очень много и сильно быстрее чем на условных плюсах, но поддержание такой команды само по себе дело непростое.

Я возьму на себя смелость заявить, что утверждение «небольшая мотивированная команда на X может сделать очень много и сильно быстрее» актуально для любого сложного языка программирования. Будь то C++, Lisp, Haskell или даже современный C#.

Даже на Java производительность разных команд может отличаться в разы.

И да, с таким подходом есть три проблемы (как минимум):

  1. Собрать такую команду.
  2. Сохранить ее.
  3. Набирать новых людей должного уровня, разделяющие взгляды на принятые в проекте решения (набирать все равно придется в силу естественной убыли).
eao197 ★★★★★
()
Ответ на: комментарий от eao197

C++ – это статически типизированный язык, выбор делается во время компиляции.

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

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

Не так страшен си

Он страшен тем, что на нем невозможно создать под себя инструменты, которые могли бы упростить работу на этом языке. Особенно если оставаться в рамках ANSI C.

У плюсов, скажем честно, с этим всё ещё хуже.

Нет. У плюсов куча проблем (и, поскольку язык больше и сложнее, чем Си), то и проблем больше. Хотя бы потому, что одна из его проблем – это совместимость с Си (на очень большом подмножестве Си).

Но, в отличии от Си, C++ позволяет создавать инструменты, которые упрощают тебе работу.

Стоимость этого, однако, велика. Т.к. нужны люди, которые смогут в этих инструментах разобраться. А не такие, которые увидят шаблон, который параметризуется шаблоном и сразу «ай как сложна!»

Ну и да, в современном мире места для C++ (в процентном соотношении) остается все меньше.

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

А может потому и «писались», что после того как появились другие инструменты, люди пошли писать на них вместо лиспа? Нет, возможно если бы в своё время под настольники типа AT ранних перенесли какой разумный сабсет дело бы пошло, но никто этим не занимался, а работало там сам помнишь что, ну вот это вот всё типа турбо си/паскаля и в дальшейшем VB, дельфей и плюсов всё и сожрало, просто потому что лисп был неприменим в реальных условиях. Хотя тоже не совсем так, Грэм как раз в середине 90-х свой viaweb на лиспе пилил и был доволен, но почему-то он такой оказался один, а viaweb потом то ли сдох, то ли переписали на что-то ещё когда в яхусторз переделали.

Тем не менее, литература была(даже на русском переводная), даже железо уже в середине 90-х было, даже люди были которые лисп ещё на ЕС-ках использовали, но почему-то сдохло и осталось в загончике для «типа особо умных». Тем, что все пилили бабло ты не отмажешься, просто лисп в какой-то момент стал нахер не применим.

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

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

alysnix ★★★
()
Ограничение на отправку комментариев: