Записки программиста.
Oct. 1st, 2009 09:44 amHungarian Notation
[Отвечаю на Фимин вопрос к предидущему посту: "Пап, а что ты имеешь против Hungarian notation, просто интересно..."]
Да не то чтобы против - просто это плохо совместимо как с современными языками, так и с современными принципами программирования.
Пришло это из очень давних времен, когда основным инструментом были ассемблеры или другие языка без (или почти без) контроля типов. И - делать информацию о типе (как то, целое, плавающее и.т.д.) частью имени было остроумным способом контролировать тип полу-вручную. Скажем, переменная "weight" целочисленная; определим ее как "int_wait". Тогда, если я (или кто-то) будет ошибочно думать, что она плавающая, то напишет "float_waight" и ассемблер/компайлер немедленно схватит за руку: уж использование то неопределенных имен все ловят (впрочем, кроме фортрана).
Мне это, правда, никогда не нравилось: раздутые длинные имена переменных делали программу трудной и для написания и для чтения/понимания.
Но, другой серьезный недостаток этого класса именований состоит в том, что он противоречит одному из самых мощьных принципов - абстрагированию.
Представим себе, что нам нужно написать код для решения системы линейных уравнений, скажем, одну
из разновидностей метода Гаусса. Использование чего-то вроде HN приведет нас к тому, что мы будем думать,
с какими числами мы работаем - целыми, плавающими или еще какими. И мы напишем, скажем, программу
решающую систему уравнений с плавающими коэфициентами.
А вообще-то алгоритм от этого не зависит. Может, только зависит слегка, если мы знаем, что ьы имеем дело с полем
или кольцом. И, если имена не привязаны к типам, мы можем написать универсальный код. Он бедет правильно работать для любых чисел: плавающих, с большой точностью, комплексных. А если мы не считали, что нам нужно поле,
то и с целыми числами и даже многочленами!
Практически все современные языки для встроенных типов такой код примут. А в языках с поддержкой абстрактных типов данных - как С++ (кажется, это началось с Simula-67), мы можем без труда описать тип "многочнены от
одной переменной" или даже "многочнены от одной переменной над полем вычетов по модулю 2". И наш код будет
так же хорошо работать.
Замечу, что здесь главным является не только (а может и не столько) возможность написать более универсальный код, а еще и разбиение праблемы на две части, абстрагирующиеся дрег от дрега. В случае чисел это тривиально, а вот в случае многочленов, проблемы решения уравнений и операций с многчленами (да и опрераций с числами) совершенно независимы: нужно только знать, что, скажем, уравнения имеют дело с кольцом, а кольцо многочленов должно быть над полем.
И это позволяет применять принцип "разделяй и властвуй" - решить отдельно две небольшие проблемы всегда проще чем одну комбинированную большую. И трудность растет обычно нелинейно - не зря разделение задачи на мало зависимые, более абстрактные компоненты, часто бывает очень непростой (часто, главной) задачей создания прграммного обеспечения.
Но, впрочем, абстракции абстракциями, а скажем отличать параметры функций от других переменных я люблю -
обычно в имена параметров я добавляю подчеркивание в конец.
Еще распространено синтаксически различать этементы текущего объекта (this - я о C++, конечно) от локальных переменных - что-нибудь вроде префикса "m_" . Но я
это не люблю, потому что это нагружает использованием того-же ненужного префикса в случаях, когдо объект или пойнтер явно указаны. Уж лучше было бы форсировать написание "this->name", как это и сделано в некоторых более современных чем С++ языках.
[Отвечаю на Фимин вопрос к предидущему посту: "Пап, а что ты имеешь против Hungarian notation, просто интересно..."]
Да не то чтобы против - просто это плохо совместимо как с современными языками, так и с современными принципами программирования.
Пришло это из очень давних времен, когда основным инструментом были ассемблеры или другие языка без (или почти без) контроля типов. И - делать информацию о типе (как то, целое, плавающее и.т.д.) частью имени было остроумным способом контролировать тип полу-вручную. Скажем, переменная "weight" целочисленная; определим ее как "int_wait". Тогда, если я (или кто-то) будет ошибочно думать, что она плавающая, то напишет "float_waight" и ассемблер/компайлер немедленно схватит за руку: уж использование то неопределенных имен все ловят (впрочем, кроме фортрана).
Мне это, правда, никогда не нравилось: раздутые длинные имена переменных делали программу трудной и для написания и для чтения/понимания.
Но, другой серьезный недостаток этого класса именований состоит в том, что он противоречит одному из самых мощьных принципов - абстрагированию.
Представим себе, что нам нужно написать код для решения системы линейных уравнений, скажем, одну
из разновидностей метода Гаусса. Использование чего-то вроде HN приведет нас к тому, что мы будем думать,
с какими числами мы работаем - целыми, плавающими или еще какими. И мы напишем, скажем, программу
решающую систему уравнений с плавающими коэфициентами.
А вообще-то алгоритм от этого не зависит. Может, только зависит слегка, если мы знаем, что ьы имеем дело с полем
или кольцом. И, если имена не привязаны к типам, мы можем написать универсальный код. Он бедет правильно работать для любых чисел: плавающих, с большой точностью, комплексных. А если мы не считали, что нам нужно поле,
то и с целыми числами и даже многочленами!
Практически все современные языки для встроенных типов такой код примут. А в языках с поддержкой абстрактных типов данных - как С++ (кажется, это началось с Simula-67), мы можем без труда описать тип "многочнены от
одной переменной" или даже "многочнены от одной переменной над полем вычетов по модулю 2". И наш код будет
так же хорошо работать.
Замечу, что здесь главным является не только (а может и не столько) возможность написать более универсальный код, а еще и разбиение праблемы на две части, абстрагирующиеся дрег от дрега. В случае чисел это тривиально, а вот в случае многочленов, проблемы решения уравнений и операций с многчленами (да и опрераций с числами) совершенно независимы: нужно только знать, что, скажем, уравнения имеют дело с кольцом, а кольцо многочленов должно быть над полем.
И это позволяет применять принцип "разделяй и властвуй" - решить отдельно две небольшие проблемы всегда проще чем одну комбинированную большую. И трудность растет обычно нелинейно - не зря разделение задачи на мало зависимые, более абстрактные компоненты, часто бывает очень непростой (часто, главной) задачей создания прграммного обеспечения.
Но, впрочем, абстракции абстракциями, а скажем отличать параметры функций от других переменных я люблю -
обычно в имена параметров я добавляю подчеркивание в конец.
Еще распространено синтаксически различать этементы текущего объекта (this - я о C++, конечно) от локальных переменных - что-нибудь вроде префикса "m_" . Но я
это не люблю, потому что это нагружает использованием того-же ненужного префикса в случаях, когдо объект или пойнтер явно указаны. Уж лучше было бы форсировать написание "this->name", как это и сделано в некоторых более современных чем С++ языках.