А если вы делаете рефакторинг, например, «AsyncProducer» переименовываете в «AsyncFactory», имена ресиверов тоже автоматически изменяются или это надо делать вручную?
Я, кстати, про runtime изначально ничего не говорил.
В Go главным образом используются проверки на этапе компиляции. Посмотрел, в Wikipedia даже есть пояснение на этот счет:
Duck typing is similar to, but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time.
The OCaml, Scala, Go, Elm, and Gosu languages support structural typing to varying degrees.
Which is better? There are advantages to both approaches. Structural typing is arguably more flexible — one common complaint in JavaLanguage… On the other hand, it is very common that two objects that are structurally equivalent are semantically different...
Если класс реализует нужный вам интерфейс правильно — то неважно: хотели ли его реализовать или «так случайно получилось».
На самом деле это важно. Реализация интерфейса предполагает выполнение заявленного контракта по этому интерфейсу.
Если просто удачно совпадают сигнатуры методов, то это абсолютно не означает, что методы будут работать так, как может быть задумано каким-либо интерфейсом.
Кстати, в Питоне похожая ситуация с возможностью именования. Однако, так на этот счет есть рекомендация:
...Often, the first argument of a method is called self. This is nothing more than a convention: the name self has absolutely no special meaning to Python. Note, however, that by not following the convention your code may be less readable to other Python programmers, and it is also conceivable that a class browser program might be written that relies upon such a convention...
У этого объекта, в отличие от других доступы приватные поля, например. По отношению к этому объекту нарушается (может не использоваться или не подходит) инкапсуляция.
Я не говорю, что это проблеме нерешаемая. Я хочу сказать, что этой проблемы в принципе могло не быть.
Сделали, ведь, gofmt — решили проблему на канонический формат кода. Могли бы и не делать gofmt, тоже решали бы эту проблему (правда, каждый по-своему).
Ну есть разные варианты, в т.ч. явно в комментариях каким-либо образом описать свои намерения. Но в том же Java, например эта проблема решена на уровне языка.
Или это может быть решено с помощью тестов на интерфейс, в котором так же будут описаны и намерения, и проведена проверка на корректность имплементации интерфеса.
Может быть частично проблему решает и упомянутый Oracle.
Понятно, что авторы Go хотели «как лучше», но это «как лучше» тоже без последствий не обошлось.
Вы выше написали: «что нам в рабочем code style напридумывали люди с полугодом опыта в golang, но зато с десятком лет в java, c или perl».
В моем понимании, это следствие того, что в java, с++, js этой свободы нет (и не надо) и программисту не нужно задумываться, как назвать receiver. Обычно при написании кода есть, над чем подумать более полезном. А задумываться, как называть receiver — это трата времени и снижение эффективности.
В Go ведь сделали штатный форматер кода? Да, это отлично, вероятность различия формата минимизирована.
Так же есть рекомендации по названию интерфейсов, например. Тоже хорошо.
Но свобода в именовании ресивера по факту — это заусенка в языке, которая тяготит и может стать источником конфликтов в команде и становится, как у вас.
Из опыта/пожеланий могу сказать еще несколько пунктов.
1. Все же отсутствие возможности (необходимости) задекларировать реализуемый интерфейс ухудшает естественную документируемость кода. Это важно при чтении кода.
2. Возможность произвольно назвать receiver в методе (это, например, «v» в func (v Vertex) Abs() float64 ..) по факту приводит к разнобою в именовании этих receiver-переменных в разных местах. По-моему, в этом месте дана ненужная свобода. Лучше бы чего-то зарезервировали или советовали бы использовать одинаковое название. Сейчас имеется разнобой и необходимость задумываться, а как назвать эту переменную — лишняя трата времени.
3. Думаю, было бы здорово иметь возможность писать комментарии в Markdown (как в Rust, например).
Я не могу себе представить как кто-то, кто разрабатывает на Go предложит настолько радикально и калечаще поменять нечто, что совершенно не важно для тех, кто этот код на самом деле пишет.
Хочу заметить, что переход стиля от одного к другому может быть полностью автоматизирован (руками ничего переименовывать не надо). Можно даже сделать форк на эту тему.
хочу как в питоне
Про питон особо не знаю, скорее как в JavaScript.
Естественно, вероятность принятия такого решения стремится к нулю. Я скорее хотел узнать, тяготит ли такое соглашение еще кого-то.
А если новое имя конфликтует с переменными в функции, то еще и их нужно переименовать.
Я, кстати, про runtime изначально ничего не говорил.
В Go главным образом используются проверки на этапе компиляции. Посмотрел, в Wikipedia даже есть пояснение на этот счет:
Duck typing is similar to, but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time.
The OCaml, Scala, Go, Elm, and Gosu languages support structural typing to varying degrees.
Причем здесь Duck typing?
Речь идет о Structural type system против Nominal type system.
См., например, Nominative And Structural Typing.
Which is better? There are advantages to both approaches. Structural typing is arguably more flexible — one common complaint in JavaLanguage… On the other hand, it is very common that two objects that are structurally equivalent are semantically different...
Вот о чем я говорю.
На самом деле это важно. Реализация интерфейса предполагает выполнение заявленного контракта по этому интерфейсу.
Если просто удачно совпадают сигнатуры методов, то это абсолютно не означает, что методы будут работать так, как может быть задумано каким-либо интерфейсом.
На примере стандартной библиотеки можно увидеть, что не всегда это соблюдается.
Где-то пишут так:
а где-то так:
Но очевидно, что такое правило приводит еще к паре неприятных случаев.
Первый — это использование «i» в качестве ресивера, переменной, которая обычно применяется в циклах.
Второе — это использование «l» в качестве идентификатора. За такое нужно бить сильно и больно по пальцам (за сходство с цифрой 1):
Кстати, в Питоне похожая ситуация с возможностью именования. Однако, так на этот счет есть рекомендация:
...Often, the first argument of a method is called self. This is nothing more than a convention: the name self has absolutely no special meaning to Python. Note, however, that by not following the convention your code may be less readable to other Python programmers, and it is also conceivable that a class browser program might be written that relies upon such a convention...
См. The Python Tutorial: 9.4. Random Remarks
Вот тут вы что имеете в виду?
И это касается только вашего кода или вообще любого кода на Go?
Сделали, ведь, gofmt — решили проблему на канонический формат кода. Могли бы и не делать gofmt, тоже решали бы эту проблему (правда, каждый по-своему).
Или, нужно выяснить, имелись ли намерения у автора кода реализовывать какой-то интерфейс или это «случайно получилось».
Ну выше JekaMas упомянул конфликт/спор.
Не скажу, что от свободного именования ресивера только минусы. Естественно, есть и плюсы.
Но по моему мнению и опыту «кодирования в соответствии с рекомендациями от golang» я сделал вывод, что минусов больше, чем плюсов.
А не отмотав к сигнатуре как вы узнаете название ресивера?
Ну есть разные варианты, в т.ч. явно в комментариях каким-либо образом описать свои намерения. Но в том же Java, например эта проблема решена на уровне языка.
Или это может быть решено с помощью тестов на интерфейс, в котором так же будут описаны и намерения, и проведена проверка на корректность имплементации интерфеса.
Может быть частично проблему решает и упомянутый Oracle.
Понятно, что авторы Go хотели «как лучше», но это «как лучше» тоже без последствий не обошлось.
Вы выше написали: «что нам в рабочем code style напридумывали люди с полугодом опыта в golang, но зато с десятком лет в java, c или perl».
В моем понимании, это следствие того, что в java, с++, js этой свободы нет (и не надо) и программисту не нужно задумываться, как назвать receiver. Обычно при написании кода есть, над чем подумать более полезном. А задумываться, как называть receiver — это трата времени и снижение эффективности.
В Go ведь сделали штатный форматер кода? Да, это отлично, вероятность различия формата минимизирована.
Так же есть рекомендации по названию интерфейсов, например. Тоже хорошо.
Но свобода в именовании ресивера по факту — это заусенка в языке, которая тяготит и может стать источником конфликтов в команде и становится, как у вас.
1. Все же отсутствие возможности (необходимости) задекларировать реализуемый интерфейс ухудшает естественную документируемость кода. Это важно при чтении кода.
2. Возможность произвольно назвать receiver в методе (это, например, «v» в func (v Vertex) Abs() float64 ..) по факту приводит к разнобою в именовании этих receiver-переменных в разных местах. По-моему, в этом месте дана ненужная свобода. Лучше бы чего-то зарезервировали или советовали бы использовать одинаковое название. Сейчас имеется разнобой и необходимость задумываться, а как назвать эту переменную — лишняя трата времени.
3. Думаю, было бы здорово иметь возможность писать комментарии в Markdown (как в Rust, например).
Хочу заметить, что переход стиля от одного к другому может быть полностью автоматизирован (руками ничего переименовывать не надо). Можно даже сделать форк на эту тему.
Про питон особо не знаю, скорее как в JavaScript.
Естественно, вероятность принятия такого решения стремится к нулю. Я скорее хотел узнать, тяготит ли такое соглашение еще кого-то.
Т.е. что бы идентификатор _<...> — был приватным, а любой другой — публичным. Ну и тогда название функций можно было бы писать со строчной буквы.
Иными словами, вместо
Хотелось бы видеть:
Кто-то есть с таким же мнением?