Программирование для начинающих: методики и языки


Запись доклада и презентация
Пару месяцев назад Виталий Брагилевский рассказывал про выбор первого языка программирования. Разумеется, этот выбор зависит от кучи факторов, но есть проверенные временем и исследованиями конкретные языки и методики, которые можно и нужно рекомендовать в первую очередь.

Какое-то время интересуюсь темой и — о, чудо — мои любимые языки и курсы оказались в итоговой рекомендации автора. К тому же теперь для неверующих у меня в рукаве есть козырь в виде Бравита, который говорит, что я «шарю в теме» :)

В конце доклада Виталий предложил такую схему:


Рекомендуемый порядок изучения языков/направлений, чтобы не хармить мозги почём зря

Выделены три уровня:

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

Когда первокурсник или школьник начинает изучать программирование, то ни он сам, ни, тем более, преподаватель не знают, к чему это приведёт. Задача языков первого уровня — не мешать студентам учиться мыслить алгоритмически и строить абстракции. Язык для начинающего должен быть простым инструментом, формирующим высокоуровневое мышление. Специализация — следующий шаг (второй и третий уровень).

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

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

Язык Racket, курс How to Design Programs


Язык Racket появился в процессе работы над методикой How to Design Programs.

Учебные материалы:

О языке

Когда мы говорим Racket, мы часто имеем ввиду не сам язык, а подмножества языков, которые на Racket созданы. Racket — это язык для создания языков. Он хоть и ЯП общего назначения, но его основная фишка — language oriented programming.

Racket поставляется со своей средой разработки, которая называется DrRacket:

Dr. Racket
DrRacket: редактор кода с REPL-ом, окно с запущенной программой и стэппер (позволяет запускать программу пошагово)

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

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

Учебный процесс

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

Или отправлять корову на прогулку:

Или запилить Space Invaders (проект в конце первой части курса от UBC).

Профессиональным программистам этот курс поможет научиться мыслить в функциональном стиле и использовать принципы проектирования на основе данных (Data-Driven Design):

Read Shriram Krishnamurthi's answer to Why should I read the book How to Design Programs? What does it offer to a programmer with experience? I have been programming for 5 years now. I have experience in C++, Java, and Python. on Quora

Заниматься по HtDP — полезное, интересное и весёлое занятие. Вот Джон Кармак, например, со своими детьми тоже игры на Racket писал:

Альтернатива SICP


The Structure and Interpretation of the
Computer Science Curriculum
HtDP был создан как более структурированная и доступная альтернатива курсу «Структура и интерпретация компьютерных программ», он же SICP.

Если SICP был разработан в первую очередь для студентов MIT с хорошей математической базой и навыками в электротехнике, то HtDP сделали так, чтобы он подошёл вообще всем. Создатели курса считают, что навыки проектирования программ пригодятся людям любых профессий.

Хороший код — сразу

HtDP круто прокачивает факторинг кода (писать код так, чтоб не надо было потом рефакторить). Навыки проектирования прививаются через пошаговые рецепты для работы с данными, функциями и программами в целом. Тесты — неотъемлемая часть процесса проектирования.

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

The typical course on programming teaches a “tinker until it works” approach. When it works, students exclaim “It works!” and move on. Sadly, this phrase is also the shortest lie in computing, and it has cost many people many hours of their lives. In contrast, this book focuses on habits of good programming, addressing both professional and vocational programmers.

Видимо, поэтому слово «факторинг» гораздо менее популярно, чем слово «рефакторинг»:

Типизация

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

Вот пример определения типа Ball с конструктором, селекторами и примером использования в функции:

(define-struct ball (x y dx dy angle))
;; Ball is (make-ball (Natural[0, WIDTH],
;; Natural[0, HEIGHT],
;; Integer,
;; Natural[0, 359]))
;; x, y - coords of the center of the ball
;; dx, dy - velocity (could be < 0 or > 0): amount of pixel for changing x and y
;; angle - the angle of the ball
(define B1 (make-ball 10 10 3 3 0)) ; moving top->down, left->right, not rotated

(define (fn-for-ball c)
(... (ball-x b) ; Natural[0, WIDTH]
(ball-y b) ; Natural[0, HEIGHT]
(ball-dx b) ; Integer
(ball-dy b) ; Integer
(ball-angle b))) ; Natural[0, 360]

Пример функции, которая принимает тип Ball и возвращает тип Ball:

;; Ball -> Ball
;; Produces new ball coords, direction and angle:
;; - changes ball coords by velocity;
;; - changes velocity direction when edge is reached;
;; - changes angle by 1 deg.
(check-expect ; at the start
(next-ball (make-ball 0 0 3 3 0))
(make-ball (+ 0 3) (+ 0 3) 3 3 (+ 0 1)))

;; ...some more tests...

(define (next-ball b)
(make-ball
(next-coord (ball-x b) (ball-dx b) WIDTH)
(next-coord (ball-y b) (ball-dy b) HEIGHT)
(next-velocity (ball-x b) (ball-dx b) WIDTH)
(next-velocity (ball-y b) (ball-dy b) HEIGHT)
(+ (modulo (ball-angle b) 360) 1)))

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

Язык Pyret, курс Programming and Programming Languages


Ahoy world!
Это моё любимое. Язык, книга, методика — всё офигенное, современное и ни разу не скучное.

Учебные материалы:

Язык Pyret базируется на принципах HtDP. Это следующий шаг в адаптации методики для более широкой аудитории:

Pyret is driven by the How to Design Programs (HtDP) philosophy of programming education; one could almost view it as a language designed to make teaching from HtDP comfortable.

Один из идеологов Pyret и PAPL — Шрирам Кришнамурти, который работал и продолжает работать над HtDP и Racket. Мой любимый препод, всегда с удовольствием смотрю его лекции и доклады.

Не могу не упомянуть Bootstrap — набор методик для факультативных занятий по школьным дисциплинам через программирование, где также используется Pyret.

На занятиях школьники прокачивают алгебру и физику, создавая игрушки. Прорабатывают школьные предметы через программирование. Так сделали специально, чтобы ученики охотнее посещали занятия по Computer Science и чтобы учителя школьных предметов были заинтересованы в этом. Изящное решение задачи «как повысить уровень компьютерной грамотности среди школьников». У Шрирама есть доклад, как они внедряли это в школах. Очень интересно.

Кроме физики и алгебры в Bootstrap есть ещё Data Science и реактивное программирование.

Материалы Bootstrap открыты, регулярно проходят онлайн-занятия для инструкторов (см. анонсы в Твиттере).

Язык Python, курс CS61A


Курсов по введение в Computer Science на Python тыщи, но выделить хочется один — CS61A: Structure and Interpretation of Computer Programs от Калифорнийского университета в Беркли. Версия того самого SICP-а. Раньше в Беркли его читали по классике, используя язык Scheme. Нынче адаптировали для Питона и сделали ещё более доступным.

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

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

Курс ведёт John DeNero. Раньше он работал в Гугле, занимался переводами и обработкой естественных языков.

Язык PascalABC.NET

Язык PascalABC.Net разработан в Южном Федеральном Университете. Это всё, что я про него знаю :)

Учебные материалы:

Что выбрать для самостоятельного изучения?

Самый крутой, всеобъемлющий, влияющий на мышление, приносящий светлое будущее курс — How to Design Programs.

Самый интересный с точки зрения современных тенденций — Programming and Programming Languages. Функциональное программирование, статическая типизация, вывод типов. В Pyret даже refinement types есть, но при это он проще и дружелюбнее, чем Python. Racket, кстати, тоже.

Самый практичный курс с точки зрения работающего программиста — CS61A. Проверенная методика, очень популярный язык.

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

А вообще все эти курсы и языки — клёвые. Даже если у вас за плечами годы опыта, уверен, в любом из них вы найдёте что-то новое и интересное.