LINUX.ORG.RU
 

Кто там кукарекал про С++?


0

11

Задача: разработать кроссплатформенное клиент-серверное приложение под Windows/Linux на С++ (boost, ace, etc.), клиент построчно считывает с консольки введёные числа, отправляет на сервер, сервер в ответ плюёт разложением чисел на простые множители. Стандартное тестовое задание, ничего интересного.

Ну что же, собрался духом, за вечер родил чуть около пол тысячи строк, чтоб всё как положено: асинхронность, многопоточность, все дела. Такое ощущение, коллеги, будто накормили грязью, кресты не умеют ни в замыкания, ни в нормальную асинхронность, ни в управление памятью, они вообще ничего не умеют. Вроде бы, написано 5 строк, а на деле почти не фига не делают, код раздут, абсолютно невыразителен, я уж не представляю что с ним будет, если его ещё раскидать на десяток классов, как это обожают делать отдельные особо одарённые личности.

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

class server
{
public:
  server(boost::asio::io_service& io_service, short port)
    : io_service_(io_service),
      acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
  {
    session* new_session = new session(io_service_);
    acceptor_.async_accept(new_session->socket(),
        boost::bind(&server::handle_accept, this, new_session,
          boost::asio::placeholders::error));
  }
  .......

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

  • Разбор параметров командной строки
  • Клиент-серверная архитектура
  • Полностью асинхронный многопоточный tcp-сервер
  • Поддержка unicode, IPv6 и BigInteger из коробки
  • Мемоизация (благодаря ленивости) из коробки
  • Полная кроссплатформенность (*nix, Mac OS, Windows etc.)
  • Правильность тривиально доказывается мат. индукцией по коду
  • Исходник чуть больше 60 строк (в 8 раз меньше, чем на крестах)

Если поднатужиться (я не стал) и заменить алгоритм нахождения простых чисел/простых множителей на более оптимальный, то ко всему прочему получаем автоматическую распараллелизацию алгоритмов из коробки (см. Data Parallel Haskell) и произодительность на уровне чистого Си/Фортрана.

Кто там пищал, что хаскель сугубо академический язык, что ничего реальго на нём написать невозможно? Кто там кукарекал про С++? Как вы с ним вообще работаете? Это же мазохизм в чистом виде (см. мыши и кактус)


[#]  

так ты это, не тушуйся, пиши то-то серьезное на хаскеле, потом все покажешь, а то красивые примеры на 60 строк можно для любого ЯП найти, в том числе и для С++

anonymous ()
[#]  
pianolender

c/с++ - по новым меркам довольно низкоуровневые языки. Задачи на них решать можно, работают решения хорошо (ну то есть как написать, конечно). То, что строк кода получается больше - это не обязательно показатель того, что объем кода пропорционально вырос, потому что такие вещи как, например, обозначение структурных блоков ('{','}'), которые в современных языках вроде питона делаются мночисленными и многообразными whitespace-символами, занимают отдельные строки. Это едва ли может служить аргументом против вашего тезиса, но сравнивать лучше байты, а не строки.

Ну, а "сложность" восприятия и написания кода на c/c++ - это плата за гибкость и универсальность, думаю.

* ()
[#] Ответ на: комментарий от pianolender 09.02.2012 13:57:17  
encyrtid
>>-----Цитата---->>

Ну, а "сложность" восприятия и написания кода на c/c++ - это плата за гибкость и универсальность, думаю

<<-----Цитата----<<

Употребление таких слов как "гибкость" в одном предложении с C++ следует приравнивать к грамматическим ошибкам.

** ()
[#]  
>>-----Цитата---->>

накидал за полчаса решение на Haskell

<<-----Цитата----<<

Читер ;) Иш какой умный. На хаскеле-то любой сможет! А ты на C++ смоги!

Основная проблема GHC, это наверное динамическая линковка. Поддерживать он ее поддерживает... Но как-то странно: развертывание она не упрощает, размер не снижает, и DLL-hell'у способствует.

**** ()
[#]  
geekless

Всё правильно. Вот как раз недавнее обсуждение аналогичного вопроса: http://users.livejournal.com/_winnie/335669.html (в комментах там и аналог того же кода на хаскеле дан)

Сейчас пилят такой язык как OCC, возможно это будет наконец-то статически типизированный ООП язык с человеческим лицом.

** ()
[#] Ответ на: комментарий от geekless 09.02.2012 14:09:16  
>>-----Цитата---->>

Сейчас пилят такой язык как OCC

<<-----Цитата----<<

Опять пытаются запилить глючную реализацию System F в смысле Хиндли-Милнера?

**** ()
[#]  
>>-----Цитата---->>

Кто там пищал, что хаскель сугубо академический язык, что ничего реальго
на нём написать невозможно? Кто там кукарекал про С++?
Как вы с ним вообще работаете?
Это же мазохизм в чистом виде (см. мыши и кактус)

<<-----Цитата----<<

Г. вопрос, давай аналог skype на вашем убогом хаскеле
со всем функционалом как в skype

anonymous ()
[#] Ответ на: комментарий от pianolender 09.02.2012 13:57:17  
>>-----Цитата---->>

в современных языках вроде питона

<<-----Цитата----<<

Окстись, какой [нецензурно] питон? Идея была предложена Питером Ландиным, отцом внедрения лямбда-исчисления в языки программирования. А именно в его языке ISWIM (прямой предок ML) в 1966-м (!!!!!) году.

**** ()
[#] Ответ на: комментарий от Macil 09.02.2012 14:17:50  
geekless
>>-----Цитата---->>

Окстись, какой [нецензурно] питон? Идея была предложена Питером Ландиным, отцом внедрения лямбда-исчисления в языки программирования. А именно в его языке ISWIM (прямой предок ML) в 1966-м (!!!!!) году.

<<-----Цитата----<<

Ну питон это современный язык — факт. А кто там когда что придумал, никого не волнует. Все современные идеи IT растут из 60-х, это вполне очевидно. Просто некоторым идеям потребовалось полвека, чтобы "обычные программисты" до них доросли.

** ()
[#]  

Выложи свое решение, поржем вместе.

>>-----Цитата---->>

Вроде бы, написано 5 строк, а на деле почти не фига не делают,

<<-----Цитата----<<

вынеси в метод и не будет

>>-----Цитата---->>

код раздут

<<-----Цитата----<<

Сдается у кого-то просто руки из жопы...

()
[#] Ответ на: комментарий от PiPi 09.02.2012 14:48:02  
>>-----Цитата---->>

вынеси в метод и не будет

<<-----Цитата----<<

Так вот у кого ООП головного мозга, теперь понятно.

>>-----Цитата---->>

Сдается у кого-то просто руки из жопы...

<<-----Цитата----<<

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

>>-----Цитата---->>

код раздут

<<-----Цитата----<<

Основная проблема, в том, что С++-фанатики ничего другого, кроме этого высера мертвого страуса, и не знают. Поэтому вношу поправку: код оче сильно раздут, по сравнению с нормальными языками.

* ()
[#] Ответ на: комментарий от mix_mix 09.02.2012 14:55:43  
Reaper

> То есть и код в бустовской доке уже не в счёт

Ты бы свой показал, а не из доки бустовской, кто тебя знает, чё ты там понаписал.

** ()
[#] Ответ на: комментарий от PiPi 09.02.2012 14:48:02  
>>-----Цитата---->>
>>-----Цитата---->>

Вроде бы, написано 5 строк, а на деле почти не фига не делают,

<<-----Цитата----<<

вынеси в метод и не будет

<<-----Цитата----<<

Гениально! Теперь я тоже знаю.

()
[#] Ответ на: комментарий от mix_mix 09.02.2012 14:55:43  

если надо писать серьезный софт - берется ace, если поделку вроде твоей - Qt, и строк кода там будет столько же, хватит уже ныть по поводу буста

anonymous ()
[#] Ответ на: комментарий от geekless 09.02.2012 14:09:16  
>>-----Цитата---->>

статически типизированный ООП язык с человеческим лицом

<<-----Цитата----<<
>>-----Цитата---->>

по ссылке: разбить строку в список, отсортировать и отбросить повторяющиеся значения [...] Функция написана на страшной смеси Си и Си++ (кстати, а что, в STL не предусмотрен алгоритм split для строк? что за каменный век?) и занимает добрую экранную страницу

<<-----Цитата----<<

Ох лол, и то правда. Разбить строку?

istringstream iss(str);
vector<string> tokens;
copy(istream_iterator<string>(iss),
         istream_iterator<string>(),
         back_inserter<vector<string> >(tokens));
или
typedef vector< string > split_vector_type;
split_vector_type SplitVec;
boost::split( SplitVec, str1, boost::is_any_of("\t ") );

О боже, как же это красиво и элегантно!

* ()
[#] Ответ на: комментарий от anonymous 09.02.2012 15:05:22  

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

anonymous ()
[#] Ответ на: комментарий от mix_mix 09.02.2012 15:06:28  
>>-----Цитата---->>

О боже, как же это красиво и элегантно!

<<-----Цитата----<<

QStringList tokens = str1.split( "\t " );

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

anonymous ()
[#]  

Кто-то должен был это запостить

Почему я не люблю С++

1) Не может в управление памятью 2) Не может в LALR грамматику 3) Как следствие, не может в человеческий синтаксис 4) Не может в денотационную семантику 5) Не может в настоящие макросы (с темплейтами отсос - не могут в квазицитирование) 6) Следствие - не может в человеческий полиморфизм (не говоря про higher-order), только убогое кодовысерание. 7) Не может в referential transparency 8) Linear typing ... и остальные миллиарды отсосов

Зато может в: 1) Нетипизированный секс с указателями 2) Аппликативный порядок 3) УТЕЧКИ УТЕЧКИ УТЕЧКИ 4) Зловонную кучу Стандартов не реализованных в полном объеме ни одним компилятором 5) Стандарты наполовину состоят из undefined behavior и implementation-defined 6) Следовательно, миллиард практически не диагностируемых "приятных" неожиданностей. etc.

anonymous ()
[#] Ответ на: Кто-то должен был это запостить от anonymous 09.02.2012 15:19:46  

Re: Кто-то должен был это запостить

Почему я не люблю С++

1) Не может в управление памятью
2) Не может в LALR грамматику
3) Как следствие, не может в человеческий синтаксис
4) Не может в денотационную семантику
5) Не может в настоящие макросы (с темплейтами отсос - не могут в квазицитирование)
6) Следствие - не может в человеческий полиморфизм (не говоря про higher-order), только убогое кодовысерание.
7) Не может в referential transparency
8) Linear typing
... и остальные миллиарды отсосов

Зато может в:
1) Нетипизированный секс с указателями
2) Аппликативный порядок
3) УТЕЧКИ УТЕЧКИ УТЕЧКИ
4) Зловонную кучу Стандартов не реализованных в полном объеме ни одним компилятором
5) Стандарты наполовину состоят из undefined behavior и implementation-defined
6) Следовательно, миллиард практически не диагностируемых "приятных" неожиданностей.
etc.

anonymous ()
[#] Ответ на: комментарий от anonymous 09.02.2012 15:11:42  
geekless
>>-----Цитата---->>

QStringList tokens = str1.split( "\t " );

<<-----Цитата----<<

Ага, и сразу возникает вопрос, почему QStringList, а не абстрактный Iterable<String> или Iterator<String>. Он хотя бы унаследован соответствующим образом?

>>-----Цитата---->>

берешь нужную библиотеку и

<<-----Цитата----<<

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

** ()
[#] Ответ на: комментарий от geekless 09.02.2012 15:22:15  
>>-----Цитата---->>

Он хотя бы унаследован соответствующим образом?

<<-----Цитата----<<

он не должен наследоваться, все необходимое для совместимости с STL есть

>>-----Цитата---->>

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

<<-----Цитата----<<

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

anonymous ()
[#] Ответ на: комментарий от anonymous 09.02.2012 15:33:25  
geekless
>>-----Цитата---->>

предлагаешь все засунуть в ЯП, чтоб обеспечить единообразие?

<<-----Цитата----<<

Намекаю, что всю историю выросших из Си языков можно описать как историю попыток реализовать тип String.

** ()
[#] Ответ на: комментарий от geekless 09.02.2012 15:37:35  
>>-----Цитата---->>

Намекаю, что всю историю выросших из Си языков можно описать как историю попыток реализовать тип String.

<<-----Цитата----<<

В хаскеле с этим тоже не фонтан: Есть String, ByteString и Text. Причем, два последних в lazy и eager вариантах.

**** ()
[#] Ответ на: комментарий от geekless 09.02.2012 15:37:35  
>>-----Цитата---->>

Намекаю, что всю историю выросших из Си языков можно описать как историю попыток реализовать тип String.

<<-----Цитата----<<

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

anonymous ()
[#] Ответ на: комментарий от LongLiveUbuntu 09.02.2012 15:49:52  
>>-----Цитата---->>

У меня к тебе большая просьба: сделай вменяемую IDE для Хаскелля и я с удовольствием буду на нем писать.

<<-----Цитата----<<

Emacs же. Нужно только правильно научиться его готовить.

* ()
[#] Ответ на: комментарий от LongLiveUbuntu 09.02.2012 15:49:52  
snefjyent
>>-----Цитата---->>

У меня к тебе большая просьба: сделай вменяемую IDE для Хаскелля и я с удовольствием буду на нем писать.

<<-----Цитата----<<

Emacs.

()
[#] Ответ на: комментарий от anonymous 09.02.2012 15:50:59  
geekless

Блин, всё, выключаю сарказмогенератор.

Речь шла не только о строках, но и вообще о стандартных типах языка: контейнерах, классах для IO и т.п. Количество велосипедов, разработанных в этой области, просто выходит за все разумные пределы. А виной тому во многом, в числе прочего, бедность выразительных средств языка. Системы типов, в частности.

Ну и отдельно не удержусь и пну, какими средствами в C++ реализуется "модульность". Заголовчные файлы — это модно и прогрессивно, чо.

** ()
[#]  
qnikst

а где там закрытие сокетов и т.д.? (не знаю как в бусте, но в вышеприведённом коде уж совсем скелет сервера)

** ()
[#] Ответ на: комментарий от geekless 09.02.2012 15:22:15  
>>-----Цитата---->>

Ага, и сразу возникает вопрос, почему QStringList, а не абстрактный Iterable<String> или Iterator<String>. Он хотя бы унаследован соответствующим образом?

<<-----Цитата----<<

Ты не поверишь, да, QStringList это и есть наследованный QList<QString>, но с небольшими плюшками, типа фильтрации по регэкспу и тд. :)

* ()
[#] Ответ на: комментарий от geekless 09.02.2012 15:57:42  
>>-----Цитата---->>

Речь шла не только о строках, но и вообще о стандартных типах языка: контейнерах, классах для IO и т.п. Количество велосипедов, разработанных в этой области, просто выходит за все разумные пределы.

<<-----Цитата----<<

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

>>-----Цитата---->>

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

<<-----Цитата----<<

для хаскеля, например, есть такой же набор велосипедов, хоть и поменьше конечно - т.к. ЯП менее распространен, особенно среди "нубов"

>>-----Цитата---->>

какими средствами в C++ реализуется "модульность". Заголовчные файлы — это модно и прогрессивно, чо.

<<-----Цитата----<<

зато есть и плюс - совместимость с С

anonymous ()
[#]  
vertexua

Мы ведь таки говорим о High Performance и Heavy Load, иначе к чему понты с асинхронностью, производительностью?

Часто проблема построения High Performance систем в том, что вы верите что имплементация платформы работает быстро. Вот есть актеры, которые позволяют упрощать паралельные вычисления путем эфективного использования ядер процесора и распределении работы актеров среди них. Есть обычные актеры Scala и актеры Akka - известные решения. Проблема в том, что часто решение на базе актеров на Scala, которое использует 8 ядер будет медленнее однопоточного кода на С++. Тут нужно все бенчмаркать и говорить о конкретных числах.

Насколько ваше волшебное решение на хаскелле быстрее кода на С++ в реальном бенчмарке? Ведь там же асинхронность, мемоизация... )

*** ()
[#] Ответ на: комментарий от Waterlaz 09.02.2012 16:24:50  
>>-----Цитата---->>

Динамическая линковка нафиг не нужна.

<<-----Цитата----<<

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

Кроме того, динамическая линковка теоретически должна упрощать развертывание (при наличии стабильного ABI). Ну и разделяемая память - не пустой звук вообще-то.

**** ()