?

Log in

No account? Create an account

Previous Entry | Next Entry

ushastyi пишет:
…популярность и быстрый рост Джавы во многом обусловлена ее социальностью — легко научиться что-то программировать. В сравнении с внешне похожим, но куда более сложным С++, в умелых руках способным творить чудесные программы и системы.

Социальность не всегда значит хорошо. Если меня спрашивают, а такое порой случается, то в качестве языков для обучения студентов я всегда рекомендую именно асоциальные языки. Их сложность и строгость гарантируют, что человеку придется напрягать мозги и разбираться, а это безвозвратно, к счастью, не проходит. Впоследствии другие языки покажутся простыми.
Три раза дададада!!! Учеба, кстати, в отличие от работы (и научной, и инженерной), есть процесс индивидуальный, или, в этих терминах, асоциальный. Если вам предстоит обучаться вычислительной математике, учитесь программированию на функциональном, асоциальном языке. Второй язык уже может быть любым.

Tags:

Comments

thedeemon
Dec. 17th, 2011 10:36 am (UTC)
>совершенно точно делает код менее оптимальным.

Как же это? Они ж на стеке, и "выделение/освобождение" происходит у компилятора в голове - переназначением смещений стека именам. Для самой программы это вообще бесплатно. Разве что в некоторых экзотических реализациях, вроде SML/NJ, где фреймы в куче выделяются, там да, чем больше фреймов, тем медленнее.

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

Разделение на процедуры и функции плохо само по себе тем, что создает у новичка представление, будто это концептуально разные вещи. А это уже "плохому учить".
pphantom
Dec. 17th, 2011 10:54 am (UTC)
Если объем небольшой, то тогда это действительно стек (в большинстве реализаций). Но точно тот же самый результат получится и в том случае, если переменная будет объявлена где-то в начале функции/процедуры. Т.е. в этом случае разница просто отсутствует.

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

А вот разделение на процедуры и функции часто оказывается удобным. Это "одно и то же" в первую очередь с точки зрения машинной реализации (а также языков-потомков C, по той же самой причине), но не во всех случаях без исключения.
thedeemon
Dec. 17th, 2011 03:40 pm (UTC)
Как же разница отсутствует. Вот есть у нас функция, внутри которой три цикла один после другого. Внутри циклов используются свои переменные. В паскале мы должны описать их отдельно и они займут каждая свою память. А в Си-подобных языках переменные будут описаны внутри циклов, при выходе из одного цикла его переменные "перестанут существовать" и переменные следующего будут размещены физически на их месте. Памяти будет потрачено меньше, регистров распределять надо будет на меньшее число переменных, и кэш сработает лучше, все это ведет к лучшей производительности.

Процедуры и функции - одно и то же не столько с т.з. реализации, сколько в теории типов. Недаром в функциональных языках есть тип unit и его значение (). Функция из целого в целое имеет тип Int -> Int, целочисленная функция "без аргументов" имеет тип unit -> Int, процедура с целым аргументом - unit -> Int, процедура без аргументов - unit -> unit. Всякая функция что-то принимает и что-то возвращает, процедура отличается лишь типом возвращаемого значения.
thedeemon
Dec. 17th, 2011 03:43 pm (UTC)
Поправка: процедура с целым аргументом - Int -> unit.
pphantom
Dec. 17th, 2011 04:19 pm (UTC)
Это в предположении, что компилятор вообще не оптимизирует код, чего в реальной жизни сейчас уже почти не бывает.

Сейчас попробовал потестировать подобный пример на трех языках, у которых переменные описываются в "выделенных" блоках (Паскаль, Ада, Фортран) и для которых у меня под рукой есть компиляторы. Ада (GNAT) и Фортран (GFortran, SunF, Open64, IFC) сделали в точности то, что должно было получиться - области использования переменных были найдены и локализованы, лишние ресурсы не потребовались. Паскаль (FPC) не сделал этого только с полностью отключенной оптимизацией. Так что...

Процедура может модифицировать свои аргументы. Это ее главное отличие от функции, и в тех языках, где процедур нет, приходится использовать костыли для эмуляции этой возможности. Функциональные языки тут не аргумент - они иначе устроены.
thedeemon
Dec. 17th, 2011 04:43 pm (UTC)
А, это хорошо, что такая оптимизация есть.

Это где так сказано, что главное отличие процедуры в возможности модификации аргументов? В основном пишут, что главное отличие - возвращение результата, а изменяемые аргументы и у функции паскалевской могут быть. Аргумент у меня не сами ФЯ, а теория типов. Те языки просто к ней ближе.
pphantom
Dec. 17th, 2011 05:08 pm (UTC)
Именно. И читается такой код, если он правильно написан, лучше.

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