Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Роб Пайк одержим идеей создания простого и легкого concurent language и Go это не первая попытка, были еще Limbo, Squeak, Newsqueak.
Как корпоративный язык он плох, т.к. качество кода на Go зависит исключительно от самомотивации разработчиков. В Go ничто не мешает скатиться до низкоуровневого императивного кода и писать в стиле C.
полностью рабочий сайт предусматривает наличие редактируемых текстов, вывод их, админку для этих текстов итд.
В любом случае в полноценном сайте человек (заказчик) должен иметь возможность хотябы просмотреть то что сайт предполагает сохранять
… смог бы сделать на много быстрей с валидацией и простейшей админкой хотябы на просмотр оставленного посетителями). Об этом и речь, скорость разработки, а мне тут расказывают как они быстро хеловорлд напишут. Я говорю про разницу во времени....
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 минут. А вот на пхп, с опытом в 7 лет, это действительно ближе к реальности
пхп сам по себе шаблонизатор
Чего только стоит загрузка файла на сервер, на пхп это реально за 5 минут делается, а на го?
file, _, err := c.Request.FormFile("file")
хелловорлд за 40 минут, поэтому ты неправ!, и плевать что я вообще о другом говорил.
«Простой и легкий concurrent язык» это по сути своей и есть сишка без арифметики над указателями и каналами и зелеными потоками, не более.
Там получается проще, чем копирование файлов?Проще копирования файлов может быть только копирования файла. Одного. Ваш КО.
А чтобы не велосипедить на скриптах при деплое в продакшене, можно сделать deb-пакет, например, или использовать контейнеры.
Он не закрытый, в отличие от .NET
Что нельзя реализовать в Go имеющимся набором стандартных и дополнительных библиотек?
Если средства, созданные на языке распространяются в _официальном_ дистрибутиве Linux (Red Hat, Fedora и др.), говорит ли это о популярности? Есть ли в этих дистрибутивах хоть что-то, созданное на .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
И я не хочу в корпорации, стартапы и петакластеры. Я хочу общаться с умными, образованными людьми, с которыми можно говорить в терминах левых и правых сверток, влияния этого на ленивость и рекурсивность, и комбинаторов неподвижной точки для функций, отвечающих морфизмам в категории графов.
аналитическое дифференцирование в компилтайме на C++ для научной работы
В Go с зависимостями в этом плане, конечно, круче.Те же яйца, вид сбоку. Кто-то вендорит, кто-то собирается против edge-версий библиотек, притаскивая какую-то версию go get, кто-то тащит godep. А то и всё вместе.
Я всего года полтора на питоне писал и за это время не видел ни одного плюс-минус большого и при этом, читабельного проекта.
Чего только monkey patching стоит, не разобраться вообще.
В Go с зависимостями в этом плане, конечно, круче.
Интересуют именно преимущества, а не отличия.А в чём разница? Нет, я не издеваюсь, я серьёзно. Потому что я просто не верю, что вы сможете взять два любых, более-менее распространённых, языка и при их сравнении найти вообще хоть что-то, что не было бы «палкой о двух концах».
Пример абстрактных, сферических преимуществ в вакууме (не Go vs. Python, а для любого языка):«Сферические кони в вакууме» меня не волнуют. Пожалуйста примеры двух языков — можно будет говорить.
1) высокая производительность (еще никому не мешала),Мешает. Причём очень сильно. Не видел ни одного языка который бы не платил за высокую производительность сложностью синтаксиса и/или безопасностью. А зачастую и тем и другим.
2) более короткие названия функций и классов из стандартной библиотеки, что позволяет банально быстрее писать код,Но затрудняет чтение оного кода. Сможете скезать без заглядывания в mac что делает какая-нибудь функция strxfrm?
3) большое разнообразие стандартной библиотеки,Зачастую приводит к тому, что есть несколько несовместимых способов сделать что-либо.
4) наличие большого числа мощных IDE,Тут, пожалуй, соглашусь, хотя замечу что подобное преимущество зачастую используется разработчиками языка для того, чтобы сложный, многословный и запутанный код всё-таки как-то можно было писать. Типичный пример — Java. После появляния «большого числа мощных IDE» там появилась куча библиотек, которые без IDE пользоваться практически невозможно, да и с IDE — проблематично.
5) широкое комьюнити, большое количество re-usable кода.Та же самая проблема, что и с «большим разнообразием стандартной библиотеки». Наличие 100500 несовместимых версий одного и того же «велосипеда». Бич, собственно, С и C++.
Дальше продолжать смысла нет, но думаю все согласятся, что выше перечислены явные преимущества, а не просто особенности.В «сферически-вакуумном» смысле — может быть. На практике — все эти «явные преимущества» тянут за собой «паровозом» соответствующие недостатки.
Нет никакого практического смысла иметь в памяти суррогатные пары — это замедляет и усложняет алгоритмы работы со строками, не принося никакого профита.Это вы что-то с чем-то спутали. Практический смысл есть и он, как бы, очень простой: данные приходящие в вашу программу их могут содержат и вам что-то с этим нужно делать.
Все используемые сейчас символы укладываются в кодовое пространство UCS-2.Все используемые символы — да, все испольуемые данные — и близко нет.
Так что поддержка юникода в мейнстримовых языках весьма не плоха — быстрая и покрывает большую часть практических нужд.То есть умение программы запуститься и что-то там сделать не вылетая с UnicodeEncodeError — уже не относится к «практическим нуждам»? Ню-ню.
Другое дело, что программы на питоне могли бы поступать более дружелюбно и, например, тут же предлагать исправлять бардак в файловой системе.«Более дружелюбно»? Нет уж, guile, который тихо и незаметно корёжит «неправильный» UTF-8 — это ещё хуже, чем Python. Python можно худо-бедно использовать, а с Guile лучше вообще никогда не связываться. Так как вылетающее исключение можно поймать и обработать (неприятно, могут быть финансовые потери, но не смертельно), а испорченные данные зачастую восстановить просто нельзя, если вы узнаёте о том, что в «борьбе за юникод» они безнадёжно испорчены, слишком поздно.
Но и ругать их за то, что они не игнорируют проблемы, а сигнализируют о них как можно раньше — странно.С какого перепугу вдруг? «Непарные суррогаты» (под Windows) и «испорченный UTF-8» (под Linux) — это данность. Вам может это дизайнерское решение не нравится, и вы можете стонать по этому поводу сколько угодно, но правильно написанная программа должна с ними работать. API так устроен. Извольте соответствовать. Пользователя не волную глубинные идеи — ему нужна программа, которая работает. А не падает.
Я и сейчас зачастую имею такие проблемы, когда я получаю здоровые Shapefile из ArcGIS с полигонами, которые по незнанию клиенты сохраняют в локальной кодировке, и я ее должен угадывать, тыкая пальцем в небо (так как клиенты понятия не имеют о кодировках).И вы будете иметь их и в дальнейшем. Вот только разрулить их в Python'е на порядок сложнее, чем в Go.
Возможно они не осилили PEP 0393 и решили использовать массив байт (0-225) для экономной записи, я не знаю.Строка в Go — это просто последовательность байтов, не более того. Есть range loop (про который я говорил), который как бы «рассчитан на UTF-8» но все языковые конструкции (в том числе пресловутый range loop) вполне корректно обрабатывают невалидные UTF-8 строки.
Короче, к Go можно придираться очень долго, но строки в нем сделаны очень даже неплохо.Ну дык. И главное их преимущество — то, что они не юникодные!
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.
Content-Encoding: gzip и несжатым текстом в body) и многие другие прелести, которых не ощутишь, пока работает со своими или просто нормальными API, но которые ощущаются, как только ступишь на выжженные пустоши реального мира, где стаи ракопауков носятся в воздухе.— регистронезависимый поиск подстроки в строкеА ничего, что это делается по разному в разных языках? Уж если вы знаете язык строки, то указать ещё и её кодировку — не проблема.
— перевод из одного регистра символов в другой
— определение валидности UTF-8 строки перед записью в базу, чтобы мусор не записатьСовершенно непонятно чем функция, получащая «набор байт» и проверяющая его хуже «юникодных строк»
Я не знаю ужаса со строками в 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
Что я не так понимаю в жизни? :-)Да. Вы не понимаете, что речь идёт не об неиспользовании Юникода, а о том, что ни язык, ни стандартная библиотека не форсируют его использование.
http-equiv и если нужно перекодировть — превращается в танцы с бубнами.App::Cpan.3perl.gz породит имя файла в котором будут непарные суррогаты. Go с этим отлично справится, Python — скорее всего сойдёт с ума, потому что мало какие библиотеки работают с файлами так, как предписывает PEP 383.Вы же понимаете, что это проблемы пользователей CygWin?С какого перепугу? Это проблемы пользователей, у которых не работает ваша программа — чините.
У меня не появляется файлов с неюникодными именами. ЧЯДНТ?Возможно не используете Python? Или довели борьбу с фатальным недостатком до совершенства. Не знаю. Я с разного рода проблемами, возникающими из-за кривой поддержки юникода в Python'е борюсь регулярно. В Python2 это относительно несложно (игнорируйте все эти юникодный строки — и будет вам большое такое «щастя»), в Python3 — это стало просто катастрофой.
Да и выбирать язык по недостаткам, напоминающими анекдот «а вы попробуйте на шкаф залезьте!» несколько странно.Почему нет? Чем странней ситуация, в которой обваливается ваша программа тем выше шанс того, что у вас она работать будет, а у заказчика — рухнет. После чего он вас «пошлёт» с вашими идеями что неработоспособность вашей программы — это не ваша проблема. И будет, ЧСХ, прав.
Вообще, интересно много ли заказчиков готовы платить за цугвин.Они не платят «за цугвин». Они платят, вы не поверите, за программы. Решающие (или обещающие решить) их задачи. Которые, внезапно, не работают если на компьютере есть CygWin и он насоздавал «неправильные» файлы.
Я цугвин видел только в каком то наколеночном опенсорсе, который на рабочий комп попасть не мог.А я его видел как часть интернет-магазина. Или, скажем, 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-строкуЕсли какая-нибудь библиотека выдёт вам юникодную строку, то нужно либо постараться убедить её этого не делать, либо придётся-таки в этом конкретном места мучиться, да.
Компиляция под любую платформу одной строчкой. 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? Не собирается почему-то.
Ага, разогнались.
Под armv7 я собирал — linux версия работает на андроиде и кастомной плате с cortex-A8 процессоре.Кроме arm-linux-gnueabi существуют и другие target'ы, которые не всегда поддерживают linux или darwin. На cortex-a/r arm-мир не заканчивается: есть cortex-m, есть разные arm7/9/11. Так что утверждение «Компиляция под любую платформу одной строчкой» выглядит чересчур самоуверенно.
Это не лучший пример.Ок, принято, docker довольно сложная система. Когда я пробовал писать простейшие программы использующие goroutine'ы и каналы у меня по умолчанию ldd показывал, как минимум libc и pthread. Для получения статичного бинарника надо прилагать некоторые усилия. Возможно, сейчас поведение по умолчанию изменилось.
Так что утверждение «Компиляция под любую платформу одной строчкой» выглядит чересчур самоуверенно.
-ldflags "-linkmode external -extldflags -static"
потому что это как два пальца обоссать
import std.algorithm.sorting;
auto x = [2,1,3];
x.sort!q{ a < b }; // эквивалентно x.sort();
writeln( x );
Ну, банально, как отсортировать массив в 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)
}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);
}Посудите: можно нанять 100 посредственных программистов, дать им в руки Go и эта армия обезьян будет генерить вам много «неплохого» и очень даже поддерживаемого кода!
А что касается Пайка, то он разводила еще тот. Знакомый из гугла жаловался, что Пайк написал какую-то внутреннюю систему запросов, которая просто лохотрон полный и теперь им это все поддерживать надо и никто от этого не в восторге. Короче говоря, среди гуглеров у Пайка репутация далеко не однозначная.
забаненный во всех Go-коммьюнити
Вышеприведённая байка была рассказана знакомым знакомого одного из ребят в чате, которому лично не понравился Sawzal
location /test_json {
return 200 '{"message": "Hello, world!"}';
}
They’re not capable of understanding a brilliant language but we want to use them to build good software.
Они не в состоянии понимать пробздетый язык, но мы все равно хотим, чтобы они делали хороший софт.
Как хочу — так и перевожу. «Пробздетый» означает «крутой», «продвинутый», можно было догадаться. Хотя если ты унылый старпер (что вероятно, иначе вопросов бы не возникало), то это не моя забота.
Кому и зачем все-таки нужен Go?