Информация
- В рейтинге
- 1 860-й
- Откуда
- Санкт-Петербург и область, Россия
- Зарегистрирован
- Активность
Специализация
Бэкенд разработчик
Ведущий
C#
Java
Rust
Golang
Многопоточность
C
Системное программирование
Разработка игр
Unity3d
Алгоритмы и структуры данных
В том что
impl X- это не тип а выражение вида какой-то тип реализующий ограничениеX. Это не имеет никакого отношения к языкам с наследованием типов где передача типа туда где нуженXозначала бы приведение дочернего типа к родительскому. Здесь никакого приведения кXнет, потому что это даже не тип.Могут ответить аналогичным образом - не нужно везде видеть ООП. Трейты в Rust это по сути классы типов вдохновленные Haskell, синтаксическая схожесть с интерфейсами не делает их таковыми.
На эти вопросы давно даны ответы как со стороны сообщества:
Так и с официальной стороны:
В официальных руководствах прописано - нет в Rust нет наследования. Не нужно пытаться его там видеть.
Согласен что это вопрос терминологии но все же в Rust нет того что привычно называют наследование в других языках а именно иерархической системы наследования типов.
Вот допустим есть у нас несколько трейтов и структура:
Теперь мы хотим реализовать User для Player и подразумеваем что User наследует Identifiable и соответственно расширяется всеми его методами и должно быть что-то наподобии:
Нас наругали, потому что несмотря на то что вроде бы User должен расширяться от Identifiable, это не так, он перенял только ограничения а не его методы. Ну оке премудрости Rust:
Окей, все работает. Попробуем сделать текст на наследование типов. Опустим момент что структуры никак не могут наследоваться друг от друга, ну допустим у нас только наследование от трейтов работает. Если Player наследуется от User значит вместо любого User можно подставить Player. Проверяем:
Нет нельзя. Но мало того такой код не работает, так еще и компилятор пишет прямо что: нужен тип а найден трейт. Т.е. с точки зрения Rust трейты это вообще не типы.
В сухом остатке имеем:
трейты не наследуются друг от друга а только аккумулируют ограничение
в между трейтом и структурой нет отношения наследования типов
трейт в принципе не является типом
Все встает на свои места если смотреть на это под другим углом. В той же Java или C# интерфейсы - это типы и даже более того классы. Между всеми классами есть отношение наследования благодаря которому наследник перенимает природу родителя как в части данных так и в части поведения. Наследник может быть использован вместо родителя.
Ничего подобного нет в Rust. Есть структуры и есть трейты выступающие контрактами - задача компилятора проверить что типы соответствуют контрактам.
Т.е. Rust решает похожие задачи похожими на вид инструментами но в действительности иным подходом. Можно конечно пытаться натягивать наследование на глобус но мне кажется, в практическом плане, проще смотреть через призму контрактов.
Спасибо за отзыв. Так или иначе, думаю плюсовые шаблоны и эрлановкие clauses можно смело отнести к синтетике на уровне генерации кода.
Не совсем так. Статья широко охватывает чуть более общие понятия реализации актуальные для всех языков. В том числе актуально и для Go в котором используется и мономорфизация для параметрического полиморфизма и упаковка для интерфейсов с использованием таблиц виртуальных функций. Так как в прошлой статье был затронут Go в части утиной типизации, решил и тэги оставить примерно такие же, так как по сути здесь раскрывается как это работает. Просто именно примеров на Go нет но все остальное также актуально. Возможно дойдут руки, напишу статью отдельно для Go, как там все устроено.
Подскажите пожалуйста, чем был обусловлен выбор именно в пользу Zig а не к примеру Rust?
Мне кажется если заменить Rust на Go/Java/C#? в данной ситуации, то судя по описанию результат был бы таким же.
Очень занимательно это читать, учитывая что автор книги давным давно полюбил ФП и пишет на Clojure:
также автор книги раньше утверждал что:
но если зайти к нему на Github то можно увидеть такие функции:
https://github.com/unclebob/skillBoard
Автор уже давно сам своим рекомендациям не следует но вы разумеется следуйте.
Нет, точно также как не могу утверждать что любой код на Go будет такой же читабельный как на C#. Это вообще палка о двух концах. Там где Go будет превосходить в одном месте, из-за этих же качеств будет проигрывать в другом. Уже писал про DSL, там где нужна концентрация на правилах и более высокоуровневой логике а не реализации, Go в хлам проиграет. Другой пример стандартизация. Из-за минимализма, в Go отказались добавлять в стандартную библиотеку и язык многие вещи, которые разработчики вынуждены весосипедить или подключать разношерстные библиотеки. Как итог зоопарк решений вместо единообразия. Разработчики других языков работают с одними и теми же решениями одинаковым образом а в Go работают с зоопарками и велосипедами, где новому разработчику будет проще освоиться на проекте думаю вопрос риторический.
В общем все относительно. Не отрицаю что в Go многое сделано для читабельности но не нужно это гиперболизировать.
Не нужно считать создателей других ЯП идиотами, которые не догадались вернутся в 80-десятые за читабельностью. Любое достоинство вытекает из недостатка и Go не исключение, то что в одном случае будет читабельно и хорошо, в другом превратиться в тыкву. За примером ходить далеко не нужно, любая предметная область где можно зарулить с DSL на Go будет вызывать кровь из глаз. Потому что нельзя победить проблемы просто радикально упоровшись во что-то одно.
У меня недавно был удачный пример, сначала написал приложение на Go, потом по воле обстоятельств пришлось переписать его на C#. Спойлер, чуда не произошло. Проект на C# выглядел заметно приятнее: был минималистичнее, проще и читабельней чем на Go. Это я не про то что Go плохой а скорей про то надоели эти сказки про его ультимативную читабельность.
Многие гоферы охренели после этой новости, а многие назвали это бессилием
На самом деле скорей нет чем да. Все тоже самое можно получить взяв тот же C# к примеру. Сила Go в минимальных сроках его изучения с одной стороны и не дурных характеристиках - с другой. По итогу для компании - это палочка выручалочка. Можно хантить разрабов с других языков и быстро их переучивать на Go.Скилл некромантии. Чтобы дать бизнесу утилизацию ресурсов памяти и процессора, для начала нужно найти ресурсы в виде разрабов.
Говорят, мир где принято делать все правильно и реальные мир иногда не одно и тоже
Kotlin прикольный. Довелось на нем проект написать. Но это по сути джавазаменитель. Да добавили null-безопасность(на которую библиотеки кладут прибор), да более приятный синтаксис и прикольные фичи но... Никаких новых идей или ультимативных киллер-фич, которые бы помогли ответить на вопрос - зачем брать этот язык вместо Java.
Взять тот же Go. Он набрал популярность из-за определенных фич: минималистичность, позволяющая нанимать не только гоферов но и всяких джавистов и очень быстро их переучивать, производительность, решение проблемы асинхронных операций из коробки, на выходе простой бинарник без необходимости морочить голову виртуальными машинами. Это аргументы. А что предлагает Kotlin? Null-safe? Этого мало. Корутины? Так они и так везде есть, так сейчас еще в Java завезли виртуальные потоки. Красивый и удобный синтаксис? Не самый сильный аргумент. Возможность писать все на Kotlin: фронтенд, мобилки, бэкенд и т.д? Хорошая идея, но не взлетело. В немалой степени еще проблема что Kotlin узник JVM и в огромном числе проблема он просто не может перегнать Java. Удел Kotlin по идее - заменить Java, но не смотря не очень существенные успехи, тоже не взлетело в той мере в которой хотелось бы.
По итогу остается послевкусие. Язык то выучен полноценный и время на это потрачено но вот существенной пользы от этого мало.
По джаве да, но и то не всем. По C# большие сомнения. C#/.net с его экосистемой настолько круче Kotlin практически во всем, что я даже не знаю какие мотивы должны быть у человека для того чтобы ему это зашло.
При всех минусах исключений, вот как раз в место нахождения ошибки там полный порядок. В Go все очень сильно зависит от того насколько удачно ошибка написано. Если вам вернется "number is incorrect" - удачи по всему проекту искать хотя бы примерно откуда это прилетело.
Пытаемся удалить файл которого нет:
А что будет если разработчик просто забудет или не увидит что функция возвращает ошибку?
Уже давно, это последовательность байт а не char.
It’s important to state right up front that a string holds arbitrary bytes. It is not required to hold Unicode text, UTF-8 text, or any other predefined format. As far as the content of a string is concerned, it is exactly equivalent to a slice of bytes. Rob Pike.
Это распространенное заблуждение которое кочует из статьи в статью про ФП.
Это не декларативный стиль, это такой же императивный стиль. Вы буквально описали что делать: отфильтровать и затем просуммировать. Просто это спрятано внутри.
Декларативный пример это SQL ил html. Где вообще нет прямой связи между описываемым результатом и тем как это будет достигнуто.
Видно что Вы или редко или не сталкивались с такими задачами. Лично по моему опыту, классическая ситуация, аналитики РП уговорили сделать тяп ляп в 100 строк кода сейчас, потому что сдаем проект через полгода и забываем. На деле, через полтора года - теперь чтобы "переработать под более удачную архитектуру" нужно в 10-15 раз больше времени а исправление багов почему то стало занимать не часы а дни и недели.
Никогда такого не было и вот опять.
В целом если это не оправдано то да. Но часто бывает что с прошлой архитектурой работать очень сложно и неудобно. Работа будет малоэффективной, задачу и баги будут делаться долго. За чей счёт?
А теперь спросите себя насколько создание интерфейса или дописывание в него метода замедляет разработку. На 10-60 секунд? А когда потребуется все таки писать тесты сколько это сэкономит?
Сколько потеряет компания когда их мелки сервис разрастется, когда нужно будет куча ресурсов и в конце концов когда все равно все перепишут на на Go или C# и потратят на это огромную кучу денег вместо того чтобы сделать сразу нормально. Сколько компаний с этим столкнулось и столкнутся.
Никогда такого не было и вот опять.
У Вас противоречие - если тимлид раздает задачи разным людям значит все эксперты в своих областях и рассказываете Вы про человека на котором держится все команда.
В целом со многих согласен. Но...
В статье типичная ошибка - качели в одну сторону. Вы описываете как вредит оверинжиниринг. Но жизнь то вещь сложная и разработка тоже. Нельзя просто "Если возможно написать сервис в 100 строк — лучше написать так ", если бы там все просто было и оверинженерига бы не было а оно рождается из как раз из гипертрофированных попыток исправить тот ад который обычно случается после подобных советов.
Сложность в балансе.
Все это выглядит как лечение симптомов а не причины. Причем лечение симптомов закономерно приводящее к другим проблемам. Начнем с того, что упрощения автора во многих случаях просто делают пресловутую гексагональную архитектуру бесполезной. К примеру, он предлагает делать прямые вызовы репозиториев, при этом не задумываясь зачем вообще репозитории чаще всего спрятаны и к каким проблемам это может привести. Немножко подумаем и поймем что репозиторий можно отдавать только на чтение. Почему? Потому что если мы позволяем модифицировать данные в любом месте проекта то весь смысл слоеной архитектуры, теряется.
Следующий момент который автор не осознает - это аспекты промышленной разработки. В реальности, когда над проектом работают несколько человек то важнейший аспект это простота и единообразие подхода. К сожалению или счастью, средний разработчик не искушен понимание архитектурных изысков и уместности и давать ему возможность делать на своей усмотрение - плохая затея. Проект очень скоро будет представлять из себя клубок запутанного кода. Каждый разработчик как уникальная снежинка начнет делать по своему. Намного лучше тупо писать эти интерфейсы везде к примеру и где-то писать больше кода, чем заставлять среднего разраба вставать перед выбором писать или нет а другого разраба пытаться понять чем руководствовался первый.
Другой намного более важный вопрос которым стоит задаться: гексагональная архитектура - это вообще корректный подход к разработке плюсы которого перевешиваю минусы? Если немного отстранится от хайпа и карго культов, мы имеет сильно овер-инженерный подход, который даже "по учебнику" получается не очень и предлагается интерпретировать все правила вольным для каждого разработчика образом походу теряя те преимущества которые данный подход обещал. Может быть немного притормозить и оглянутся по сторонам?
А если ошибки нет и просто что-то не работает не подавая виду не нужно будет SpringBoot по запчастям разбирать чтобы понять что не так попутно гадая на картах?
Видно не сталкивались с проблемами которые легко не выясняются.
А то что мы вместо того чтобы писать решение занимается бюрократией с вызовом
расовоправильных видов синтаксиса это мы так ценность вносим?Но, есть и обратная сторона. В той же Java из-за многословности разработчики понапридумывали костылей. Ладно Lombok если более менее на кодогенерации работает и предсказуем. Но огромная часть Java это дикое количество АОП. И вроде бы язык не самый вариативный а приложения порой работают также непредсказуемо как на JS, когда в рантайме выясняется что нет какого-то класса потому что версии библиотек не сошлись. Одного языка мало, нужна еще и адекватная экосистема.
Простой вопрос - зачем? Единственное что приходит на ум это то что разработчики не знают язык на котором пишут, ну тогда и меры другие нужно принимать наверное.
Если бы было так то все бы писали на Haskell или Rust.
Я так до конца и не понял статья шуточная или на полном серьезе.