В Go нет шаблонов. Ряд контейнеров встроен в язык (вектор и map), но всем не хватает шаблонов. Так как очень часто требуется несколько разных типов, но с одинаковыми обработчиками. И многое другое.
Хорошо, а как вы оцениваете выразительные фичи Перла? Например, всем известная программа: $??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see
Очень выразительно, не правда ли?
Разработчики Go, я так понимаю, пошли иным путем. Если тебе нужно сделать парсер, то воспользуйся специальным инструментом, например, flex/bison.
Когда компилируется большой проект, компилятор может сотни (или тысячи) раз компилировать один и тот же заголовочный файл. А если этот файл содержит в себе сложные шаблонные конструкции? Тут спасает только прекомпиляция заголовков, когда компилятор один раз компилирует все часто используемые большие заголовочные файлы, а потом просто использует полученный код при компиляции исходников.
Чем вам шаблоны не угодили? Шаблоны это мощнейшая фича С++, которая позволяла делать на нем то, что язык изначально не поддерживал (STL, например).
Подозреваю, что не видно, так как не нужно.
Кто сказал, что аналог должен обладать той же скоростью работы? Он должен выполнять ту же функцию.
Просто в Go программа получается легко читаемой. Берешь кусок кода и почти сразу понятно, что он делает. На том же С++ это совсем не обязательно (например, если взять кусок кода с декларацией парсера через boost::spirit, особенно, если для сокращения писанины активно использовался using).
Для С возможно. Для С++ другого пути нет, ИМХО. Так как С++ очень сложный язык, компиляция программы, которая активно использует шаблоны (тот же буст), это вообще тушите свечи — компилятор зашивается из-за объемов разворачиваемых шаблонов. Одно спасение — прекомпилированные заголовки. Но блин, как-то это все криво. Вообще, заголовочные файлы (как и препроцессор) это страшный анахронизм Си, не в последнюю очередь из-за которого страдает развитие С++.
Тут речь в первую очередь про экспорт шаблоных функций. Что вообще изначально было криво. А то что C++ ABI не совместим у разных компиляторов известно очень давно.
Основная масса API — имеет интерфейс С. И вот его обернуть во все, что угодно, проблем нет.
А что с Go? Там просто многие привычные подходы поставлены с ног на голову. Все на С++ привыкли, что берем библиотеку, наследуемся от базового класса и юзаем производный. В Го все иначе. Библиотеки объявляют необходимый им интерфейс, а ты в программе уже пишешь класс (структуру), которая соответствует этому (возможно, не только этому) интерфейсу.
Да, в Go не хватает дженериков. Из-за этого ряд задач решается неэффективно или муторно.
Легко. У Go есть интерфейсы и рефлексия. sync.Map же как-то написали. Другое дело, что по сравнению с дженериками он сильно проиграет по скорости работы и выразительности использования (дженериков реально в Go не хватает). Но поставленную задачу на нем сделать можно.
Про eDSL ничего не скажу. Я бегло посмотрел что это, разбираться не стал. Скорее всего, это на Go сделать нельзя. А вот задачу, которую решают с помощью eDSL решить на Go можно. Другое дело, может быть это будет не так эффективно или не так выразительно.
Вы видимо меня не совсем верно поняли. Когда подключаете заголовочный файл от старого проекта, то этот заголовочный файл интерпретируется как не соответствующий новому стандарту. Как вариант, можно реализовать через модуль (юнит). Т.е. старый кусок кода собирается в модуль, экспортирующий интерфейс в современном виде. Накладных расходов в рантайме я не вижу. А уж про ABI так вообще молчу. Причем тут двоичная совместимость? Речь идет про фронт компилятора, а бэк можно и старый оставить.
Никто не мешает сделать эту совместимость частичной. указываешь номер стандарта в первой строчке исходника и все. Если не указан, то считается последний стандарт с поддержкой си.
А зачем считывать все при перемещении в конец? Если речь про обычный файл, то делаем lseek на -n байт от конца и парсим строки. Если недостаточно — еще откатываемся назад. Это сложнее, конечно, но быстрее работает. Меня в less это убивает — очень долго в конец переходит…
Если честно, я вообще не вижу смысла в вашем коде. Так как вторая проверка статуса имеет смысл только внутри первой.
А причем тут вообще while (cond) {… break; }?
Зря отказались от методов в пользу обычных функций. Большинство компиляторов оптимизируют их по разному. В частности, указатель this хранится и передается в отдельном регистре, который у обычных функций для этих целей не используется. В обычной жизни разницу не заметить, конечно, но высоко нагруженные и имеющие множественые вызовы методов одного класса программы будут иметь заметную разницу в скорости.
Очень выразительно, не правда ли?
Разработчики Go, я так понимаю, пошли иным путем. Если тебе нужно сделать парсер, то воспользуйся специальным инструментом, например, flex/bison.
Чем вам шаблоны не угодили? Шаблоны это мощнейшая фича С++, которая позволяла делать на нем то, что язык изначально не поддерживал (STL, например).
Кто сказал, что аналог должен обладать той же скоростью работы? Он должен выполнять ту же функцию.
Просто в Go программа получается легко читаемой. Берешь кусок кода и почти сразу понятно, что он делает. На том же С++ это совсем не обязательно (например, если взять кусок кода с декларацией парсера через boost::spirit, особенно, если для сокращения писанины активно использовался using).
Основная масса API — имеет интерфейс С. И вот его обернуть во все, что угодно, проблем нет.
Да, в Go не хватает дженериков. Из-за этого ряд задач решается неэффективно или муторно.
Про eDSL ничего не скажу. Я бегло посмотрел что это, разбираться не стал. Скорее всего, это на Go сделать нельзя. А вот задачу, которую решают с помощью eDSL решить на Go можно. Другое дело, может быть это будет не так эффективно или не так выразительно.
А причем тут вообще while (cond) {… break; }?