Pull to refresh

Comments 91

Идеальный язык системного программирования пока не сделан, увы. И Go конечно даже и не претендует на это звание:) Но в Go есть некоторые идеи, которые лично мне понравились (и которые ИМХО вполне могли бы войти в «идеальный язык» в качестве фич):
1. Структурная типизация. Как дополнение к классической номинативной она была бы очень интересна.
2. Встраивание вместо наследования. Удивительно простая и очевидная вещь, которую следовало бы ввести еще в Си. Можно сказать что это более низкоуровневая реализация наследования. А возможность «встраивать» указатели вообще дает крайне интересые эффекты.
3. Ну и оператор вывода типов := сам по себе весьма милый… знаете, мелочь — а приятно, что именно так сделали. Правда недоделали до конца, и внутри выражений объявлять таким образом новые переменные нельзя.
Немного не ясно значение понятия «системное программирование». Вот в зарубежных версиях документации даже Swift подаётся как «a systems programming language», а wiki говорит:
A System programming language is usually used to mean «a language for system programming»: that is, a language designed for writing system software as distinct from application software. System software is computer software designed to operate and control the computer hardware and to provide a platform for running application software, and includes such things as operating systems, utility software, device drivers, compilers, and linkers.
То есть, следует различать системное программирование от программирования микроконтроллеров с 4кб памяти.
Я имел в виду всего лишь «нескриптовое» программирование. Не знаю есть ли правильный адекватный термин. То есть все то, что обычно делают на C/С++, включая и классическое «системное» программирование, и «встраиваемое» (для микроконтроллеров, в том числе самостоятельные прошивки без ОС), и достаточно большую часть «прикладного», включая и софт с GUI, и геймдев, и серверное ПО.
У этого термина есть очень много трактовок. Самая строгая — язык может считаться подходящим для системного программирования если позволяет прямой доступ к железу и на нём можно написать hard real-time OS. C / Rust / D этим критериям соответствуют, Go — нет.

Процитированное определение из вики довольно бесполезно, так как под него подходят чуть ли не все промышленные языки, оно описывает скорее намерения, чем формальные свойства.
Все эти три пункта в том или ином виде присутствуют во всех трёх нативных языках «новой волны» (Go / D / Rust), едва ли тут можно говорить о новаторстве :)
Я бы так не сказал. В D и Rust присутствуют разные не менее интересные фичи, но конкретно структурная типизация и встраивание вместо наследования, насколько я помню, только в Go.
Встраивание вместо наследования: traits в Rust (частично, проблемы с встраиванием переменных), template mixin + alias this в D (полностью)
Структурная типизация: traits в Rust (полностью), template constraints в D (частично, подмножество duck typing)

Мне кажется, что сообщество всех трёх языков вообще настолько сильно «в теме» дизайна языков программирования, что о новаторстве вообще трудно говорить применительно к отдельным фичам, только о сумме принятых решений.
И тем не менее на Go написан некоторый достаточно серьезный софт, например, Docker.
«Некоторый достаточно серьезный софт» можно написать практически на чём угодно. Наличие такого софта — это, скорее, показатель не какой-либо характеристики языка, а степени мотивированности разработчиков.
При достаточной мотивированности порог входа практически не важен.
UFO just landed and posted this here
Почему? Просто потому, что ею пользуются уже 20 лет? Это не критерий, вот Хосни Мубарак тоже 20 лет просидел в кресле, но не обязательно потому, что был хорош:)
1. Для нее созданы тонны фреймворков и библиотек на все случаи жизни.
2. Это не просто язык, а платформа. Причем достаточно широкая.
3. Которую использует серьезный бизнесэнтерпрайз.
4. Она все еще жива и неплохо развивается по разным направлениям.

Про плюсы языка я писать не буду, дабы не провоцировать холивар. На вкус и цвет все фломастеры разные.
Третий пункт доставляет) А ещё энтерпрайз использует мейнфреймы и кобол. Потому что 40 лет назад ничего другого для их задач не было, и за все эти годы они вложили в эту тему стотыщ миллионов денег. И да, тоже написали тонны фреймворков и библиотек на все случаи жизни. И кобол/бейсик/1С/java — давно уже не просто язык, а платформа.
)))
Хорошо, каковы ваши варианты? :)

PS:
Платформа — это не просто «вагон библиотек», а нечто немного более другое. Вспомним Java ME, Java SE, Java Embedded и т.д.
Да уж, кого-то, видимо, Java совсем обидела, что даже в карму не поленились зайти и отметить это.
ИМХО Всё, что вы привели, на мой взгляд, отнюдь не доказывает, что Java хороша :)
Так я и не утверждаю, что это silver bullet. Просто факт в том, что она уже десятки лет активно используется в достаточно серьезных вещах и активно развивается.
И кстати, а какие параметры однозначно указывали бы, что язык Z хорош, а Y, по сравнению с ним — плохой?
Не уверен, что мы до автора докричимся (ибо перевод), но Ruby и Python — практически ровесники PHP, насколько мне известно.
Lisp. Абстрактные синтаксические деревья никогда не теряют популярности c:
Haskell, ML, Lisp, Prolog, Oz.
Можно еще Erlang добавить.
UFO just landed and posted this here
Ничего не скажу про PHP, но пихать личное мнение в переводы и правда не очень красиво.
А я лично скажу, что PHP великолепный язык, если из него вырезать половину легаси-функций, остальные стандартизировать и перелопатить парсер, что бы он не валился на на строках вида: "(function(){})();", короче… Если весь пых переписать, оставив лишь поведение и объектную модель, то будет великолепным =)
Если весь пых переписать, оставив лишь поведение и объектную модель, то будет великолепным =)

Если сделать из пыха скриптовую stateless-джаву?)
Ну есть ещё один вариант, переименовать Java в PHP… ну допустим PHP версии 6, её ведь все ждут? И добавить доллары. Я считаю — это уж точно победа будет. Go будет стоять в сторонке и нервно покусывать свои паскалеобразные выводы типов.
Почему же, оставить. Всё это можно списать на неумолимый прогресс, ядерное развитие и небольшой отказ от некоторой обратной совместимости ;)
перелопатить парсер, что бы он не валился на на строках вида: "(function(){})();"

Уже сделано.

вырезать половину легаси-функций, остальные стандартизировать

Совсем глупости, типа magic quotes — выбрасываются помаленьку. В остальном, совсем выбросить не получится, для BC придется оставить как алиасы, а так — проводятся эксперименты, думаю, что-то такое увидим в php 7 или php 8.
Всё описанное в статье (включая мощную систему типов, обобщения с ограничениями, интерфейс Iterable для реализации типов с поддержкой for-each, ковариацию и контравариацию, отсутствие nil) есть в языке Ceylon (http://ceylon-lang.org/). При этом язык уже добрался до 1.0.
По непонятной для меня причине, информационные источники обходят этот язык стороной. Единственное моё предположение, что причина это JVM (хотя Scala и Clojure всё-таки более-менее известны). Кроме JVM в качестве бэкенда поддерживается JS, у авторов есть мысли по поддержке LLVM.
Рекомендую всем, у кого есть время и интерес в подобных языках, ознакомиться. Просто не мог пройти мимо статьи, в которой опять обделили Ceylon.
Миллионы кодеманкей не могут ошибаться!
Если вы достаточно хорошо знакомы с этим языком — предлагаю вам написать краткую вводную статью здесь, для более широкого «продвижения в массы».
Присоединюсь к этому пожеланию.
Не, julia (http://julialang.org) лучше… Он даже быстрее Go… ))
Слишком далеко до первой версии. Хотя, конечно же, не известна изначально задуманная ветка версий.
У него проблема с кросс-взаимодействием с джавой, так же как и у скалы в некоторых (многих) случаях. В отличие от него, Kotlin как раз на эту тему заморочен. И тоже умеет компилиться в JS. Но вот до 1й версии пока не добрался, да
Ну не знаю, неизменяемые состояния — штука очень специфическая. Изначально она вообще появилась потому, что в математике практически невозможно определить операцию присваивания. Когда математики изучали лямбда-исчисление, они как раз придумали, как обойтись вообще без присваивания.
Другими словами, фатальный недостаток изменяемых состояний — они плохо описываются математической теорией.
Но железо-то, точнее кремний, только с присваиванием и работает, и компилятор Haskell таки выдаёт на выходе километры MOV-ов.
Другими словами, фатальный недостаток неизменяемых состояний — они не поддерживаются оборудованием.
Вот и думайте, какой из недостатков менее фатален.
UFO just landed and posted this here
Изменяемые состояния очень просто и понятно описываются конечными автоматами.
Которые, конечно же, очень просты и понятны для анализа, когда у них 1050 состояний (примерно столько состояний необходимо для расчёта SHA-1). Так-то состояние можно и некоторым количеством функций памяти представлять. Проблема же в том, что подавляющее большинство математических методов опираются на выражения, а не вычисления — а выражения не имеют состояния и неотъемлемого понятия времени.
в математике практически невозможно определить операцию присваивания

Ошибаетесь. Изменяемое состояние представляется математически (и в чистом функциональном программировании) без каких-либо осложнений. В том же Хаскеле для него есть аж четыре монады (State, ST, STM, IO) с разной спецификой. Первые две из этих монад совершенно чистые, причем.

В самом простом случае, достаточно всего лишь завести некую струкутуру, которая хранит в себе глобальное состояние, а каждая функция будет принимать ее и возвращать помимо своего значения еще и новое состояние (так работает монада State).
А какая разница, поддерживается неизменяемое состояние оборудованием или нет, если программы с этим самым неизменяемым состоянием всё равно достаточно быстры? Программы всё-таки пишутся для людей, и не имеет никакого значения, нравится процессору исполнять программу или нет.
Изменяемые состояния объединяют время и состояние в одну сущность, порождая кучу ошибок. И это фатальный недостаток изменяемых состояний — с ними сложней работать, они создают ошибки и дают меньше гарантий.

А не то что они плохо описываются математической теорией.
Самое интересное, что в промежуточном представлении современных компиляторов переменные неизменяемые (single assigment) — при каждом присваивании компилятор заводит новую переменную. А только на последнем этапе неизменяемые переменные с учетом их времени жизни мапятся на реальные изменяемые регистры и ячейки памяти. Так удобнее для оптимизации.
Столько копий сломано в холиварах, а программируют все в мейнстриме до cих пор на Алголе в разных модификациях :)
Это же здорово, огрехи в языке не значат что срочно нужно заменять его другим, в тоже время расширяет кругозор. Я из застрявших на php, но с лёгкостью, когда понадобилось сделал проект на nodejs, в другой раз чтобы не переписывать с нуля, продолжил писать на RoR. Просто сравниваешь плюсы и минусы и выбираешь победителя для конкретного проекта, а не язык на всю жизнь.
Статья неплоха, но излишне придирчива. Видно, что автор не особо программировал на Го, иначе он увидел бы ещё кучу других недостатков. Но в любом случае финальное «заключение» автора отбивает охоту читать всю статью ибо нет ему веры:

> Go не делает ничего нового
Полная чепуха. Горутины, каналы, интерфейсы — это замечательные инновационные парадигмы.

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

> Go — шаг назад по сравнению с другими современными языками
У нас появилась линейная шкала, где можно отмерить вперед и назад? Вот приснопамятный PHP — это шаг вперед, назад, или все-таки вбок (или вообще в другое измерение ;))? Го прекрастно заполняет нишу между низкоуровневыми языками типа C/C++, Java и медленными, но удобными Ruby,Python и другие. Недаром на Го переходят в основном не С-шники, а как раз рубисты и питонисты.
Горутины, каналы, интерфейсы — это замечательные инновационные парадигмы.

Да я вас умоляю. Этим идеям десяток лет, не меньше.

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

Ага, но не такие недостатки. Авторы Go решили просто проигнорировать успешные разработки в области языков программирования, чтобы сделать попроще. (К сожалению язык проще, чем Brainfuck, придумать сложно).

У нас появилась линейная шкала, где можно отмерить вперед и назад?

Можно сравнивать отдельные параметры, что автор на протяжении всей статьи и делает.
Горутины, каналы, интерфейсы — это замечательные инновационные парадигмы.

Да я вас умоляю. Этим идеям десяток лет, не меньше.

Совершенно верно. Ровно то же можно сказать про все инновационные фичи других свежих языков программирования, таких как Rust, D, Julia… Так что если отвлечься от занятий казуистикой и копанием в архивах научных статей по ИТ, то приходится признать, что исходное утверждение «Go doesn't really do anything new.» не так уж соответствует действительности, как может хотеться некоторым.

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

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

Если бы авторы Go решили все делать как в Rust, то у них и получился бы Rust. В таком непростом деле как проэктирование ЯП не все решения являются единственно правильными — чаще приходится идти на компромисы. Да, Go мог бы быть лучше в некоторых аспектах, но не факт что цена этого улучшения стоила бы того.

У нас появилась линейная шкала, где можно отмерить вперед и назад?

Можно сравнивать отдельные параметры, что автор на протяжении всей статьи и делает.

Сравнивать нужно сравнимое, не так ли? Зачем утверждать что Go не подходит для программирования микроконтроллеров, если Go и не проэктировался для этого? Вот PHP не подходит для программирования микроконтроллеров, теперь сжечь все учебники по PHP?
| Да я вас умоляю. Этим идеям десяток лет, не меньше.

Идеям да, даже больше десятка лет… А реализациям? Можете привести примеры более-менее успешных языков реализующих Хоаровскую СSP?

| Ага, но не такие недостатки. Авторы Go решили просто проигнорировать успешные разработки в области языков программирования…

Поверьте авторы с их опытом разработки языков точно знали, что делали… А вы явно пытаетесь судить о вкусе устриц, которых не ели… Если вам нужны реально работающие приложения, это одно. А если вам нужны «успешные разработки в области языков программирования», это другое. Напишите пару нормальных проектов на Haskell'е, потом обсудим…
>> Можете привести примеры более-менее успешных языков реализующих Хоаровскую СSP
Occam? :-)
Я могу еще пару языков привести… Например, лимбо… Но назвать их сколь-либо популярными сложно…
Думаю на транспьютерах язык был весьма популярен
Ну да… Только сами эти транспьютеры можно было на пальцах пересчитать… )
>> Можете привести примеры более-менее успешных языков реализующих Хоаровскую СSP?
Erlang
Забавно что при этом у низкоуровневой Java есть generics, в отличие от go.
Ну вроде это просто сахар для Object, т.е. тот же Interface а не полноценные generics как в C#/C++. Может что в последних версиях Java поменялось, я не в курсе.
На уровне тип-системы и compile-time это +- полноценные generics. А то что в runtime их не существует — особенность, с которой надо мириться.

В контексте статьи выше — они покрывают те примеры что у автора.
В своё время высказывался по оригинальному варианту статьи. Сильно сомневаюсь, что автор на самом деле хоть что-то пишет на Go. Ни rust ни haskell он сам не использует, судя по его репозиторию. Там в основном питон и cи. На Go там только клон btcd без единого коммита. В общем компетенция автора во всех трёх языках упоминаемых в статье, вызывает сомнения…

Тем кто реально писал на Go подобное сравнение делать бы даже в голову не пришло. Go реально рабочий язык разработки, успешно решающий вполне конкретные практические задачи. И решающий явно лучше других.
Rust даже в beta не вышел и у него даже нет формализованнного стандарта. Грубо говоря, языка как такового еще нет, есть только название языка и базовые концепции синтаксиса.
Нaskell — академический язык, с очень высоким порогом входа. В мире очень мало (относительно других языков) команд, пишущих реальные проекты на Haskell'е. Он эдакий современный smalltalk, из которого идеи и приемы разработки растаскивают по другим языкам…

Он просто не в курсе, чем силён Go…
Кстати, можете пояснить, почему любители Go постоянно упоминают «формальный стандарт» или «спецификацию». Ни от кого больше такого упора на её наличие не встречал.
У Rust есть doc.rust-lang.org/rust.html — тут весь язык расписан довольно подробно. Крупные публичные проекты на нём уже есть. Сторонних библиотек пока не так много разве что.
Дело в том, что у языка Go есть дизайн. В спеках и сопутствующих документах рассказано, почему и для чего было сделано именно так, а не по другому. Следование указаниям спецификации позволяет избежать тех ошибок, от которых авторы языка и хотели избавить программистов.
Не знаю, почему другие не интересуются спецификациями. Без этого совершенно не понятно как разрабатывать на rust'е проекты с более-менее длительным жизненным циклом. Элементарный style guide невозможно устаканить без стабильного синтаксиса. Выход новой версии компилятора ломающего обратную совместимость автоматически ведет к переписыванию проекта.
Сразу скажу, лично я к Rust'у отношусь позитивно и стараюсь следить за развитием языка. Но на данном этапе он с Go не конкурент. Более того, складывается впечатление что конкурентами в полной мере они и не станут. Скорее Rust будет вытеснять тяжеловесный Haskell и прочие… А Go так и останется языком дуболомной сетевой и системной разработки, когда надо написать быстрые и конкретные инструменты без заумных абстракций…
Rust и Haskell по областям применения практически не пересекаются.
Концепция времени жизни в Rust очень сложна. Разбираться в связанных с ней ошибках при компиляции тяжело (хотя и проще, чем отлаживать код на C++ :-)). В приложениях, где допустима ленивость и сборка мусора Haskell еще долго останется предпочтительнее.
Теснить Rust будет в первую очередь C и C++. А потом Java, Go и Python из области разработки GUI (где отказ от GC и хорошая параллельность поможет обеспечить хорошую реактивность не слишком большой ценой).
Rust даже в beta не вышел и у него даже нет формализованнного стандарта. Грубо говоря, языка как такового еще нет, есть только название языка и базовые концепции синтаксиса.
Rust готовится в этом году зарелизиться. Afaik, особых синтаксических изменений больше не предвидится (до 2.0; остальное прячут под feature gates), сейчас доделывают какие-то специфические вещи и шлифуют стандартную библиотеку.
Нaskell — академический язык...

Что значит «академический»? Вы полагаете, что Haskell можно использовать исключительно для академических целей?

… с очень высоким порогом входа.

Смотря как входить…
По прочтении статьи создаётся впечатление, что этот ваш Go — просто попытка переизобретения Java десяти-пятнадцатилетней давности, поправьте, если ошибаюсь. А еще в нём можно не писать тип переменной при присваивании — большой шаг вперёд :)
Вы хотя бы прочли спецификации языка перед тем как делать такие утверждения. А то судите по Go только со слов других людей, которые сами не факт что разбираются в предмете обсуждения. Go проэктировался в первую очередь для высококонкурентной обработки данных, призваный сместить текущую парадигму потребления ресурсов многоядерных CPU через использование тредов.
Да, я действительно не прочитал, поэтому оговорился о том, что впечатление такое создалось после прочтения статьи. Всё равно, я не очень понимаю, почему смещение текущей парадигмы потребления ресурсов так помешало сделать те же дженерики, например.
Конкретно дженерики ради простоты. Язык все ещё находится в стадии становления, думаю, вопрос дженериков просто отложили как не самый важный, возможно в версии 2.0 что-то такое добавят.
Где-то слышал, что отсутствие некоторых фич, вроде шаблонов типов, связано с желанием максимально ускорить компиляцию.
Правда ль, нет? Призываю в ветку экспертов!
Я не эксперт, но был на нескольких митапах по Go в San Francisco и задавал вопрос по generic'ам. Мой вольный пересказ: generics — это конструкция, которая повлияет на все другие аспекты языка — структуры, функции, методы, интерфейсы, каналы, пакеты — на все. На данный момент в языке все эти конструкции — ортогональны. Таким образом ввод generics сильно усложнит язык — как реализацию, так и использование. Также generics сами по себе — сложная вещь, есть подходить основательно (variance, type constraints). Разработчики Go не хотят вводить generics «чтобы было». Они пока не нашли решения, как можно ввести generics в go, чтобы это не навредило языку. Может и не найдут, но от generics окончательно и бесповоротно они не отказываются пока.
Вот грустно это, что на дворе 21-й век, космические корабли бороздят просторы хабра, а гугл релизит язык с претензиями на мэйнстрим, и без вменяемой поддержки generic programming. Ну не такая это сложная штука, и много где уже реализована, так что задизайнить базовую поддержку вполне можно было (вариантность, сложные type constraints и прочее можно оставить на потом, это все прекрасно прикручивается поверх).
Вряд ли проблема со скоростью компиляции дженериков есть где-то, кроме С++
вариант из Rust — «трейты» [или «примеси»/«миксины», в зависимости от перевода — прим. переводчика]
Всё же traits и mixins — разные зверюшки независимо от перевода :)
Смотрю я на этот Rust и ничегошеньки в этих !"№;%:?*()_ не понимаю. Очень много пунктуации.
Не зря Роб Пайк говорит на каждой конференции (по крайней мере из просмотренных мною):
Go разрабатывался как компилируемый язык, который бы ощущался как скриптовый.

Это у разработчиков на ура получилось.

Отсутствие возможностей переделать синтаксис языка «под себя» как по мне — только плюс, хоть бы потому, что в среде разработки на функцию можно попасть в один клик, а перегруженный оператор поди найди — где и как.
Возмущения по поводу отсутствия аналогов Option и Maybe в Go тоже мне не ясны, хоть бы потому, что при желании сделать объект-обертку для подобной схемы — дело нескольких минут.

Короче говоря — на фоне преимуществ (простота, скорость, параллелизм) аргументы «против» как-то не очень убедительны.
Насчёт Rust'a — язык от переизбытка символов успешно избавляется с новыми версиями.
UFO just landed and posted this here
В Go методы можно вызывать и на Nil'ах тоже, обрабатывая этот случай, если это нужно. В терминах Java получается, что внутри метода this==null, а непосредственно вызов метода не приводит к NPE. Также go-way подразумевает корректную обработку таких нулевых значений, например Nil слайсы ничем не должны отличаться от пустых (и не отличаются в стандартных функциях).
Это не прямая альтернатива Option, но по-своему позволяет решить заметную часть связанных с Nil'ами проблем.
Прочитал о Option более детально — согласен, недооценил. В Go отловить на этапе компиляции указатель на nil не получится.
>> Отсутствие возможностей переделать синтаксис языка «под себя» как по мне — только плюс, хоть бы потому, что в среде разработки на функцию можно попасть в один клик, а перегруженный оператор поди найди — где и как.

Это скорее претензии к тем IDE, которые не умеют делать Go to Definition на операторах. Например, VS это замечательно умеет для C# — если навести мышой на оператор, подсказка дает его полное название (включая класс, где он определен) и сигнатуру, а Go to Definition прыгает туда.
Перевод приличный, спасибо за старания! Могу посоветовать дальше просто начать переводить смысл пар предложений, не хватаясь за структуру. Потом надо просто перепрочесть, чтобы проверить смысл. Тогда стиль будет более естественный русскому языку.

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

> Вместо возврата строки или нулевого указателя мы возвращаем объект, который может содержать, а может не содержать строку.

Более свободный перевод даст возможность использовать порядок слов, ведь в русском языке он заменяет и логическое ударение, и артикль, то есть степень определённости. Здесь, например, «строку» лучше поставить перед «может содержать, а может и не содержать», которая будет замыкать предложение, ведь логическое ударение именно на эту конструкцию.

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

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

www.haskell.org/haskellwiki/Applications_and_libraries/Robotics
Не совсем то, конечно, т.к. тут команды поступают через внешний интерфейс. Один мой друг программировал лего через NXT, хвалил библиотеку.

Го во многом хорош, но возможностей интеграции с языком и zero cost abstractions всё-же сильно не хватает.
Что в Гоу нет указателей и небезопасного кода — враньё. Там есть модуль unsafe как раз для этого и предназначенный.
Sign up to leave a comment.

Articles