LINUX.ORG.RU

[C++?] Серьезный вопрос.


3

2

Просьба ответит серьезно, желательно с аргументами за или против.

Предистория:
Когда то давным давно (я тогда еще только закончил 9-ый класс) я увидел в газете объявление о наборе в летнюю группу по изучению классического программирования. В тот момент я был с компьютером на ты и "очень" хорошо в них разбирался (переустанавливал Windows каждый месяц, хаял Microsoft просто потому, что после моих настроек W приходилось постоянно переустанавливать). Группа по классическому программированию так и не набралась, но набралось 1 человек на Visual Basik for Applications. Я соглсился быть вторым и начались занятия.
Все, что мне там объясняли я схватывал быстро. Меня пригласили продолжить обучение в сентябре на курсе "моделирование".
Там уже был Pascal, который я тогда совсем не знал. Сам курс был очень разношорстный: мы изучали и использование мыши через прерывание, готовились к различным олимпиадам. Параллельно я изучил Pascal.
Потом был Delphi. К концу 10-го класса я уже неплохо владел приемами программирования и вовсю клепал бесполезные программулины. Потом поступил в универ на программиста. Там тоже был Delphi, и я особо не напрягаясь писал все лабы (к моменту поступления я уже был знаком с логикой указателей, самописные стеки и графы, etc).
На 2-ом курсе в гостях у знакомого я разобщался с человеком, который уже насколько лет работал в нерезиновой программистом. Он мне и открыл глаза на мир: "Delphi здох. Его уже похоронили и забыли. Сейчас необходимо знание C++, C#. Необходимо занание паттернов проектирование". Вобщем много чего он мне наговорил. Книжек умных насоветовал, подкинул MSVS 2008, кучу электронных книжек. Я изучил C# по книжке Шилдта. Читал "Идеальный кол" (автора уже не помню). Потом купил(!) себе книжку Шилдта про С++. Мне понравился язык. Тем более что мне казалось, что именно он и есть общепринятый стандарт. Наиболее удобный язык для программиста.

А недавно в соседней теме за упоминание это С++ меня чуть было не съели со всем чем можно. Так-то.

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

Спасибо всем, кто осилил это многобукаф.

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

> получить сериализацию потока? чтобы потом можно было его десериализовать и запустить снова?

Ненавижу, бл*дь, термин "поток".

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

>> Что-то типа http://cvs.haskell.org/Hugs/pages/libraries/base/Data-Graph.html?

> Подозреваю, что там используется нециклическое представление (??).

Для представления циклической структуры можно воспользоваться указателями, но работать в таком случае придётся в монаде IO

> Если да, то это может быть иногда крайне неэффективно.

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

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

> Проблема в том, что в момент создания объекта а нам нужен уже готовый объект b, и наоборот. Либо мутабельность...

Ну дык вроде с помощью монад должно легко делаться...

kemm
()
Ответ на: комментарий от unC0Rr

>это ещё и фамилия

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

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

>А еще как быть с реализацией событийной модели, где есть объект, испускает событие, и есть другой объект, который слушает это событие?

а вот в этом смысле хаскельное FRP (тот же Reactive) уделывает многих:

http://netsuperbrain.com/blog/

можно ещё посмотреть на Yampa, там очень красивая событийная модель (но проект не развивается); классические observer-like (push/pull) модели есть в Grapefruit

>Если хаскель это позволяет делать

насчёт циклических структур данных не скажу (хотя сомневаюсь, чтобы это было действительно так уж проблематично), а касательно FRP могу утверждать однозначно; более того, если будет желание с этим повозиться и возникнут вопросы - feel free to contact me :)

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

>Имха, лучшие варианты. Не допускают неоднозначностей.

ну ок, уговорили

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

>А можно сделать так, чтобы объект а указывал на объект b, который в свою очередь указывал на объект а?

можно

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

Спасибо, но я пока решил для начала разобраться с окамлем. Думаю в будущем заюзать f# для одной задачи конвертирования из одного предметного языка в другой. Чтобы импортировать чужие файлы.

Значит, хаскель позволяет это сделать. Буду знать.

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

> Да, время компиляции действительно увеличивается примерно в 2 раза, но по-моему это не так критично.

10 раз в сравнении Си такого же объёма - легко. И это не предел.

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

>>Ненавижу, бл*дь, термин "поток".

> thread, тред, нить, что ещё? какой вариант лучше?


Лучшим вариантом будет записать "поток" в маленькую чёрную книжечку и потом гнобить им tailgunner'а, где ни попадя =)

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

>Лучшим вариантом будет записать "поток" в маленькую чёрную книжечку и потом гнобить им tailgunner'а, где ни попадя =)

благодарю за идею :)

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

>Топикстартер ушел учить С++ =)

что ж, подождём пока вернётся. если он ещё вернётся, конечно

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

>И большая разница по эффективности и объёму работы между макросом вокруг qsort и шаблоном?

Огромная. Макрос же может только создать функцию с именем qsort_int/qsort_unsigned_int. А имена-то тебе придумывать.

Но самое главное, что ты некисло извратишься для эффективного сравнения, т. к. в одном случае надо непосредственно "<" или ">" по месту втыкать, а в другом -- функции для сравнения. Поэтому у тебя будет еще куча макросоподобной бяки, чтобы обеспечить эффективность. В случае с template все уже сделано за тебя наилучшим образом.

linuxfan
()
Ответ на: комментарий от dave

Проблема в том, что в момент создания объекта а нам нужен уже готовый объект b, и наоборот. Либо мутабельность...

Зависит от задачи, но иногда можно обойтись и без монад, а лишь ленивостью:

data Fancy = Fancy {
                value ::Int, 
                nextFancy :: Fancy
                }

createFancyPair a b = let x = Fancy a y
                          y = Fancy b x
                       in (x, y) 
                       
(x, y) = createFancyPair 1 2
main = do
    print ( value x )
    print ( value y )
    print (value $ nextFancy x)
    print (value $ nextFancy $ nextFancy x)
Waterlaz ★★★★★
()
Ответ на: комментарий от mv

>10 раз в сравнении Си такого же объёма - легко. И это не предел.

Бустами и template'ами не злоупотребляй. Не можешь -- продолжай поклоняться мультиметодам и клевым defmacro.

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

> Бустами и template'ами не злоупотребляй. Не можешь -- продолжай поклоняться мультиметодам и клевым defmacro.

Спасибо за беспокойство, но моя работа, к сожалению, - голый Си. Кстати, можешь в списочек ещё MOP добавить, он мне в последнее время превелико доставляет.

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

> А можно пару ссылок на проекты где MOP используется? Интересно посмотреть.

Поиском по ~/.asdf/site:

http://www.cliki.net/Philip-Jose
http://www.cliki.net/cl-gtk2
http://www.cliki.net/cl-serializer
http://www.cliki.net/cl-walker

Это что от "причёсанного" MOP в виде Closer to MOP зависит (MOP в ANSI CL не включён, поэтому разные реализации его по разному умеют). Список непричёсанных, самостоятельно обврапливающих разные реализации, куда больше будет.

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

>эээ...щито? каким образом я должен заюзать boost, чтобы получить сериализацию потока? Я ссылку прикрепил. Применяешь то, что там написанно для кутэшного объекта потока, например. Также вроде бы в MPI есть средства для сериализации (точно сказать не могу, так как не разу не приходилось пользоваться), что позволяет тебе "замораживать" и более сложные модели, например, с разделяемой между процессами/тредами памятью или со взаимным закидыванием сообщениями.

>при чём тут массивы/векторы - не уловил Массиы/векторы - это я насчёт сериализации любого типа объектов тем методом уже писал. Ну, что если там есть обычные динамические массивы, то так уже не получится.

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

> Я ссылку прикрепил. Применяешь то, что там написанно для кутэшного объекта потока, например.

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

kemm
()
Ответ на: комментарий от linuxfan

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

FAIL дважды -- 1. попытки испугать ежа голой жопой^W^W^W выпускника матмеха СПбГу с красным дипломом и 2. я не фанат ленивых вычислений

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

О Мудрейший, ты просветил меня и т.д.

А теперь просвети дальше. Есть быдлозадача -- написать функци посчета определенного интеграла от a до b от функции f. Допустим, для простоты, что точность подсчета задана раз и навсегда -- это 2-й двоичный знак с конца double, и в качестве аргумента не передается. Напиши пожалуста объявление (декларацию, прототип) этой функции на Си (1 строка).

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

> И большая разница по эффективности и объёму работы между макросом вокруг qsort и шаблоном?

Макрос, для начала, будет вместо qsort, а не вокруг.

На *стандартном* С быстро найдутся случаи, когда ты обломишься. Если же юзать гнутые расширения ( typeof, ({}), локальные метки, ...), то можно наваять достаточно много.

Кстати, exception-unsafe код можно писать и на С. В знаменитом sendmail был один баг c setjmp/longjmp, который можно назвать именно так.

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

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

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

>>эээ...щито? каким образом я должен заюзать boost, чтобы получить сериализацию потока?

>Я ссылку прикрепил. Применяешь то, что там написанно для кутэшного объекта потока, например.

Ого! :-D

Слушай, зачем тебе программировать, а? Есть другие интересные компьютерные профессии, например, "оператор ПК".

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

>Напиши пожалуста объявление (декларацию, прототип) этой функции на Си (1 строка).

double integral(const double a,const double b,double (*f)(const double x));

В чем подвох?

>FAIL дважды -- 1. попытки испугать ежа голой жопой^W^W^W выпускника матмеха СПбГу с красным дипломом и 2. я не фанат ленивых вычислений

Мое мнение о краснодипломниках ухудшилось -- что я могу еще сказать.

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

> На *стандартном* С быстро найдутся случаи, когда ты обломишься. Если же юзать гнутые расширения ( typeof, ({}), локальные метки, ...), то можно наваять достаточно много.

Хмм, интересно, перенесётся ли это на ICC? (с MSVC++ всё ясно)

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

>double integral(const double a,const double b,double (*f)(const double x));

А почему не double integral(const double a,const double b,double (*const f)(const double x)) тогда уж?

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

>Можно и так.

А в чем фан того чтобы ставить квалификатор const на параметры, передающиеся по значению?

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

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

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

double integral(const double a, const double b, double (*f)(const double x));

В чем подвох?

Лямбды у тебя нет, вот в чем (и напомню, тут Си, а не плюсы).

Как ты запишешь теперь вот такое:


double integral( const double a, const double b, double (*f)(const double x) );
double g(double x, double y, double z); /* код из внешней библиотеки */ 

double h(unsigned int n) {
  double r=0, N=n;
  unsigned int i=0;
  for( ; i<n; i++ )
    r += integral( 0, 1, ( double x => integral( 0, 1, ( double y => g(x,y,i/N) ) ) ) );
  return r/N;
}

без лямбды? Чтобы твои костыли не выглядели слишком просто, напомню — у нас числодробилка, так что функции g, h, integral (и вообще, все что ты понапишешь) могут вызываться из разных нитей одновременно (так что static юзать нельзя).

З.Ы. void* в pthread_create не зря стоит — так же придется переписать прототип твоего integral-а

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

> Хмм, интересно, перенесётся ли это на ICC?

У интеля на сайте есть таблица поддержки расширений жцц. Так что практически -- да.

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

Параметрические функции? Ну что ж, расширишь определение интеграла. Без лямбд вполне себе живется. И напоминаю: лямбда-функции без захвата лексического окружения (замыкания или closures) не нужны.

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

> Ну что ж, расширишь определение интеграла. Без лямбд вполне себе живется.

Не-не-не.

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

А мы посмотрим на эти попытки и на получившийся код "взрыв на макаронной фабрике".

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

>То есть лямбды в C++ не нужны на твой взгляд?

На мой взгляд, острой необходимости в них нет.

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

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

Если тебе нужна параметрическая функция, то все что надо — передать дополнительные параметры в функцию вычисления интеграла и соответствующим образом подправить функцию f. Это даже не C++, это чистый C.

С плюсами:

template<typename T,typename F>T integral(const T a,const T b,F f);

struct parametric_f {
  double param1, param2, param3;
  parametric_f(double p1,double p2,double p3) : param1(p1), param2(p2), param3(p3) {}
  double operator()(double x) {...}
};

// использование
double int = integral(1.0,2.0,parametric_f(4,5,6));
linuxfan
()
Ответ на: комментарий от linuxfan

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

То есть твой протип integral-а оказался все же неправильным? Тогда напиши правильный прототип (или, альтернативно, строй костыли для передачи дополнительных параметров иным способом). Напомню, речь идет о Си.

> и соответствующим образом подправить функцию f

Код, пожалуста (эквивалентный моему). Ведь "Без лямбд вполне себе живется".

> double int = integral(1.0,2.0,parametric_f(4,5,6));

( double int ? )

Плюсовые примеры приводить не надо (если твой код почистить и улушить, то получится что-то типа bind2nd, которому по юзабилити даже до boost::lambda далеко)

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

Напомню, речь идет о Си.

Если речь идет о C, то void *params в качестве дополнительного параметра решает все проблемы.

Код, пожалуста (эквивалентный моему).

Какой «твой код»? Что-то я кода в упор не вижу, только какой-то невнятный «псевдокод».

Плюсовые примеры приводить не надо (если твой код почистить и улушить, то получится что-то типа bind2nd, которому по юзабилити даже до boost::lambda далеко)

Я определенно расхожусь с тобой во мнении относительно возможности использовать boost::lambda.

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