tl;dr: Go достаточно многословный и строгий язык программирования с очень предсказуемой и стремительной кривой обучения, что делает его крайне удачной технологией для обучения программированию новоприбывших!
Я только приехал из штатов, после Google Code-In 2014 Grand Prize Trip, отдохнувший и веселый. Какое-то время думал написать отчет о том, чем призеры там занимались, как нас приняли в Mountain View и обо всем этом, но в какой-то момент понял, что все это совершенно бесполезно. Совсем недавно я по воле случая должен был помочь своему товарищу с домашкой по информатике (там было что-то вроде selection sort). Реализация требовалась на паскале, а я паскаль знаю очень плохо, как впрочем и другие неактуальные, по большей мере, языки программирования, вроде Ada.
В меня ударила молния и укусил гофер, после чего мое тело мутировало в какую-то
Довод №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А это не так очевидно.
Конец
Ну, это все. Спасибо всем, кто осилил этот дамп моего сознания, надеюсь, что кому-то это было интересно. Прикольно будет, если какой-то инициативный чувак с преподавательскими навыками прочтет и в последствии родит рабочую образовательную систему! Нет, это правда будет отлично! Ах да, не стесняйтесь задавать у меня какие-либо вопросы: в комментариях и даже в личке!
Комментарии (96)
BalinTomsk
19.06.2015 20:52+1Я вот Go не знаю, но например на C++ можно точно также писать на небольшом его подмножестве, даже включив опции комилятора «считать предупреждения за ошибки», все будет тоже также валится. А можно и на C++/CLI перейти для надежности.
Так чем таки Go хорошь?
kvark
19.06.2015 21:22+5Как бы я ни хотел найти лучшую замену Питону для обучения, но Go для этого не создавался. Насколько я помню, львиную долю времени мы, будучи школьниками и студентами, писали алгоритмы и структуры данных. Без обобщений такие вещи делать некрасиво, а пользоваться втсроенными в язык — значит ничему не научиться.
И раз уж мы затронули эту злободневную тему, не расскажете ли преимущества «бутсрапинга или кодогенерации» перед нормальными обобщениями?northbear
19.06.2015 22:32+4Чтобы было что обобщать, надо для начала научиться делать частности. Генерики формируют дополнительный слой абстракции, который на начальном этапе не нужен…
kvark
19.06.2015 23:11Я по большей частью согласен, НО «дополнительный слой абстракции» — это скорее про «бутсрапинг или кодогенерация», чем про нормальные родные обобщения. К тому же, никто не заставляет их сразу использовать.
northbear
19.06.2015 23:59Кодогенерация это инструмент, а не конструкция языка. Как-то специально его изучать в рамках дисциплины программирования смысла нет.
namespace Автор
19.06.2015 22:44Скажите пожалуйста, когда последний раз, в реальном проекте, вы действительно были вынуждены писать свою структуру данных, которая действительно нуждается в обобщениях? Будьте добры, наведите юскейс.
kvark
19.06.2015 22:52+4Как минимум год назад, но суть не в этом. Речь идёт про обучение, где нужно понять, как такие вещи в принципе делаются, прежде чем бросаться использовать библиотечные функции.
namespace Автор
19.06.2015 23:28-6Я не вижу потребности в обобщенном программировании при обучении.
kvark
20.06.2015 00:50+5Давайте тогда уже и механизм исключений не изучать, раз его в Go не завезли. И наследование, и алгебраические типы, и функциональное программирование. Вы понимаете, какова вообще суть обучения?
namespace Автор
20.06.2015 00:52-8Мы говорим про обучение программированию в принципе или на конкретном ЯП? Что исключения, что алгебраические типы, что функиональщина — это специфические для того или иного ЯП фишки.
kvark
20.06.2015 00:58+4Go достаточно многословный и строгий язык программирования с очень предсказуемой и стремительной кривой обучения, что делает его крайне удачной технологией для обучения программированию новоприбывших!
Я так понял контекст, что речь идёт о программировании в целом. Исключения есть практически во всех широко используемых языках, проще перечислить, где их нет (Go, Rust, что ещё?). Алгебраические типы также есть во многих языках: Scala, Erlang, Haskell, Rust, etc. Сказать, что это специфические ЯП фишки — явное лукавство.namespace Автор
20.06.2015 01:04-3Я не могу понять суть ваших претензий, но да, в контексте речь о программировании в целом.
lair
20.06.2015 16:03+5Как вы выражаетесь, «функциональщина» — это не специфические для ЯП «фишки», а целый подход к программированию, который планомерно ползет в языке, где раньше никакого ФП не было. И это и к лучшему.
namespace Автор
22.06.2015 00:00-1Дело в том, что ФИШКИ из ФП есть далеко не везде и я не считаю необходимым в обязательном порядке их изучать.
lair
22.06.2015 00:02+3Так не изучайте фишки, изучайте подход. Собственно, это ведь ровно для того и делается — чтобы знать, что еще бывает за пределами известных тебе языков, чтобы выбирать язык и инструмент под задачу.
namespace Автор
22.06.2015 00:23-1Я вообще ничего против функциональных ЯП не имею, интересная область. Я просто считаю, что тут за уши функциональщину притянули. Изначальная претензия была формата: «а как это так ты собираешься учить программированию и не расскажешь про алгебраические типы, да?!», вообщем-то и притянутая за уши.
lair
22.06.2015 00:25+1А это как раз очень правильная по духу претензия. Обучая программированию надо рано или поздно показывать все более-менее распространенные инструменты, чтобы в будущем они не вызывали непонимания.
namespace Автор
22.06.2015 00:36-1И какое это имеет отношение конкретно к языку Go, как языку для обучения программированию?
lair
22.06.2015 00:40Вероятно, такое, что он не так хорошо для этого подходит, как вы пытаетесь показать?
namespace Автор
22.06.2015 00:44-1Я не говорил, что Go это язык, который научит ВСЕМУ программированию. Функциональное программирование — это вовсе не необходимое, а скорее вероятное подмножество в соотв. навыке.
lair
22.06.2015 00:47Знаете, а так можно о чем угодно сказать — что это вовсе не необходимое, а вероятное подмножество. Кроме умения думать, которому ни один язык не научит.
Разговор, заметим, начался не с ФП, а с дженериков, обучение которым вы тоже не считаете нужным. Чем обосновано ваше «это не нужно» и «это нужно»?namespace Автор
22.06.2015 00:52-1Дженерики не то чтобы не нужны, скорее просто не необходимы. Программировать можно и без них, ровно как и без map/reduce. Конкретно дженерики вводят слишком много непрозрачности, чтобы навязывать их прямо-таки начинающим программистам.
lair
22.06.2015 00:56+2Программировать можно много без чего. Как вы определяете, что нужно, а что нет в обучении?
(И нет, не надо ничего навязывать, надо показывать возможности.)
kvark
20.06.2015 01:05+4Понимаете, в чём ирония… Ладно бы там вообще не было обобщений, как в С. А то ж есть, вот они (map, array), но даны богом свыше и недостижимы простым смертным.
NightmareZ
19.06.2015 23:54Я вот в Go не разбираюсь, потому не в теме. Расскажите, пожалуйста, как в Go поступают в случае, когда нужен список? Вот в одном случае список целочисленных переменных, в другом — строк, в третьем — структур каких-нибудь.
namespace Автор
20.06.2015 00:07На самом деле то, о чем вы сейчас говорите — это достаточно редкий случай, в котором можно даже кодогенерацию применить. Но в общем случае, список это slice типа interface{}. Оный удовлетворяет абсолютно любые переменные.
kvark
20.06.2015 00:16Постойте, а разве в Go нету встроенного обобщённого списка?
namespace Автор
20.06.2015 00:19+2golang.org/pkg/container/list — он обобщает через interface{}
kvark
20.06.2015 00:31+4Ок, встроенными оказались только массивы (array) и отображения (map), насколько я вижу. Аскетичненько так.
namespace Автор
20.06.2015 00:44На самом деле массивами пользуются очень редко, потому что в них мало силы. Другое дело, слайсы! Но да, встроенных контейнеров больше нету.
david_mz
22.06.2015 00:10Встроеные обобщённые типы — массивы/слайсы, мапы и каналы. Они действительно «даны свыше» и программист сам создать аналогичные типы не может, так устроен язык.
NightmareZ
20.06.2015 00:27+3То есть мы юзаем список некоторого базового типа, в который можно запихнуть что угодно? Я правильно понимаю? А как тогда из этого списка значения вытаскивать? Кастовать к нужному типу?
kvark
20.06.2015 00:36+3Грубо говоря, гошная статическая система типов в такой задаче сдаётся без боя.
namespace Автор
20.06.2015 00:48Да, статический type switch:
// element is interface{} switch casted := element.(type) { case int: {} case string: {} default: {} }
deviator
20.06.2015 07:13ну это совсем не комильфо… всё вроде строго, а тут БАЦ! и разные типы в контейнер помещаются…
если в контексте обучения программированию, то это как-то сбить с толку может и выстроить в голове не правильные логические последовательности и паттерны мышления (контейнер -> нужно проверять тип элемента), которые в других языках будут не всегда работать (проверка типа такая нужно только ЯП с дин. типизацией, о которой Вы в контексте обучения отзываетесь не лестно). но это конечно имхо
сколько ещё неоднородностей подобных язык таит в себе сей?dmbreaker
20.06.2015 10:04Вы просто не писали на Go. Приведенный выше пример — это «как можно», а не «как обычно». Обычно никто не использует такие слайсы (а следовательно и проверку типа), а обходятся строго типизированными.
roman_kashitsyn
20.06.2015 09:07+3Скажите, а вам нравится буквально копипастить по несколько функций для того, чтобы воспользоваться, например, очередью с приоритетами?
mird
21.06.2015 12:20Для изучения алгоритмов и структур данных генерики не нужны (а скорее даже вредны, создают лишний оверхед и ухудшают эффективность структур данных).
lair
21.06.2015 12:51Это зависит от их реализации.
mird
21.06.2015 12:53Но ты согласен, что для изучения алгоритмов и структур данных они (генерики) не необходимы?
lair
21.06.2015 12:56+1Это интересный вопрос.
С одной стороны, очевидно, что можно учиться без них, и нужно уметь проектировать структуры данных, не использующие дженереки.
Но с другой стороны, задача «написать дженерик-кучу» радикально отличается от задачи «написать конкретную кучу», а ее тоже нужно уметь решать.
Так что я бы, наверное, сначала давал без дженериков, а потом бы их добавил.
AterCattus
19.06.2015 21:53+1А организовать пробное обучение Go для тех, кто уже хоть как-то знает хоть какой-то ЯП, скажем в Питере, было бы занятно и познавательно.
northbear
19.06.2015 22:26-9"… Реализация требовалась на паскале, а я паскаль знаю очень плохо..."
Уж лучше бы вы не позорили гоферов. После такой заявки как-то рассуждать о Go, как языке обучения, мягко говоря, не комильфо…
Паскаль самое что ни на есть прямое подмножество языка Go, только нет интерфейсов и фигурные скобки заменяются на begin/end. Ну еще пара несущественных нюансов…namespace Автор
19.06.2015 22:42+4Вы сейчас говорите абсолютную ересь! Go действительно взял что-то от паскаля (не так уж и много, к слову), но это не делает последний его подмножеством.
northbear
19.06.2015 22:52-9Как вы можете утверждать много/немного, если сами говорите, что плохо знаете Паскаль?.. ))
Единственное, что есть принципиального у Go, чего нет в Паскале — это интерфейсы, замыкания и, в большинстве реализаций Паскаля, функций как базового типа. Всё остальное то же самое, кроме того, что в Паскале:
— Присваивание :=
— Точка с запятой в конце инструкции ставится всегда
— Переменные объявляются всегда
— Есть цикл while
Остальные различия чисто косметические…Xlab
19.06.2015 23:01+7Из вашего комментария понял, что паскаль это как Go, только без первого, второго… пятого и десятого, зато присваивание := и точка с запятой есть.
northbear
19.06.2015 23:47-3Ну, уже неё плохо… Если бы вы были ещё знакомы с JavaScript, то вы бы ещё поняли про замыкания и тип функция. А интерфейсы это из java…
namespace Автор
19.06.2015 23:26+4Go и Pascal это два совершенно разных языка. Pascal действительно оказал влияние на Go, но это влияние не составило и десятой части того, что вложили в спецификацию Go.
BaRoN
20.06.2015 02:23+1Ну, Go это всё равно такой Паскаль с каналами, горутинами и сборщиком мусора :) Мне такого языка не хватало во времена, когда я писал на Паскале — и я ушёл в Java. А сейчас Go — это такой Паскаль, с фичами от JVM-языков.
valexey
20.06.2015 11:41+6В Go := не является присваиванием как раз, в отличае от Паскаля. В Go := является объявлением переменной c одновременной её инициализацией, а не присваиванием.
А вот присваивание в Go это =northbear
20.06.2015 21:06-2Читайте внимательно комментарии, на которые отвечаете. Где я написал что в Go := это обычное присваивание?
andyN
20.06.2015 00:48-6Отсутствие классов есть недостаток. Все-таки, в реальном мире программирования, классы используются очень часто, и ООП надо учить «с пеленок» (программистских). Я бы сказал, что это одна из основ программирования в принципе, которая неразрывно связана с моделированием объектов (в т.ч. реального мира) и их использованием.
namespace Автор
20.06.2015 01:05На самом деле, класс — это очень абстрактное понятие. Go это полноценный ООП язык, который реализует инкапсуляцию, наследование, полиморфизм и все вот эти ООПшные примочки.
andyN
20.06.2015 01:07Я Вам поверю, т.к. не очень хорошо знаком с Go. Есть ссылочка почитать об этом кратенько? Прямо вот чтобы за пару минут понять и просветлиться.
dmbreaker
20.06.2015 10:13+4После того, как я поработал с Go, стало очевидно, что то ООП, которое нам продают другие языки — оно не совсем правильное :)
Многие ассоциируют ООП с наследованием, а Go ассоциирует его с интерфейсами. И сейчас я соглашусь с авторами Go, что это гораздо правильнее. Правильнее не с точки зрения определения ООП, а с точки зрения построения архитектуры приложения и его будущего развития. Наследование чаще приносит больше вреда, нежели пользы. Я вообще не видел ни одного примера большого приложения, где наследование использовалось бы только там, где это нужно — обязательно кто-то поленится и вместо поддержки интерфейса просто отнаследуется, а потом эту «архитектуру» приходится поддерживать.
deniskreshikhin
20.06.2015 12:57+1Практически все паттерны в Go реализуются тем же путём, как и в ООП языках. habrahabr.ru/post/240917
risik
20.06.2015 06:36+1> Потрясная кривая обучения
Было бы интересно посмотреть на эту кривую. Не могли бы Вы описать план курса по основам программирования на go?
deviator
20.06.2015 07:20+3очень классно было бы, если бы Вы попробовали научить кого-нибудь из младших братьев/сестёр (не своих, так друзей) и предоставили бы результаты «исследования»: в каких моментах именно go дети чаще ошибаются, что даётся сложнее/проще и тд
а так получается агитация и мало доказательств
ystr
20.06.2015 08:24О том, что опытный программист полностью осваивает Go, со всеми его подводными камнями, за несколько выходных, уже неоднократно говорили
А есть ли ссылки на подобный опыт «изучения за несколько выходных»?dmbreaker
20.06.2015 10:15+3Это бред. За несколько выходных можно начать писать на Go. А вот чтобы начать писать на нем «красиво» — нужно хотя бы месяца 3 на нем поработать. И да, подводных камней немного, но они есть и за несколько выходных их все не обойдешь.
ystr
20.06.2015 11:15+4Поясню почему спросил: я тот самый «опытный программист» (39 лет, проф. стаж 17 лет, общий стаж программирования 24 года), но вот от Go меня просто «воротит». Так что хотелось бы каких-то «success stories» про изучение Go в кратчайший сроки или что-то вроде того.
dmbreaker
20.06.2015 12:57Сакцесс стори такие, что разработчики, которые никогда на Go не писавшие — начинают это делать через 3-7 дней после знакомства с языком. Они конечно не асы после этого, но работать с языком уже могут. Есть несколько компаний, которые переходят на Go, с подобным успешным опытом.
Хотелось бы поинтересоваться отчего вас воротит? И какой у вас бэкграунд языковой?ystr
20.06.2015 13:05+4Оставим мою персону за рамками обсуждения. Меня интересует только:
О том, что опытный программист полностью осваивает Go… за несколько выходных, уже неоднократно говорили
Где говорили, ссылки, кто говорил, кто переходил?
ImLiar
20.06.2015 10:13+6Помнится, год назад автор так же восторженно восхвалял Qt, заявляя что всем срочно нужно прыгать на кресты.
Теперь вот Go.
Интересно, что будет дальше. Господа, сделаем ставки?namespace Автор
22.06.2015 00:06-3год назад автор так же восторженно восхвалял Qt, заявляя что всем срочно нужно прыгать на кресты.
Насколько сильно я вас заставлял переходить на Qt и кресты, в частности?
Теперь вот Go.
Повторяю предыдущий вопрос: заставлял ли я вас сейчас «прыгать» на Go?
dom1n1k
20.06.2015 12:29+2Меня учили на примере Паскаля и на тот момент это был, пожалуй, наилучший выбор.
Я считаю, что первый язык для обучения должен обладать следующими качествами:
1. Быть не слишком сложным (ну это очевидно). Поэтому C/C++ отпадают.
2. Но в то же время не слишком упрощенным, не «детским» — а пригодным для реальной коммерческой разработки. То есть учебный опыт должен быть не чисто игровым («а теперь забудьте всё, что учили раньше, сейчас мы займёмся нормальными вещами»), а практическим. Например, в наше время некоторых ещё учили на Бейсике, хотя он уже был полностью устаревшим и неактуальным. Поэтому же отпадают все слишком экзотические языки.
3. Обязательно быть типизированным. Учащийся должен хорошо различать различные структуры данных и понимать, что автоматическое приведение типов — это плюшка, а не данность. Не должно быть поначалу слишком много скрытой магии.
4. Обязательно иметь понятие указателя. Даже в нынешнюю эпоху сборщиков мусора учащийся должен получить базовое представление о работе с памятью, что происходит «под капотом», о передаче по ссылке/значению. Не сразу в хардкорной версии C++, но должен.
5. Быть процедурным, поскольку это самая простая, естественная и логичная идеология.
Так что да, Go — это очень хорошая кандидатура.dmbreaker
20.06.2015 12:58+1Go не процедурный все же. Есть и привязка методов к структурам и наследование через композицию.
lair
20.06.2015 16:00+6Проблему инкапсуляции решили до безобразия интересно: все поля структуры, которые начинаются с символа верхнего регистра идут наружу, а все остальное остается внутри.
Это не «решили проблему инкапсуляции», это «придумали еще одну конвенцию». Это никак не отвечает на вопрос «какие поля надо прятать, а какие — нет» — который, собственно, является проблемой инкапсуляции.namespace Автор
22.06.2015 00:08-1Ты конечно же прав.
Конкретно в данном случае я имел ввиду под «проблемой» инкапсуляции то, что сходу сказать, можно использовать метод или нет, нельзя и был не очень прав, потому что это не проблема вовсе.
newpavlov
20.06.2015 18:29+2Лично я считаю, что лучшим обучающим языком программирования является Python, тут и REPL, и достаточная высокоуровневость позволяющая не задумываться об ньюансах реализации, концентрируясь на сути алгоритмов, и хорошая реализация различных парадигм программирования, более чем подходящаяя для введения в них, и громадное количество библиотек, которые позволят сразу решать интересные обучающемуся проблемы (начиная от игр, и заканчивая научными вычислениями, обработкой и визуализацией данных), ну и разумеется практическая применимость самого языка в широком спектре областей. Да, на его примере нельзя будет толком рассказать о компиляции в машинные коды, о статической типизации, и о многих других вещах, но, не думаю, что всё это больше технические детали, достойные углубленных курсов, нежели чем жизненно необходимые вещи для начинающих.
Презентация же Go как обучающего языка (и, например, как по-настоящему системного), на мой взгляд, это чистое натягивание ежа на ужа, которое будет делать языку больше вреда, чем пользы, ибо рекламируя язык в неподходящих областях, создаётся дурная репутация, которая будет автоматически распространяться и на области где этот язык чрезвычайно хорошо.
ystr
21.06.2015 09:31+2Я тут посмотрел перечень всех статей автора данной статьи и обнаружил одну интересную для меня вещь. Этому автору, оказывается, 16-17 лет отроду. Он школьник, даже не студент. Вот статья от 10-го мая 2013-го года, где он прямо говорит:
Меня зовут Илья Ковалевский, я ученик 8-Б класса киевского лицея
Так что относитесь к предложению о Go как лучшем языке для обучения как к личному опыту автора :)namespace Автор
22.06.2015 00:12Мне 16 лет, я действительно школьник и не в коем случае не студент, но когда я начал учить Go у меня уже было за плечами 3 года опыта работы с С++, из них 2 — в FOSS.
northbear
22.06.2015 08:10+2Хм… Мой пардон… Тогда снимаю свой, можно сказать, «наезд» на счет Паскаля. В вашем случае это вполне нормально, вы еще не профессиональный разработчик.
Пишите статьи от себя. Не надо пытаться выглядеть «крутым» разработчиком. Вы и так достаточно круты для своего уровня. Я, по крайней мере, в ваши годы не умел так хорошо излагать свои мысли…
В общем я с вами согласен. Go — хороший язык для изучения в качестве первого языка. Пока не дойдет до конкурентных вычислений. Там уже требуется иметь теоретический бэкграунд. Параллельные/многопоточные вычисления это отдельная дисциплина…
Главный же плюс Go, в отличие от того же Паскаля — это актуальность…
avdept
21.06.2015 11:22+2WTF am I reading?
>>В Go нету указателей, а только ссылки.
>>Go has pointers. A pointer holds the memory address of a variable.
tour.golang.org/moretypes/1
namespace Автор
22.06.2015 00:16Черт, а тут я тут похоже облажался. Дело в том, что в С++ ссылка (reference) может указазывать только на один и тот же самый объект, а в случае с указателем (pointer) — это не так. Поэтому мне кажется, что указатель в Go это скорее ссылка, нежели указатель (в контексте С++, например). Я не прав?
roman_kashitsyn
22.06.2015 08:11+2поэтому мне кажется, что указатель в Go это скорее ссылка, нежели указатель (в контексте С++, например)
Т.е. вы хотите сказать, что в Go нет возможности изменить значение переменной, содержащей указатель?
Почему тогда следующий код работает:
?package main import "fmt" func main() { x := 5 y := 7 p := &x fmt.Printf("%v\n", *p) p = &y fmt.Printf("%v\n", *p) }
namespace Автор
22.06.2015 09:09Все верно, я просто опять запутался в этих определениях. Да, все-таки указатели, пойду поправлю статью, спасибо!
areht
29.06.2015 23:59+4> Жестко? Еще бы! Но знаете, такая жесткость, она воспитывает!
Воспитывает что? Ненависть к программированию?
Сколько часов в школе программирование нынче, что на это времени не жалко?
> «а как наследовать два класса одновременно???»
А в Go проще что ли?
type Reader interface {
Read(p []byte) (n int, err error)
}
type ReaderInv interface {
Read(p []byte) (n int, err error) // Читаем в обратном порядке
}
type MultiReader struct {
Reader
ReaderInv
}
И, наконец, я хочу сделать как-то так:
switch t := t.(type) {
case Reader:
t.Read(...)
case ReaderInv:
t.Read(...)
case MultiReader:
t.Read(...)
}
думаете я получу предсказуемый результат? Только не надо говорить «а не надо так делать!», я на любом языке могу так не делать.
Что-то я не вижу, что бы проблемы с наследованием волшебным образом исчезли.
flerant
В принципе, аргументация понятная, но ответ на вопрос, хорош ли язык для обучения программированию можно дать только на основе реального опыта использования его в таком качестве. Потому что не исключено, что избавившись от одних подводных камней, создатели языка набросали других.