Здравствуйте, меня зовут Дмитрий Карловский и я.. изобрёл $mol только для того, чтобы ваши глаза кровоточили, глядя в его код. Во всяком случае, такое ощущение может сложиться, если почитать разного рода околоJSНые чаты, но не обращаться к первоисточникам, где все технические решения вытекают из чисто прагматических рассуждений. Один из таких анализов позвольте представить вашему вниманию.

Способы записи

camelCase

Традиционно используются в именах переменных и полей во многих современных языках.

❌ Требуется много нажатий шифта вовремя.

❌ слипшиесяСловаТрудноЧитать.

❌ Проблемы с аббревиатурами: sdpFmtpLine, encodeURICoponent.

❌ Имеет проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

PascalCase

Традиционно используются для имён классов и глобальных неймспейсов.

❌ Требуется много нажатий шифта вовремя.

❌ СлипшиесяСловаТрудноЧитать.

❌ Проблемы с аббревиатурами: XMLHttpRequest, HTMLBRElement, IDBOpenDBRequest, RTCDTMFSender.

❌ Одноимённые имена файлов могут вызвать проблемы в не чувствительных к регистру файловых системах.

❌ Проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

lowercase

Традиционно используется для имён нативных событий в браузере.

❌ слипшиесясловатрудночитать.

❌ проблемы с аббревиатурами: onicegatheringstatechange.

UPPERCASE

Традиционно используется для cтандартных элементов в некоторых DOM-API (tagName, например)..

❌ СЛИПШИЕСЯСЛОВАТРУДНОЧИТАТЬ.

❌ Требует временного включения caps lock при вводе или зажатия шифта.

❌ проблемы с аббревиатурами: BGSOUND.

❌ Текст с малым числом выносных элементов сложно воспринимать: FIGCAPTION.

❌ Одноимённые имена файлов могут вызвать проблемы не чувствительных к регистру файловых системах.

❌ Имеет проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

kebab-case

Традиционно используются для имён в HTML, CSS, Lisp, а также в именах файлов.

❌ Редакторы не считают эти имена единым именем (выделение даблкликом, ctrl+стрелка и тп).

❌ Не допустимо в большинстве языков программирования.

❌ Имя получается на несколько символов длиннее.

❌ Лишние символы ломают Fuzzy Search в IDE/DevTools, так как они не встречаются в пути.

SHAWERMA-CASE

Традиционно используются для имён нестандартных элементов в некоторых DOM-API (tagName, например).

❌ Редакторы не считают эти имена единым именем (выделение даблкликом, ctrl+стрелка и тп).

❌ Не допустимо в большинстве языков программирования.

❌ Требует временного включения caps lock при вводе.

❌ Имя получается на несколько символов длиннее.

❌ Текст с малым числом выносных элементов сложно воспринимать: ACME-TOOLBAR-DROPDOWN.

❌ Лишние символы ломают Fuzzy Search в IDE/DevTools, так как они не встречаются в пути.

❌ Одноимённые имена файлов могут вызвать проблемы не чувствительных к регистру файловых системах.

❌ Имеет проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

snake_case

Традиционно используются в "олдскульных" языках (C, C++, Rust, Erlang, OCaml) и языках с упором на читаемость (Ruby, Python) для локальных имён и имён полей.

❌ требуется_много_нажатий_шифта.

❌ Имя получается на несколько символов длиннее.

❌ Лишние символы ломают Fuzzy Search в IDE/DevTools, так как они не встречаются в пути.

Cobra_case

❌ Требуется_много_нажатий_шифта.

❌ Имя получается на несколько символов длиннее.

❌ Лишние символы ломают Fuzzy Search в IDE/DevTools, так как они не встречаются в пути.

❌ Одноимённые имена файлов могут вызвать проблемы не чувствительных к регистру файловых системах.

❌ Имеет проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

SCREAM_CASE

Традиционно используется для констант.

❌ Требует зажатия шифта при вводе.

❌ Имя получается на несколько символов длиннее.

❌ Текст с малым числом выносных элементов сложно воспринимать: SVG_MORPHOLOGY_OPERATOR_UNKNOWN.

❌ Лишние символы ломают Fuzzy Search в IDE/DevTools, так как они не встречаются в пути.

❌ Одноимённые имена файлов могут вызвать проблемы не чувствительных к регистру файловых системах.

❌ Имеет проблемы с наложением стилей в CSS (в зависимости от типа элемента и типа селектора стиль может не примениться).

Смешение стилей

Традиционно проявляется при попытке использовать традиционное именование для каждого языка по отдельности. В разных местах одна и та же сущность имеет разное форматирование имени.

❌ Требуется дополнительное ментальное напряжение на ассоциацию и конвертацию разных форматов одного имени.

❌ Тут и там необходимы конвертации между стилями написания.

❌ Не везде возможна автоконвертация. Например в TypeScript на уровне типов такое затруднительно.

❌ Поиск всех вхождений одного имени в проекте приходится повторять для каждой формы написания.

❌ Суммирует недостатки всех употребляемых стилей.

Нативные API

Web API развивались стихийно, так что не стоит удивляться необоснованному разнообразию форматов имён в разных местах:

  • JS:

    • PascalCase — классы

    • camelCase — поля, функции

    • lowercase — события

    • SCREAM_CASE — константы

  • CSS: kebab‑case везде

  • HTML:

    • lowercase — стандартные элементы и атрибуты

    • kebab‑case — нестандартные элементы и атрибуты

Отдельно стоит отметить смешение стилей, ведь одна и та же сущность может именоваться по разному в разных языках:

  • Имена стандартных элементов:

    • JS: lowercase, UPPERCASE, PascalCase

    • HTML: lowercase

    • CSS: lowercase

  • Имена нестандартных элементов:

    • JS: kebab‑case, SHAWERMA‑CASE, PascalCase

    • HTML: kebab‑case

    • CSS: kebab‑case

  • Имена атрибутов:

    • JS: camelCase, lowercase

    • HTML: kebab‑case, lowercase

    • CSS: kebab‑case, lowercase

  • Имена CSS‑классов:

    • JS: camelCase

    • HTML: kebab‑case

    • CSS: kebab‑case

Особняком стоит химерное именование констант типа SVG_MARKERUNITS_USERSPACEONUSE.

Рекомендации

✅ Оптимальный выбор - snake_case, как наиболее удобочитаемый и наименее проблемный.

Соглашения в $mol

  • snake_case — любые имена в XHTML и CSS, локальные имена в JS

  • Cobra_case — имена локальных фабрик в JS

  • $nake_case — глобальные имена в JS, соответствующие FQN.

Послесловие

Надеюсь этот разбор будет для вас полезным, даже если выводы окажутся совсем иными.


Актуальный оригинал на $hyoo_page.

Комментарии (19)


  1. VaalKIA
    00.00.0000 00:00
    +6

    В статье вы пишите, что разные стили используются для разных сущностей, а в голосовалке предлагаете голосовать за один для всех... facepalm

    Я использую PascalCase для процедур и функций и snake_case для переменных. Если бы я использовал camelCase тогда бы процедуры и переменные состоящие из одного слова невозможно было бы различить (camal процедура и snake переменная).

    P. S. 1. "СлипшиесяСловаТрудноЧитать", не соглашусь, 90% времени они используются как токен, подошла бы даже картинка, это не художественный текст, что-то у вас не так с критериями.

    1. " Одноимённые имена файлов" Шта?! Какое отношения имена файлов имеют к языку?

    2. "CSS" Мы о языках программирования или о чём?

      какая-то дичь, дальше анализировать не стал.


    1. nin-jin Автор
      00.00.0000 00:00

      В голосовалке можно выбрать несколько вариантов.

      Как токен воспринимаются лишь частоупотребимые словосочетания сильно отличающиеся от других. В остальных 90% случаев таки приходится читать что там написано.

      Имена файлов часто встречаются в коде, а файлы часто именуются в соответствии с содержащимися в них сущностями.

      Мы о компьютерных языках.

      Время, которое вы потратили на комментарий, лучше бы потратили на чтение - пользы больше было бы.


  1. LyuMih
    00.00.0000 00:00

    После дофигаЛет JsReact вчера пришлось с удивлением познакомиться на питоновскую_змею в переменных


  1. ILaeeeee
    00.00.0000 00:00
    +1

    Использовал Camel, пока не появился как то проект со множеством сущностей и сложными алгоритмами, где нужно было очень досконально и длинно назвать переменные и методы, иначе они спутывались. В итоге, перешел на Snake, можно сказать вынужденно, т.к. из всех вариантов этот наиболее лёгким для моего восприятия оказался.

    Сейчас я ещё из БЭМ фишку взял, как модификатор (в моём варианте "__модификатор"). Когда нужно немного разграничить похожее, типа: person_post__title, person_post__description (это когда нет функционала сложных переменных, или их использование нецелесообразно).


  1. Proydemte
    00.00.0000 00:00
    +1

    Сделать анализ наиболее часто используемых библиотек в вашей области и использовать подобный стиль.


    Лично я за camelCase, по историческим причинам, snake_case ассоцируется со всякими php и то. и даёт подсознательное ощущение кода низкого качества (ощущение, не значит что код и правда плохой).


    PS. Забыли добавить ещё про всякие префиксы, суффиксы, венгерские нотации и т.п.


  1. CTheo
    00.00.0000 00:00
    +2

    Для меня основной аргумент против camel_case - подчеркивание слишком путается с точкой. Сравните:

    Red.GreenBlue = 0
    RedGreen.Blue = 0
    red_green.blue = 0
    red.green_blue = 0


    1. kablag
      00.00.0000 00:00
      +1

      программисты на R плачут :)


      1. light_and_ray
        00.00.0000 00:00
        +1

        Программисты на R всегда плачут


  1. adeshere
    00.00.0000 00:00
    +2

    Если правильно понимаю, в современных языках имена функций и переменных чаще всего регистрозависимы? Тогда мой лайфхак с функциями мало кому поможет. Но кому-нибудь может и пригодится, так что

    все-таки напишу.

    У меня фортран, и он к регистру нечувствителен. Вдобавок моя IDE не показывает определение функции, когда в коде встречается ее вызов, и я не могу перейти к описанию/телу функции одним кликом. А это часто бывает нужно.

    В результате я сформировал такой стиль: при вызовах функций в программе я пишу мнемонически наиболее удобочитаемое имя (сначала это был snake_case -стиль, сейчас предпочитаю PascalCase, но старые библиотеки пока еще не все отрефакторил). А в шапке-описании функции (которая у меня всегда стоит перед телом функции) и в теле функции ее имя написано UPPERCASE (если необходимо - с подчеркиванием).

    Например

    Описание и тело функции:

    C.....LOGICAL*4 ALL_SYMBOLS_IN_SET(STRING,SET)....................C
    C                                  c*(*) c*(*)                    C
    C     Функция ALL_SYMBOLS_IN_SET проверяет, что в строке STRING   C
    C  встречаются ТОЛЬКО символы из набора SET и пробелы             C
    C.................................................................C
          LOGICAL*4 FUNCTION ALL_SYMBOLS_IN_SET(STRING,SET) 
    .....

    Использование:

    ...
    if (.not. all_symbols_in_set(search_string,'*<>=+-0123456789.,eEdD'))then
    ...

    Когда мне нужно посмотреть описание функции, я выделяю ее имя и делаю глобальный поиск. В окошке с результатами поиска строчки с капслоком сразу же выделяются визуально (т.к. все остальные преимущественно в нижнем регистре). Остается кликнуть по нужной строке и открыть окно с описанием функции.


  1. gev
    00.00.0000 00:00
    +4

    Мне нраввится вот такой стиль:

    music = Rock'n'Roll
    f' x = x 

    =)


  1. ajratr
    00.00.0000 00:00
    +3

    В статье, все способы имеют только минусы. А потом опа, нате ... из под кровати, змея оптимальный выбор. Почему?

    Такое ощущение, что автор писал, держа что то в голове и считает, что об этом всем известно. У меня машинка для чтения мыслей в ремонте. Может как то подробнее про змею развернете?


    1. nin-jin Автор
      00.00.0000 00:00
      -2

      Там же написано почему.


      1. ajratr
        00.00.0000 00:00

        Наверное конец дня и голова плохо работает. Толи я как то не туда смотрю. Может я не в теме и контекста не вижу. Но всё же. Где там?


        1. nin-jin Автор
          00.00.0000 00:00
          -3

          Ложитесь лучше спать, утро вечера мудренее.


          1. ajratr
            00.00.0000 00:00
            +1

            Вы ушли от ответа, на казалось бы простой вопрос. Где там?


      1. dynamica
        00.00.0000 00:00
        +7

        Оптимальный выбор - snake_case, как наиболее удобочитаемый и наименее проблемный.


        Худший выбор - snake_case, так как наимение читаемый и наиболее проблемный.

        Раунд.


  1. uvelichitel
    00.00.0000 00:00

    А мне вот и не приходилось "предпочитать" кейс. Его определяли идиоматика языка( Python<PEP8>, Go<https://go.dev/doc/effective_go#mixed-caps>, Haskell), стиль проекта или культура компании...


  1. funca
    00.00.0000 00:00

    Можно вспомнить ещё JSON, который часто используется как формат обмена данными. snake_case в назначениях ключей объектов увеличивает размер передаваемых данных на ровном месте. camelCase компактнее за счёт отсутствия символов подчеркивания.

    Когда этот JSON записывается в логи, а логи нужно где-то хранить, то разницу в размере видно невооружённым взглядом, просто по счетам за сторадж.

    Если серьезно, используйте тот стиль, который наиболее употребим на конкретной платформе. Даже если он лично вам по каким-то причинам кажется не оптимальным. Вы же не в вакууме пишете - унификация даст гораздо больше преимуществ.


  1. NeoCode
    00.00.0000 00:00
    +1

    Обычно использую camelCase (для переменных/полей+методов) или PascalCase (для типов). В основном ориентируюсь на стиль Qt, т.к. нередко его использую. Слипшиеся слова как раз не трудно читать, просто не нужно делать их слишком длинными. Трудно - разлипшиеся, имя не воспринимается как единое целое, текст программы "обедняется" за счет использования только одного регистра вместо двух. Но к сожалению в С++ это почему-то стандартный формат для библиотек.