python

Копают только вниз

  • суббота, 21 ноября 2015 г. в 02:10:54
http://habrahabr.ru/company/piter/blog/271347/

Здравствуйте, уважаемые читатели.

В последнее время нас заинтересовала серия Зеда Шоу "The Hard Way", которую хотелось бы как минимум частично перевести на русский язык. Поскольку порой мы действительно не ищем легких путей, начать хотелось бы с книги о языке C:



Серия ориентирована в первую очередь на начинающих. Для тех, кто любит язык C, а также для их оппонентов, полагающих, что лучше стартовать с чего-нибудь попроще, мы публикуем немного сокращенную статью Эвана Миллера, написанную в конце прошлого года. Возможно, в зависимости от реакции на эту статью, мы решим дополнительно перевести и опубликовать отрывок из книги мистера Шоу либо даже его ответ на критику, высказанную Тимом Хентенааром, а пока приглашаем вас под кат, где, как нам представляется, изложены самые общие соображения в пользу актуальности этой книги.

Когда я учился водить машину (мне тогда было чуть больше 15), мама настаивала, чтобы я практиковался на отцовской Mazda Miata: это был серебристый двухдверный кабриолет с откидным верхом.

Управлять «Миатой» было непросто. Мало того, что в ней не было автоматической коробки передач, вдобавок из этой машины было практически невозможно заглянуть назад. Солнце настолько прожарило пластиковое заднее стекло, что на свернутом откидном верхе, казалось, можно было готовить бутерброды.

«Миата» отнюдь не была и самой безопасной машиной, причем компания «Mazda Motor Corporation» даже не пыталась утверждать обратное. Это была просто доступная машина, на которой приятно кататься, такая бюджетная BMW. Помню, отцовская «Миата» была такой узкой и приземистой, что когда я ездил на ней по федеральной магистрали, даже закрадывались мысли: «А если я попытаюсь проскочить на ней под полуприцепом, дальнобойщик что-нибудь заметит»?

Еще у нас был минивэн и внедорожник — более крупные и надежные машины с прозрачными задними стеклами. Многие родители предпочли бы учить подростка вождению именно на них. Но не моя мама.

«Однажды ты окажешься на вечеринке», — объясняла она мне с уверенностью, которой позавидовал бы Нострадамус, — «и там будет машина, которую никто не сможет вести, потому что у нее будет ручное переключение скоростей. А ты должен суметь, и учиться этому нужно сейчас, иначе никогда не справишься с ручкой переключения».

Осваивать ручную коробку передач — не самое интересное занятие, и я думаю, что никогда бы этим не занялся, если бы не тот пророческий авторитет, которым пользовалась мама у нас дома. Но, напрактиковавшись, я в итоге смог ездить на «Миате» в пределах разрешенной скорости, не заливая водительское сиденье потом и слезами.

С тех пор прошло много лет, и я заметил интересную закономерность. Мы, гордое меньшинство — закаленные мастера ручной передачи — оказались гораздо более умелыми, чем те, кто привык полагаться на коробку-автомат. Мы увереннее владели машиной, лучше представляли себе, как работает двигатель автомобиля. Даже если нам ни разу не доводилось заглянуть внутрь коробки передач, мы знали, что такое «повышающая передача» в автоматической коробке, как с ее помощью экономить бензин. Мы знали, что означают таинственные цифры 1 и 2 под надписью «Drive», какую службу они могут сослужить, когда съезжаешь по склону. И в каждый момент времени мы, вероятно, на интуитивном уровне лучше представляли себе, что происходит с машиной — лучше, чем приверженцы автоматической коробки.

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

Любезный читатель, я написал все это не для того, чтобы отрекламировать себя в качестве превосходного водителя малобюджетных кабриолетов, и не чтобы выступить против засилья автоматических коробок в автомобильной индустрии. На самом деле, я просто усматриваю важные параллели между распространением таких коробок в автопроме и языка Python — в программировании.

Python удобен, во многих отношениях он значительно превосходит язык C. Но если вы приучите подростка ездить на автоматической коробке передач, то можете быть практически уверены, что он и не подумает осваивать переключение скоростей. Советуя неофитам изучать Python, мы плодим неофитов, которые никогда не попробуют писать код на C. Думаю, это плохо.

Высказывая это мнение, я оказываюсь в меньшинстве, поэтому тем более хочу пояснить здесь мою точку зрения. Не так давно Python потеснил Java в качестве самого популярного вводного языка программирования, изучаемого в университетах. Эрик Рэймонд, автор программной статьи «How To be a Hacker» рекомендует Python в качестве первого языка. Его безусловно поддерживает Питер Норвиг в своей знаменитой работе “Teach Yourself Programming in Ten Years”. Пол Грэм даже рассказывает о специфическом «Парадоксе Python».

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

Вопреки поверхностной привлекательности Python — его синтаксиса, интерактивности, библиотечной поддержки, широкого сообщества и превосходной документации — выбирая его в качестве первого языка программирования, вы сталкиваетесь с серьезной проблемой. Программист, знающий только Python, не обладает достаточными представлениями о работе компьютера. Он может воспринимать C в качестве мистического искусства, вызывающего смешанные чувства страха и неприязни. Страха — потому что программисту рассказали, что C сложен, а неприязни — потому, что сложности C якобы являются морально устаревшими пережитками более аскетичных времен. Появился даже новый трюизм: «человеческое время ценнее процессорного».

Но Python и C — не просто альтернативы друг другу, где один язык — более медленная и удобная замена другому. Python также нельзя считать безусловным технологическим прогрессом по сравнению с С. Лучше воспринимать Python и C как языки, сосуществующие в самостоятельных параллельных срезах реальности, где C на уровень ближе к машине.

Пол Грэм подобрал красивую метафору (как всегда, правда?) о потенциале языков программирования, который он описывает в качестве своеобразного вертикального континуума. Языки с минимальными возможностями расположены внизу, с максимальными — вверху. Где-то посередине находится гипотетический язык Blub, который чуть менее чем полностью напоминает C. Грэм считает, что пользователи Blub будут презирать все языки, лежащие ниже Blub в этом континууме — Cobol, машинный язык, т.д. — и просто не смогут понять возможности тех языков, что лежат выше.

Это великолепный образ, но давайте рассмотрим данную метафору с другой стороны. Возможно, Python лежит выше C, а Lisp подобен вишенке на торте абстракций, но изучение Python или Lisp не слишком помогает понять, как именно работает компьютер, на котором зиждется этот континуум. Таким образом, несмотря на то, что Lisp-программисты кажутся всеведущими небожителями, в иерархии языков программирования заглянуть «вниз» ничуть не проще, чем «вверх».

На самом деле, я бы даже сказал, что смотреть вниз сложнее, чем вверх. Чистый Lisp-щик, рассматривающий код C, видит только скверный синтаксис, незнакомые функции и таинственные комментарии о кэш-строках. А C-программист, глядя вверх, видит целый букет вещей, реализованных на C.

Популярность Python связана с тем, что он занимает в описанном континууме позицию выше среднего. Он абстрактнее C и производительнее в работе, но не настолько абстрактен, чтобы у вас голова пошла кругом от метапрограммирования и рекурсии.

Беда в том, что равно как Lisp кажется вычурным и избыточным среднему Blub-программисту, так и C производит аналогичное впечатление на питонщика. Что это за указатели, о которых все говорят? «Звучит мудрено (размышляет питонщик) и если я до сих пор как-то работаю без этих указателей, обойдусь без них и дальше».

Поэтому питонщики в большинстве своем никогда не станут изучать C.

Бесспорно, можно сделать долгую и успешную карьеру в IT, не зная C. Однако культура программирования без изучения C дает ряд порочных эффектов, которые непосредственно связаны с тем, что человек знакомится с программированием на примере Python.

Во-первых, все меньше и меньше людей, способных писать превосходные программы. Чтобы отлично программировать — для ПК, мобильных устройств, инопланетных кораблей — вы должны четко представлять, как компьютер и операционная система функционируют на самом низком уровне. Сколько структур данных умещается в кэш процессора? Почему код работает медленно, а встроенный профилировщик утверждает, что быстро? Когда я приказываю операционной системе что-либо сделать, что она действительно делает? Думаю, все эти вещи можно вызубрить, но ничто так не помогает приобрести необходимую интуицию, как написание и оптимизация большого количества кода на C.

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

Умерьте гнев на минуточку и выслушайте мои аргументы.

Я считаю, что для таких «умников», собирающихся изучать программирование, Python в качестве первого языка непривлекателен по двум причинам. Во-первых, изучить Python не так уж и сложно. Ключевые концепции этого языка как следует не цепляют технарей-интеллектуалов и, соответственно, не вызывают особого интереса. Изучать Python, я бы сказал, несколько скучно. Все равно как ходить в школу, где нет профильных классов.

Второй механизм описала моя знакомая, которая недавно записалась на воркшоп по Python. Она сказала, что с большим удовольствием учила циклы и функции. Они были маленькими, понятными, самодостаточными. Но потом преподаватель решил продемонстрировать «всю мощь Python» и потратил оставшуюся часть занятия на написание какой-то бесполезной программки с Python Twitter API.

Обращение с библиотеками — важный навык, это вам подтвердит любой профессиональный разработчик. Однако если преждевременно познакомиться с библиотеками, то они воздвигают целую стену абстракций, при виде которой умные люди чувствуют себя просто огорошенными. Так и моя знакомая думала, что вот-вот станет изучать секретные законы, управляющие компьютерами; вместо этого преподаватель просто выкатил перед ней монолитное пользовательское приложение с совершенно непроницаемой абстракцией клиентской библиотеки. Не освоив, прежде всего язык — и не научившись читать исходный код этой библиотеки — моя знакомая оказалась без инструментов, при помощи которых можно было бы копнуть поглубже и понять, что происходит у основания цепочки вызовов.

«Просто плохой воркшоп попался», — скажете вы. Но на этом примере я хочу подчеркнуть более масштабную проблему: не изучив для начала C, программист оказывается лишен необходимых орудий, позволяющих понять, что именно происходит в используемой системе. Если вы — умный и пытливый питонщик, то вскоре докопаетесь до плотных пород языка C. Под этими горизонтами, скажут вам, «бойся драконов, костей и отладчиков». Соответственно, если вы не будете достаточно отважны и не проигнорируете предупреждений «да не берись ты за этот C», вы никогда не исследуете глубин, на которые можно забраться просто из любопытства.

Напротив, сишник, пытающийся понять фрагмент кода на C, в худшем случае должен будет перелопатить кучу заголовочных файлов, man-справки и исходного кода. Но едва ли ему попадется какой-нибудь странный пакет Lisp или Python. Копают всегда вниз, а не вверх. Такова суть компьютеров.

**
Мотивация программиста бывает двоякой: либо как можно лучше решить задачу, либо понять, как работают те или иные вещи. Бесспорно, Python отлично подходит для решения задач. Об этом свидетельствует популярность Python на стартапах и университетских курсах (в том числе, по Data Science). Если вы собираетесь за всю жизнь изучить только один язык программирования, то Python — надежный, эффективный и разумный выбор.

Но Python совершенно не годится для тех, кто интересуется принципами работы компьютера. Это проблема, поскольку в долгосрочной перспективе самые лучшие программисты получаются из людей, одолеваемых тягой к знаниям. Возможно, в краткосрочной перспективе это не лучшие сотрудники — читают на работе книги, внедряют какую-то бессмысленную оптимизацию — но, миновав достаточное количество кроличьих нор, они смогут начертить вам настоящую карту страны чудес.

В этом, полагаю, и заключается реальная проблема с «программированием без C» — а также с более глобальной идеей о том, что вводные языки программирования должны быть «выразительными» и «доступными для начинающих». Гильдия программистов теряет как раз тех людей, которые могли бы собой ее украсить.

Хочу подчеркнуть, что не имею в виду людей, которые хотят совмещать программирование с основной работой (ученые, журналисты, веб-дизайнеры, т.д.). Я говорю о тех, кто интересуется программированием как таковым и думает, что однажды мог бы преуспеть в этом деле.

Вкратце остановлюсь и на том, почему в университетах преподают именно Python (а раньше преподавали Java). Основная причина в том, что задача университетов – не в том, чтобы воспитывать программистов-асов. На большинстве факультетов стараются просто подготовить как можно больше успешных выпускников, которые пойдут в аспирантуру или найдут высокооплачиваемую работу. Ни то, ни другое не требует исключительного программерского мастерства.

С точки зрения преподавателя, язык программирования — это материал, на котором нужно изучить основы информатики: алгоритмы, структуры данных и т.д. Python — золотая середина, поскольку его легко изучить (профессора довольны), а еще он используется в коммерческих проектах (профессора просто ликуют). Добавьте сюда популярность Python в университетах, изобилие онлайновых материалов, а также повсюду цитируемое (и редко оспариваемое) утверждение, что Python — «хороший учебный язык». Ну что с ним может пойти не так?

Мне кажется, что люди, попадающие в программирование через Python, упускают массу всего интересного. Существует распространенное мнение, что кайф программирования — решать разнообразнейшие задачи в минимальном объеме кода, вовсю используя клиентские библиотеки, т.п. Это справедливо в случаях, когда человек должен управиться с работой, уложившись в сроки. Но если ваша основная мотивация — чему-то научиться и стать первоклассным программистом, то гораздо интереснее будет писать программы, работающие не столь эффективно, но оставляющие пищу для размышлений.

Для людей, которые никогда раньше не программировали, язык C — отличный тренажер. Указатели и их арифметика не имеют близких аналогов в повседневном мире. Изучая этот язык, вы будете натыкаться на, казалось бы, бессмысленные сообщения об ошибках и иметь дело с недетерминированными отказами. Если у вас проблемы с арифметикой, то вы можете повредить стек вызовов; забудете о простой проверке граничных условий — и куча посыплется как карточный домик. Иногда вам захочется вломить монитору или порыдать на клавиатуре.

Но дело того стоит: язык C помогает получить хорошее представление о том, что именно делает компьютер. Вы почувствуете себя как подросток, сражающийся с ручной коробкой передач. Задавая вопросы «почему?» и закапываясь все глубже, вы постепенно усвоите модель процессов, архитектуру процессора, иерархию памяти, разберетесь в операционной системе и т.д. Именно эта ментальная модель, а не язык C как таковой, поможет вам сориентироваться в абстракциях, которые написали другие и создавать программы, которые некогда казались вам немыслимыми.

Итак, если вы хотите научиться мастерски программировать — на любом языке — то не поддавайтесь на уговоры изучать Python или, упаси Бог, Lisp, а начинайте путь с C. Сверху открываются шикарные виды, но если вы хотите покорить гору, то взбираться на нее лучше всего снизу.
О книгах Зеда Шоу

Проголосовал 101 человек. Воздержалось 25 человек.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.