А можно подробней? Я плохо понимаю, почему самописный рендерер не может быть в итоге пристойным.
Сейчас, понятно, со шрифтами ноль полный там в плане пристойности, но если проект будут развивать, то тема шрифтов, полагаю, будет одной из главных в плане критики/пул-реквестов.
Вы пытаетесь frontend JS представлять на месте традиционных системных языков. Но мы же тут о другом — «веб-решение» подразумевает другую модель взаимодействия с пользователем, и там где раньше вам нужно было «читать файл», сейчас вы «принимаете HTTP-запрос». Банальный пример — загрузка изображения. В случае нативной десктопной аппликации вам без умения читать файла с файловой системы не обойтись, в случае с веб-приложением — бекенду это не нужно, зато нужно уметь принимать изображение от клиента.
А так на JS можно делать все, node.js вам в пример.
потому что это единственный способ сделать красивый кроссплатформенный GUI на данный момент
Не только поэтому.
появился мир смартфонов/планшетов и просто новый подход к вопросу — «я хочу пользоваться интерфейсом с любого из своих устройств»
как следствие, интерфейс должен работать и на мобильном телефоне и на экране телевизора
веб-приложениям не нужно заниматься обновлениями приложений конечному пользователю — а это для многих ситуаций громадный выигрыш, часто решающий
количество «виджетов» созданных для современных фронтендов будет покруче, чем у того же Qt. тут недавно была статья на хабре, как Highcharts.js прикручивали к Qt — подобной крутости charts-библиотек под десктопные UI нет и уже вряд ли будут
Я бы добавил в статью упоминание о том, что database/sql — это универсальный способ для работы с БД, вне зависимости от драйвера, и научившись работать с ним, работа с любой новой БД остается практически неизменной в плане кода.
Нет-нет, проблема в другом. Есть скрипт, который я хочу запускать через gorun. go и gorun поставить на сервер — не проблема, и все что мне нужно — чтобы скрипт можно было запускать, как, ну, обычный sh-скрипт. Но если мне нужен доступ к myqsql из этого Go-скрипта (или любой third-party package), то уже не получится просто так запускать — нужно на целевом сервере (в моем случае их много) устанавливать GOPATH и go get-ить туда нужный package, чтобы скрипт работал.
Ну, это больше не проблема, это так — заморочка. )
Тоже использую Go для административных скриптов иногда, запускаемых через shebang (#!) — одна из проблем, это заморочки с GOPATH, если нужно использовать сторонние пакаджи (mysql, к примеру). Но для большинства задач — намного более приятный опыт и уверенность в коде, нежели с bash.
Хендлинг ошибок в баше и чуть более сложная логика — это боль.
Кроме того, для unix и windows данный скрипт пришлось бы писать отдельно, решение с Go кроссплатформенно.
Да, это причина, по которой народ массово ломанулся С++ в Python/Ruby в свое время — буст продуктивности. Но у меня с Python тоже сильно не сложилось — начиная от большой сложности с деплоем и пакаджингом и заканчивая, собственно, скоростью и прожорливостью. Тоесть, если С++ давал хорошую скорость, но маленькую продуктивность, то Питон — наоборот.
Но по ощущениям Go ближе к Питону — он «чувствуется», как динамически-типизированный язык, это правда. И, кстати, если верить общему впечатлению по статьям/комментариям в коммьюнити, то больше всего на Go переходит именно народу с Python и Ruby, а C++-хардкорщики воспринимают его в штыки.
Смотрите, я в процессе разработки Go не участвую, поэтому в этом споре(?) с одной стороны есть вы, утверждающие, что язык написания не имеет значения, и есть авторы Go, которые, собственно, своими ручками это все пишут, и утверждают, что для них язык имеет критическое значение, чтобы идти дальше. Угадайте, чья сторона аргументации мне кажется более правильной?
Да, про заминусованную просьбу показать пример — это не лично к вам, конечно же, было.
Насчет условия упираемости — попытаюсь свой поинт написать с точки зрения личного опыта, а не теоретических рассуждений.
Я пишу, в основном, серверный/сетевой софт, иногда прикладное/gui/мобильное всякое — и основные используемые языки — C/C++/Python. Для меня проблема давным давно не в «сэкономить лишний такт процессора или лишний килобайт», а в том, чтобы быстро выдавать качественный и надежный продукт, который работает в современной софтверной экосистеме, с современными технологиями и протоколами. И C++ и Python обладают целым рядом недостатков, которые превращали ежедневную работу в унылую тоску, боль и борьбу с инструментарием, вместо написания кода. К С++ основная претензия — это излишняя сложность, которая только возрастает с годами. Чтобы написать простенькую по меркам 2015 года программу (скажем, простенький REST-backend) — нужно 5+ лет опыта C++, доскональное знание библиотек STL/Boost/ACE/TAO (а их именно нужно знать, с документацией и интуитивностью их API большие проблемы) и несколько томов литературы. Блин, да мне для создания переменной нужно думать, какой из десятка умных поинтеров буста выбрать! И это для простой программы, которая просто не будет падать. Тот фан, который некогда был от процесса написания кода, куда-то исчез.
И тут появляется Go — который был рожден как результат абсолютно таких же измышлений и недовольства существующим инструментарием, только от людей, в тысячи раз умнее меня, от людей с колоссальнейшим опытом в разработке ПО, и хорошим тылом в виде Гугла, позволившего им начать новый язык. Практически всё в Go мне понравилось сразу — и идеология KISS в фундаменте дизайна, и отталкивание от практического опыта, а не от теоретических выводов PLT, и очень низкий порог входа — вобщем, буквально за несколько часов я уже чувствовал, что язык знаком давным давно, а еще через пару вечером уже мог писать production-level код. И всё это с фантастическим тулингом, возможностями по профайлингу, оптимизации, тестированию и прочему.
В Go почти каждый аспект ежедневной работы, который раньше отнимал минуты и часы, стал занимать секунды. Я снова смог сконцентрироваться на написании кода, а не на борьбе с инструментами. Мой первый серьезный stress-тест для Go был на одном международном мероприятии, где мне понадобилось написать софт, который бы парсил псевдо-зашифрованный протокол, вычленял из него 60-кб xml-пакеты, разбирал их, извлекал нужные данные, кормил их небольшой стейт-машине, и генерировал выходные данные, отдавая в консоль, в файлы, и, желательно — на веб-интерфейс по веб-сокету.
Этот код я писал на коленке, и на Go (и это еще по ходу изучения stdlib) это заняло у меня около суток — большая часть времени ушла на разбирание протокола. Но я ни на минуту не отвлекался на проблемы языка, на лишние обертки и геттеры/сеттеры, на то «как это делать по-правильному» и «как выравнивать отступы». При этом я тут же создавал для каждой функции тесты — благо, это занимало не больше пары минут.
И это был реально глоток свежего воздуха после последних лет мучений с С++ и Python. Я снова получал удовольствие от самого процесса написания кода, и я был чертовски продуктивен. Сперва я сам не поверил, что вот эту, хорошо структурированную программу (там было 5 пакаджей, из которых два — эмуляторы источника данных и прокси-дупликатор), покрытую тестами, документированную(!), понятную и читабельную — я написал почти за сутки, и это при том, что я походу еще и открывал для себя новые библиотеки stdlib, изучая документацию. При этом я совсем не хардкорщик с феноменальной памятью, и не набираю на клавиатуре 800 символов в минуту.
И меня ошеломило, когда я попытался представить, сколько времени у меня ушло бы на подобную по качеству и понятности реализацию на С++.
Эта программа работает, кстати, до сих пор, на нескольких точках, и работает как часы. А да, и писалась она на макоси, а работать должна была на windows.
Но к чему я это всё вспомнил? Сейчас я использую Go ежедневно, в нескольких больших проектах, и всё также ежедневно наслаждаюсь огромной продуктивностью, которая появилась в Go. Если вы цените выражение «время — деньги», то продуктивность тут — прямой синоним слова «деньги». Для меня, по крайней мере.
Само собой, я хочу этим делиться с коллегами, друзьями и остальными — помогать людям тоже открывать для себя эти возможности. Я ведь тоже Go для себя открыл внезапно, просто наткнувшись на какой-то интересный пост в блоге.
И вот, на фоне всего этого, подходит коллега или анонимус в интернете, и говорит — Go — сакс, потому что «там нет эксепшенов»/«там нет generics»/«там нет динамической линковки»/«там нет Хиндли-Милнера» etc. И ты такой, стоишь и думаешь первым делом — «стоп, а как же я без этого жил, если для человека это блокер?». Начинаешь глубже разбираться в теме, и понимаешь, что речь лишь о привычке. Кто-то потратил буквально годы жизни, чтобы научиться правильно использовать исключения, или решил, что программирование шаблонами — это некая ступень в программировании, ниже которой опускаться нельзя. И человек не готов отказаться от привычки, и тратит мое и свое время, чтобы мне доказать — что «да пошла она твоя продуктивность, главное — это наличие generics».
И тут ты второй раз думаешь — «блин, ну может я и вправду что-то не понимаю.». Читаешь, разбираешься в теме еще глубже — вроде понятно, какие реальные юз-кейсы. И думаешь — ну окей, ну могут быть, действительно, случаи, где было бы хорошо (но не обязательно) иметь встроенные генерикс — но готов ли ты пожертвовать субсекундной компиляцией? Или кроссплатформенностью? Или понятностью системы типов? Готов ли пожертвовать продуктивностью — которая есть результат совокупного дизайна всех аспектов языка, ради того, чтобы появилась возможность делать задачу, которая реально еще даже не встречалась ни разу, на 10 строчек короче?
И я точно знаю, что нет, не готов. Если кто-то придумает как в Go сделать генерики, не ухудшая всю эту радость — супер, все только за будут. Но пока никто не придумал, и этому есть реальная причина.
Возможно, так и есть. Но я уже не первый раз задаю этот вопрос — покажите примеры задач, где отсутствие generics — блокер, и ни одного адекватного ответа пока не было, к сожалению.
Не знаю, мне уже прямо неудобно. Вот такие комментарии с аналогиями «любителей динамических языков» писать легко, это понятно. Но до сих пор ни один человек в этой ветке не смог привести пример из реального проекта, где generics был бы стоппером, и не решался идиоматически Go.
Мне кажется это ведь просто — если программист и вправду жить не может без generics и считает, что это обязательный атрибут современного программирования — то должно быть легко вспомнить реальный случай и привести его в пример.
Просьбу эту заминусовали, вместо того, чтобы дать ответ по сути. Показательно, по-моему.
И это лишь подтверждает чисто теоретическую тему спора. На практике отсутствие generics в Go никак не мешает писать очень качественный код.
Если активно используется interface{} и нет от этого никакого дискомфорта
В том-то и дело, что interface{} не используется «активно». Даже проскакивает периодически в статьях для новичков — мол, interface{} в большинстве случаев вам не нужен, не лепите его где не нужно.
Я абсолютно согласен со всеми утверждениями про «в Go полу-статическая, полу-динамическая типизация» — но у меня нет в голове стереотипов, заставляющих записывать это сразу в минус. И против реализации generics темплейтами тоже ничего особо не имею (кроме того, что откуда-то берется стимул их использовать по любому случаю, и код становится почти не читабельным, и уж совсем не-дебагельным) — но я понимаю и разделяю позицию авторов Go.
то в рантайме накладных расходов дополнительных тоже не будет — то есть их будет не больше чем при ручном приведении и проверки типов.
Autoboxing/unboxing — это не оверхед?
PPS. Если не секрет, а на чем вы писали до Go? Какими еще языками пользуетесь?
Сначала на С, потом (и в основном) на С++, потом ушел на Python, который чуть упростил жизнь, но по понятным причинам это был несправедливый размен. А потом наткнулся на Go и буквально через пару вечеров смог писать production-level код. Так что для меня Go — это полноценная замена С++, которым я был недоволен по многим пунктам, но альтернативы которому особо не было.
Кстати, возможно мне так просто понимать позицию авторов Go по многим вопросам, потому что моя причина ухода от С++ совпала с причинами появления Go.
И всё же — «их отсутствие обходится» — это заведомо предвзятая фраза.
Чуть ниже запостили ссылку на отличный сводный док по тому, какие есть реальные применения generics и как эти же задачи решаются в Go без generics (и это не тоже самое, что «обходится») — рекомендую почитать всем в этой ветке.
И я хочу все таки обсудить реальные блокеры без generics, а не «полезно» или «так будет чуть лучше». Потому что это «чуть лучше», с учетом тех потерь, которые принесет реализация генериков в языке, станет «много хуже» в общем.
Нет, это не тот ответ. Обратный ответ («Сколько в вашей программе generic-типов? Вместо каждого из них можно использовать interface{}») точно такую же пользу несет.
Просто расскажите о реальном куске кода, где без generics — ужасно, некрасиво, костыли и так далее. Ну серьезно, это не должно быть проблемой. Будет тема для более предметного обсуждения хоть.
Сейчас, понятно, со шрифтами ноль полный там в плане пристойности, но если проект будут развивать, то тема шрифтов, полагаю, будет одной из главных в плане критики/пул-реквестов.
А так на JS можно делать все, node.js вам в пример.
Не только поэтому.
Ну, это больше не проблема, это так — заморочка. )
golang.org/pkg/path/filepath/
Кроме того, для unix и windows данный скрипт пришлось бы писать отдельно, решение с Go кроссплатформенно.
Но по ощущениям Go ближе к Питону — он «чувствуется», как динамически-типизированный язык, это правда. И, кстати, если верить общему впечатлению по статьям/комментариям в коммьюнити, то больше всего на Go переходит именно народу с Python и Ruby, а C++-хардкорщики воспринимают его в штыки.
Насчет условия упираемости — попытаюсь свой поинт написать с точки зрения личного опыта, а не теоретических рассуждений.
Я пишу, в основном, серверный/сетевой софт, иногда прикладное/gui/мобильное всякое — и основные используемые языки — C/C++/Python. Для меня проблема давным давно не в «сэкономить лишний такт процессора или лишний килобайт», а в том, чтобы быстро выдавать качественный и надежный продукт, который работает в современной софтверной экосистеме, с современными технологиями и протоколами. И C++ и Python обладают целым рядом недостатков, которые превращали ежедневную работу в унылую тоску, боль и борьбу с инструментарием, вместо написания кода. К С++ основная претензия — это излишняя сложность, которая только возрастает с годами. Чтобы написать простенькую по меркам 2015 года программу (скажем, простенький REST-backend) — нужно 5+ лет опыта C++, доскональное знание библиотек STL/Boost/ACE/TAO (а их именно нужно знать, с документацией и интуитивностью их API большие проблемы) и несколько томов литературы. Блин, да мне для создания переменной нужно думать, какой из десятка умных поинтеров буста выбрать! И это для простой программы, которая просто не будет падать. Тот фан, который некогда был от процесса написания кода, куда-то исчез.
И тут появляется Go — который был рожден как результат абсолютно таких же измышлений и недовольства существующим инструментарием, только от людей, в тысячи раз умнее меня, от людей с колоссальнейшим опытом в разработке ПО, и хорошим тылом в виде Гугла, позволившего им начать новый язык. Практически всё в Go мне понравилось сразу — и идеология KISS в фундаменте дизайна, и отталкивание от практического опыта, а не от теоретических выводов PLT, и очень низкий порог входа — вобщем, буквально за несколько часов я уже чувствовал, что язык знаком давным давно, а еще через пару вечером уже мог писать production-level код. И всё это с фантастическим тулингом, возможностями по профайлингу, оптимизации, тестированию и прочему.
В Go почти каждый аспект ежедневной работы, который раньше отнимал минуты и часы, стал занимать секунды. Я снова смог сконцентрироваться на написании кода, а не на борьбе с инструментами. Мой первый серьезный stress-тест для Go был на одном международном мероприятии, где мне понадобилось написать софт, который бы парсил псевдо-зашифрованный протокол, вычленял из него 60-кб xml-пакеты, разбирал их, извлекал нужные данные, кормил их небольшой стейт-машине, и генерировал выходные данные, отдавая в консоль, в файлы, и, желательно — на веб-интерфейс по веб-сокету.
Этот код я писал на коленке, и на Go (и это еще по ходу изучения stdlib) это заняло у меня около суток — большая часть времени ушла на разбирание протокола. Но я ни на минуту не отвлекался на проблемы языка, на лишние обертки и геттеры/сеттеры, на то «как это делать по-правильному» и «как выравнивать отступы». При этом я тут же создавал для каждой функции тесты — благо, это занимало не больше пары минут.
И это был реально глоток свежего воздуха после последних лет мучений с С++ и Python. Я снова получал удовольствие от самого процесса написания кода, и я был чертовски продуктивен. Сперва я сам не поверил, что вот эту, хорошо структурированную программу (там было 5 пакаджей, из которых два — эмуляторы источника данных и прокси-дупликатор), покрытую тестами, документированную(!), понятную и читабельную — я написал почти за сутки, и это при том, что я походу еще и открывал для себя новые библиотеки stdlib, изучая документацию. При этом я совсем не хардкорщик с феноменальной памятью, и не набираю на клавиатуре 800 символов в минуту.
И меня ошеломило, когда я попытался представить, сколько времени у меня ушло бы на подобную по качеству и понятности реализацию на С++.
Эта программа работает, кстати, до сих пор, на нескольких точках, и работает как часы. А да, и писалась она на макоси, а работать должна была на windows.
Но к чему я это всё вспомнил? Сейчас я использую Go ежедневно, в нескольких больших проектах, и всё также ежедневно наслаждаюсь огромной продуктивностью, которая появилась в Go. Если вы цените выражение «время — деньги», то продуктивность тут — прямой синоним слова «деньги». Для меня, по крайней мере.
Само собой, я хочу этим делиться с коллегами, друзьями и остальными — помогать людям тоже открывать для себя эти возможности. Я ведь тоже Go для себя открыл внезапно, просто наткнувшись на какой-то интересный пост в блоге.
И вот, на фоне всего этого, подходит коллега или анонимус в интернете, и говорит — Go — сакс, потому что «там нет эксепшенов»/«там нет generics»/«там нет динамической линковки»/«там нет Хиндли-Милнера» etc. И ты такой, стоишь и думаешь первым делом — «стоп, а как же я без этого жил, если для человека это блокер?». Начинаешь глубже разбираться в теме, и понимаешь, что речь лишь о привычке. Кто-то потратил буквально годы жизни, чтобы научиться правильно использовать исключения, или решил, что программирование шаблонами — это некая ступень в программировании, ниже которой опускаться нельзя. И человек не готов отказаться от привычки, и тратит мое и свое время, чтобы мне доказать — что «да пошла она твоя продуктивность, главное — это наличие generics».
И тут ты второй раз думаешь — «блин, ну может я и вправду что-то не понимаю.». Читаешь, разбираешься в теме еще глубже — вроде понятно, какие реальные юз-кейсы. И думаешь — ну окей, ну могут быть, действительно, случаи, где было бы хорошо (но не обязательно) иметь встроенные генерикс — но готов ли ты пожертвовать субсекундной компиляцией? Или кроссплатформенностью? Или понятностью системы типов? Готов ли пожертвовать продуктивностью — которая есть результат совокупного дизайна всех аспектов языка, ради того, чтобы появилась возможность делать задачу, которая реально еще даже не встречалась ни разу, на 10 строчек короче?
И я точно знаю, что нет, не готов. Если кто-то придумает как в Go сделать генерики, не ухудшая всю эту радость — супер, все только за будут. Но пока никто не придумал, и этому есть реальная причина.
Извините за длинный комментарий, но как-то так.
Мне кажется это ведь просто — если программист и вправду жить не может без generics и считает, что это обязательный атрибут современного программирования — то должно быть легко вспомнить реальный случай и привести его в пример.
Просьбу эту заминусовали, вместо того, чтобы дать ответ по сути. Показательно, по-моему.
И это лишь подтверждает чисто теоретическую тему спора. На практике отсутствие generics в Go никак не мешает писать очень качественный код.
В том-то и дело, что interface{} не используется «активно». Даже проскакивает периодически в статьях для новичков — мол, interface{} в большинстве случаев вам не нужен, не лепите его где не нужно.
Я абсолютно согласен со всеми утверждениями про «в Go полу-статическая, полу-динамическая типизация» — но у меня нет в голове стереотипов, заставляющих записывать это сразу в минус. И против реализации generics темплейтами тоже ничего особо не имею (кроме того, что откуда-то берется стимул их использовать по любому случаю, и код становится почти не читабельным, и уж совсем не-дебагельным) — но я понимаю и разделяю позицию авторов Go.
Autoboxing/unboxing — это не оверхед?
Сначала на С, потом (и в основном) на С++, потом ушел на Python, который чуть упростил жизнь, но по понятным причинам это был несправедливый размен. А потом наткнулся на Go и буквально через пару вечеров смог писать production-level код. Так что для меня Go — это полноценная замена С++, которым я был недоволен по многим пунктам, но альтернативы которому особо не было.
Кстати, возможно мне так просто понимать позицию авторов Go по многим вопросам, потому что моя причина ухода от С++ совпала с причинами появления Go.
Чуть ниже запостили ссылку на отличный сводный док по тому, какие есть реальные применения generics и как эти же задачи решаются в Go без generics (и это не тоже самое, что «обходится») — рекомендую почитать всем в этой ветке.
И я хочу все таки обсудить реальные блокеры без generics, а не «полезно» или «так будет чуть лучше». Потому что это «чуть лучше», с учетом тех потерь, которые принесет реализация генериков в языке, станет «много хуже» в общем.
Просто расскажите о реальном куске кода, где без generics — ужасно, некрасиво, костыли и так далее. Ну серьезно, это не должно быть проблемой. Будет тема для более предметного обсуждения хоть.