Pull to refresh

Comments 252

UFO just landed and posted this here
Роб Пайк одержим идеей создания простого и легкого concurent language и Go это не первая попытка, были еще Limbo, Squeak, Newsqueak.

Я как бы немного да в курсе, да. «Простой и легкий concurrent язык» это по сути своей и есть сишка без арифметики над указателями и каналами и зелеными потоками, не более.

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

Ну во-первых, никто не куда не скатывается: в Go принято писать низкоуровневую императивную лапшу в стиле С, это идиоматика языка и она очень классно работает. Во-вторых, gofmt && gometalinter просто не позволяют писать отвратительный код, он так или иначе будет «неплох», ничего не поделаешь. Я не понимаю, зачем маленьким и амбициозным командам нужен такой убогий язык, как Go. Куда круче для «маленьких» работает выразительный питон, например, для которого кучу всего уже написано.
s/не куда/никуда

А что касается Пайка, то он разводила еще тот. Знакомый из гугла жаловался, что Пайк написал какую-то внутреннюю систему запросов, которая просто лохотрон полный и теперь им это все поддерживать надо и никто от этого не в восторге. Короче говоря, среди гуглеров у Пайка репутация далеко не однозначная.
UFO just landed and posted this here
ну, если мало денег, то можно и на пхп писать, а со временем переписывать, это быстро и дешево, на старте быстродействие редко важно так как быстрота разработки
UFO just landed and posted this here
У стартапа априори нет аудитории, стартап стартует без аудитории, и затем аудиторию набирают. Да и 1 млн пользователей не так уж и много для пхп, он выдержит и больше, хостинг будет дешевле, разработчиков больше, которые уже знают язык хорошо, и не будут лезть в мануал чтоб узнать как же это увеличить словарь, ато размер подошел к концу, или как залить файл на сервер.
Если нужно что-то сделать быстро, то лучше подойдет язык который уже известен, с граблями которые уже известны. А если нужно что-то сделать надежно, то это не стартап, и не го, увы. Для каждого свое время и место.
И тут, внезапно, go — быстр в изучении, быстр в разработке, быстр в работе, требует меньше дорогих серверов для обслуживания того же объема трафика.
Очень быстр в работе:
http://www.techempower.com/benchmarks/#section=data-r11&hw=ec2&test=plaintext
rapidoid (Java) 397,666 100.0%
go-raw (Go) 50,295 12.6%

Очень быстр в разработке: постоянное написание велосипедов, вместо реиспользования кода (привет, дженерикам) очень этому способствует.
Данные как минимум устарели, не вижу fasthttp в списке. А он в 10(десять) раз быстрее стандартного net/http в go по результатам бенчмарков.
О дженериках я с вами спорить не буду, не понимаю, как люди вообще могут что-то без них писать, сплошные велосипеды.
Не поленитесь и добавьте реализацию на fasthttp :-)
Реквесты они вполне себе принимают, правда обновляют результаты лишь раз в пол года.
Я вот пол года назад добавил туда vibe.d: vibe.d (D) 27,974 7.0%
Тот ещё тормоз. Хотя, он запускается там в дебаг режиме, ибо в релизном банально падает.
Давайте напишем одно и то же приложение, вы на го а я на пхп, и мы сравним у кого это выйдет быстрей? Не нравится пхп? Возьмите питон, руби или ноду, тоже языки отличные для старта, где можно найти хорошего программиста, который быстро все сделает что нужно. А ресурсы в наше время не дорогие, этот аргумент давно уже ушел на второй план. Человеко-часы на много дороже, а опытного гофера еще попробуй найди.
Хахаха, хорошая шутка. Ну, кто подкинет ТЗ? Но условимся, что это не будет сайт-визитка, а какой-нибудь полноценный веб-сервис с парой тысяч условных посетителей в секунду.

Я на php потратил лет 7, и здорово представляю, что там да как. На ноде тоже написал несколько полноценных SaaS, и в целом несколько последних лет это была нода и изредка c/c++ для нативных модулей.
Go же я использую пару месяцев. Но потягаться, думаю, смог бы, будь в Вашем предложении хоть капля здравого смысла.
Ок, в то время пока гофер будет делать свой «суперпупербыстрыйсайт», пхп-шник/подставьте свой язык популярный, уже будет на этом сайте первых клиентов получать и деньги иметь. Никто не спорит что го выдержит больше нагрузку, а нужна она на старте? У вас есть уже эти пата тысяч посетителей? Я смотрю здесь много стартаперов собралось, все прекрасно понимают как все работает, создают сайт и сразу бабло течет рекой. Дело в скорости разработки, пхп прекрасно выдерживает нагрузки в сотни конектов в секунду, этого для старта более чем с головой достаточно, но скорость разработки у пхп в разы быстрей чем на го, особенно у человека который 7 лет потратил на пхп. То что вы напишете на го за неделю, на пхп потратите от силы пару дней, и на пхп оно будет стабильней и продуманней с точки зрения архитектуры на будущее.
Вот как «популярность» языка влияет на скорость разработки?
Сайт-визитку с формой заказа я сделаю на go за 15 минут, ровно как и на php. Конечно в Go у меня совсем мало опыта, гораздо меньше чем в php, но он гораздо проще, потому скорость разработки будет примерно равна.
Так-же и с бóльшими проектами.
А еще его простота дает возможность любому опытному php/js/python/… программисту за пару-тройку вечеров освоить go до уровня самостоятельного написания проектов.
Нет, ты очень преувеличиваешь свои силы насчет сайта визитки на го за 15 минут. А вот на пхп, с опытом в 7 лет, это действительно ближе к реальности. Вот как влияет скорость от популярности языка. Одна фраза «как сделать ХХХ на языке УУУ» приведет с большей вероятностью к решению проблемы на популярном языке. Вы не будете гуглить решения простейших проблем на пхп, вы это все уже знаете, это вьелось в подкорку с опытом работы, с го у вас такого нет, разница в скорости у вас будет на порядок (именно в прямом смысле, десяток и более), а то что вы спорите, лишь добавляет мне уверенности что с го вы не работали нормально, поэтому разница в скорости разработки еще увеличивается. Нет на го хороших разработчиков, а если и есть, то их на сколько мало, что ими можно пренебречь (как в математике). Отсюда и скорость разработки.
У меня ушло 20, с версткой. Go ~40 строк с простейшей валидацией формы и сохранением в бд. Надеюсь вопрос закрыт? github.com/mirrr/kkk

ps. минус за «тыканье»
Это не сайт визитка, это кусок говна, уж извините за выражение, мы про стартапы говорили или про одну функцию для сохранения строки в базе? Вы действительно так туго соображаете или издеваетесь? Я вам про полноценный сайт говорю, а не про страничку на пару строк. Давайте еще сравним как быстро вы напишете хелло ворлд? Это просто гениально было! Аплодирую!
Уж извините, если сайт-визитка на go умещается в пару строк. Но думаю это не повод переходить на оскорбления.
Добавлю, что о стартапах здесь говорили только Вы. Никогда не занимался стартапами в вашем понимании этого слова, потому об этом ни слова не написал. Мой хлеб — проекты, которые на старте имеют больше посетителей в минуту, чем многие стартапы в год.
И код, который вы назвали говном, не просто «функция сохранения в базу». А полностью рабочий сайт, который выводит вебстраницу с текстом и формой обратной связи, а так же обрабатывает ее, с валидацией и выводом сообщений пользователю, что собственно вполне попадает под описание сайта-визитки.
Потому, прежде чем что-то писать, советую ознакомится с предметом обсуждения, а не выставлять себя дураком.
Я уже понял что ваш хлеб — хелоуворды недоделаные (да, снова личности, увы, не могу по другому обьяснить свои слова). То что вы показали не «полностью рабочий сайт», а именно поделка, функция сохранения в базу. полностью рабочий сайт предусматривает наличие редактируемых текстов, вывод их, админку для этих текстов итд. Но если вы в таком виде отдаете сайты заказчику (это я сделал вывод из слов «полностью рабочий сайт»), то у нас разные мнения по этому поводу. А насчет больше или меньше посетителей, то это, опять же, понятие относительное, некоторым и страница с формой — полноценный сайт, другим и 100 пользователей в секунду высокие нагрузки.

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


Вы путаете сайт и CMS. За 15 минут CMS с нуля, без использования фреймворков, не написать пехепешнику даже с 15 годами опыта. А разворачивание готовой CMS и настройка её через админку к разработке мало отношения имеет.
Я не путаю ничего, цмс подразумевает не просто фронтенд с админкой, она предполагает некий набор стандартный возможностей. В любом случае в полноценном сайте человек (заказчик) должен иметь возможность хотябы просмотреть то что сайт предполагает сохранять. Ту же поделку, тот же человек на пхп (учитывая его опыт) смог бы сделать на много быстрей с валидацией и простейшей админкой хотябы на просмотр оставленного посетителями). Об этом и речь, скорость разработки, а мне тут расказывают как они быстро хеловорлд напишут. Я говорю про разницу во времени, а мне в скорости го приложения. Научитесь слушать собеседника для начала.
В любом случае в полноценном сайте человек (заказчик) должен иметь возможность хотябы просмотреть то что сайт предполагает сохранять
… смог бы сделать на много быстрей с валидацией и простейшей админкой хотябы на просмотр оставленного посетителями). Об этом и речь, скорость разработки, а мне тут расказывают как они быстро хеловорлд напишут. Я говорю про разницу во времени....


Омг, окей, добавил админку, с авторизацией и просмотром записей.

Это было болью, заняло полдня
admin := r.Group("/admin")
admin.Use(gin.BasicAuth(map[string]string{"admin": "secret"}))
admin.GET("/", func(c *gin.Context) {
	fbks := []feedback{}
	session.DB("mydb").C("feedbacks").Find(gin.H{}).All(&fbks)
	c.HTML(200, "admin.html", gin.H{"feedbacks": fbks})
})


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


И вы, конечно же, такое чудо создадите с нуля за 15 минут, да:
на го за 15 минут. А вот на пхп, с опытом в 7 лет, это действительно ближе к реальности


?
http://www.yiiframework.com/doc/blog/1.1/ru/prototype.scaffold
это рас
миграции — куча библиотек, с ошикарной документацией
это два
пхп сам по себе шаблонизатор, с довольно таки высокими возможностями обработки в шаблонах
это три
не нужно цепляться за слова, хело ворлд на всех языках пишется очень быстро, другое дело что я со всем вышеперечисленным работал и хорошо знаю, это значительно ускоряет время разработки, в го такого пока нет, а если и есть, то возможностей меньше, придется очень много самому писать, это значительно снижает скорость разработки.
Чего только стоит загрузка файла на сервер, на пхп это реально за 5 минут делается, а на го? По памяти кто-то напишет код загрузки файла?
Я могу еще продолжать, и самое интересное все прекрасно понимают что на то они и популярные языки, скорость разработки на них велика, в ущерб другим вещам, но как же так, я написал хелловорлд за 40 минут, поэтому ты неправ!, и плевать что я вообще о другом говорил.
пхп сам по себе шаблонизатор

Ну так и в Go есть родной шаблонизатор, в чем преимущество?

Чего только стоит загрузка файла на сервер, на пхп это реально за 5 минут делается, а на го?

На go это занимает целых 5 секунд:

file, _, err := c.Request.FormFile("file")


хелловорлд за 40 минут, поэтому ты неправ!, и плевать что я вообще о другом говорил.

Да хрен вас поймешь, уважаемый, о чем Вы говорите. Я говорил о времени разработки, вы о какой-то «популярности», стартаперах, сайт-визитку упорно называете хелоувордом. А вместо аргументации оскорбления и истерика.
Давайте с другой стороны: вы утверждаете что скорость разработки и цена затрат на пхп и го одинаковы для среднестатистического сайта? Вот я считаю что нет, на пхп будет дешевле и быстрей, исходя из тонны существующий библиотек, тонны существующих ответов и тонны людей знающих пхп. Вот и все. То что вы сделали страничку с формой за 40 минут, не поменяет ничего, вы же сделаете на пхп это быстрей, и чем больше функционала, тем больше будет пропасть между пхп и го, у вас же. Об этом я говорю.
«Простой и легкий concurrent язык» это по сути своей и есть сишка без арифметики над указателями и каналами и зелеными потоками, не более.

Если убрать каналы, то получится Erlang.
UFO just landed and posted this here
UFO just landed and posted this here
Восхитительно! До этого читал именно как «упоротых» и всё отлично складывалось, спасибо за комментарий!
UFO just landed and posted this here
И что мешает писать монолит, состоящий из маленьких, законченых модулей?
Надо только добавить что на нем легко делать и потдерживать микросервисы. Это все из за легкий деплоев и маленкий требываний к ресурсам. Так что есть много стартапов которым это очень нравится(меньше возни с серверами и меньше серверов)
Непонятно про deployment… В случае Java/.Net всё можно свести к схеме: копируем бинарники в новую папку, далее меняем конфиг сервера, чтобы смотрел уже в новое место. А как в Go? Там получается проще, чем копирование файлов?
Там получается проще, чем копирование файлов?
Проще копирования файлов может быть только копирования файла. Одного. Ваш КО.
А конфиг вшит в исполняемый файл? Например, на какой порт будет смотреть прога, в случае веба?
Укажите в командной стоке. Как вы думаете, зачем Goggle лет пять (или семь?) назад добавил в ядро Linux'а patch, который отменил ранее действовашее жёствое окраничение на длину командной строки в жалкие 131072 символов?
Еще можно использовать переменные окружения, например указать их в systemd сервисе или любом супервизоре.
я говорил в сторону Rails например.Там целая наука что и как unicorn puma и другие представители зоопарка. Как на Java делать обновления кода (не важно сколько) с gracefull restart?
В rails сейчас как и везде деплой делается перезапуском докер контейнера
Чтобы изменить конфиг сервера нужно сначала поднять сервер и создать для него конфиги.
В java уже можно не поднимать сервер вручную, встраивайте сервер в jar и все. Всякие Spring Boot это делают из коробки.
Никогда не понимал, зачем всё это, если Eclipse WTP (или какие там альтернативы в других IDE) сам поднимет хотите Tomcat, хотите Jetty, да ещё и будет автоматом редеплоить приложение в запущенный прогретый контейнер, вместо того, чтобы каждый раз вручную запускать веб-сервер в непрогретой JVM.
я говорю о продакшн деплое, сейчас уже вполне можно обходиться встроенным контейнером не скачивая какой нибудь tomcat, для разработки понятное дело в той же идее можно отдельные классы в рантайме редеплоить
ИМХО, как раз в контейнер сервлетов гораздо удобнее деплоить, чем копиировать jar-файл, потому что:

1. Когда мы деплоим war-файл, наше веб-приложение автоматом перезапускается. В случае с jar-файлом надо изобретать велосипед на скриптах.
2. Для деплоя war-файлов есть уже куча готовых утилит (cargo, который доступен через maven и через jenkins), в случае jar-файлов приходится поднимать ftp или ssh и велосипедить на скриптах.
3. В случае war-файла из коробки в том же tomcat есть zero downtime deployment, в случае jar-файла приходится… ну вы поняли.

В общем, embedded сервер полезен когда вы делаете совсем уж маленькую утилитку на <1000 строк за пару дней, и настройка WTP, Tomcat, Cargo и т.п. занимает больше, чем разработка самого приложения. Сам недавно так делал. В любом другом случае war-файл во всех отношениях удобнее.

Единственный контраргумент — это докер, но моя практика с ним показала, что это пока ещё не совсем зрелый инструмент и тот же нормальный zero downtime deployment делается костылями и велосипедами на скриптах. Да и не очень хорошо docker дружит с java, т.к. каждый контейнер — это своя изолированная JVM, а много мелких служб гораздо экономнее по памяти поднимать в одной JVM.
Мой опыт показывает, что деплоить war намного менее удобно, чем запускать jar со встроенным сервлет-контейнером. По пунктам.

1. Редеплой часто бывает не production-ready. Например, в jboss as в своё время редеплой хоть и работал, но периодически глючил.
2. Деплой через cargo — медленный и неудобный для разработки, а безопасность его под вопросом в продакшене. Медленный — потому что копируются все ресурсы приложения, а потом вся эта штука разворачивается контейнером. При использовании встроенного сервлет-контейнера достаточно лишь перезапустить процесс. Ничего копировать и распаковывать не нужно. Это что касается окружения разработки. А чтобы не велосипедить на скриптах при деплое в продакшене, можно сделать deb-пакет, например, или использовать контейнеры. Дополнительный плюс такого подхода будет в том, что не придётся долго рассказывать админам, как выполняется деплой. Обновил пакет — и всё работает. Что же касается безопасности деплоя через сокет в продакшене, достаточно отметить, что были эксплоиты для различных серверов приложений, которые эксплуатировали дырки в админках. Конечно, эти порты наружу не будут открыты, но в случае эмбеддед сервера этой проблемы вообще нет.
3. Не в курсе про томкат, может быть там все действительно хорошо с zero downtime, но я бы поостерёгся редеплоить приложения в продакшене (см первый пункт).

Сравнить скорость cargo и ембеддед можно легко, если есть в наличии проект, war которого занимает мегабайт 70. cargo будет деплоить эту штуку сильно дольше, чем просто запустится новый java-процесс. А высокая скорость рестарта при разработке — высокая производительность программистов, то есть наше всё.
Стоит добавить, что частый редеплой приложения при не очень удачных библиотеках и/или сервлет-контейнере/аппсервере может приводить к OOM по permgen/metaspace. Получается такой «zero» downtime, что лучше уж как-нибудь без него. Как минимум, регулярно ловим на jboss as 7.
Хочу сразу оговориться, что cargo я упомянул только в контексте production, разумеется, делать деплой с его помощью при разработке — это слишком долго, с этим гораздо лучше справляется IDE.

Теперь почему запускать jar-файл — это долго. Потому что при запуске jar-файла стартует новая JVM, которая все методы, как самого embedded-контейнера, так и вашего приложения, интерпретируются, до тех пор пока они не выполнятся очень много раз. Далее, скорость запуска контейнера — фигня, т.к. вот типичное такое приложение на 200 LOC стартует следующим образом:

1. Запускает миграции БД или хотя бы удостоверяется, что все существующие миграции уже применены.
2. Читает Spring-конфигурацию и сканирует classpath, собирает бины.
3. Читает JPA-конфигурацию, строит мапперы и т.п.

Опять же, всё это на непрогретой JVM. В итоге — 30-60 секунд. Экономия в 2-3 секунды на деплой (именно столько получается у меня — ЧЯДНТ?) — капля в море. Реально спасти тут может не embedded-сервер, а какой-нибудь jrebel.

А чтобы не велосипедить на скриптах при деплое в продакшене, можно сделать deb-пакет, например, или использовать контейнеры.

И что я с этим deb/rpm-пакетом буду делать? scp && ssh (yum install && systemctl restart)? А можно как-нибудь автоматизированно? Тот же cargo — это нажатие одной кнопочки в jenkins, а то и вовсе проставление специально именованного тега в git.
После того как я это прочитал
Рад что в GO деплой одни бинарным файлом и рестарт на лету без потери запросов
Только ваше обьяснения тут хватит чтоб это понять
В Java деплой одним файлом, и имя ему — war. И рестартует без потери запросов. А главное — без того, чтобы заходить на сервер по какому-нибудь ssh.

Каким образом go рестартует веб-приложения без потери запросов? Ссылку можно?
ну да, а JVM уже на каждой машине стоит, ага
Можно подумать, ОС на каждой машине стоит. А так, вот пара вариантов:

1. sudo yum install
2. docker-образ, причём либо просто с предустановленной JVM, либо сразу с приложением
Корпорациям часто требуется решение, которое удовлетворяет следующим пунктам:
1. Поддержка (дали монету — починили багу)
2. Возможность смены вендора (например, для Java, если Oracle откажется от поддержки, можно работать с IBM, похожее с базами данных, хоть и не настолько легко, для .Net есть открытый CoreCLR, а также Mono).
3. Зрелость (присутсвие языка на рынке N лет, наличие библиотек)
4. Наличие опытных разработчиков (причем как с опытом в этом решении, так и с опытом работы в предметной области)
5. Наличие формальных преимуществ, по сравнению с используемыми решениями.

У Go есть проблема с пунктом 5 (ибо обещанной производительности нет, всё на уровне java, которая на уровне .Net, кроме математики, которую сейчас логичнее делать на GPU и OpenCL, который может дать ускорение на порядки). Упрощение по сравнению с С тоже сомнительное, ибо под старичка есть море компиляторов, а если нужен GC, то подойдет и Java Card, .Net Micro Framework и еще куча известных технологий.

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

Потому и получается, что несмотря на попытки гугла войти в Enterprise Development, все пока неудачно…
Насчет пп2. Исходный код компилятора Go написан на Go, вы сможете пересобрать и доработать его сами. Он не закрытый, в отличие от .NET, Java и пр.

Насчет пп3. Это можно проверить только контр-примерами. Что нельзя реализовать в Go имеющимся набором стандартных и дополнительных библиотек?

Насчет удач-неудач и пп5, что вам известно про Docker? ( hub.docker.com/_/golang )
Он тоже написан на Go (исходы github.com/docker/docker )

С ноября 2013 года частичная поддержка Docker включена в дистрибутив Red Hat Enterprise Linux версии 6.5[3] и полная — в 20-ю версию дистрибутива Fedora.
wiki

Если средства, созданные на языке распространяются в _официальном_ дистрибутиве Linux (Red Hat, Fedora и др.), говорит ли это о популярности? Есть ли в этих дистрибутивах хоть что-то, созданное на .NET, Java? Почему?

Я не говорю в данном комментарии о преимуществах или недостатках языка, а задаю вам вопросы, ответы на которые вы дадите для себя.
И сами все поймете.
Он не закрытый, в отличие от .NET

У .Net есть открытый Roslyn вообще-то.

Что нельзя реализовать в Go имеющимся набором стандартных и дополнительных библиотек?

С учетом CGO это вообще отпадает по определению. Вкомпилить можно что угодно. Даже для C++ есть вариант.

Если средства, созданные на языке распространяются в _официальном_ дистрибутиве Linux (Red Hat, Fedora и др.), говорит ли это о популярности? Есть ли в этих дистрибутивах хоть что-то, созданное на .NET, Java? Почему?

В данном случае GO не имеет к этому никакого отношения. А .Net и Java всегда будут иметь проблему в виде рантайма.
Если средства, созданные на языке распространяются в _официальном_ дистрибутиве Linux (Red Hat, Fedora и др.), говорит ли это о популярности? Есть ли в этих дистрибутивах хоть что-то, созданное на .NET, Java? Почему?
Ни о чём не говорит. В репозиториях той же федоры можно легко найти софт на java, .net (mono), go, d, haskell и даже более экзотических языках. Или вы неспособны вызвать repoquery --whatrequires java-1.8.0-openjdk и посмотреть какие пакеты зависят от него?
если нужен GC, то подойдет и Java Card
Там в большинстве случаев нет GC. Есть object deletion, который не всегда поддерживается и не рекомендуется.

всё на уровне java, которая на уровне .Net
Тесты по java (сравнение с .net) в статье, на которую вы ссылаетесь, некорректны. Усреднять прогоны на непрогретой jvm — глупость. Не считая того, что hotspot с улучшениями из jrockit несколько отличается от 6u24, которая была в 2011.
обещанной производительности нет, всё на уровне java

По-моему, у джавы проблемы не с производительностью, а с диким потреблением памяти. Как с этим у Go?
отлично!
play! hello world 600MB
revel hello world 3MB
UFO just landed and posted this here
И я не хочу в корпорации, стартапы и петакластеры. Я хочу общаться с умными, образованными людьми, с которыми можно говорить в терминах левых и правых сверток, влияния этого на ленивость и рекурсивность, и комбинаторов неподвижной точки для функций, отвечающих морфизмам в категории графов.

Значит, вы по складу ума больше не инженер, а учёный. Ваше — это, скорее, информатика, а не разработка. Статья, очевидно, направлена разработчикам.
UFO just landed and posted this here
аналитическое дифференцирование в компилтайме на C++ для научной работы

А, кстати, правда, что основной челлендж в эзотеричности метаязыка — ну т.е. что нельзя просто так взять и нафигачить макрос, как на лиспе или хотя бы как на Template Haskell? И, если да — почему никто за все эти десятилетия не придумал какой-нибудь Template C++ (наверно, он должен как-то по-другому называться, да)? Это практически невозможно или никому не нужно?
UFO just landed and posted this here
Илья, в чем преимущества Go по сравнению с Python (раз уж Вы на нем пишете)? Кроме быстродействия. Не холивора ради, с Go мы просто плохо знакомы.
Дык эта. Статическая типизация, нэ? Это, понятно, палка о двух концах, как обычно: мешает писать маленькие прототипы, но помогает при написании больших программ. Если у вас в проекте один-два человека задействованы — то это скорее минус, если хотя бы десяток — уже скорее плюс.
Вот этот все правильно написал ^
Можно писать на подмножестве Cython, получив кстати как приятный бонус возросшую производительность. Что еще, помимо типизации? Которая не «преимущество», а все-таки «палка о двух концах». Интересуют именно преимущества, а не отличия.
Помимо типизации есть один жирный минус питону: читабельность. Я всего года полтора на питоне писал и за это время не видел ни одного плюс-минус большого и при этом, читабельного проекта. Чего только monkey patching стоит, не разобраться вообще. Язык еще порой бывает через чур выразительный. С зависимостями, конечно, все не очень хорошо. Я так до конца и не понял, как у меня pip работает, что где и лежит и как что. В Go с зависимостями в этом плане, конечно, круче.
В Go с зависимостями в этом плане, конечно, круче.
Те же яйца, вид сбоку. Кто-то вендорит, кто-то собирается против edge-версий библиотек, притаскивая какую-то версию go get, кто-то тащит godep. А то и всё вместе.
Я всего года полтора на питоне писал и за это время не видел ни одного плюс-минус большого и при этом, читабельного проекта.

Возможно вопрос гайдлайнов, практик по организации кода и структуры проекта и их соблюдения на код ревью? У нас почти весь веб, за исключением пару erlang проектов на python стеке (django, falcon+sqlalchemy). Вопрос с пониманием не возникал.
Субъективно в golang есть тоже свои нюансы с читабельностью, например решение разграничивать область видимости сущности по ее названию. Например у меня после ряда языков уже сложился шаблон что если это объявление сущности- то пишем с большой буквы, а если ее инстанс — c маленькой. Или например обработка ошибок, когда четверть кода состоит из конструкций if err != nil {}

Чего только monkey patching стоит, не разобраться вообще.

А зачем вы его используете? Субъективно, редко где он нужен кроме моков в тестах, и его применение должно быть обоснованно. Да, он позволяет делать очень злые, неявные вещи, но с другой стороны unsafe в go тоже позволяет выстрелить себе в ногу.

В Go с зависимостями в этом плане, конечно, круче.

Да, «круче», особенно когда появляется необходимость использовать конкретные версии зависимостей. И тут начинается —
разработчики не вдохновились гайдлайном держать мажорные версии по разным репозиториям, а значит нужно использовать различные обертки поверх go get или gopkg сервис с конструкциями вида cat requirements | xargs go get.

P.S. Go действительно интересный язык который имеет свои плюсы, но стоит так же адекватно его оценивать и понимать что это не серебряная пуля.
например решение разграничивать область видимости сущности по ее названию. Например у меня после ряда языков уже сложился шаблон что если это объявление сущности- то пишем с большой буквы, а если ее инстанс — c маленькой.

«Венгерская нотация же» — скажет кто-то.
Интересуют именно преимущества, а не отличия.
А в чём разница? Нет, я не издеваюсь, я серьёзно. Потому что я просто не верю, что вы сможете взять два любых, более-менее распространённых, языка и при их сравнении найти вообще хоть что-то, что не было бы «палкой о двух концах».

Отступы в питоне делают код более компактым и более читабельным, но могут приводить к губительным ошибкам при копировании. Шаблоны в C++ дают возможность делать черезывачайно быстрый код, но чреваты сложностью и «разбуханием» бинарников. Дженерики в Джава удобны, но чреваты вылетанием «странных» исключений в весьма неожиданных местах. И т.д. и т.п.

«Чистые» преимущества разве что в каких-нибудь эзотерических языках бывают.
Пример абстрактных, сферических преимуществ в вакууме (не Go vs. Python, а для любого языка):

1) высокая производительность (еще никому не мешала),

2) более короткие названия функций и классов из стандартной библиотеки, что позволяет банально быстрее писать код,

3) большое разнообразие стандартной библиотеки,

4) наличие большого числа мощных IDE,

5) широкое комьюнити, большое количество re-usable кода.

Дальше продолжать смысла нет, но думаю все согласятся, что выше перечислены явные преимущества, а не просто особенности.
Пример абстрактных, сферических преимуществ в вакууме (не Go vs. Python, а для любого языка):
«Сферические кони в вакууме» меня не волнуют. Пожалуйста примеры двух языков — можно будет говорить.

1) высокая производительность (еще никому не мешала),
Мешает. Причём очень сильно. Не видел ни одного языка который бы не платил за высокую производительность сложностью синтаксиса и/или безопасностью. А зачастую и тем и другим.

2) более короткие названия функций и классов из стандартной библиотеки, что позволяет банально быстрее писать код,
Но затрудняет чтение оного кода. Сможете скезать без заглядывания в mac что делает какая-нибудь функция strxfrm?

3) большое разнообразие стандартной библиотеки,
Зачастую приводит к тому, что есть несколько несовместимых способов сделать что-либо.

4) наличие большого числа мощных IDE,
Тут, пожалуй, соглашусь, хотя замечу что подобное преимущество зачастую используется разработчиками языка для того, чтобы сложный, многословный и запутанный код всё-таки как-то можно было писать. Типичный пример — Java. После появляния «большого числа мощных IDE» там появилась куча библиотек, которые без IDE пользоваться практически невозможно, да и с IDE — проблематично.

5) широкое комьюнити, большое количество re-usable кода.
Та же самая проблема, что и с «большим разнообразием стандартной библиотеки». Наличие 100500 несовместимых версий одного и того же «велосипеда». Бич, собственно, С и C++.

Дальше продолжать смысла нет, но думаю все согласятся, что выше перечислены явные преимущества, а не просто особенности.
В «сферически-вакуумном» смысле — может быть. На практике — все эти «явные преимущества» тянут за собой «паровозом» соответствующие недостатки.
> А в чём разница?
Разница между Python и Go в рантайме. Multicore green thread scheduler решает. Это строго преимущество.
Кстати вспомнил про одно преимущество, которое на первый взгляд кажется недостатком: в Go нет почти никакой поддежки юникода в языке. Единственное место, где Go хоть что-то знает про юникод — это range loop.

Почему это преимущество, а не недостаток? Потому что подход языков типа Java или Python'а — это «идеальный мир». Где, скажем, имена файлов — записаны в известной кодировке и могут быть преобразованы в последовательность Unicode'ных codepoint'ов. Но поскольку сие неверно ни в Windows, ни в Linux (хотя и по разным причинам), то нормальная работа с файлами требует специальной поддержки во всех библиотеках… а их разработчики, разумеется, всем этим не заморачиваются.

На практике оказывается, что спецподдержка Юникода в языке часто приводит к проблемам, не помогая при этом решить ни одной практически важной задачи. А мир python'а из-за этого оказался ещё и расколот надвое: есть python2, где юникод просто мешает и есть python3, где работа с ним сделана так, что хочется найти того, кто это придумал и что-нибудь ну очень нехорошее сделать.

Насколько конкретно для вас это важно — опять-таки, зависит от ваших задач.

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

Как то же отсутствие monkey patching'а: да, человеку привыкшему что любой косяк в интерфейсе можно исправить за счёт его исправления «на лету» из другого куска кода тяжело с этим смириться, но очень скоро понимаешь что взамен ты получаешь более продуманные интерфейсы и меньшее число странных ошибок.

Собственно об этом и вся статья…
> На практике оказывается, что спецподдержка Юникода в языке часто приводит к проблемам, не помогая при этом решить ни одной практически важной задачи.

Я в шоке… то-то я мучался с кодировками 15 лет назад при поддержке десятка языков в ASCII сборках Win32.
Теперь, когда у меня во всем стеке прозрачный Юникод и я просто могу работать со строками не заморачивась, даже когда у меня арабский с английским перемешан, я думал, что у меня все в порядке.
А оказывается, я только себе проблемы создаю, и лучше вернуться к однобайтным строкам?!?!

Что я не так понимаю в жизни? :-)
Это типичный приём евангелистов — выдавать недостатки за преимущество.
простите, но я не понимаю вашего ответа — без аргументации он не имеет смысла

я знаю про кучу проблем, которые я в прошлом имел с однобайтными кодировками, когда половина текста могла состоять из вопросиков (потому что кодировки были и близко не совместимы), клиенты ругались на потерянные названия файлов и т.п.
Я и сейчас зачастую имею такие проблемы, когда я получаю здоровые Shapefile из ArcGIS с полигонами, которые по незнанию клиенты сохраняют в локальной кодировке, и я ее должен угадывать, тыкая пальцем в небо (так как клиенты понятия не имеют о кодировках).

С UTF-8 и Unicode у меня таких проблем нет.

Что я делаю не так? Почему вы меня убеждаете, что я евангелист, и моя жизнь с однобайтными кодировками должна улучшиться? Я честно не понимаю…
Всё вы правильно делаете :-) Евангелисты — те два с половиной человека, что без конца пиарят го на хабре. Сейчас они с пеной у рта доказывают, что «это вам не нужно!», а когда это таки реализуют, то будет новый виток хвалебных статей в духе «теперь это есть и у нас! как мы без этого раньше жили? срочно обновляться!»
ok, дошло.
я неправильно понял ваш предыдущий комментарий…
По вашей логике выходит, что вы (и еще два с половиной хабраюзера) — антиевангелисты? Ок. )
Вы путаете вопрос поддержки кодировок внешних данных и вопрос поддержки Unicode ядром языка. Как правило, языки, якобы поддерживающие Unicode на уровне синтаксиса ядра («у нас все строки хранятся как Unicode»), поддерживают его весьма ограниченно, например, сравнение производится всё равно побайтово, а не с помощью UCA и результаты могут быть неправильными, или поддерживается только устаревший UCS-2.

Unicode сам по себе не очень удачный стандарт, и вряд ли в мэйнстримовых языках в обозримом будущем будет его полноценная поддержка.
Согласитесь, даже устаревший UCS-2 и сравнение строк, не учитывающее умляуты/лигатуры/акценты, все же лучше работы с потоком байт. Просто если язык худо-бедно поддерживает Unicode, от стандартные UI виджеты его тоже поддерживают. В старых VC++ и Delphi, в неюникодных исполняемых файлах, это были просто танцы с песнями.

А для правильной нормализации/сортировки можно ICU прикрутить.

Альтернативы Юникоду, при всех его недостатках, не будет — слишком много переписывать.
Вот в «худо-бедно» проблемы и кроются, имхо. Как по мне то лучше пускай на уровне ядра языка объявлено что-то вроде «строки для нас просто последовательность байт/слов, мы не делаем каких-то предположений об их кодировке, для этого есть библиотеки», чем «мы используем Unicode в кодировке UTF-16 со следующими ограничениями: (список на 4 листа)».
Даже не полная поддержка всех 30 спецификаций консорциума юникода — это несоизмеримо лучше полного отсутствия поддержки хотя бы одной, но самой важной — Unicode Standart (http://www.unicode.org/versions/Unicode8.0.0/). В которую UCA как бы не входит. UCS-2 отличается от UTF-16 лишь наличием суррогатных пар у последней (https://ru.wikipedia.org/wiki/UTF-16). Нет никакого практического смысла иметь в памяти суррогатные пары — это замедляет и усложняет алгоритмы работы со строками, не принося никакого профита. Все используемые сейчас символы укладываются в кодовое пространство UCS-2. В тех же специфичных случаях, когда требуется работать с древнекитайскими иероглифами имеет смысл использовать UCS-4 (он же UTF-32), но не UTF-16. Так что поддержка юникода в мейнстримовых языках весьма не плоха — быстрая и покрывает большую часть практических нужд. В некоторых языках даже есть выбор какую ширину символа использовать (1,2,4), хотя в идеале строки должны автоматически выбирать оптимальную ширину символов при создании, ведь они же всё равно в большинстве реализаций являются неизменяемыми.
Нет никакого практического смысла иметь в памяти суррогатные пары — это замедляет и усложняет алгоритмы работы со строками, не принося никакого профита.
Это вы что-то с чем-то спутали. Практический смысл есть и он, как бы, очень простой: данные приходящие в вашу программу их могут содержат и вам что-то с этим нужно делать.

Подход Go: нас это не волнует, все библиотеки с ними работают настолько хорошо, насколько возможно, программист сам решает — хочет он работать с такими строками или нет.

Подход Python'а: действие по-умолчанию при обнаружении подобной строки — завалить нафиг всю программу. Если человек ну очень хочет, что программа всё-таки не падала — он может это сделать, но для этого ему нужно добавить обработику данных в соотвествии с PEP 383 во все библиотеки, которые он использует.

Собственно потому в Python 3.1 поддержку суррогатов потому и добавили, что иначе языком просто пользоваться было нельзя. Если бы всё было так, как вы говорите, то никакого PEP 383 не было бы.

Вот объясните мне: чем подход Python'а лучше?

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

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

Мне почему-то кажется что «показать крякозябры» вместо надписи «Установка завершена» всё-таки лучше, чем откатываие нафиг всю установки системы из-за того, что кто-то где-то перепутал указание кодировки в одном месте (реальный, невыдуманный пример: так ведёт себя текстовая установка одной из версий Fedora'ы… в последней версии вроде поправили).
Собственно, описанная вами проблема как раз и проистекает из языков типа го и си, которые не видят разницы между строками и массивами байт и позволяют писать в имена файлов всякое непотребство. Другое дело, что программы на питоне могли бы поступать более дружелюбно и, например, тут же предлагать исправлять бардак в файловой системе. Но и ругать их за то, что они не игнорируют проблемы, а сигнализируют о них как можно раньше — странно.
Другое дело, что программы на питоне могли бы поступать более дружелюбно и, например, тут же предлагать исправлять бардак в файловой системе.
«Более дружелюбно»? Нет уж, guile, который тихо и незаметно корёжит «неправильный» UTF-8 — это ещё хуже, чем Python. Python можно худо-бедно использовать, а с Guile лучше вообще никогда не связываться. Так как вылетающее исключение можно поймать и обработать (неприятно, могут быть финансовые потери, но не смертельно), а испорченные данные зачастую восстановить просто нельзя, если вы узнаёте о том, что в «борьбе за юникод» они безнадёжно испорчены, слишком поздно.

Но и ругать их за то, что они не игнорируют проблемы, а сигнализируют о них как можно раньше — странно.
С какого перепугу вдруг? «Непарные суррогаты» (под Windows) и «испорченный UTF-8» (под Linux) — это данность. Вам может это дизайнерское решение не нравится, и вы можете стонать по этому поводу сколько угодно, но правильно написанная программа должна с ними работать. API так устроен. Извольте соответствовать. Пользователя не волную глубинные идеи — ему нужна программа, которая работает. А не падает.

И вот на Go написать подобную программу проще, чем на Python'е. Вот и всё.

Как я уже сказал: возможно в каком-то другом мире, где используется особая файловая система, не допускающая «испорченных» строк в виде имён файлов, Python и будет удобен, но в нашем мире на операционках Linux, MacOS и Windows Python3 из-за идиотски реализованной поддержки юникода является чем-то, что… лучше просто не использовать. Python2 — в этом смысле ещё не так ужасен. Там вы хотя бы должны прилагать усилия, чтобы выстрелить себе в ногу. Python3 — по умолчанию (без специальных извращений) порождает просто-напросто неработающие программы.
Кривой софт независимо от поддержки юникода может натворить дел. А тот, который не валидирует ввод и вывод — точно натворит.

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

Особенно когда файлы уже есть, а прикладной софт отказывается их открывать, а вместо этого падает с какими-то неясными сообщениями об ошибках…
Прикладной софт должен выдавать имена в виде, принимаемом ОС. Если ОС принимает имя файла от одного прикладного софта и отдаёт ему его без «кернел паник», то и другой софт не должен падать от таких имён.
Посмотрите на поведение Windows Explorer'а. Он все эти случаи вполне себе нормально обрабатывает. И да, делается это путём засовывания суррогатов в том виде в каком они есть в файлы и показа пользователю. А почему нет?
Вы специально что ли называете файлы с непарными суррогатами? :-D

Приложение как бы и не должно работать с некорректными данными. А то накосячит ещё. А замалчивание ошибок — очень дурная практика.

У меня нет файлов с именами в кривой кодировке. И у меня нет софта, который такие создаёт. А если такой и будет обнаружен — он будет удалён и заменён на аналог, таким делом не промышляющий.

А то, что ОС позволяет насрать по среди комнаты вовсе не означает, что это надо делать, и что все, кто проходит мимо должны равномерно это дерьмо по комнате размазывать.
Я и сейчас зачастую имею такие проблемы, когда я получаю здоровые Shapefile из ArcGIS с полигонами, которые по незнанию клиенты сохраняют в локальной кодировке, и я ее должен угадывать, тыкая пальцем в небо (так как клиенты понятия не имеют о кодировках).
И вы будете иметь их и в дальнейшем. Вот только разрулить их в Python'е на порядок сложнее, чем в Go.

Оттого, что Python3 «издал указ» и объявил что отныне и вовеки текст должен быть только и исключительно в Юникоде мир не изменился. В нём по прежнему существуют разные кодировки, по прежнему используются протоколы, смешивающие ASCII-текст и бинарные данные — и со всем этим нужно как-то работать.
Да поддерживает Go юникод, поддерживает. Возможно они не осилили PEP 0393 и решили использовать массив байт (0-225) для экономной записи, я не знаю. Тем не менее, for-range цикл в Go при индексации оперирует не байтами, а рунами (code point), так что не надо паниковать, Go полностью поддерживает юникод. Они говорят, что string позволяет хранить строки в любой кодировке, но обычно, повторяю, обычно это именно юникод. Том Кристинсен делал доклад на тему поддержки юникода в разных языках программирования (тыц) и сказал вот такую вещь: «Of all the languages I played around with for this talk, Go was hands down the easiest — and possibly the most pleasurable — to use UTF‐8 with.»

Юникод сложно, юникод ооочень сложно сделать правильно, потому что есть такая вещь как нормализация. И большинство ЯП ее делают неправильно из-за своих же ошибок. Короче, к Go можно придираться очень долго, но строки в нем сделаны очень даже неплохо.
Возможно они не осилили PEP 0393 и решили использовать массив байт (0-225) для экономной записи, я не знаю.
Строка в Go — это просто последовательность байтов, не более того. Есть range loop (про который я говорил), который как бы «рассчитан на UTF-8» но все языковые конструкции (в том числе пресловутый range loop) вполне корректно обрабатывают невалидные UTF-8 строки.

Короче, к Go можно придираться очень долго, но строки в нем сделаны очень даже неплохо.
Ну дык. И главное их преимущество — то, что они не юникодные!

Я работал с массой систем, которые имеют специальную поддержку Юникода в строках — от Win32 API до Python'а с Java'ой. Я видел массу проблем, которые этот подход создаёт, но я не знаю ни одной задачи, которую бы эта поддержка решала.

Часто в качестве примера приводится возможность обратиться «к символу» по индексу или быстро узнать количество «символов» в строке. Отлично — но для чего вам это нужно? Чтобы проверить впишется ли строка в поле ввода? Не поможет даже с моноширинным шрифтом — вспомните про halfwidth and fullwidth forms, диакритику и разнообразные спецсимволы. Для того, чтобы понять — влезет ли строка в поле базы данных? А зачем вам это? Используйте UTF-8 в базе данных — и у вас не будет этих проблем.

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

Тогда зачем это всё? У нас есть чудная «поддержка юникода», которая помогает нам «бороться с проблемами, вызванными поддержкой юникода» — это всё-таки странная идея, чесслово.

Покажите мне пример хотя бы одной практической задачи, которую весь тот ужас, который со строками в python'е устроили помогает решать — и будет о чём поговорить.
Пожалуйста:
1. У вас есть шаблон, написанный в кодировке UTF-8.
2. У вас есть база данных в кодировке UTF-16.
2. К вам пришёл HTTP запрос с данными в кодировке windows-1251
3. Вам нужно по запросу пользователя найти записи в базе данных, подставить в шаблон и вернуть пользователю, не запутавшись в кодировках.
И в каком же месте «суперпрогрессивная поддержка юникода», требующая обязательно везде и всюду знать кодировку заранее, вам поможет?

Вот где она помешает — я вам скажу: если в пункте 3 к вам пришёл «запрос с данными в кодировке windows-1251», но при этом у него в заголовке написано «text/html; charset=UTF-8» (это — законный вариант, читайте спецификацию), то вы, скорее всего, обрушите всю вашу программу ещё до того, как у вас появится шанс узнать, что документ всё-таки в windows-1251, а не в utf-8.

Также ваша база может вернуть вам данные с суррогатами (если кто-то использовать UCS-2, а не UTF-16). И тут вы тоже можете «словить» проблем.

Так что вреда от поддержки юникода в вашем примеры будет вагон. А вот где эта поддержка вам поможет… я даже и не знаю. Не просветите — какое конкретно действие она сделает в этой цепочке проще? Или надёжнее? Или вообще хоть чем-нибудь поможет?

Да, Python содержит много разных вещей, которые помогают сделать работу со строками не такой болезненной (ссылки я уже давал). Но если бы строки изначально не знали ничего про юникод, то работать с ними было бы проще!
А вот так:
1. Сетевой драйвер получает запрос, по заголовкам понимает, что запрос в кодировке WIN-1251, декодирует во внутреннее представление UCS-2 и передаёт управление коду приложения.
2. Работаем с данными не задумываясь о кодировках.
3. Делаем запрос к базе, драйвер базы кодирует данные в кодировку базы — UTF-16 и декодирует ответ от неё в UCS-2.
4. Грузим шаблон, драйвер файловой системы автоматически определяет (BOM, xml-pi и тп), что шаблон в кодировке UTF-8, декодирует во внутреннее представление — UCS-2 и передаёт управление коду нашего приложения.
5. Формируем страницу не задумываясь о кодировках.
6. Отдаём страницу сетевому драйверу, он по заголовкам запроса понимает, что клиент ожидает ответ в кодировке WIN-1251, и кодирует ответ именно в эту кодировку.

В результате само приложение ничего не знает о кодировках, при этом взаимодействие с разными системами происходит в разных кодировках. А вот как вам поможет язык, который ничего не знает о кодировках? Вставит UTF-16 данные в UTF-8 шаблон и не поперхнётся? А потом вы будете возмущаться чего это программа на питоне падает при работе с полученными таким образом данными?

Я вам, наверно, открою глаза, но сетевые библиотеки работают не со строками, а с потоками байт, анализируя их они определяют кодировку, декодируют поток байт в нативные строки (сразу или лениво — не важно) и передают управление пользовательскому коду, которому по барабану в какой кодировке пришёл запрос. А даже если у пользователя в запросе написано, что запрос в кодировке UTF-8, а прислал он WIN-1251, то упадёт не вся программа, а ему резонно будет выдана ошибка 400 Bad Request ещё на подлёте к приложению.

Если есть основания полагать, что в базе могут оказаться суррогатные пары, то я буду использовать UCS-4. Именно он, емнип, и используется в питоне с третьей версии.

1. Сетевой драйвер получает запрос, по заголовкам понимает, что запрос в кодировке WIN-1251, декодирует во внутреннее представление UCS-2 и передаёт управление коду приложения.
Ещё раз: этого — недостаточно, так как кодировка указанная «внутри» перебивает кодировку, указанную в заголовках.

2. Работаем с данными не задумываясь о кодировках.
Программа «сворачивается в трубочку» и оседает на пол.

3. Делаем запрос к базе, драйвер базы кодирует данные в кодировку базы — UTF-16 и декодирует ответ от неё в UCS-2.
Но как, сэр? В UTF-16 отдельно стоящие суррогаты запрещены, в UCS-2 — разрешены!

4. Грузим шаблон, драйвер файловой системы автоматически определяет (BOM, xml-pi и тп), что шаблон в кодировке UTF-8, декодирует во внутреннее представление — UCS-2 и передаёт управление коду нашего приложения.
Никаких BOM'ов в реальных XML'ях нету.

6. Отдаём страницу сетевому драйверу, он по заголовкам запроса понимает, что клиент ожидает ответ в кодировке WIN-1251, и кодирует ответ именно в эту кодировку.
И снова «старая песня о главном». По заголовках запроса ничего понять нельзя, так как там написано UTF-8. Настоящая кодировка задана внутри документа через <meta charset="windows-1251">. Это — законный и корректный запрос.

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

А вот как вам поможет язык, который ничего не знает о кодировках?
Очень просто: этот язык не будет мне мешать. У меня будет модуль, который определит кодировку документа, а когда мне захочется перегнать данные из USC-2 в UTF-16 — то я сам смогу решить что мне делать с суррогатами и стоит ли с ними что-либо делать вообще.

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

Я вам, наверно, открою глаза, но сетевые библиотеки работают не со строками, а с потоками байт, анализируя их они определяют кодировку, декодируют поток байт в нативные строки (сразу или лениво — не важно) и передают управление пользовательскому коду, которому по барабану в какой кодировке пришёл запрос.
Если вас не волнует работоспособность программы — то да, такой подход возможен. А если волнует — то лучше не иметь вообще библиотек, работающих со «строками» и работать везде с последовательностями байт.

А даже если у пользователя в запросе написано, что запрос в кодировке UTF-8, а прислал он WIN-1251, то упадёт не вся программа, а ему резонно будет выдана ошибка 400 Bad Request ещё на подлёте к приложению.
Но ему-то нужна не ошибка 400 Bed Request, а полноценный ответ. Он ведь ничего плохого не сделал и правильно указал кодировку в документе.

Если есть основания полагать, что в базе могут оказаться суррогатные пары, то я буду использовать UCS-4. Именно он, емнип, и используется в питоне с третьей версии.
Изменяет, изменяет. UCS-4 (вернее хитрожопое представление, которое «снаружи» выглядит как USC-4) появилось только python3.3.

Но это ровным счётом ничего не изменило: данные при преобразовании из последовательности байт во внутреннюю кодировку как терялись, так и теряются, избежать этого можно — но этого не происходит по умолчанию, от «полноценной поддержки юникода» по прежнему нет никакой пользы, но есть куча вреда. Об этом уже многие писали. Вот тут, например.
UFO just landed and posted this here
Стоит учитывать, что реальный мир отличается от спек w3c.

Реальный мир содержит json с невалидным utf8 или смесью cp1251 и utf8 в разных полях json object'а, документы с неправильной кодировкой в заголовках (или с заголовком Content-Encoding: gzip и несжатым текстом в body) и многие другие прелести, которых не ощутишь, пока работает со своими или просто нормальными API, но которые ощущаются, как только ступишь на выжженные пустоши реального мира, где стаи ракопауков носятся в воздухе.
Ну как примеры задач:
— регистронезависимый поиск подстроки в строке
— перевод из одного регистра символов в другой
— определение валидности UTF-8 строки перед записью в базу, чтобы мусор не записать
Как только возникнет несколько вариантов представления одной и той же строки в юникоде — начнутся проблемы.

Использование регулярных выражений и изменение регистра зависит не только от самих строк, но и от языка, на котором они написаны, что является внешней информацией по отношению к самой строке. В любом случае, эти операции мало когда имеют смысл на unicode-строках до нормализации в NFD/NFC/NFKD/NFKC, если не затаскивать всю мощь icu в каждую библиотеку.

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

— определение валидности UTF-8 строки перед записью в базу, чтобы мусор не записать
Совершенно непонятно чем функция, получащая «набор байт» и проверяющая его хуже «юникодных строк»
UFO just landed and posted this here
Я не знаю ужаса со строками в Python, как-то не пользуюсь им, но индексация символов нужна, например, для того, чтобы строить n-граммные индексы. Логично иметь триграмму, например, из трёх глифов, а не из трёх байт.
Согласен. Но объясните мне, пожалуйста, как вот такие вот строки вам в этом помогут:
$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type «help», «copyright», «credits» or «license» for more information.
>>> len('ää')
3
Я вот, честно, не вижу никакого выигрыша.

Проблема в том, что индексация символов не помогает работать с глифами. Perl6 вроде умеет работать с глифами, но не Java и не Python.
UFO just landed and posted this here
Что я не так понимаю в жизни? :-)
Да. Вы не понимаете, что речь идёт не об неиспользовании Юникода, а о том, что ни язык, ни стандартная библиотека не форсируют его использование.

В Go используется (по соглашению) UTF8. Но все утилиты, которые могут осмысленно работать со строкой как с последовательностью байт работают со строкой как с последовательностью байт. Если вы хотите где-то форсировать Юникод (проверить UTF-8 строку на валидность) — вы можете это сделать, соответствующие утилиты вполне имеются. Но это ваш выбор, язык Go его не форсирует.

Вы можете получить кусок, состоящий из смеси текста и бинарных данных (HTTP, SMTP, далее везде) и спокойно его обработать. В Питоне для этого вам нужно совершать весьма странные телодвижения. А такая простая вещь, как посмотреть на формат HTML-файла, найти там тег http-equiv и если нужно перекодировть — превращается в танцы с бубнами.
То есть в Go я могу создать файл с не-юникодным названием, и эта возможность выстрелить в ногу (причём, скорее не себе, но всем вокруг) считается за преимущество?
Ты можешь, но для этого надо будет очень постараться.
1. Ды, вы можете. И в Питоне вы тоже можете, что характерно, так что в этом у них полный паритет.
2. Преимуществом является не тот факт, что вы можете создать файл с не-юникодным названием, а тот факт, что появление такого файла не приводит к тому, что ваши пользователи не могут войти в систему.

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

Причём для этого не нужно какой-то экзотики. Пример, с которым я сталкивался лично: CygWin при создании под Windows файла App::Cpan.3perl.gz породит имя файла в котором будут непарные суррогаты. Go с этим отлично справится, Python — скорее всего сойдёт с ума, потому что мало какие библиотеки работают с файлами так, как предписывает PEP 383.
Вы же понимаете, что это проблемы пользователей CygWin? У меня не появляется файлов с неюникодными именами. ЧЯДНТ?

Да и выбирать язык по недостаткам, напоминающими анекдот «а вы попробуйте на шкаф залезьте!» несколько странно.
Вы же понимаете, что это проблемы пользователей CygWin?
С какого перепугу? Это проблемы пользователей, у которых не работает ваша программа — чините.

У меня не появляется файлов с неюникодными именами. ЧЯДНТ?
Возможно не используете Python? Или довели борьбу с фатальным недостатком до совершенства. Не знаю. Я с разного рода проблемами, возникающими из-за кривой поддержки юникода в Python'е борюсь регулярно. В Python2 это относительно несложно (игнорируйте все эти юникодный строки — и будет вам большое такое «щастя»), в Python3 — это стало просто катастрофой.

Да и выбирать язык по недостаткам, напоминающими анекдот «а вы попробуйте на шкаф залезьте!» несколько странно.
Почему нет? Чем странней ситуация, в которой обваливается ваша программа тем выше шанс того, что у вас она работать будет, а у заказчика — рухнет. После чего он вас «пошлёт» с вашими идеями что неработоспособность вашей программы — это не ваша проблема. И будет, ЧСХ, прав.
Да, я не использую ни питон, ни цугвин. И мои программы внезапно работают. Явно надо что-то менять. Осталось придумать зачем использовать то, от чего у пользователей файлы не такие создаются (если не просить при этом биткоинов за удаление, конечно).

> И будет, ЧСХ, прав.

Да, надо бы в дистриб деинсталятор цугвина с питоном запилить (а что, цугвину можно мне свиней подклыдывать, а мне — нет? я «чиню свою программу», ага). И антивирус, заодно. Это же моя проблема, что пользователь по порносайтам лазает всякую фигню скачивает?
Хотя нет, проще сразу компы с вшитым своим маркетом продавать.

Вообще, интересно много ли заказчиков готовы платить за цугвин.
Вообще, интересно много ли заказчиков готовы платить за цугвин.
Они не платят «за цугвин». Они платят, вы не поверите, за программы. Решающие (или обещающие решить) их задачи. Которые, внезапно, не работают если на компьютере есть CygWin и он насоздавал «неправильные» файлы.

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

«Чудесная поддержка юникода» вам эти проблемы насоздаёт, «грубый и неправильный Go» — нет. Так кто из них лучше?
> При этом CygWin может и не ставиться явно, а быть компонентом другой системы

Если Вы отвечаете именно на то, что процитировали — у вас не получилось.

Я цугвин видел только в каком то наколеночном опенсорсе, который на рабочий комп попасть не мог. А значит у техподдержки есть корректный ответ «переустановить винду». Тем более, если у вас нормальной обработки ошибок и так не задумано.

Что характерно, когда у пользователя крешиться весь софт, кроме написанного на благословенном Go, пользователя такой ответ даже не отпугнет.

> Так кто из них лучше?

Лучше цугвин починить, а не строить костыли вокруг теоретически возможного пользовательского окружения.
Я цугвин видел только в каком то наколеночном опенсорсе, который на рабочий комп попасть не мог.
А я его видел как часть интернет-магазина. Или, скажем, Google'ового SDK.

Что характерно, когда у пользователя крешиться весь софт, кроме написанного на благословенном Go, пользователя такой ответ даже не отпугнет.
В том-то и дело что «весь софт» не крешится. FAR это отлчино отрабатывает. Explorer, разумеетя, тоже. Проблемы — только с софтом на Python'е и Java. Вроде бы даже .NET'овские поделия к этому нормально относятся.
В Python2 это относительно несложно (игнорируйте все эти юникодный строки — и будет вам большое такое «щастя»)
Тоже не всегда. Если какая-нибудь библиотека прислала unicode-строку, то вывести её в stdout уже нетривиально, т. к. поведение print u"фыва" отличается в зависимости от того, перенаправлен ли вывод.

Если перенаправлен, то будет выглядеть так:
Traceback (most recent call last):
  File "t.py", line 2, in <module>
    print u"фыва"
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
Если какая-нибудь библиотека прислала unicode-строку
Если какая-нибудь библиотека выдёт вам юникодную строку, то нужно либо постараться убедить её этого не делать, либо придётся-таки в этом конкретном места мучиться, да.

Большинство библиотек в python2 никакого юникода не порождают и сложностей, с этим связанных, не создают.
Если правильно помню, развлечение было после ner, где приходится работать уже со строками.
UFO just landed and posted this here
Закон Парето никто не отменял. От самых тупых ошибок типа засовывания строки туда, где хотят число или наоборот спасёт любая.
Отличная заметка, спасибо! Если не познавательная, то как минимум новая точка зрения. Но язык (Ваш, не Go) делает мне больно.
Тот язык, дизайн которого я сейчас потихоньку разрабатываю? Так это даже не альфа — так, наброски.
Ааааа, ты про мою речь. Так это просто авторская подача, мне так нравится писать, живой текст получается.
Дело твоё, но мне после прочтения захотелось настроить фильтр и больше такого не получать в ленту. Просто потому что.
Кому как. Товарищу комментом ниже, например, понравилось.
Ни дыры не понял, но почитал бы этого автора еще.
Такая же фигня с исходниками на гоу))
Как насчет литературы? Если опытный разраб хочет прочесть 1 книгу (на английском), чтоб полностью освоить Go (за редельку свободного времени), то что вы порекомендуете?
Книги никто не отменял конечно, но советую пройти официальный Тур go, ещё очень класный ресурс gobyexample.com. Опытный разраб может выучить Go до приличного уровня за пару дней.
UFO just landed and posted this here
Зачем Go? Меня лично привлекает совокупность его особенностей:
1. Компиляция под любую платформу одной строчкой. GOOS, GOARCH и вперед — винда, макось, айфон, андроид.
2. Натив код + сборщик мусора
3. Один бинарник и ноль зависимостей от компонентов ОС. Это просто прекрасно, когда ты открываешь в IDA импорт секцию и видишь пустой список. Бинарнику нужны только syscall'ы и больше ничего. Есть исключения разве что на винде и iOS. И то, это зависимости от API ОС.
4. Огромная стандартная библиотека + простейшая процедура подключения сторонних библиотек
5. Горутины

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

Go расположился во всем аккурат между С/С++ и C#/Java и этим он привлекает. И тут скорее не язык сам интересен, а инфраструктура вокруг него, которая, впрочем, благодаря особенностям языка и стала возможна.
> .Net/Java — все хорошо, но рантайм за собой тянуть

Microsoft .NET Native
Честно, не пробовал. Ну и проблема не в том, что рантайм прям мешает — на винде ради бога. Но вот у меня линукс на арме. Какие у меня там варианты с дотнетом кроме сборки руками моно или .net core?
Ну у меня линукса на арме нет, но Xamarin вроде фреймворков не требует?
На подходе еще один проект под название LLILC. Это компилятор MSIL -> IR (который LLVM).
github.com/dotnet/llilc
Компиляция под любую платформу одной строчкой. GOOS, GOARCH и вперед — винда, макось, айфон, андроид.
mips-none-eabi? arm-none-eabi? Не собирается почему-то.

Один бинарник и ноль зависимостей от компонентов ОС.
Ага, разогнались.
ldd /usr/bin/docker
	linux-vdso.so.1 (0x00007fff2698f000)
	libsystemd.so.0 => /usr/lib/libsystemd.so.0 (0x00007ffa846f9000)
	libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007ffa84384000)
	libdl.so.2 => /usr/lib/libdl.so.2 (0x00007ffa84180000)
	libdevmapper.so.1.02 => /usr/lib/libdevmapper.so.1.02 (0x00007ffa83f24000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007ffa83b80000)
	libcap.so.2 => /usr/lib/libcap.so.2 (0x00007ffa8397c000)
	librt.so.1 => /usr/lib/librt.so.1 (0x00007ffa83774000)
	libm.so.6 => /usr/lib/libm.so.6 (0x00007ffa83476000)
	libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007ffa8325f000)
	liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007ffa83039000)
	liblz4.so.1 => /usr/lib/liblz4.so.1 (0x00007ffa82e27000)
	libgcrypt.so.20 => /usr/lib/libgcrypt.so.20 (0x00007ffa82b45000)
	libgpg-error.so.0 => /usr/lib/libgpg-error.so.0 (0x00007ffa82931000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffa845a1000)
	libudev.so.1 => /usr/lib/libudev.so.1 (0x00007ffa846d5000)
	libattr.so.1 => /usr/lib/libattr.so.1 (0x00007ffa8272c000)
mips-none-eabi? arm-none-eabi? Не собирается почему-то.

MIPS вроде и не поддерживает, а арм. А какой именно арм то? Под armv7 я собирал — linux версия работает на андроиде и кастомной плате с cortex-A8 процессоре. armv7 версия под darwin при условии external linkining и CGO работает на iOS, но зависит от парочки системных API, которые не делают погоды. Речь естественно о сборке Go проектов, а не самого Go.

Ага, разогнались.

Это не лучший пример. Если посмотреть исходный код, то там вовсю используется CGO, а там можно накрутить кучу зависимостей, что они и сделали. Сам по себе Go на моих проектах выдает бинарники, которые ни от чего не зависят. Сейчас проверил gitlab раннер для их CI под макось gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/osx.md — опять пустая импорт секция. Что не удивительно, ибо это одно из преимуществ GO.
Под armv7 я собирал — linux версия работает на андроиде и кастомной плате с cortex-A8 процессоре.
Кроме arm-linux-gnueabi существуют и другие target'ы, которые не всегда поддерживают linux или darwin. На cortex-a/r arm-мир не заканчивается: есть cortex-m, есть разные arm7/9/11. Так что утверждение «Компиляция под любую платформу одной строчкой» выглядит чересчур самоуверенно.

Не говоря уже о том, что под bare metal (собственно *-none-eabi) на го нужно переписывать ощутимую часть стандартной библиотеки. Это та ниша, где живут c/c++/rust, хотя последний не из коробки и не в полном объёме (только libcore, а не libstd). Про go видел только PoC для запуска на bare metal (без goroutine/channel, ессно).

Это не лучший пример.
Ок, принято, docker довольно сложная система. Когда я пробовал писать простейшие программы использующие goroutine'ы и каналы у меня по умолчанию ldd показывал, как минимум libc и pthread. Для получения статичного бинарника надо прилагать некоторые усилия. Возможно, сейчас поведение по умолчанию изменилось.
Так что утверждение «Компиляция под любую платформу одной строчкой» выглядит чересчур самоуверенно.

Тут скорее то, что имеет значение распространено, а как уже в одной статье говорилось, мир захватили x86-x64 и arm. С первым проблем нет, со вторым покрыты архитектуры armv5-armv8, что дает ощутимый кусок. Вот на этом всем go скорее всего без проблем будет работать при условии, что там ОС стоит совместимая.
mips (в огромном количестве сетевого оборудования), arm cortex-m (который тоже описан в armv6-armv8), arm7tdmi, pic, avr куда более распространены чем всякие x86/amd64. В современном ноутбуке на amd64 обычно не менее 3-4 arm cortex-m.
Все усилия сводятся к прибавлению к go build флагов:

-ldflags "-linkmode external -extldflags -static"

Но да, можно было флаг покороче придумать.
Да, это только даёт статическую линковку.

Это не даёт сборку под большинство embedded target, отсутствие syscall'ов и т. п., что утверждалось квантором «любую», насчёт которого и было моё замечание, которая обсуждается в остальной части ветки, оказавшейся под прицелом вашего плюсомёта.
Да я вобщем мимо пробегал, ответил на:
Для получения статичного бинарника надо прилагать некоторые усилия.

В остальное не вдавался, потому как моя работа связана с одной платформой.
потому что это как два пальца обоссать


Программисты в этом случае используют другую метафору: «как два байта переслать».
Иной раз два байта переслать не так и просто)
Могли бы пояснить подробнее, что подразумеваете под
> С технической стороны, ниша у Go довольно скромная: сеть

Что значит сеть?
За этот вопрос в slack'e гоферов я был поднят на смех. До сих пор не знаю что именно имели в виду проффесора
Ну, сеть. Любой софт, который отвечает за оркестрирование и коммуникацию компьютеров (серверов) связаных сетью.
Разработка бэкенда для сайтов — это «сеть»?
Оркестрирование это что? Администрирование? Active Directory?
Если грубо, то автоматическое администрирование — запуск и остановка серверов, правка их конфигов и т. п. автоматически в зависимости от ситуации, например, нагрузки или сбоев.
Ну наконец-то дельная заметка о Go. Спасибо!
Как С++ програмист, я стал ненавидеть Go чуточку меньше :)
Как С++ программист не могу не спросить, а чем именно вызвана ваша ненависть?
Тем, что надо выбрать один кросс-платформенный компилируемый язык, и на нём сконцентрироваться, а не создавать по 2 новых языка в год. На мой взгляд, С++ — лучший язык в своём классе, и под него уже написано огромное количество библиотек, а эти ваши Go только распыляют внимание программистов и тормозят прогресс.
1. Go — язык явно другого класса для решения других задач. Хотя, может быть мы говорим о разных классах задач?
2. То, что С++ лучший в своём классе не значит, что нужно останавливать прогресс. Когда-то и ассемблер был лучшим в своём классе. Если бы никто не стал делать новых языков С++ так никогда и не появился бы. Прогресс и конкуренция — всегда хорошо, а много языков лучше чем один.
3. ИМХО, тормозят прогресс как раз те, кто предлагает отбросить всё новое и заниматься только тем, что всем хорошо знакомо. Развиваться лишь в одном направлении и отрицать всё, что не укладывается в привычную схему — это тупик и квинтэссенция ограниченности.
2 и 3 — тоже верно, хорошее замечание.
C++ лучший в своем классе скорее вопреки, а не благодаря. И я буду очень рад, если его заменит что-то, что нормально умеет в модули, быструю компиляцию, простую кросс компиляцию без бубнов и мегабайтных мейкфайлов. Это как минимум. Где-то его Go уже вытесняет отчасти именно благодаря упомянутым вещам, но хотелось бы вообще забыть об этом языке в пользу чего-то более умного с умной и быстрой инфраструктурой.
М-м. Компиляция весьма быстрая, с кросс-платформенной компиляцией проблем нет (проект собирается безо всяких бубнов и мегабайтных makefile под Мак и iOS — clang, Линукс и Андроид — GCC, и Винду — MSVC). Модули — да, беда, но должно стать полегче, когда их стандартизуют (сейчас над этим идёт работа).
Весьма быстрая компиляция? Просто нет.

Если бы все было так замечательно, то мы бы жили в прекрасном мире. На деле же даже сборка маленькой библиотеки с makefile и autoconf это пытка. Я недавно собирал под виндой с помощью кросскомпилятора libevent. Я задолбался вручную патчить сгенерированные мне makefile и configuration. В итоге еще и пришлось патчить хедеры openssl, но собралось. А должно собираться в один клик — git clone, build и все, все работает. Можно сказать — винда, проблемы вечные. Я потом пытался собрать crosstools-ng под макосью — я так и не смог это сделать под yosemite. Постоянные ошибки, которые кое как решались. Но в конце появилась одна, которую решить так и не получилось. Никакие решения в интернетах не помогали. Большое спасибо, что хоть кто-то выкладывает готовые сборки хотя бы для макоси. Кто-то еще понимает, что make это не так просто и безболезненно. Даже под теми ОС, под которыми это типа должно без проблем собираться.

Благо все таки есть проекты, которые умеют собираться. OpenSSL у меня оставил вполне хорошие впечатление будь это сборка под windows для linux arm или iOS. Да, я сейчас в основном упомянул С проекты. Но тут разницы мало в этом контексте.

А про модули знаю, но это не решит проблему legacy кода.
Виндовые проекты часто собираются без проблем, проблемы как раз с линуксовыми / кросс-платформенными, в основном. Потому что make, configure и вот эта вся гадость. С библиотеками огромная проблема, я ж не спорю. Но проблема эта не только в языке, но и в криворуких девелоперах.
Все проекты, над которыми я работаю — личные и коммерческие — собираются в один клик как минимум на 3 разных осях (Вин / Линукс / Мак), и никаких особых усилий я для этого не прикладывал, просто нормально писал проект с самого начала.
Вы сейчас практически описали язык D. Там есть всё это и даже больше.
Честно говоря, мне не совсем ясна ниша D. Для системного программирования он слабо пригоден из-за рантайма и GC, для написания модулей к управляемым языкам — по той же причине, а для бэкэндов есть специализированные языки, тот же Go.
GC опционален. Да, многие модули его всё же требуют, но вы не обязаны их использовать.
Не понял в чем проблема писать на нём модули для управляемых языков.
D, конечно, не идеал, но всяко лучше примитивного Go.
ИМХО, Go примитивен, потому что его именно таким и сделали. Именно в этом его основное достоинство. Он предназначен для ниши, в которой ничего сложного и не надо. В этом смысле, сложность D — скорее недостаток при сравнении с Go. Не думали, что Go набирает популярность, именно потому, что для некоторых проектов нужен именно простой язык, с простой сборкой, с простым деплоем одним бинарником и с мощной стандартной библиотекой?
У Go простоя реализация и спецификация, программы же получаются переусложнёнными из-за необходимости велосипедить. D же позволяет сделать интерфейс, который реально прост в использовании. Ну, банально, как отсортировать массив в Go? В D я это делаю так с любым объектом реализующим интерфейс диапазона со случайным доступом:

	import std.algorithm.sorting;
	auto x = [2,1,3];
	x.sort!q{ a < b }; // эквивалентно x.sort();
	writeln( x );


Если бы D пиарили хотябы в половину меньше, чем го, то все переходили именно на него. И плюсовики в первую очередь, ибо в D сделано хорошо, всё, что в C++ сделано плохо.

В D тоже простая сборка, простой деплой одним бинарником и стандартная библиотека по мощнее будет. Основной недостаток D — маленькое комьюнити, которое не наклепало ещё кучу модулей на все случаи жизни.
Ну, банально, как отсортировать массив в Go?

Открыть документацию golang.org/pkg/sort и скопипастить пару строчек для реализации интерфейса сортировки
Вы покажите эквивалентный код :-) Там как минимум 4 строчки надо скопипастить на каждую комбинацию типа_элемента+функции_сортировки. И это не просто реализация интерфейса, это создание отдельного подтипа, в котором зашивается алгоритм сортировки.
По ссылке пример боевого кода с пользовательским типом, зачем мне абстрактные бессмысленные примеры. Все выглядит вполне нормально и обыденно. Реализуем для нашего типа интерфейс сортировки и вперед. Мериться строчками в данном случае неблагодарное дело, которое не имеет никакого значения к реальным преимущества языков. Код Go элементарен и не настолько сильно больше. Я вспоминаю C#, где не сильно меньше надо делать — для каждого пользовательского типа нужно реализовать интерфейс сравнения, чтобы он сортировался. Обыденный паттерн нынче.
Go:
package main

import (
	"fmt"
	"sort"
)

// A couple of type definitions to make the units clear.
type earthMass float64
type au float64

// A Planet defines the properties of a solar system object.
type Planet struct {
	name     string
	mass     earthMass
	distance au
}

// By is the type of a "less" function that defines the ordering of its Planet arguments.
type By func(p1, p2 *Planet) bool

// Sort is a method on the function type, By, that sorts the argument slice according to the function.
func (by By) Sort(planets []Planet) {
	ps := &planetSorter{
		planets: planets,
		by:      by, // The Sort method's receiver is the function (closure) that defines the sort order.
	}
	sort.Sort(ps)
}

// planetSorter joins a By function and a slice of Planets to be sorted.
type planetSorter struct {
	planets []Planet
	by      func(p1, p2 *Planet) bool // Closure used in the Less method.
}

// Len is part of sort.Interface.
func (s *planetSorter) Len() int {
	return len(s.planets)
}

// Swap is part of sort.Interface.
func (s *planetSorter) Swap(i, j int) {
	s.planets[i], s.planets[j] = s.planets[j], s.planets[i]
}

// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
func (s *planetSorter) Less(i, j int) bool {
	return s.by(&s.planets[i], &s.planets[j])
}

var planets = []Planet{
	{"Mercury", 0.055, 0.4},
	{"Venus", 0.815, 0.7},
	{"Earth", 1.0, 1.0},
	{"Mars", 0.107, 1.5},
}

// ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
func main() {
	// Closures that order the Planet structure.
	name := func(p1, p2 *Planet) bool {
		return p1.name < p2.name
	}
	mass := func(p1, p2 *Planet) bool {
		return p1.mass < p2.mass
	}
	distance := func(p1, p2 *Planet) bool {
		return p1.distance < p2.distance
	}
	decreasingDistance := func(p1, p2 *Planet) bool {
		return !distance(p1, p2)
	}

	// Sort the planets by the various criteria.
	By(name).Sort(planets)
	fmt.Println("By name:", planets)

	By(mass).Sort(planets)
	fmt.Println("By mass:", planets)

	By(distance).Sort(planets)
	fmt.Println("By distance:", planets)

	By(decreasingDistance).Sort(planets)
	fmt.Println("By decreasing distance:", planets)

}



D:
import std.stdio;
import std.algorithm;

// A couple of type definitions to make the units clear.
alias real earthMass;
alias real au;

// A Planet defines the properties of a solar system object.
struct Planet {
	string name; 
	earthMass mass;     
	au distance;
}

Planet[] planets = [
	{"Mercury", 0.055, 0.4},
	{"Venus", 0.815, 0.7},
	{"Earth", 1.0, 1.0},
	{"Mars", 0.107, 1.5},
];

// ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
void main() {

	// Sort the planets by the various criteria.
	planets.sort!q{ a.name < b.name };
	writeln("By name:", planets);

	planets.sort!q{ a.mass < b.mass };
	writeln("By mass:", planets);

	planets.sort!q{ a.distance < b.distance };
	writeln("By distance:", planets);

	planets.sort!q{ a.distance > b.distance };
	writeln("By decreasing distance:", planets);

}


Видимо я что-то не понимаю в этой жизни.
Замечательно конечно, но я не вижу тут большого практического преимущества у Д. Просто потому что в реальной задаче я не буду этим заниматься — этим будет заниматься база данных скорее всего, а с учетом позиционирования Go именно так и будет. А если будет иначе, то не будет 100500 вариантов сортировки. Go отчего и поднялся, потому что он нашел свою нишу, в которую его силами гугл и заталкивает. В этой нише ему это все не особенно нужно — подготовкой массивов данных в сервисах обычно занимаются другие части системы. А D, будучи языком общего назначения, возможно как раз и нужно, чтобы покрывать намного больший круг задач. Но даже в этом случае данный конкретный пример не показывает мне практических преимуществ, чисто теоретическая мерка цифрами.

А если уж прям так хочется сделать короче, не знаю зачем вообще, то первая ссылка в гугле даст достаточно решений stackoverflow.com/questions/28999735/what-is-the-shortest-way-to-simply-sort-an-array-of-structs-by-arbitrary-field В том числе практически идентичное тому, что представили вы.
Почему же это такого простого и лаконичного решения как "практически идентичное" нету в официальной документации?

Ответ прост:
1. Это решение использует interface{}, то есть статическая типизация идёт лесом.
2. В рантайме это решение использует рефлексию, что бьёт по производительности.
D — не вариант для плюсовиков из-за GC, говорю как плюсовик. То что его можно отключить — вообще не аргумент, и вы сами знаете почему. Вариантом для плюсовиков пока что выглядит Rust. Go — компромисс между Java и python, а вот ниши для D не вижу. Он слишком сложный для веба (сложнее джавы), при этом его достоинства по сравнению с ней не очевидны.
Ох не знаю про раст. Каждый раз при виде кода мне становится страшно. Выглядит и читается это все намного сложнее С++ и по описанию его возможностей похоже намутить непонятных в будущем никому конструкций на нем будет еще проще, чем на плюсах
А вы на плюсах пишете? Просто для статистики.
Даже не представляю почему. Поддержка GC оскверняет язык? Но я согласен, что поддержка владения на уровне языка — куда более привлекательная для системного программирования штука, чем GC.

А в чём он сложнее явы?
UFO just landed and posted this here
Прочитав пост, ожидал что в комментариях divan0 будет рассказывать, что эту статью написал школьник и что подобные статьи сообществу только вредят. А так же что Go няша и Роб Пайк тоже няша. И вообще, какое право имеет какой-то там школьник упоминать Пайка в негативном контексте.

Ожидания не оправдались.

Поэтому, теперь жду статьи-разоблачения с заголовком «И всё же, кто и зачем использует Go», в которой мы прочитаем красочную историю как всё стало круто в тех компаниях, которые используют Go заменив им язык X (тут можно рандомно подставить любое название языка программирования). А те кто выскажут свои сомнения будут автоматически зачислены в олигофрены, которые не могут разглядеть всю красоту, силу и мощь языка Go.
Посудите: можно нанять 100 посредственных программистов, дать им в руки Go и эта армия обезьян будет генерить вам много «неплохого» и очень даже поддерживаемого кода!


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


Такие набросы на Пайка просто не могут остаться без ответа. Поругана честь предводителя.
Жжошь, чертила, напалмом жжошь!
Да ну, этот, забаненный во всех Go-коммьюнити, школьник мечется между любовью и ненавистью к Go уже давно, и никак не может отпустить двач из своего сердца. Общаться там бесполезно, лишь повод для очередной пачки попкорна ) Вышеприведённая байка была рассказана знакомым знакомого одного из ребят в чате, которому лично не понравился Sawzal (именно так назывался тот инструмент). Теперь эта история обрела окрас «просто лохотрон полный», «никто не в восторге», «репутация неоднозначная». К слову, Sawzal свою работу в Google выполнял много лет более чем отлично, но сейчас уступил место Go в Google, где-то был paper на эту тему.

Так что, вы, конечно, сами выбирайте, как фильтровать что вам рассказывают и кто рассказывает. Слушайте больше не что вам говорят, а почему вам это говорят.
Я как раз в такие истории не верю. Просто интересно наблюдать ваши баталии в комментариях. Прочитав этот пост уже приготовил попкорн, а баталий что-то и нет :) По прошлому опыту решил что вы уже готовите хороший пост, так что попкорн пока далеко не убираю.
Нет, мне такое не интересно )
Ок, прячу попкорн до следующего вброса :)
Я её давно прочитал и вот уже потерял надежду что она появится на Хабре. Всё-таки, почти две недели прошло с момента её публикации. Причём, наткнулся на неё случайно и только после прочтения решил посмотреть кто её написал :)
забаненный во всех Go-коммьюнити

В неофициальной golang bridge слаке, где погоняют неадекватные феминистки и в вашем русскоязычном слак-бомжатнике? С каких пор это все Go сообщество? Короче, чет у тебя больная фантазия разыгралась, остывай.

Вышеприведённая байка была рассказана знакомым знакомого одного из ребят в чате, которому лично не понравился Sawzal

Эта история (про то, что Пайка мало кто в гугле любит) была рассказана мне топовым инженером гугла за кружкой пива, лол. Короче, кончай выдумывать факты. Иии я кстати не уверен, что это именно Sawzal был.
Делал несколько высоконагруженных бэкендов на Go (баннерокрутилки, RESTful апи и т. д.). Не могу даже представить альтернативных языков для столь быстрой и качественной разработки надежных, шустрых приложений.
А с какими ещё языками вы знакомы?
Знаком со многими, основной стек разработки:
С/С++, Go, Java, C# ну и всякие там PHP+JS+etc
И вы хотите сказать, что реально глубоко знаете кучу этих языков? (особенно мне нравится запись c/c++)
Мне, как С++ программисту, вообще не нравится запись C/C++. C — вообще язык простой, почти элементарный, тогда как плюсы — намного запутанней. Ставить их в один ряд, когда говоришь о знании этих языков — как минимум странно.
По сути так и есть, для разработки рест и работы с бд много не надо! чисто инструмент который было бы удобно использовать и не заморачиваться с кодом и деплоем! нет и джава тоже корпоративные штуки! еще один язык от большой корпорации не есть зло! просто еще один взгляд на бакенд! Самое главное чтобы порог вхождения для новичков был небольшим! А там кому понравится те и подтянуться @
Каждый раз переизобретается (условно) Basic (в хорошем смысле) с поправкой на время, и каждый раз все те же аргументы за и против.
Судя по минусам, подтверждается теория о рефлекторном неприятии слова «basic». Хоть бы аргументировали.
Наверное непонятно, при чем здесь basic.
Парадигма языка с низким уровнем вхождения и меньшим количеством способов «выстрелить в ногу». С поправкой на уровень развития технологий. Я же написал — условно.
В моем случае Go отлично подошел для написания бэкенда с несложной логикой. В качестве веб-фреймворка используется gin, для сохранения/получения промежуточных данных key-value хранилище bolt. Если взять для примера запрос, для обработки данных которого использутеся простая логика из цикла с парой вложенных условий с сохранением состояния через mutex, на отдачу ответа уходит ~40-50µs.
Возможно для вашей задачи вообще не нужен был бекенд на Go. Посмотрите на связку Nginx + Tarantool.
Спасибо за наводку!

1) В этом запросе логика простая, но в сервисе уже появились несколько сложных запросов, которые активно используют стандартную библиотеку, а она в Go весьма богатая.
2) У нас 32 ядра в процессоре и когда прилетит одновременно 32 запроса их выполнение распределится по всем ядрам и суммарно выполнятся за те же ~40-50µs если конечно по логике приложения не нужен будет лок на запись или сборщик не начнет работу.
3) Скорость работы очень радует, тесты просто роута, возвращающего json были близки к ретурну nginx-а:

location /test_json { return 200 '{"message": "Hello, world!"}'; }
Ребята, раз уж я здесь, подскажите, насколько юзабелен может оказаться Go для написания веб сервиса по изучению английского языка?) Нужны всевозможные драг энд дроп перетаскивания, тесты, вставки слов и прочие грам упражнения, обернутые в красивую оболочку.

Никогда в жизни не прогал под веб, уровень относительно низок (все на голом энтузиазме), но есть хорошая идея, реализация на PC и желание портировать это все в веб. Ищу самую быструю в изучении связку фронтэнда плюс бекэнда, чтоб прямо на ходу учится. Буду крайне благодарен любым советам.

Может кто-то может подсказать какие-то хорошие книги/туториалы по написанию веб приложений step by step?
P.S. Я тут немножко посмотрел в сторону Angular JS + Ruby on rails — это нормальная комбинация? Angular с первого взгляда, достаточно простой, по поводу всего остального не знаю)
Рискую оказаться непонятым. Возможно, вам подошла бы эта книга, если бы существовала. Просто все остальные советы взорвут вам мозг, сколько всего придётся изучить, если вы говорите, что «Никогда в жизни не прогал под веб».

Кому-то всё-таки стоит задуматься о выпуске такой книги, вот и аудитория уже подбирается :)
но если серьезно, я good learner, и прога мне очень нравится, поэтому могу выделять по 3-4 часа в день 7 дней в неделю без напряга. Поэтому и было бы здорово узнать, в какую сторону лучше всего копять.
Копать в сторону получения образования с последующим трудоустройством, потом в сторону набора опыта в роли джуна, а дальше… как повезет…
UFO just landed and posted this here
Вы меня не совсем поняли. Мне нужно программирование, ради работы на какую-то компанию, чтобы повезло. Я выучил Делфи с нуля для того, чтобы осуществить свою идею, и смог выйти на уровень порядка 1000 долларов пассивного дохода благодаря худо-бедной реализации. Теперь я хочу попробовать выйти на новый уровень, также самостоятельно, потому что мне это интересно.

Я понимаю, что здесь сидят профи, и каждый считает должным минусануть карму или комментарий за нубо-вопрос, но я не претендую на звание профи. Я понимаю, что программирование не для лошпедов, и с нуля никто ничего толкового не напишет. НО. Мне это интересно, и я люблю бросать вызовы в первую очередь себе. Поэтому я искренне надеялся получить небольшой толчок в сторону того, на что изначально обратить внимание и в какую степь копать. Ни стеб, снобизм, а просто обычный человеческий совет.
*Мне не нужно программирование, ради работы на какую-то компанию, чтобы повезло
Вы не в том месте задаёте свой вопрос.
Для вопросов, подобных вашему, существует отдельный ресурс: toster.ru
UFO just landed and posted this here
Красивую оболочку в вебе вы будете писать на HTML/CSS/JS (или обертках над ними). Если задачи сервера сводятся к передаче заданий из базы данных, проверке соответствия ответа правильному и ведению статистики, то почти без разницы на каком из популярных языков писать сервер.
Спасибо, уже затарился попкорном, и смотрю курсы на Линде по Javascript, code efficiency и web services.
Сейчас будут минусовать, но я все равно выскажусь.
namespace, поймите меня правильно, заходя на хабр я не хочу увидеть текст, имеющий художественную ценность уровня Толстого, Стейнбека или хотя бы Драйзера…

Но можно все-таки если и употреблять слова «срач», «высер», «воротить жопу» то как-то со смыслом что-ли…
А не начинать и завершать ими статью для эффекта Черчилля
Уважаемый автор.
Хрен с ними со срачами и высерами
Но цитату из Роба Пайка
They’re not capable of understanding a brilliant language but we want to use them to build good software.

Вы перевели как:
Они не в состоянии понимать пробздетый язык, но мы все равно хотим, чтобы они делали хороший софт.

С каких пор, brilliant переводится как пробздетый? Что вообще означает это странное слово?

После такого перевода вопрос, что автор имел в виду звучит особенно издевательски.
Как хочу — так и перевожу. «Пробздетый» означает «крутой», «продвинутый», можно было догадаться. Хотя если ты унылый старпер (что вероятно, иначе вопросов бы не возникало), то это не моя забота.
По-моему, ты ресурсом ошибся.
Я тут в четыре раза дольше тебя сижу, будешь мне еще рассказывать. Обтекай.
Апелляция к возрасту это когда Данилюк меня в каждом втором своем посте называет школьником. Я же просто показал пацану, где его место.
Вот правильно люди говорят — тщательно выбирай себе врага, рано или поздно ты станешь на него похожим. Я сейчас вижу что namespace и divan0 действуют по идентичной схеме, пользуются одинаковыми техниками убеждения и манипуляции, отличие только в стиле подачи (первый — пьяная гопота, второй — унылый «мама сказала в бидоне»).
Ну дело не в том, что я унылый старпёр. Дело в том, что Роб Пайк — унылый старпёр, и переводить его надо, как унылого старпёра, а не как молодёжного хипстера. Потому, что так уж он говорит. Или писать, как хотите, но тогда убрать цитирование и добавить пометку, что так уж вы слышите мир :)
Это мой перевод и мой пост. Я как хочу, так и оформляю его. Огромное спасибо за твой совет, но я оставлю все как есть — мне так больше по душе.
Ты ведь не только оформляешь свой пост как хочешь, ты ещё приписываешь Робу Пайку слова, которых он не говорил. Одумайся!
Нуичточтоонприписываетпайкусловакоторыеоннеговорил.
Явоттожепишукомментарийинехочуставитьпробелы.
Потомучтоэтомойкоментарийкакхочутакиоформляюего.

Авыстарыйстарпер.
Иястарыйстарперхотямнедвадцатьпятьлет.
Новидимоужестардлянемспейса.
Ну тогда ты не старпер, а просто лошара.
Это был сарказм ;)
@namespace комментарий:
Как хочу — так и перевожу. «Пробздетый» означает «крутой», «продвинутый», можно было догадаться. Хотя если ты унылый старпер (что вероятно, иначе вопросов бы не возникало), то это не моя забота.

Лошпет, мне не нужно объяснять, что сарказм, а что нет. Обтекай.
Забавно, что ваш комментарий читается с ходу без запинок, хотя и мешанина.
Вчитайтесь в пост внимательнее: ничего не напоминает? Да, это он, неповторимый и незабываемый стиль журнала «Хакер» начала нулевых. Так уже лет десять никто не пишет. Так что тема старпёрства раскрыта не полностью.
robust — устойчивый к изменениям
Коллеги, а чем вызвано столь бурное обсуждение языка go. Неужто действительно хорош?
Не настолько, насколько вокруг него бурлит. Но настолько, чтобы ознакомиться и оценить его пользу для своих задач
ИМХО, потому что прикладных языков не так уж и много и появление практически любого нового вызывает бурные обсуждения в соответствующих сообществах.
Sign up to leave a comment.

Articles