Как всегда, всё упирается не в то, что можешь писать ты, а в то, что может написать твой сосед (и с чем тебе потом придётся трахаться).
О том, как трахаться с Erlang, я могу писать очень много. Начиная с библиотек из стандартной поставки, и заканчивая плачевным состоянием килотонн говнокода с github и отсутствием репозитария вроде cpan или hackage.
Кстати, я давно заметил странную тенденцию программистов на Erlang пихать это несчастное ООП на gen_server повсюду, даже где это сто лет не нужно.
C++, Java - это прикладные языки для решения реальных задач. Их пользователи делом заняты и на абстрактный срач у кого длиннее (вызов main) не поведутся.
Хочешь потрепаться - упоминай Lisp, Haskel и Erlang.
А по теме не важно какой у кого OOP, главное чтобы круглые скобочки к месту использовались.
мне снятся разные цэ-пе-пе кошмары. например ты рассказываешь как аналишься двумя крестами и улыбаешься. это очень страшно. пожалуйста, испарись и сотрись из мироздания, я же не пишу на крестах!!!
Могу и на C, могу и на Lisp :-) Мне другое интересно :-) Почему макре, который проверяет параметр на предмет того, что он может быть только f или g, т.е.
(defmacro run-f-or-g (f)
(if (member f '(f g))
`(,f)
(error "Neither f nor g")))
большинство предпочитает километровые простыни, утыканных угловыми скобками, и, начитавшись всяких книжонок, доказывают, что макросы - суть зло? :-) Вот ведь что удивительно то :-)
PS. Один мой знакомый web-дизайнер, когда увидел какой-то заголовочный файлик из boost воскликнул: «вот это да, сколько тут HTML-тегов!» :-) Это так его шаблоны цепепе вдохновили :-) Гг :-)
Идиот смайлик, вопрос был про другое: если у вас глаза красные от C++, то почему вы не можете заработать себе на жизнь программируя на любом другом языке?
макросы - суть зло? :-)
Кто вам доказывает, что в Lisp-е макросы — суть зло?
Это в C++ и в C макросы зло и нужно хорошенько подумать, прежде чем их использовать. Хватит ли вам ума это понять?
если у вас глаза красные от C++, то почему вы не можете заработать себе на жизнь программируя на любом другом языке?
Сказано, что можно :-) Но какое это имеет отношение к справедливой критике необходимости написания километровых простыней «трэитсов» лишь для того, чтобы оставаясь в рамках цепепе, отсеивать недопустимые функции на этапе компиляции, демонстрируя, что в других языках это решается с помощью элементарнейших макр? :-)
Это в C++ и в C макросы зло и нужно хорошенько подумать, прежде чем их использовать. Хватит ли вам ума это понять?
В C без макр вообще никак :-) В C++ можно без макр, но бывают случаи, когда когда иерархии состоят из сотен классов, которые имеют общего предка и вместо написания бойлерплэйта из десятка строк в каждом классе гораздо более разумно упаковать этот бойлерплэйт в макру, которую писать в области объявлений членов класса :-) Так это макры - это добро :-) Хватит ли ума понять? :-)
Раз вы этого не делаете и глаза у вас красные от C++, то, очевидно, что нельзя. Так почему?
Но какое это имеет отношение к справедливой критике необходимости написания километровых простыней «трэитсов» лишь для того, чтобы оставаясь в рамках цепепе
Потому что вы идиот и не понимаете, что если программа пишется на C++, то приемы из Lisp-а к ней не применимы. И, следовательно, ваш вопрос нужно переформулировать по другому: почему софт все еще массово разрабатывается на C++, а не на вашем любимом Lisp-е?
И ответ вполне очевиден: потому что Lisp, по большому счету, никому не всрался. Причем уже очень и очень давно. Тем более в областях, где между собой толкаются C, C++, Ada, Eiffel, Modula и недавно подключившиеся Go с Rust-ом.
Это, кстати, и причина того, что на жизнь программированием на Lisp-е вы заработать себе не можете. Отсюда и необходимость приходить и пытаться троллить C++ников.
Так это макры - это добро :-) Хватит ли ума понять? :-)
Раз вы этого не делаете и глаза у вас красные от C++, то, очевидно, что нельзя. Так почему?
Если на базе такой логики разрабатывать программы на цепепе, то жди неопределённого поведения :-) Дело в том, что цепепе - один из языков, на котором пишется софт :-) К моему глубочайшему сожалению :-)
Потому что вы идиот и не понимаете, что если программа пишется на C++, то приемы из Lisp-а к ней не применимы.
Опять же логика из оперы «ветер дует, т.к. деревья ветками машут» :-) Приёмы и идиомы - суть зависимости языка программирования, а не наоборот :-) Т.е. то, что в цепепе нельзя сравнить строчку в компайл-тайме, а в Лиспе - можно, - это проблема цепепе как языка, а не приёмов :-) (С помощью которых там принято вызывать статические функции косвенно через аргумент шаблона :-)
И, следовательно, ваш вопрос нужно переформулировать по другому: почему софт все еще массово разрабатывается на C++, а не на вашем любимом Lisp-е?
Так я этот вопрос тоже задавал - это же удивительно, почему большинство элементарным макрам предпочитают километровые простыни трэйтсов :-) Парадокс :-)
И ответ вполне очевиден: потому что Lisp, по большому счету, никому не всрался. Причем уже очень и очень давно.
Но почему? :-)
Это, кстати, и причина того, что на жизнь программированием на Lisp-е вы заработать себе не можете. Отсюда и необходимость приходить и пытаться троллить C++ников.
Опять демонстрация фэйла логического анализа :-)
Докажите это на вашей же задаче. В C++.
Да легко :-) Когда надо с помощью using ввести в область видимости наследника имена предка - конструкторы и статические члены - в сотне мест - короче завернуть эти using в макру и использовать в сотне наследников, чем вручную, получая «неимоверное удовольствие», писать эти 4-5 using в каждом классе-наследнике :-)
Так я этот вопрос тоже задавал - это же удивительно, почему большинство элементарным макрам предпочитают километровые простыни трэйтсов :-) Парадокс :-)
Вы темой не ошиблись? Здесь люди обсуждали разницу в уровне поддержки ООП в Java и C++. А вы хотите, чтобы вам объяснили, почему Lisp давным-давно не нужен.
Да легко
Код покажите. Чтобы функция принимала на вход функцию, но в компайл-тайм проверялось, что это либо функция A::f или B::g. Ваше условие. Покажите ваше решение в C++ на макросах.
Код покажите. Чтобы функция принимала на вход функцию, но в компайл-тайм проверялось, что это либо функция A::f или B::g. Ваше условие. Покажите ваше решение в C++ на макросах.
Бугага :-) Я ему про Фому, а он мне про Ярёму :-) Про использование макросов в цепепе уже было объяснение - уменьшить бойлерплэйт в объявлениях классов наследников, которых много :-) Задачу про A::f и B::g я решал в своём коде километровыми специализациями шаблонов структур со статическими членами :-) Вот так:
Ну теперь понятно, почему у вас от C++ глаза красные:
Конечно, язык потому что утомительный дюже :-)
начиная от велосипедостроения на ровном месте
Где тут велосипедостроение? :-) Нежелание использовать турбо-мега-мостра boost::filesystem для банального парсинга пути? :-) Зачем мне это говно, если есть функции стандартного POSIX.1-2001? :-)
и заканчивая неумением использовать RAII.
Бугага :-) Если бы я ещё на каждый такой чих создавал шаблоны классов вроде Path, то глаза были бы ещё красней :-) RAII :-) Бугага :-)
И все! Никаких, блин, простыней с потоками сознания.
Бугага :-) Если бы я ещё на каждый такой чих создавал шаблоны классов вроде Path, то глаза были бы ещё красней :-) RAII :-) Бугага :-)
Идиот, прочтите, наконец, документацию по unique_ptr. Ваши пляски вокруг strdup-а и free легко заменяются на unique_ptr с кастомной функцией освобождения памяти. Что-то вроде:
Кстати говоря, возвращаемое значение strdup нужно контролировать. Иначе нарветесь на крах программы.
Итого, смайлик, вы показательный кусок идиота. Сначала сами пишете такой ублюдочный код на C++, за который руки нужно отрывать, а потом сваливаете всю вину на язык.
И все! Никаких, блин, простыней с потоками сознания.
Мне нужно было обернуть лишь 2 функции - basename, dirname в цепепешный вариант :-) Мой шаблон имеет смысл только для этих 2-х ф-ий - отсюда и ограничение, которое было возложено на компилятор :-) В твоём же говнокоде в process_path можно передать любую ф-ю, а не только удовлетворяющую семантике basename/dirname :-) И это делает адепт цепепе, где по заявлениям его создателя «упор делается на технологию компиляции» :-) Браво :-)
Идиот, прочтите, наконец, документацию по unique_ptr. Ваши пляски вокруг strdup-а и free легко заменяются на unique_ptr с кастомной функцией освобождения памяти. Что-то вроде:
А я не хочу uniqu_ptr :-) Я хочу try/catch - это ведь стандартные конструкции языка :-) И если для тебя или ещё кого-то использование стандартных конструкций языка является чем-то плохим, не идиоматичным, как вы там любите говорить, то тогда такой язык ущербен - в нём много матерных слов - try/catch :-) Ч.т.д.
Итого, смайлик, вы показательный кусок идиота. Сначала сами пишете такой ублюдочный код на C++, за который руки нужно отрывать, а потом сваливаете всю вину на язык.
Субъективное мнение :-) А язык уродлив, это факт :-) Семантика особенно :-)
где надо было умудриться превратить строку в вектор, в котором вставить вручную терминирующий ноль :-) Т.е., здравствуй Си :-) Т.е. это просто ахтунг :-)
Шиза косит? Это же вам потребовалось задействовать C-шные функции для C++ных строк. Отсюда и необходимость в промежуточной C-шной строке. Для чего нужен буфер, с нулевым символом в конце.
Использование vector дает этот самый буфер. Причем с RAII сразу. Причем с исключением в случае нехватки памяти.
Да и работать это будет, скорее всего, шустрее strdup, т.к. strdup-у нужно сначала найти 0-символ в исходной строке, а это лишний проход по памяти.
Ну и если смущает, что process_path может дернуть кто угодно и передать что угодно, то решается это несколькими способами. Самый простой — определить process_path внутри пространства имен impl или details и объявить это пространство имен деталями реализации. Соответственно, если кто-то вызвал process_path, тот сам себе буратино. Если же хочется хардкорного контроля, то опять же без трехэтажных шаблонов:
Сложный высокопроизводительный софт, как правило инфраструктурный, но не обязательно: GCC, clang/LLVM, HHVM, MSSQL, MySQL, MongoDB, RethinkDB, Couchbase, Chrome, Firefox, IE, Opera, Lightroom/Photoshop и т.д, и т.п.
Чтобы функция принимала на вход функцию, но в компайл-тайм проверялось, что это либо функция A::f или B::g. Ваше условие.
Пусть будет так: функция на вход принимает указатель на интерфейс I. И надо чтобы в фунции в компайл-тайм проверялось, что реализация приходит только из класса 'class A : public I' или 'class B : public I'. Теперь внимание вопрос: какой в этом смысл?
Хотя это наверное еще надо радоваться, что вслед за лиспером и полусишником не пришел джавер и не прикрутил к этому всему IoC. Тогда бы точно был бы финиш.
Тебе не понравилось, что автор использует clojure или elixir в своих примерах? Но надо же на каком-то языке, пусть даже псевдо-коде, иллюстрировать идеи. Считай clojure за тот-же псевдо-код. А то, что clojure даже есть нужные библиотеки, это только плюс.
Или тебе не понравилось, что автор недостаточно глубоко осветил вопрос? Тебе как эксперту, написавшему свою библиотеку, должно быть грех жаловаться. Книга, в общем, обзорная. А для обзорной книги предмет освещён нормально.