Комментарии 105
Что имеется в виду под "Нарушение привычного синтаксического порядка"?
Если порядок как он должен быть в англ. языке, то я часто отхожу от этого порядка ради более быстрого поиска функций в autocomplete.
Например пишите вы:
let job = new Cr...
… и начинаете искать среди кучи сущностей Order, Post, User свой CreateOrderJob
А можно просто написать:
let job = new Or...
… и сразу будет доступен список действий для сущности Order
и в частности OrderCreateJob
, что гораздо удобнее и быстрее, хотя да, по правилам английского языка — неверно.
Ну и в файловой системе всё будет сгруппировано по сущностям.
А я потом читаю Ваш код, натыкаюсь на это — и зависаю.
Думая — «Счет создает работу… угу… Ну вот как это???»
Кроме того, у меня автодополнение по слову Order выдаст в том числе и CreateOrderJob. Я бы в вашей ситуации выбрал правильный с точки зрения языка вариант.
Для группировки в файловой системе есть каталоги. В разных языках тоже часто есть модули, неймспейсы и т. п. чтобы писать, например. Order.CreateJob — тут мозг не ломается, к знакам препинания он привыкший.
Причём незнание необязательно у разработчиков. Бывает бизнес требует имен транслитом в базах и, например, http API ендпоинтах. Ну и по всему приложению они расползаются.
Мне например, венгерская нотация удобна для наименования глобальных переменных, чтобы сразу знать какой тип у неё. Имена локальных пишу прописью без указания типа.
Да и пишу я не на С, но на подобном ему языке (правда, сейчас синтаксис больше похож на Java или С#, во всяком случае года 4 назад синтаксис поменяли, хотя можно писать и на старом).
Префиксы у переменных имеют смысл, если без них возможны конфликты имён.
Например считал я из текстового поля введённое пользователем значение напряжения в переменную txtU в киловольтах. Распарсил её в переменную kvU, а для расчётов сделал ещё одну
vU = kvU*1000;
А потом пришел я и застрелился, потому что в коде тысячи переменных u, U, Us, Uu, uuu, _u etc etc etc.
Так предметную область надо знать. Все однобуквенные обозначения — из предметной области взяты.
Считаем мы, к примеру трансформатор. Что обозначает локальная переменная с именем U?
И, да, я не уточнил — это всё про локальные переменные.
Это в быту "вольтаж" и иже с ним. В предметной области общепринятые буквы.
Мне кажется, логично, что человек, не владеющий предметной областью, не будет допущен до кода, считающего эту самую предметную область.
Вполне может быть допущен, если что-то с кодом сделать надо, а программиста со знанием предметной области под рукой нет.
Тем не менее, мне кажется, что это так себе идея. Там где считают трансформаторы, проблемы со знанием программирования встречаются чаще, чем со знанием предметной области.
Считаем мы, к примеру трансформатор. Что обозначает локальная переменная с именем U?
Вот честно говоря понятия не имею. В трансформаторе напряжений минимум два — входное и выходное. И это только в трансформаторах постоянного тока. А еще бывают переменного тока, в которых разумно считать как амплитудное, так и действующее значение напряжения. А еще трансформатор может быть трехфазным — там напряжений завались. А еще каскадные трансформаторы.
Короче говоря, вы путаете школьные буквенные обозначения в формулах и "обозначения из предметной области".
output_current := input_current * (input_voltage / output_voltage);
Ну и хранить амплитудное значение отдельно от действующего… а зачем? Они же пропорциональны.
Отдельно хранить их и правда мало смысла, но вот понимать какое из двух хранится — нужно.
Сопряжение модулей — это отдельная тема. У меня в Public не торчат ни однобуквенные имена, ни венгерская нотация. Все эти вещи — для использования внутри модуля.
Да, спасибо за исправление, я к сожалению о трансформаторах знаю только то, что они существуют и пару размытых фактов после нескольких недель в универе :)
Ну и хранить амплитудное значение отдельно от действующего… а зачем? Они же пропорциональны.
Как верно заметили выше, в некоторых случаях важно знать, какое из них мы храним (например, для вывода пользователю или для расчетов).
Но когда использование float обходится слишком дорого, можно и указывать размерность в имени макроконстанты, которую потом переводить во внутреннее представление с самыми странными коэффициентами:
#define TIMEOUT_s 100
---
#define TIMEOUT_ticks F_CPU / 65536 / TIMEOUT_s
Если в ТЗ указано, что ввод должен быть в киловольтах — то он будет в киловольтах.
Для расчёта я его, естественно, в систему СИ переведу.
А в процедуре, которая преобразует текстовый ввод в вольты — будут все три названные переменные.
В используемом мной языке это выглядело бы примерно так:
void SomeFunction(%параметры_функции%)
{
...
char sU[32];
GetCmdArg(1, sU, sizeof(sU)); // так, например, получаем строковое значение
int iU = StringToInt(sU) * 1000;
...
}
Ни один из них не распознаётся сразу как целое слово
Почему же? Венгерская нотация — частный случай lowerCamelCase.
Чтобы префиксы читались — нужно уметь их готовить, и быть привычным к языку с разнообразными артиклями (венгерскому например, а я лично — немецкий учил).
Префикс — это как бы артикль, при чтении про себя на него не обращаешь внимания.
Префиксы должны быть простыми (составные префиксы портят всю картину) и служить для классификации объектов.
Ну, положим, btn — кнопки, txt — текст-боксы, cmb — комбо-боксы, lst — списки, и т.п. Нужно это для того, чтобы в IDE, которая сортирует всю эту нечисть по алфавиту, однотипные компоненты собрались вместе.
Другой вариант — физические расчёты. Я в качестве префиксов использовал единицы измерения, чтобы легко было формулы визуально проверять.
По первой части — автор так и написал, со временем вырабатывается привычка и читать становится легче. Не уверен, правда, что я хочу вырабатывать такую привычку.
По второй части — не согласен совсем. Код, написанный математиками и академиками, обычно представляет собой буквенный винегрет, от которого братья мрут пачками. Да, можно возразить про "знайте предметную область". Но обычно код везде такой. Видимо, если начал использовать однобуквенные переменные — то уже не остановиться, даже для "нормальных" сущностей. Да и к тому же, моё знакомство с подобным кодом обычно происходит в сценарии "у нас есть код, он тормозит (крашится/невозможно добавить фичу), можешь помочь?". Да, могу… открываю проект и чувствую, как седею.
напрягает только сокращение
Они стандартны. Содраны у мелкомягких в чистом виде.
На счёт единиц суффиксами — вы правы. Так действительно лучше.
составные префиксы
А вот это я считаю — против самой идеи. Префиксы не должны быть составными и их должно быть в общей сложности немного.
В коде ты ведь тоже пишешь char* mystring, а не mystring c* — тип всегда предваряет имя.
неестественно проговаривать про себя при чтении
Проговаривать про себя при чтении — в принципе неестественно.
Имхо венгерская плоха в первую очередь тем, что мешает автокомплиту в IDE — никогда не помнишь, с какой буквы надо начинать набор.
Скажем, во freeRTOS все API — с венгеркой. И это просто адище:
xTaskCreate
xTaskCreateStatic
vTaskDelete
vTaskDelay
vTaskDelayUntil
uxTaskPriorityGet
vTaskPrioritySet
Пояснение: u — unsinged, v — void, x — хз что. Да, ux — это unsigned хз что.
И вот какая мне, блин, разница, что возвращают эти функции? Почему они все не начинаются со слова task, они ведь все относятся к блоку манипуляции тасками?! А вот. И, разумеется, большинство IDE начинают поиск только если первую букву угадаешь.
Вы привели типичный пример неправильного использования венгерской нотации.
Вы привели типичный пример неправильного использования венгерской нотации.
Именно! Вроде бы, товарищ Спольски это называет "Наивная венгерская нотация" — когда к переменной приписывается формальный тип, который никого не интересует.
Ну и я хотел привести пример кода, с которым людям все еще приходится работать сейчас; причем freeRTOS обещает сохранять обратную совместимость вечно.
Но как быть с ВыгрузкаПоДебиторскойЗадолженностиИПоЗадолженностиОтПосредниковРаботающихСУдержаниемКомиссииГрафикБудущихПлатежей?
ЗЫ. У кого экран шире 1280 — конец слова виден?
Вообще такое должно решаться на уровне номенклатуры. Например, присвоение номеров отчётам. В итоге получим код вида
ReportService.getReport(128256);
ReportService.getReport(128256);Одна из первых рекомендаций обычно: не используй магические числа, используй именованные константы.
Так что ReportService.getReport(REPORT_EXPORT_DEBTS_AND_BLAHBLAH_BLAH_WITH_FUTURE_TRANSACTION_PLAN_BLA);
ВыгрузкаПоДебиторскойЗадолженностиИПоЗадолженностиОтПосредниковРаботающихСУдержаниемКомиссииГрафикБудущихПлатежей?Если вы сформулируете внутреннюю логику бизнес-процессов или нормативов, для чего именно понадобились именно эти данные, то, скорее всего, вам удастся придумать более лаконичную формулировку. Главное — последовательно использовать одну и ту же терминологию во всём проекте.
ЗЫ. У кого экран шире 1280 — конец слова виден?
Если не забуду — дома проверю.
min-width: 1024px;
max-width: 1164px;
ИМХО универсальных принципов именования не найти, ассоциативные цепочки у людей существенно разные, так что как вы функцию не назовёте, кому-то всё равно будет глаз колоть, на экран не влезать и под курсором мешаться. Комментируйте код, господа.
cntr_nm_code = 38;Пример специально подогнан под желаемые выводы.
«cntry» вместо «country», «ctr» вместо «counter» — уже всем понятно с первого взгляда (аналогично с id, idx, num, val, cur, buf, ptr, tmp и пр.).
Разбирать выражение, растянувшаяся на несколько строк только из-за пустопорожних километровых имён — вот это действительно, мягко говоря, утомляет…
Очень толковая книжка — «практика программирования» Кернигана и Пайка как раз про это говорила.
website.userAdd();Классический способ построения номенклатур «сверху вниз» наподобие «карандаши цветные». Это правильно и удобно.
Мимикрия слов (Name, name, _name и _Name в одной функции)Вот настоящее зло, начиная с самой идеи назвать переменную «имя» без уточнения чьё именно имя… Бросаются из крайности в крайность, то сочиняя имена, занимающие всю строчку, то экономят несколько знаков любой ценой, разрешая конфликты извращениями с регистрами и подчерками. Нет ничего лучше классической сишной нотации.
book_name_set(book, book_name) { book->name = book_name; }
уже всем понятно с первого взгляда
Да щаз! Это требует запоминания точно так же, как префиксы венгерской нотации или однобуквенные обозначения предметной области.
Это не "карандаши цветные", это "карандаш добавить".
«ctr» вместо «counter» — уже всем понятно с первого взгляда
с первого взгляда ctr я распарсил, как control. А для counter/count много лет уже живет сокращение cnt.
«cntry» вместо «country», «ctr» вместо «counter» — уже всем понятно с первого взгляда (аналогично с id, idx, num, val, cur, buf, ptr, tmp и пр.).
cur это валюта, курсор или что-то текущее?
sck(dic) = set_current_key(dictionary)
fck(slt) = file_check(system_library_template)
pow, exp, len, str, eval, enum, var, val — никого ведь не смущают?
если про ключи то: pk, capk, exp тоже вполне употребимо.
file check можно сократить до fcheck (printf/fprintf) или fchk если букву жалко.
Не заостри Вы на этом внимания и я тоже не обратил бы. =)
P.S. Зачем сокращать country — мне решительно непонятно.
О!
cntr_nm_code
преобразуем в lowerCamelCase и получается
cntrNmCode
Венгерская нотация!
Без префикса, указывающего тип переменной, это будет не венгерская нотация.
Наоборот. Спольски говорил, что префикс должен указывать что угодно, но не тип переменной.
Суть венгерской нотации сводится к тому, что имена идентификаторов предваряются заранее оговорёнными префиксами, состоящими из одного или нескольких символов.Ссылка
…
Применяемая система префиксов зависит от многих факторов:
запись типа переменной в её идентификаторе (венгерская нотация)Ссылка
Спольски упомянут только как автор идеи использовать префиксы для обозначения подтипов (да и то, если указания типа не хватает).
Тогда нужно править статью на википедии.
В общем изначально под типом подразумевалась область использования, что ли, а не тип переменной. Вроде «безопасной» и «небезопасных» строк или координат относительно строки и разметки (здесь вообще имя переменной состоит только из префикса).
Да и то это больше зависит от языка, где эта нотация используется. В некоторых изначальная её версия особого смысла иметь не будет.
Под типом изначально понимался смысловой тип. Он может быть разным от языка к языку и от предметной области к предметной области.
Во, выше я писал, что у меня в физических расчётах единицы измерения типами были.
В более практическом случае (где я до сих пор пользуюсь венгерской нотацией) — это классы элементов управления на форме. Чтобы не плодить имена, т.к. может существовать группа разнородных элементов управления, ассоциированных с одной вводимой сущностью.
По непонятной причине люди пишут код так, словно до этого они вообще ничего в жизни не писали и не читали. Ну или как будто планету захватили злые кровососущие инопланетяне и код пишется под дулами их протонных бластеров.
Рискну предположить, что это потому, что люди пишут код значительно медленнее, чем все остальное (особенно начинающие разработчики, либо опытные разработчики в новом языке/фреймворке, с непривычки). В мозгу начинающего разработчика код именно что составляется из отдельных букв и символов, вручную. Оптимизированные образы «слов» и «выражений» еще не выработаны, поэтому мозг даже и не пытается проверять написанное на соответствие этим самым образам. В этом отношении код начинающего разработчика напоминает корявые прописи четырехлетнего ребенка
За собой, кстати, наблюдаю проблему уже другого уровня. Как известно, чеволек без прлобем может читать ткест при извстеном конткесте, даже если в нем перестлавены отльденые буквы, при условии, что предолжение и текст в целом соствалены грамотно. Я считаю себя довольно опытным разработчиком, и очень серьезно запариваюсь на соблюдение и поддержание архитектуры в своих приложениях. При этом на уровне отдельных функций/операторов (которые я пишу довольно быстро, почти на автомате) вполне позволяю себе писать код с мелкими нарушениями, смешивая buttonOk и okButton. А что, я же знаю, что архитектура в целом соблюдается, и эти мелкие ошибки никак не повлияют на поведение приложения в целом — вот мозг и привыкает не обращать внимания на эти мелочи.
У мозга есть физиологическое ограничение: время распознавания образа практически константа, от появления перед глазами объекта до осознания мозгом что этот объект из себя представляет проходит около 500 мс.
Откуда цифра 500, если не секрет? Из того, что я видел, везде 150, например www.nature.com/articles/srep01928
Источники точно не укажу, но, например, в ссылках из статьи картина именно такая и во всех остальных исследованиях которые я изучал данные точно такие же.
Для стандартных стимулов последний пик — N400 с максимальным временем появления 500мс. На него я и опираюсь в своём суждении.
Есть также пик P600, но он проявляется только как реакция на синтаксические или им подобные аномалии.
Это лишь предположение, что 200 мс являются реальным временем распознования а остальная активность с распознаванием образов уже не связана. Боюсь что правду до составления карты человеческого мозга мы так и не узнаем.
1) www.frontiersin.org/articles/10.3389/fnhum.2019.00013/full => Yeo, L. G., Sun, H., Liu, Y., Trapsilawati, F., Sourina, O., Chen, C.-H., et al. (2017). “Mobile EEG-based situation awareness recognition for air traffic controllers,” in 2017 IEEE International Conference on Systems, Man, and Cybernetics (SMC) (Banff, AB), 3030–3035.
2) www.ncbi.nlm.nih.gov/pmc/articles/PMC3081809
3) en.wikipedia.org/wiki/Face_perception => «For temporal profile of shape and surface processing, around 150ms seemed to be critical moment, perhaps where integration of shape and surface features happen, leading to successful face recognition, as face reconstruction accuracy also reached significance around that time frame».
Если с этими статьями что-то не так — я могу без проблем еще найти, пол гугла откликается на «150 ms brain cognition» и за последние десять лет я эту цифру встречал бесконечное количество раз.
И вот такие картинки в лекциях:

Вторая ссылка — выдвигается теория, что мышление идёт циклами по 260–390 мс. На основе экспериментальных и симулированных данных. Ну допустим, я готов поверить в усреднённые 325 мс, хотя и с большой натяжкой.
Третья ссылка — тоже ничего. Упоминается, что 150мс, вероятно, один самых важных моментов в распознавании лиц, интеграция формы и поверхности. Не полное время, а самый важный момент.
Бейсбол не подходит как пример, мяч бросает человек, он не появляется внезапно в воздухе, реакция отбивающего это в первую очередь реакция на движения подающего.
Если вам почему-то важно убедить меня в справедливости ваших данных, то приводя ссылки на статьи такого размера в качестве примера приводите, пожалуйста цитаты из них. Я потратил очень много времени на прочтение.
Основная причина, по которой я сомневаюсь в ваших цифрах указана мной выше, это N400. Если распознавание образа происходит 3а 150 мс, то какова роль этого пика? Я могу согласиться, что за 150 мс происходит какой-то важный этап, например нахождение соответствия между образом перед глазами и образом в памяти, но никак не в то, что это полное время осознания того, что перед глазами находится определённый объект.
1) «The RPT finds that the brain activity correlated with CONSCIOUS perception of a stimulus occurs on the earlier side, approximately 150 ms after stimulus presentation, as opposed to the late wave of activity posited by GNWT at >300-400 ms» (https://www.reed.edu/psychology/scalp/thesis/files/Goldblatt_Thesis_2016.pdf)
2) «Unfortunately, the literature is still inconsistent with regard to
even basic aspects of the time course of visual word recognition.
In particular, the latency ranges for lexico-semantic information retrieval are still intensely debated, with estimates ranging from before 150 to about 350 ms» (https://www.scienceopen.com/document_file/5b111e86-f4e3-4182-b5cf-4e70967026a3/PubMedCentral/5b111e86-f4e3-4182-b5cf-4e70967026a3.pdf)
3) Вот тут пара интерресных коррелянтов, которые я обычно использую чисто в инженерных целях при работе со звуком и видео: www.pubnub.com/blog/how-fast-is-realtime-human-perception-and-technology
Вопрос про «какая роль N400» я не совсем понимаю. Как он коррелирует с задержкой осознания? Чтобы посчитать задержку осознания ставят эксперименты, где человек реагирует на входящие стимулы (изображение, звук, тактильные) нажимая кнопки, говоря что-то итд. После чего вычитают активность «после осознания». Для этого ставят коварные эксперименты, меняя экспериментальный параметр так, чтобы менялся только факт работы именно сознания. Бифокальное противостояние, например. ЭЭГ в этих экспериментах, насколько я знаю, вообще не используют, потому как оно показыват «погоду на марсе» — корреляция между активностью мозга и снимаемой с черепа электрической активностью есть, но она слишком грубая, чтобы хоть как-то помогать с происходящими внутри активностями.
А вот вопрос про более-менее точную задержку интересен. Похоже, несмотря на обилие цифры в 150мс я не могу сходу нагуглить действительно хороших исследований, которые бы намертво закрывали вопрос. Я уточню у знакомых нейрофизиологов и буду более внимательно смотреть на эти цифры именно в экспериментах, связанных с сознанием. Если через год в этой ветке появится коммент — значит я нашел обновленную информацию))
Спасибо за ваше уточнение и сылки. Я усомнился в своей точке зрения, буду искать опровержение либо подтверждение. Должны быть исследования, причём скорее всего немало, изучающие именно скорость осознания.
Посмотрим, что будет через год)
Прошло полтора года и я встретил вот эту любопытную статью на lesswrong с хорошими референсами в пабмед на классические исследования. И мозжечек https://www.lesswrong.com/posts/AKBzhvnSLrbgAehLw/how-is-low-latency-phasic-dopamine-so-fast
И еще одна любопытная статья, где осознание хорошо фиксируется в диапазоне от 276 до 576 миллисекунд с предъявления стимула: https://hackaday.com/2021/12/15/the-real-science-not-armchair-science-of-consciousness/
Еще одна хорошая статья со ссылками на первоисточники. Процитирую: "Ordinary reaction time measured by clicking a mouse in response to an auditory, tactile, or combined auditory/tactile stimulation produced speeds in one study ranging from ∼210 to 320 ms for most people, but was as fast as 100–210 ms in trained musicians"
https://journals.lww.com/cogbehavneurol/Fulltext/9900/Consciousness_as_a_Memory_System.19.aspx
Почему translit в именовании это плохо и другие интересные особенности нашего восприятия кода