Спор о первом языке программирования: окончательное решение

Некоторые относятся к спору о выборе первого языка программирования примерно так:

ghkyvrwfwrym9w3ootnlluyldlw.jpeg

Говорят, на выбор влияет миллион фаторов и спорить по этому поводу не имеет никакого смысла. Тем не менее, холивары продолжаются.

Виталий Брагилевский решил поставить точку и на Saint AppsConf представил окончательное решение. После прочтения статьи (или просмотра доклада) вы будете знать, как правильно отвечать родственникам или знакомым, которые узнали, сколько зарабатывают в IT и что удалёнка тут не помеха, и теперь интересуются, с чего же начать.


Виталий Брагилевский работает в JetBrains и преподает в СПбГУ на факультете математики и компьютерных наук, член комитета по стандартизации языка программирования Haskell и наблюдательного комитета по разработке компилятора Glasgow Haskell Compiler языка Haskell, автор книги «Haskell in Depth».

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

Еще Дейкстра в 1972 году написал:»…the tools we are trying to use and the language or notation we are using to express or record our thoughts are the major factors determining what we can think or express at all!»

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

Если совершить в этом выборе ошибку (или чаще кто-то делает выбор за ученика), то последствия могут быть серьезными. Именно так появились программисты:

  • испорченные Фортраном;
  • пострадавшие от BASIC;
  • раздавленные C++;
  • задушенные Java.


Отсюда и шутки о том, что настоящий программист на Фортране может на любом языке написать программу на Фортране. Или истории о ребятах, которых на первом курсе мучали C++, после чего им уже вообще невозможно стать программистами — только и знают, как < и > писать.

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

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

История вопроса


Начну с так называемой проблемы Ричарда Вексельблата. Этот человек известен тем, что его PhD стала первой в департаменте Computer Science. В 1980 году он написал статью о последствиях выбора первого языка программирования (Richard L. Wexelblat. The consequences of one«s first programming language. Proceedings of the 3rd ACM SIGSMALL symposium and the first SIGPC symposium on Small systems, 1980).

Началось все в 1978 году, когда Ричард написал в журнал письмо с провокационным заголовком «Ошибки молодости, или Действительно ли Бейсик вреден для вашего здоровья?». Ответы на это письмо и послужили материалом для статьи.

vdisdwaw_oszcxbjwvnavyz8mcs.jpeg


На основе повторяющихся точек зрения Ричард Вексельблат сделал следующие выводы:

  • Скорее всего, некоторые языки (Pascal, PL/C) лучше подходят для обучения, чем другие (COBOL, FORTRAN). При этом конкретные характеристики языков выявить трудно.
  • Негативные эффекты от плохого обучения значительнее, чем от плохого языка. Верно и обратное — если учить хорошо, то и с не очень хорошим языком выйдет толк.
  • Один из респондентов отметил, что начинал с Бейсика, но его способности к программированию ничуть не пострадали. Бэйсик был таким образом оправдан.


Конечно, это было очень наивное исследование, без учета социологических факторов, тем не менее и оно позволило сделать какие-то выводы.

Изучив историю вопроса поглубже, я убедился, что исследований, посвященных выбору языка программирования, сотни. Есть даже работы, обобщающие работы по выбору ЯП, например: Kevin Parker, Bill Davey. The History of Computer Language Selection. (In Arthur Tatnall. Reflections on the History of Computing: Preserving Memories and Sharing Stories, AICT-387, Springer, pp.166–179, 2012, IFIP Advances in Information and Communication Technology (SURVEY)).

Авторы, опираясь на обширную библиографию, выделяют факторы, влияющие на выбор языка, не только для обучения, но и для реализации проектов:

  • Прагматичные: распространение в промышленности, популярность на рынке (влияние коммерческих субъектов). Тут можно вспомнить множество крупных компаний, которые продвигают свои языки через поддержку университетов.
  • Педагогические: простое окружение для простых программ (без необходимости создавать 150 вспомогательных файлов для написания «Hello world!» или конфигурировать 500 пунктов в IDE); ориентация на problem-solving, а не на синтаксис ЯП; наличие учебных материалов и преподавателей.
  • Язык и библиотеки: реализация определённой парадигмы (например, в 2000-х это было ООП); работа с графикой и интерактивность.


Многие специалисты занимаются сравнением языков, в частности относительно того, насколько они хорошо подходят для начального изучения. Linda Mannila и Michael de Raadt в своей статье «An Objective Comparison of Languages for Teaching Introductory Programming» сформулировали группы критериев оценки ЯП:

  1. Применимость в обучении.
  2. Язык и среды разработки.
  3. Поддержка и доступность.
  4. Использование за пределами вводного курса.


Вооружившись этими критериями, Linda Mannila и Michael de Raadt составили таблицу сравнения языков.

at1twhcg0oiqnjuv0w_hvwmufl4.jpeg

В оригинале у каждого критерия есть дополнительные характеристики, которые для нас не так важны. Нам интересно, что лидерами по итоговому «Authors' score» является Python и Eiffel — язык, который вряд ли можно назвать популярным.

Сначала я надеялся проранжировать ЯП по этим критериям и сделать собственные выводы, но, посмотрев на колонку Haskell, обнаружил вранье по каждому пункту! И решил, что таблица не имеет никакого отношения к действительности — вот такое «объективное» сравнение.

Поразмыслив, я пришел к выводу, что в таком сравнении нет смысла. Допустим, я бы добавил столбец с Kotlin и поставил бы галочку в каждом пункте, или не поставил. Это бы не означало ровным счетом ничего.

Тогда я решил посмотреть, а что же используется для обучения по факту. Тут картина другая.

zxpedqn7p3m3pijpzyriqh-izy8.jpeg
Источник данных.

То, что данные за 2014 год, не должно вас смущать, потому что системы высшего образования меняются очень медленно и общая картина к настоящему времени не сильно изменилась.

Python по-прежнему на первом месте, Java — отражает запросы Oracle, Sun Microsystems и других компаний на обучение именно этому языку. Среди университетов, которые начинают обучение программированию с C++ наверняка университет Техаса — там начальный курс читает Бьёрн Страуструп и, думаю, студенты справляются с ним хорошо.

Многие языки, интересные академической общественности, вообще не попали в этот рейтинг, в частности:

  • Популярные среди исследователей функциональные ЯП со статической типизацией Haskell и ML.
  • Широко распространённые в веб-разработке ЯП с динамической типизацией JavaScript, Ruby, PHP.
  • Завязанные на платформу промышленные языки Objective-C и C#/Visual Basic.


С последним как раз понятно, исторически университеты не хотят жестких привязок к чему бы то ни было.

Глас народа


Изучив историю вопроса, я решил узнать мнение современных разработчиков через опрос в twitter. Вопрос сформулировал так: «Какое свойство языка программирования вы считаете наиболее важным при выборе ПЕРВОГО языка для обучения программированию?» И предложил варианты ответов, которые довольно легко соотнести с конкретными языками.

С учетом всех технических особенностей опросов в twitter, результаты следующие.

4flgm_xiimj3niwjrwqj-pwt87m.png

Больше половины опрошенных сказали, что главное — простота. 25%, ответивших распространенность, считают, видимо, что надо сразу думать о востребованности на рынке. Высокий процент людей, которые считают, что сначала надо с указателями разобраться, меня настораживает. А то, что только 8% за богатый набор библиотек, показывает, что первый язык все-таки не должен быть предназначен для того, чтобы делать что-то реальное.

Ответы к опросу


Приведу несколько интересных мнений из обсуждения опроса.

Дмитрий Коваников (@ChShersh) — опытный разработчик и преподаватель — высказал ряд важных соображений, с которыми я полностью согласен:»Высокоуровневость и интерактивность. Чтобы получить результат работы программы и иметь возможность посмотреть его можно было с минимальным числом шагов. Программирование — это не про создание переменных, циклов или рекурсий, это про решение проблем средствами ЯП».

Артём Пеленицын (@ulysses4ever) отметил методическую составляющую: «Наличие специализированных методических (учебники, задачники, туториалы, Q&A форумы) и технических (простые и внятные IDE с минималистичным интерфейсом, степперы/дебаггеры с GUI) средств».

Андрей Мисков (@andreymiskov) напомнил о другом важном факторе:»Предсказуемость: не отвлекаться на null/undefined и 0.1 + 0.2. Постепенное увеличение возможностей: никакого ООП и мутаций, пока не освоишь данные и функции. Типа как в Racket/HtDP или в Pyret/PAPL».

Нашлись и защитники С: «Лично я считаю, что C был и остаётся самым лучшим для более фундаментального изучения. На мой взгляд, простой и достаточно интуитивный синтаксис, и много разных концепций (память, указатели, стэк, аллокации). Только одно НО, ни в коем случае не C89, минимум C99, а лучше C11».

Были и упоминания Scala, и Rust — причем в контексте типизации и простоты. Что наводит нас на мысль, что, к сожалению, языки программирования как тоталитарные секты. У них есть адепты, которые несмотря ни на что продвигают свой любимый язык и не желают прислушиваться к критике (и вообще чужому мнению).

Яркий пример такого «сектантства» — спор о том, как обозначать присваивание »=» или »:=». Этому спору уже больше 40 лет, есть статьи, посвященные только этому вопросу. И это только один повод из сотен подобных «важных вопросов».

Не надо холиварить — популяризируйте свой язык, но не действуйте как адепты тоталитарных сект.


Отличия промышленного языка от учебного


Мы уже почти пришли к тому, чтобы найти окончательное решение в задаче выбора первого языка. Осталось только определить, а чем же учебный язык отличается от промышленного.

Во-первых, в промышленном языке для достижения одной и той же цели всегда есть много способов.

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

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

Выучить ЯП, когда умеешь программировать, легко. В задаче с первым языком учиться предстоит именно программировать, а это сложнее.

По вопросу обучения программированию как таковому тоже есть книги, например такие.

kwwykkm6eilc4fdhmsu56di26nm.jpeg

В очень классической (только посмотрите на обложку) книге «Структура и интерпретация компьютерных программ» создается впечатление о программировании как о магической деятельности, а о программистах как, обладающих исключительными способностями, колдунах. Это, конечно, совершенная неправда.

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

В «How to design Programs» есть несколько важных принципов, чему нужно учить при обучении программированию:

  • Как читать постановку задачи и выявить, из каких компонентов должно состоять решение.
  • Как перенести задачу на структуру программы.
  • Тесты являются частью программы, и значит, их нужно писать сразу.
  • Учить проектированию, а не кодированию.


Beginning Student Language


Чтобы реализовать эти принципы, автор книги Matthias Felleisen придумал идею языков для обучения. Это языки, которые постепенно расширяют свои возможности.

Начинается все с BSL — Beginning Student Language — в котором есть только необходимый минимум: определение функции, вызов функции, условная операция, арифметика. И дальше, вместе с задачами, язык постепенно растёт, добавляются такие конструкции как списки, рекурсия, функции высшего порядка. Постепенно с помощью языка, уже SL, становится возможным решать более сложные задачи. Заканчивается эта цепочка языком Racket из семейства Lisp, который является замыканием всех предыдущих и позволяет программисту реализовать что угодно.

Так выглядит элементарная программа в среде DrRacket в режиме для начинающего студента.

agpzgcne3nvlkwyy_zpvlr28me8.jpeg


Pyret


Другой подход к обучению программирования предложили Shriram Krishnamurthi с соавторами. Они создали язык Pyret и опубликовали книгу «Programming and Programming Languages», потому что, повторюсь, без обучающих материалов никто язык изучать не станет.

Обратите внимание на названия некоторых глав из этого учебника:

  • Introduction to Tabular Data (4)
  • Interactive Games as Reactive Systems (11)
  • Examples, Testing, and Program Checking (12)
  • Graphs (19)
  • Processing Programs: Parsing (23)
  • Reasoning about Programs: A First Look at Types (27)
  • Objects: Interpretation and Types (32)


В 11 главе — в конце первого месяца обучения — учат писать интерактивные игры как реактивные системы. Вся программа рассчитана примерно на полгода и объекты и системы типов вводятся почти в самом её конце.

Язык Pyret строится таким образом, чтобы было можно идти по плану без забегания вперед. На нём на самом деле можно запрограммировать всё, что встречается до 27-й главы, не зная, что в языке есть типы. А в 27-й главе выясняется, что тут есть статическая типизация и ей можно пользоваться. Этот язык создан специально, чтобы двигаться от начала к концу, постепенно водя в оборот новые концепции.

Ниже пример программы на языке Pyret и среды, в которой для этого языка.

3mqftgzsp4zqmullffoywuu5_ca.jpeg


Например, тесты, которые встраиваются в программу (блок where:), — обязательная часть синтаксиса. Документирование тоже встраивается в синтаксис (doc:). Такие полезные конструкции верхнеуровнево есть в языке и их использование прививается в процессе обучения.

CodeWorld


Идея простой реализации графики реализована в среде CodeWorld. Там есть свой язык, но можно использовать Haskell и тут же получать что-нибудь красивое — для новичков это привлекательно.

xlpgli3b9ls_tw_xfvt4efk4br4.jpeg


PascalABC.NET


Наш ответ BSL и Pyret разрабатывают в ЮФУ в Ростове-на-Дону Станислав Михалкович и его студенты.

Это такой Pascal, который не устарел. В нём есть, например: foreach, внутриблочные описания переменных, case по строкам, длинные целые, обобщённые классы и подпрограммы, интерфейсы, перегрузка операций, лямбда-выражения, исключения, сборка мусора, методы расширения.

Некоторые вещи из .NET появляются там даже раньше, чем в C#. То есть в знакомой обертке синтаксиса Pascal это суперязык с полным доступом к возможностям платформы .NET. В нём реализованы современные концепции с точки зрения разработки ЯП.

ezxjuhlv8gu5arjvrh_ygjhs9p4.jpeg


Выше на скриншоте программа в 120 строчек красиво и с анимацией собирает Ханойские башни.
Проницательный читатель уже догадался, что никакого окончательного решения в вопросе выбора первого языка программирования нет. Его нет ни у меня, ни у кого-то еще. И это хорошо: нам в информатике не нужны единые учебники истории, рассказывающие единственно правильную точку зрения.

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

Начать лучше с языка, который больше для этого подходит: Racket, Pyret, Python, PascalABC.NET. Главное, чтобы начальный этап — этот первый язык — заложил основу для будущего развития.

qcz5ncpput8avmyzvl3omoqwbkw.jpeg

С языков первого уровня в этой схеме будет легко перейти на какой-то из базовых промышленных или академических языков: JavaScript, C, C#, Java, Haskell, OCaml, F#. Но если начать сразу с JavaScript, то получится Фортран-программист на новый лад, который потом везде будет писать как на JS, и это будет ужасно. А если это будет второй язык, то такой деформации не произойдет.

Дальше, когда заложена основа в определенной области, открывается миллион возможностей. На схеме показаны только некоторые из них.

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

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

Если (а как иначе, вы же читаете это на Хабре) вы уже успешно стартовали карьеру разработчика, углубились в какую-нибудь одну область и теперь хотите знать, а что происходит за её пределами и куда еще направить своё внимание, — присоединяйтесь к фестивалю РИТ++ Online. Там за два дня (25 и 26 мая) вы сможете получить срез всей IT-индустрии, а на мастер-классах с 27 мая по 10 июня прокачать отдельные навыки.

© Habrahabr.ru