tl;dr: Go достаточно многословный и строгий язык программирования с очень предсказуемой и стремительной кривой обучения, что делает его крайне удачной технологией для обучения программированию новоприбывших!
Я только приехал из штатов, после Google Code-In 2014 Grand Prize Trip, отдохнувший и веселый. Какое-то время думал написать отчет о том, чем призеры там занимались, как нас приняли в Mountain View и обо всем этом, но в какой-то момент понял, что все это совершенно бесполезно. Совсем недавно я по воле случая должен был помочь своему товарищу с домашкой по информатике (там было что-то вроде selection sort). Реализация требовалась на паскале, а я паскаль знаю очень плохо, как впрочем и другие неактуальные, по большей мере, языки программирования, вроде Ada.
![](https://habrastorage.org/files/9e3/f49/3e2/9e3f493e2b5549918d313c2af5de89de.jpg)
Довод №1. Многословность и строгость
Меня безумно раздражает слово «многословность», но если я уже взялся писать статью, то надо переводить verbose на русский. Почему многословность это хорошо? Многословность упрощает понимание кода на экране, так как при недостаточной многословности у читающего могут возникать вопросы уровня «А что эта штука ваще делает?». Можно долго упираться в крайности типа Haskell vs Cobol, но суть и так понятна. Почему многословность это плохо? Адепты религии DRY неоднократно напоминают мне о том, что в Go нет генериков (обобщенное программирование). Вместо генериков предлагают бутсрапинг или кодогенерацию. Тем не менее, архитектура языка программирования это всегда определенные сделки: ручное управление памятью против сборщика мусора, генерики против бутстрапинга, динамическая типизация против статической, это можно продолжать вечно.
Что касается строгости, то тут Go меня очень радует. Компилятор никогда не идет на уступки с программистом и любая, казалось бы, мелочь, которая в компиляторах других ЯП выльется в неприметный warning, тут — будет ошибкой компиляции. Не играешь по правилам спецификации языка — не получишь бинарник, все просто. Компилятор до того придирчив, что валит компиляцию при виде неиспользованного модуля. По-моему, это просто обосраться, как волшебно, особенно если тебе 15 лет, ты только пришел в программирование и хочешь сделать все «по-быстрее». Я прямо сплю и вижу школьника за компьютером, который пытается скомпилировать программу, но терпит фиаско; затем, проговаривая в голове все маты, которые он только знает, возвращается в редактор, чтобы убрать modulename из include-списка. Жестко? Еще бы! Но знаете, такая жесткость, она воспитывает!
Довод №2. Потрясная кривая обучения
В архитектуру Go заложена простота. Пайк где-то говорил, я уже не помню где, что они действительно вырезали все, что можно было вырезать. Ради этой простоты, в Go нету трех типов циклов (C-way), а всего один (и это без потери выразительности!), в Go нету продвинутой системы типов (но есть волшебные интерфейсы!) и в таком духе. Я уверен и даже готов поставить на это свои тапки (дорогие тапки, к слову, заграничные), что обычный такой школьник не станет читать спецификацию языка, так что не буду упоминать о ней. Так или иначе, язык, ввиду своей простоты и умеренной многословности, обеспечивает стремительную и предсказуемую кривую обучения. Но хотя бы факт того, что память-то managed, уже снимает кучу проблем уровня «так это что получается, вот эта функция у меня протекает? не может быть!».
О том, что опытный программист полностью осваивает Go, со всеми его подводными камнями, за несколько выходных, уже неоднократно говорили, но это в контексте статьи не имеет смысла. Я не занимался обучением детишек на Go, так что суровых чисел у меня нет, но я предлагаю пораскинуть извилинами. Какие три вещи забирают, на этапе обучения, больше всего времени? Чемпион, это, очевидно, ручное управление памятью и мистер «я умудрился посадить сборщик мусора на половину рантайма» в языках с managed памятью. Второе место, безусловно, занимает тематика ссылки-указатели в разных контекстах (косяки уровня «присвоил не по ссылке, а по значению»). Замыкает тройку мистер ООП, а точнее проблемы, которые возникают в реализациях ООП: «так он приватный или нет?», «деструктор мне таки делать виртуальным?», «а как наследовать два класса одновременно???» и подобные.
В Go память управляется автоматически, а значит, накосячить тут сложно. Существует правило, которое позволяет четко определить (в большинстве случаев), передавать переменную по значению или по ссылке: «Если ты собираешься передать право владения над переменной, то надо передавать по ссылке, иначе — по значению. Стандартный набор проблем с ООП не появится, потому что Go прибегнул к очень красивым решениям касательно объектно-ориентированного программирования. А именно, Pike & Co. выпилили классы, всякое „ambiguous“ наследование и прочую инкапсуляцию, предлагая структуры, интерфесы, embedding. Проблему инкапсуляции решили до безобразия интересно: все поля структуры, которые начинаются с символа верхнего регистра идут наружу, а все остальное остается внутри.
Я обрисовал картину, а выводы уже делать вам. Мне кажется, что все очень даже волшебно.
Довод №3. Многопоточное программирование
Я считаю, что детям уже в школе очень важно давать навыки работы с многопоточными приложениями. Знаете ли, мало прикольного в том, что студент, опыт которого так или иначе сводится к проектам уровня laba3, попадает в реальный проект, где одновременно выполняется много кода, все ресурсы надо закрывать на мьютексы, к тому же это все надо еще покрыть тестами… Компьютеры уже давно могут параллельно выполнять несколько задач (parallel != concurrent), за счет архитектуры процессоров и этим нужно пользоваться. Я считаю, что рядом с некоторыми классическими реализациями некоторых алгоритмов надо также давать параллельные их реализации. Того же selection sort, например.
Go избавился от злых и страшных потоков, на замену которым пришли горутины. Я думаю, что работать с корутинами (=задачами), на уровне понимания, куда легче, чем с потоками. Канал, казалось бы, просто очередь, но плюхи на уровне синтаксиса делают работу с ним интуитивно понятнее и куда очевиднее. Как бы долго я не нахваливал корутины, каналы и select, так или иначе мы все равно упираемся в мьютексы. Тем не менее, я думаю, что это все равно лучше, чем то, что мы видим сегодня в других языках, особенно говоря в контексте обучения.
Немного о Python
Какое-то время пайтон считается очень хорошим языком для обучения. Аргументы: интерпретируется, типизация, curly brackets — gotta go! Я не хочу лишний раз поднимать срач, но могу сказать, что по части кривой обучения, Python очень подлая штука. А еще у меня есть мнение, что программист начинает ценить достоинства и уважать недостатки динамической типизации только после определенного времени проведенного со статической типизацией. Я не считаю, что новоприбывшему стоит велосипедить-куралесить с динамическими типами, пока он толком не поймет, что такое тип вообще. К сожалению, для талантливого программиста Алеши из 8А это не так очевидно.
Конец
Ну, это все. Спасибо всем, кто осилил этот дамп моего сознания, надеюсь, что кому-то это было интересно. Прикольно будет, если какой-то инициативный чувак с преподавательскими навыками прочтет и в последствии родит рабочую образовательную систему! Нет, это правда будет отлично! Ах да, не стесняйтесь задавать у меня какие-либо вопросы: в комментариях и даже в личке!