четверг, 25 декабря 2008 г.

Программистам нужны простые решения?

В своем интервью Don Syme (главный разработчик языка программирования F#) сказал, что сейчас программистам нужны простые решения:

People thirst for simplicity. People need simple solutions to the problems that really matter: data access, code development, deployment, cloud computing, Web programming, and parallel programming, to name a few.

Будучи сам программистом, я не могу согласиться с таким утверждением. Мне не нужны простые решения. Простое решение, это, например, язык Oberon. Ну и где он, кто им пользуется? Даже Java и C#, которые начинались как гораздо более простые инструменты, чем C++, сейчас по сложности или приближаются к нему, или уже превзошли (в частности, C# 3.0 и готовящийся к выходу C# 4.0). Программистам нужны мощные решения. А мощность и простота редко идут рядом. Что действительно нужно, на мой взгляд, так это многослойное решение, которое можно изучать и применять, постепенно переходя от простого к сложному, как бы снимая слой за слоем. При этом обеспечивается легкое и быстрое получение первых результатов. По сути, человек быстро и незаметно подсаживается на иглу. После чего он вынужден либо изучать инструмент более тщательно, либо менять инструмент. Для достижения такой многослойности, как мне кажется, нужно придерживаться нескольких правил (все нижеследующее относится к инструментам, которые действительно делают что-то полезное): 1. Решение (инструмент) должно быть построено на основе небольшого количества простых идей и понятий. Например, SObjectizer в своей основе имеет только агентов с их состояниями, сообщениями и событиями. Все остальное, это надстройка над ними. 2. Решение (инструмент) должно быть снабжено хорошими обучающими материалами и документацией. Понятие "хороший", конечно же, субъективно. Но, например, изучать Ruby по книге "Programming Ruby" гораздо проще, чем C++ по книге "The C++ Programming Language". А все из-за того, насколько по-разному в каждой из книг построена подача материала – в одной идет плавное погружение человека в новый для него язык, а во второй – практически мгновенный переход к деталям. Поэтому что-то вроде Tutorial или Developer Guide с последовательным изложением тем от простого к сложному, это must have. При несомненной важности подобного обучающего руководства обязательно должно быть что-то вроде полного описания всех его классов, функций и пр. -- подробный Reference Manual. Поскольку очень обидно, когда после прочтения Tutorial-а пытаешься сделать что-то свое и негде найти список параметров какого-то метода. 3. Инструмент, если речь идет о более-менее серьезной библиотеке, должен иметь API нескольких уровней. Верхний уровень позволяет очень просто выполнять наиболее общие или наиболее востребованные действия. На этом уровне широко используются умолчания и пользователь, как правило, не имеет возможности делать какие-то тонкие настройки. Например, если какая-то операция полагается на использование пула потоков (thread pool), то пользователь не может указать какой именно пул потоков должен использоваться, сколько в этом пуле должно быть потоков, с каким приоритетом они должны работать и пр. Как раз такой верхний уровень API призван обеспечить легкое получение первых результатов у новых пользователей. Хороший пример – это параметры таких шаблонов, как std::vector, которые имеют значения по умолчанию. Вот, скажем, есть у std::vector такой параметр, как Allocator. А подавляющему большинству C++ программистов никогда не приходится его определять самостоятельно. Под верхним уровнем должно быть несколько более низких уровней, каждый из которых требует от программиста все лучшего и лучшего знания инструмента и понимания того, чего же программист хочет достичь. Но при этом программисту предоставляется все больше и больше возможностей. Ярким нарушением этого принципа, мне кажется, является библиотека Poco. В ней, к примеру, есть классы ActiveMethod и ActiveResult, которые используются для реализации фьючерсов. Но указать ActiveMethod, на каком именно пуле потоков должен выполняться асинхронный вызов метода нельзя. 4. Решение (инструмент) должно быть снабжено большим количеством примеров разнообразных способов его использования. Качественных примеров. Ведь зачастую фрагмент из примера посредством copy-and-paste переносится в код пользователя. Или же пример используется в качестве "рыбы" для программы пользователя. Обидно, когда библиотека содержит только примеры вида "Hello, world", либо не содержит примеров вовсе – в качестве таких примеров пытаются выдать unit-тесты. Хотя, например, в случае с ACE распространяемые с ACE тесты довольно часто оказываются вполне хорошими примерами и серьезно помогают во время изучения очередной возможности ACE. Но это, скорее, исключение. Не так уж и мало всего перечислил. Что, на мой взгляд, еще раз подчеркивает одно житейское наблюдение – не бывает простых решений сложных проблем. И для того, чтобы сделать что-то, что создает впечатление простого, нужно приложить немало усилий. Как замечательно сказал Алан Перлис:
Simplicity does not precede complexity, but follows it.
(источник).

Комментариев нет: