Java. Нет множественного наследования (и не нужно), нет непонятного траходрома с public/protected/private наследованием. Теперь, вот, правда, есть имплементация в интерфейсах. Ну ок, не так страшно же.
Вопрос господам: слышал от пары сеньоров, что имплементация интерфейса и расширение класса в java вполне себе называется наследованием. Потому они считали, что в java множественное наследование «есть» и пытались этим троллить нубов. Проблема в их головах, я правильно понял?
Это какие-то неправильные сеньёры, наследование - это расширение функционала родителя + возможность полиморфизма. Реализация интерфейса - это всего лишь возможность объекта «играть какую-то роль», но назвать это наследованием нельзя.
Java. Нет множественного наследования (и не нужно), нет непонятного траходрома с public/protected/private наследованием.
Интересная логика. Если множество A есть всего лишь подмножество B, то A оказывается лучше? Т.е. «лучше» в данном случае синоним «меньше»?
По теме: лучше в Eiffel, там к реализации ООП в статически-типизированном языке отнеслись очень тщательно. И получилось, что удивительно, вполне понятно.
А то! Все Erlang-еры с подачи Джо Армстронга в этом уверены!
PS. В дерьмокниге «Seven Concurrency Models in Seven Weeks» в главе «Actors» есть даже раздел, озаглавленный «More Object-Oriented than Objects». Так что здесь вам не тут :)
Я бы хотел узнать что имеется ввиду под ООП в данном случае. Потому что некие закрытые снаружи «объекты», общающиеся через сообщения, можно писать вообще на чём угодно.
В обоих говно :-)
Продолжим :-) Итак, спасибо за простынь от eao197 - http://www.linux.org.ru/forum/talks/12318922?cid=12324988 (комментарий) :-) Именно такая и ожидалась :-) Правда, не обязательно было корякать f_tag, g_tag, можно было бы обойтись и enum class F { f, g } и специализировать структуру call_traits по ним :-) Ну да ладно :-) Что же касается http://www.linux.org.ru/forum/talks/12318922?cid=12324998 (комментарий), то нет, нужен один шаблон, в котором имеет смысл подставить только 2 функции, а другие бессмысленны :-)
Также отличился и другой эксперт - http://www.linux.org.ru/forum/talks/12318922?cid=12325004 (комментарий), предложив использовать static_assert :-) Дорогой аноним :-) Да, можно сигнатуру ф-ии сделать параметром шаблона, но ведь было ожидаемо, что в такую ловушку ты и попадёшься :-) Видишь ли, в template<typename F> void h(F f) можно передать не только ф-ю, но и, как это принято у цепепешников говорить умное слово ФУНКТОР, который в template<void(*F)()> h() не передать :-) Что же касается твоего static_assert(F == f, ":-)"), то да будет тебе известно, но смайлик ты так и не увидишь, ибо компиляция не выполнится не по причине провала утверждения, а по причине неконстантного выражения F == f, если в качестве F будет не f :-) Смекаешь, эксперт? :-) Т.е. с таким же успехом static_assert(F == f, ":-)") можно заменить на constexpr auto a = F == f, и компиляция так же зафейлится :-) Так что зря ты утруждал себя написанием смайлика :-)
Видишь ли, в template<typename F> void h(F f) можно передать не только ф-ю, но и, как это принято у цепепешников говорить умное слово ФУНКТОР, который в template<void(*F)()> h() не передать :-)
Дура ты вертлявая, ты сам сказал, что нужно передавать только две определенные функции. А с функтором код не скомпилируется, как ты и хотел в своем условии. А теперь ты виляешь задом.
Что же касается твоего static_assert(F == f, ":-)"), то да будет тебе известно, но смайлик ты так и не увидишь, ибо компиляция не выполнится не по причине провала утверждения, а по причине неконстантного выражения F == f, если в качестве F будет не f :-)
Иди полы мой:
~$ cat ./test.cpp
#include <cstdio>
int f()
{
return 100;
}
int g()
{
return 100;
}
template<int(*F)()>
int dummy()
{
static_assert( F == f, ":-)" );
return F();
}
int main()
{
printf( "%d\n", dummy<g>() );
}
~$ clang++ -std=c++11 ./test.cpp
./test.cpp:16:5: error: static_assert failed ":-)"
static_assert( F == f, ":-)" );
^ ~~~~~~
~ $ g++ -std=c++14 test.cpp
test.cpp: In instantiation of ‘int dummy() [with int (* F)() = g]’:
test.cpp:23:30: required from here
test.cpp:16:5: error: non-constant condition for static assertion
static_assert( F == f, ":-)" );
^
test.cpp:16:5: error: ‘(g == f)’ is not a constant expression
Т.е. даже матёрые цепепешиники этот самый цепепе до конца не знают :-) Вай какой язык хороший :-)
Поскольку из основной темы вы слились, то остается повторить здесь:
Очень хочется попросить у господина смайлика решения этой задачки для любого другого статически типизированного языка. Но, боюсь, идиотизм с паре с шизофренией не оставляют шансов на получения вменяемого ответа.
void g()
{ }
void f()
{
constexpr auto a = f == g;
}
~ $ g++ -c -std=c++14 test2.cpp
test2.cpp: In function ‘void f()’:
test2.cpp:6:24: error: ‘(f == g)’ is not a constant expression
constexpr auto a = f == g;
^
Очень хочется попросить у господина смайлика решения этой задачки для любого другого статически типизированного языка.
Причём тут статическая типизация? :-) Поинт в том, что в цепепе язык шаблонов не ахти, а макросы считаются злом :-) Т.е. даже тупо сравнить 2 строчки в компайл-тайме - это целая проблема, решаемая километровыми трейтсами :-) Бугага :-)
Сам подумай :-) «ООП» - «объектно-ориентированное программирование» :-) «объектно-ориентированное» - это прилагательное :-) Понимаешь? :-) А «программирование» - это существительное :-) Правда, что на ассемблере, C, Haskell, Scheme можно программировать? :-) Если правда, то вопрос лишь в том, как это делать :-) А остальное *приложится* :-)
Я бы хотел узнать что имеется ввиду под ООП в данном случае. Потому что некие закрытые снаружи «объекты», общающиеся через сообщения, можно писать вообще на чём угодно.
Это и есть идеал ООП. Ещё важна иммутабельность возвращаемых значений, чтобы с объектом можно было общаться исключительно через его интерфейс, а не косвенно. Код в ОО-стиле действительно можно писать практически на чём угодно. Например подсистема VFS в ядре Linux использует полиморфизм, хоть и написана на чистейшем C. Другой вопрос — насколько это удобно делать.
Значит ли это, что ООП есть в ассемблере, C, Haskell, Scheme и вообще всех остальных языках программирования?
Походу, вы воспринимаете мои слова всерьез. Я лишь сказал, что после публикации статьи Армстронга, на которую вы привели ссылку, некоторые Erlang-еры стали озвучивать мнение о том, что в Erlang-е есть поддержка ООП. Как раз потому, что со слов Алана Кея ООП — это про обмен сообщениями, а раз так, то ООП в Erlang-е есть.
Это недоработка в gcc, в данном случае g - это address constant expression, который допустим в constexpr и static_assert, и msvc и clang это знают.
Да? :-) Ну ладно, я же не знал, что это недоработка gcc, поэтому и считал, что единственным решением являются простыни с полными специализациями шаблонов структур со статическими функциями-членами, именуемыми в простонародье «трэитсами» :-) Кстати, спасибо, кое-что новое узнал (про баг в gcc) :-)
Потому что некие закрытые снаружи «объекты», общающиеся через сообщения, можно писать вообще на чём угодно.
Как всегда, всё упирается не в то, что можешь писать ты, а в то, что может написать твой сосед (и с чем тебе потом придётся трахаться).
Конечно, упёртый фортранщик напишет фортран-программу и на Erlang. Но ему будет трудно. Erlang-программисту достаточно быть более-менее ленивым, и он будет писать объектно-ориентированные программы.