waqur: (Default)
[personal profile] waqur
Google потихоньку разрабатывает новый язык программирования - Go: http://www.golang.org/

В составке команды работает Кен Томпсон - один из легендарных отцов-основателей UNIX.

Язык go достаточно интересен для того, чтобы я выделил время на него: попробовать и рассказать вам.


Оставим пока в стороне вопросы о синтаксисе и парадигме, и начнём с главного. Стоит ли на него тратить время? Вспомнит ли об этом языке кто-то через 5 лет?

1. Взлетит или не взлетит?
Рассмотрим этот вопрос в общей постановке.

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

Есть ряд достаточно неплохих языков, которые набрали тягу в мире UNIX, но не годятся для создания GUI-приложений для винды: Python, Perl, Tcl/Tk, Ruby, Java. Почему? Потому что они страдают от болезни, симптомы которой можно охарактеризовать как UNIX'измы:
- зависимость от runtime-окружения - нужно ещё что-то догружать из интернета, кроме самой программы
- нужны админские права для запуска программы с флешки в гостевом режиме (если runtime-окружения на данной машине ещё нет)
- жёсткая привязка к путям в файловой системе или реестре, невозможность свободного передвижения runtime-окружения в файловой системе
- если программа #1 привязана к специфическим ошибкам runtime-окружения старой версии, обновление runtime-окружения до новой версии при установке программы #2 может сломать работу программы #1
- невозможность одновременной установки двух версий runtime-окружения или невозможность одновременного запуска программ с зависимостью на разные версии runtime-окружения

Под runtime-окружением мы понимаем и монстров вроде JRE, и просто набор DLL-файлов в папке SYSTEM32, которые туда высирает установщик (это порождает проблему, известную как "DLL Hell", если поставщик этих DLL-файлов продолжает выпускать новые версии под теми же именами).

Это с одной стороны. А с другой стороны, есть ряд языков похуже, которые (прямо скажем) не блещут гениальностью, но взлетели: Delphi, Visual Basic; в более ранние времена - Pascal, Clipper, QBasic. Почему? Потому что на них можно писать портабельный софт.

Уникальный случай - Microsoft .NET . Налицо все симптомы юниксизма в винде, отсюда вполне предсказуемый результат: несмотря на все усилия по внедрению - и маркетинговые, и технические - платформа за 10 лет так и не набрала достаточно тяги, чтобы количественно переплюнуть C++. Некоторый софт, например Evernote, сначала пишется на C#, а спустя годы - всё переносится на С++. Какая глупая трата времени вследствие изначально неверно выбранного языка программирования.

Основная причина этой ситуации в том, что непортабельный софт и сопуствующий пакет проблем (см.выше) поднимает требования к эндюзеру до уровня юниксового админа. Средний виндовый юзер - это не юниксовый админ, а блондинка-домохозяйка, и она не будет под давлением вашего софта повышать собственную админскую квалификацию, а просто отправит такую программу туда, где ей и место - в Recycle Bin. Все исключения из этого правила можно подвести под принцип "мышки плакали, кололись, но продолжали есть кактус" - корпоративная среда (привет Java/C#) и монопольное положение программы на рынке. Как только у программы появляются нативные, портабельные конкуренты - это инициирует массовый исход эндюзеров.

Такие среды как Cygwin, обладают "понижающим эффектом" - они вносят юниксизмы (зависимость от cygwin1.dll и фиксированных путей в реестре, потенциальный конфликт версий cygwin1.dll) туда, где их изначально нет, поэтому они и все скомпилированные ими программы тоже рождены исключительно ползать, несмотря на то, что это как бы C и C++.

Есть целые операционные системы, где весь софт таким образом работает, иначе нельзя. Их рыночная доля говорит сама за себя. Так же как и тот факт, кто является самым богатым человеком на планете. Money talks, bullshit walks.


2. Так взлетит или не взлетит?
Go - это компилируемый язык, который порождает нативные бинарики без зависимости на динамические библиотеки. Этим бинарикам не нужна никакая специфическая runtime-среда и не нужна какая-то специфическая структура файловой системы или реестра. Это касается всех поддерживамых платформ - Windows, Linux, MacOS X и Plan9.

Следовательно, взлетит.

Компилятор языка Go тоже не зависит от среды исполнения и свободно перемещаем по файловой системе (хотя требует настройки через окружение, которую могут делать, например bat-файлы). Go имеет полностью автономный тулчейн, то есть компилятор, компоновщик и архиватор библиотек; а также набор стандартных библиотек. Ему для работы не нужен платформенный компоновщик типа GNU binutils ld или MSVS link.exe, равно как и *.h/*.lib/lib*.a-файлы с нативной платформы.

В Go-тулчейне есть автономный C-компилятор (8с/6c) и даже ассемблер (8a/6a). Причём они порождают не какой-то там p-код, а самый настоящий машинный код. Полный контроль над платформой, абсолютная изоляция от тулчейна gcc/msvc - в общем, всё на полном фарше.


3. Парадигма языка
Императивный, структурный с элементами ООП, строго типизированный. С автоматической сборкой мусора. Функции - объекты первого класса, полная поддержка замыканий. Без поддержки шаблонов и исключений. Многопоточность и IPC встроены в ядро языка, поддерживаются легковесные потоки и типизированные каналы.


4. Для чего может быть полезен
1) Написание сценариев, управляющих компиляцией больших проектов
2) Написание небольших утилит командной строки
3) Web-программирование
4) Web-программирование в облаке
5) Обучение программированию
Языку остро не хватает нормальной поддержки GUI, впрочем портирование под него wxWidgets или Qt - всего лишь вопрос времени. Как только это произойдёт, язык начнёт напрямую конкурировать с C++ за настольные и мобильные приложения.


5. Система типов и ООП
Классики марксизма-ленинизма учат нас, что ООП стоит на трёх столпах - наследование, инкапсуляция и полиморфизм.
Впрочем, оказывается можно и по-другому.
Представьте себе абслютно строго типизированный язык, где нет операции принудительного приведения типов. "Прекрасно!" - скажете вы, - "выявление всех ошибок приведения типов на стадии компиляции, отсутствие необъяснимых путей конверсии при выполнении программы, безупречная стыковка модулей". Всё это так, но возникает проблема: как делать апкаст?

Допустим, у вас есть функция, которая читает до EOF из непозиционируемого потока, такого как пайп или сокет. Так пайп или сокет? Создавать две функции для этой цели - это даже не прошлый, а позапрошлый век программирования; а иерархическая система типов в стиле С++ или Java ослабляет безупречно жёсткую систему статического контроля на стадии компиляции.

А представьте, если бы интерфейс ("непозиционируемый поток") не был частью типа "пайп" или "сокет", а был как бы отдельно. Функция чтения-до-EOF принимает такой интерфейс. Классы "пайп" или "сокет" объявляются отдельно, возможно в другом модуле, со всеми полями и методами, но без наследования. Интерфейс - это как трафарет, он задаёт перечень полей и методов, которые должны "просвечивать" из класса, чтобы состоялся вызов функции "чтение-до-EOF". Просто по факту соответствия класса и интерфейса, лексического совпадения имён полей и сигнатур методов, происходит upcast. Downcast'а нет.

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

Публичность/приватность полей, методов и типов в классах и модулях программы задаёт первая буква. Если она большая (A-Z) - получается публичная сущность (тип/объект/функция), если первая буква маленькая (a-z) - получается приватная сущность.

Таким образом, ООП возможно без наследования.


6. К чёрту препроцессор и заголовочные файлы
Макросы препроцессора уже давно не являются чем-то незаменимым, ну а что касается включаемых файлов и связей между модулями, то здесь авторы языка Go придумали очередное изящное решение: компилятору вместо хэдеров подойдут объектные файлы других модулей, ранее собранных, ведь из них можно узнать всё необходимое. При этом, порождаемый объектный файл для текущего модуля включает все зависимости, т.е. линкеру нужен только объектный файл того модуля, где у вас определена функция main().

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


7. Заинтересовались?
http://www.golang.org/

http://code.google.com/p/gomingw/downloads/list

Date: 2011-05-17 02:37 pm (UTC)
From: [identity profile] bialix [launchpad.net] (from livejournal.com)
Как насчет создания полностью автономных программ на Python при помощи утилиты py2exe? Создается полностью автономный и независимый экзешник, ничего не нада скачивать с тырнета.

Date: 2011-05-17 03:01 pm (UTC)
From: [identity profile] waqur.livejournal.com
ну, py2exe просто сворачивает скомпилированные в p-код питоновские исходные файлы + библиотеки + интерпретатор в архив, цепляет его как оверлей к заранее скомпилированному exe-шнику, который у эндюзера разворачивает всё это хозяйство в %TMP% и запускает оттуда

это иногда работает, но в общем случае есть нюансы - XP-манифесты, права/квоты в %TMP%, аварийный останов приложения, юзер с файерволлом который запрещает скрытый запуск процессов, отслеживание зависимостей при упаковке архива (http://habrahabr.ru/blogs/python/117686/#habracut)

Date: 2011-05-17 07:37 pm (UTC)
From: [identity profile] bialix [launchpad.net] (from livejournal.com)
ничего в %TMP% не разворачивается, вы плохо с этим знакомы. А я с этим работаю не один год.

с python 2.5 проблем с манифестом не существует. эта проблема проявляется только с питонами 2.6-2.7 и только если у юзера отсутствует рантайм от msvc 2008, впрочем это слабое утешение.
Поэтому 2.5 -- выбор тех, кому надо рабочее решение без геморроя.

отслеживание зависимостей -- для простых вещей не является проблемой.

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

Интересно почему вы в список полезностей Go вынесли так мало.
Что, разве серьезные вещи (без гуи) на нем вообще нет смысла писать?

Date: 2011-05-17 07:41 pm (UTC)
From: [identity profile] bialix [launchpad.net] (from livejournal.com)
окей, если не пытаться все запихнуть в один exe, то в %TMP% ничего не разворачивается, потому что все бинарники остаются отдельными файлами. Важно иметь только один файл? Под требование "иметь переносимый бинарник" подходит и папка с файлами и dll.

Date: 2011-05-17 07:51 pm (UTC)
From: [identity profile] waqur.livejournal.com
не, ну это я так, придираюсь
в принципе, папка с набором .pyc-файлов, интерпретатором питона и батником-пускателем катит на портабельный софт

Date: 2011-05-17 07:56 pm (UTC)
From: [identity profile] waqur.livejournal.com
Интересно почему вы в список полезностей Go вынесли так мало.
Что, разве серьезные вещи (без гуи) на нем вообще нет смысла писать?


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

Я пока только пробую Go для написания сценариев, управляющих компиляцией больших проектов.

Date: 2011-05-18 02:20 pm (UTC)
From: [identity profile] waqur.livejournal.com
Я тут разобрался подробнее, оказывается у Go в тулчейне есть Си-компилятор и даже ассемблер.

Таким образом, можно на Си написать железобетонно-надёжный загрузочный модуль, который слушает сокеты, делает все эти асинхронные штучки с epoll и eventfd, и всё это на отдельной куче, которая не фрагментируется и не может внезапно исчерпаться. Время от времени этот модуль будет отфорковываться уже в отдельном процессе запускать вычисления дальше -- и они пойдут тем путём, как они идут в нормальной программе -- рантайм языка go, функции init для каждого модуля, затем функция main главного модуля на языке go, затем всё остальное. Дочерний процесс будет делать основную работу, засирая конечно кучу, и время от времени (скажем раз в 10 минут) главный процесс будет завершать и перезапускать дочерний процесс. У главного процесса ведь адресное пространство чистое, сборкой мусора и фрагментируемой кучей он не пользуется.

В таком виде это уже может работать для 'серьёзных вещей'.

Date: 2011-05-18 02:28 pm (UTC)
From: [identity profile] japanspy.livejournal.com
А после браузерных приложений и планшетов домохозяйки еще что-то инсталлируют? Кроме игр.

Date: 2011-05-18 02:41 pm (UTC)
From: [identity profile] waqur.livejournal.com
йесофкорз! Чтобы получить примерный список, зайди на любой софтовый архив типа download.com или simtel.net и выбери категорию "Most popular" или её аналог.

Открой любой журнал типа ДПК, раздел софта. Вот онлайн версия - http://www.dpk.com.ua/tests-and-reviews/software/page-1

Наконец, можно просто подойти к любому недевелоперскому компу и открыть апплет Add/Remove Programs в контрольной панели. Или к девелоперскому и просто отфильтровать MSVS, Cygwin, JDK и тому подобное.

Date: 2014-10-04 05:36 pm (UTC)
From: [identity profile] justbulat.livejournal.com
5. это аналог type classes из haskell. это не ООП, поскольку ООП - это не любой динамический полимофризм, а именно использующий наследование

6. это как раз стандартный подход, к примеру такое было аж в турбо-паскале 4.0, причём содрано с ещё более раннего ms pascal (unit и всё такое). просто С первоначально компилировался на очень маленьких машинах и они таким образом упростили себе реализацию раздельной компиляции

Date: 2014-10-05 06:50 pm (UTC)
From: [identity profile] thesz.livejournal.com
5. Изобретатель термина ООП (Алан Кей) с вами не согласится.

6. (к автору исходного текста) не сумев сделать generics, авторы Go таки делают препроцессор.

March 2024

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      

Автор стиля

Развернуть

No cut tags
Page generated 2026-03-04 07:49 am
Powered by Dreamwidth Studios