LINUX.ORG.RU

Инженерная раскладка клавиатуры (Ручей)

 ,


4

2

Всем привет.

Клавиатурные раскладки появляются редко, тема достаточно специфическая и в новостях не встречается, поэтому хочу поделиться.

В релизе xkeyboard-config-2.36 (это Fedora 37, Arch, Gentoo) появилась русская инженерная раскладка «Ручей» (Ruchey).

Смысл раскладки в том, чтобы для кириллицы был полный набор спецсимволов. Магии, конечно не бывает и часть спецсимволов набирается с помощью правого Alt (AltGr). Зеркальная раскладка есть и для латиницы, которая имеет такое же расположение спецсимволов, а также включает в себя специфические русские символы «,»,₽,§,№.

Примечательно, что при разработке автор старался, чтобы спецсимволы, по возможности, оставались на клавишах с их изображениями и тем самым было легче привыкание.

Подробности с сайта:

  • Раскладок именно две: «Русская (инженерная, кириллица)» и «Русская (инженерная, латиница)».
  • Переключаются именно раскладки, а не языки ввода. Язык ввода один - Русский.
  • Полный набор спецсимволов как в кириллической, так и в латинской раскладке.
  • Большинство спецсимволов находятся на своих местах, но часть вынесена на третий уровень и набираются при зажатом правом Alt (AltGr).
  • Часть спецсимволов смещена для удобства набора программного кода.
  • Предусмотрено, чтобы пользователь не испытывал дискомфорт при использовании AltGr.

Ограничения, которые были заданы при разработке:

  • Буквы должны оставаться на своих местах, раскладка не решает проблему скорости набора.
  • Спецсимволы, по возможности, также должны находится на своих местах, но при этом необходимо обеспечить удобный набор часто встречаемых спецсимволов в коде.
  • Перенос спецсимволов должен компенсироваться их лёгким запоминанием.
  • Не должен страдать опыт набора методом «слепой печати».

На данный момент раскладка относится «экзотическим» и расположена «base.extras.xml». В KDE экзотические раскладки работают из коробки. Для Gnome необходимо выполнить команду «gsettings set org.gnome.desktop.input-sources show-all-sources true», чтобы увидеть экзотические раскладки в списке доступных.

По сути в этой раскладке можно писать технический текст на русском без переключений.

Например без переключений можно напечатать:

§ Решение
  если А > Б && С < Д, то СП = `{А,Б,С,Д}`

Сайт проекта на GitHub


Ответ на: комментарий от den73

Потому что нужен не «английский» язык кода, а нечто, воспринимающееся как условные обозначения, а не как слова. Родной же язык (у нас - русский) воспринимается как слова, и поэтому плохо подходит для программирования и прочих абстракций.

firkax ★★★★★
()
Ответ на: комментарий от firkax

А как же книга «чистый код»? Например, понятно, что тут происходит?

funktion muutosOpiskelijatunnisteenTeksti(opiskelijatunnus){
       const opiskelijanNimiLabel = hankiOpiskelijanNimi(opiskelijatunnus);
  }
funktion toimintoHankiOpiskelijanNimi (opiskelijatunnus){
       const opiskelija = api.saadaOpiskelijaTunnuksella (opiskelijatunnus);
       paluu opiskelija.nimi;
  }
den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

А как же книга «чистый код»?

Не знаю такой книги.

Например, понятно, что тут происходит?

Да, понятно - тут две обёрточные функции. Но у них слишком длинные названия и код плохо отформатирован, неудобно. Лучше бы смотрелось так:

funktion muOpi_tunTeksti(opi_tun) {
       const opi_nNimiLabel = hankiOpi_nNimi(opi_tun);
}
funktion toHankiOpi_nNimi (opi_tun) {
       const opi_ = api.saadaOpi_Tunnuksella(opi_tun);
       paluu opi_.nimi;
}

firkax ★★★★★
()
Ответ на: комментарий от den73

Все обёрточные функции делают одно и то же - вызывают вложенную функцию, и иногда перекладывают параметры/выходные значения из одной переменной в другую и/или делают какую-нить тривиальную арифметику. Словарь тут ни при чём совершенно.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

возвращаясь к старой теме, код был такой:

function changeStudent ID Text(student ID){
        const studentNameLabel = getStudentName(studentID);
   }
function functionGetStudentName (studentID){
        const student = api.getStudentID (studentID);
        return student.name;

и вот что смог сказать о нём @firkax после того, как я перевёл этот код на финский язык:

Да, понятно - тут две обёрточные функции. Но у них слишком длинные названия и код плохо отформатирован, неудобно

Все обёрточные функции делают одно и то же - вызывают вложенную функцию, и иногда перекладывают параметры/выходные значения из одной переменной в другую и/или делают какую-нить тривиальную арифметику.

Как Вы считаете, смог ли firkax разобраться в смысле этого кода без финско-английского или финско-русского словаря? Или это ответ уровня «напряжометр»?

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

Ещё раз - в твоём коде показаны две обёрточные функции. Как они называются - не важно.

Функция «changeStudent» вызывает функцию «getStudentName» и сохраняет её результат в переменной (видимо локальной, то есть бесполезной но это я не знаю языка на котором код). Функция «functionGetStudentName» вызывает функцию «api.getStudentID» и в возвращённом ей объекте читает переменную «name». На этом всё. Больше они ничего не делают. Нет, они не получают имён студентов и прочее подобное, они только вызывают вложенную функцию. Что делает вложенная функция - неизвестно, пока нет её исходника. Как она называется - не важно.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Твоё мнение понятно - ты разобрался. Но хотелось бы независимые мнения. Я бы мог, если бы мне было не лень, дописать рядом финский перевод функции GetStudentAge, и ты бы написал, что это ещё две обёрточные функции. А о чём они и про что - ты бы точно так же не сказал бы. Такой вот мысленный эксперимент. Но можно другой. Вот тебе таблица в базе данных. О чём она?

create table opiskelija 
  (id int not null primary key
  ,ikä varchar(256)
  ,sukupuoli varchar(256)
  ,etunimi varchar(256)
  ,sukunimi varchar(256)
  ,Luokka varchar(256)
  ,stipendi varchar(256))

Скажи, не залезая в словарь. Чтобы ты не мог сказать, что это не код, а метаданные, вот тебе sql-запрос:

select ikä, sukupuoli, etunimi from opiskelija where id = :id
den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 4)
Ответ на: комментарий от firkax

Т.е. когда ты читаешь любую функцию, ты всегда игнорируешь её название, а смотришь только на то, что она вызывает, и так до атомов? А если это некое API, данное тебе как чёрный ящик, то тебе неважно, как называются функции в этом API? Т.е. что назови их getStudentName, getStudentAge, что назови их setTeacherRoom, setTeacherPhone, или просто function1, function2 - тебе без разницы будет и ты всегда смотришь только в документацию? А что делаешь, если API как чёрный ящик и документации вообще нет? Просто чтобы я понял, насколько ты серьёзно это сейчас пишешь.

И дальше, если при разборе до атомов окажется, что getStudentName возвращает комнату учителя, то для тебя это будет нормой? Часто такое в жизни попадается? Приведи хотя бы три примера, когда тебе такое попадалось.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 3)
Ответ на: комментарий от den73

По-моему ты мог бы и предсказать мой ответ - это таблица с primary key идентификатором и шестью строковыми полями каких-то данных. Запрос выбирает три из них.

firkax ★★★★★
()
Ответ на: комментарий от den73

Нет, не игнорирую. Но и как главный источник истинных данных ни в коем случае его не использую. Это хинт, но не более того. К тому же этот хинт может и отсутствовать, если функция представлена не исходником, а дизассемблированным листингом, на итог разбора это влиять не должно, только на скорость.

Если api чёрный ящик без документации то его надо реверсить. Наобум применять функции потому что «мне по названию показалось что она делает именно это» - плохая практика.

И дальше, если при разборе до атомов окажется, что getStudentName возвращает комнату учителя, то для тебя это будет нормой? Часто такое в жизни попадается? Приведи хотя бы три примера, когда тебе такое попадалось.

Мне вообще не попадались ни student ни teacher ни в каком коде ни разу. А вот такое, что функцию нельзя применять наобум - предостаточно. Вот скажи, есть функция fprintf() которая, кажется, печатает что-то в файл. А как она себя поведёт, если ты её запустишь из мультитред программы параллельно? Выведет сначала одну строку, потому другую? Или перемешает их посимвольно? Или вылетит с ошибкой или крашем? Догадки по названию уже не прокатывают? Либо читай документацию, либо смотри исходник. Причём - именно по той библиотеке, которой ты пользуешься. В старых библиотеках межтредовых блокировок там не было, в новых обычно есть.

Впрочем я не знаю зачем ты вообще начал эту тему.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

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

А скорость влияет на экономическую целесообразность, т.е. на то, имеет ли смысл этим заниматься или нет. Таким образом, понятность или непонятность слов, которыми названа функция, для тебя имеет значение.

это таблица с primary key идентификатором и шестью строковыми полями каких-то данных

Я считаю, что ты не разобрался.

Мне вообще не попадались ни student ни teacher ни в каком коде ни разу.

А что попадалось? Можешь привести 10 сущностей, которые попадались?

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

А скорость влияет на экономическую целесообразность, т.е. на то, имеет ли смысл этим заниматься или нет. Таким образом, понятность или непонятность слов, которыми названа функция, для тебя имеет значение.

Об экономической целесообразности пусть думают бизнесмены. Увы, они в этих деталях (которые ты указал) не разбираются, но почему-то всё равно думают о ней.

Я считаю, что ты не разобрался.

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

А что попадалось? Можешь привести 10 сущностей, которые попадались?

Из последнего, если не считать собственного кода (вопрос ж не про него), то например так:

proc, thread, vnode, filedescent, componentname, hz, ticks, spinlock, rwlock, clock, mutex

И да, каждую функцию вокруг этих сущностей, перед тем как использовать, я старался изучить в исходнике, чтобы быть уверенным, что она делает именно то, что я от неё ожидаю. А если и не изучить, то найти пример её использования, полностью аналогичный моему, где она работает ожидаемым образом (то есть раз там работает то и у меня будет).

void
kern_thread_cputime(struct thread *targettd, struct timespec *ats)
{
	uint64_t runtime, curtime, switchtime;

	if (targettd == NULL) { /* current thread */
		critical_enter();
		switchtime = PCPU_GET(switchtime);
		curtime = cpu_ticks();
		runtime = curthread->td_runtime;
		critical_exit();
		runtime += curtime - switchtime;
	} else {
		PROC_LOCK_ASSERT(targettd->td_proc, MA_OWNED);
		thread_lock(targettd);
		runtime = targettd->td_runtime;
		thread_unlock(targettd);
	}
	cputick2timespec(runtime, ats);
}
Вот тебе пример. Сравни, что ты мог подумать про эту функцию по названию, и что можешь узнать, таки прочитав её исходник.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

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

Обычно названия сущностей, как минимум, намекают на то, что эта сущность обозначает, хотя нюансы возможны. Даже если ты вынужден разбираться, что она делает, ты учишь нюансы и дальше для тебя название сущности является ключом, по которому вспоминаешь, о чём идёт речь. Если мы назовём proc, thread, vnode, filedescent, componentname, hz, ticks, spinlock, rwlock, clock, mutex именами e1,e2,e3,…e10, тебе вряд ли станет удобнее, Что делает твоя функция - я не знаю, т.к. она ссылается на иные неизвестные мне сущности. Видимо, замеряет время, в течение которого тред выполнялся, если тред передан. А что она делает, если передали NULL - я не знаю. Наверное, и в случае этой функции ты один раз разберёшься и запомнишь, что она делает, на это её название всё же как-то намекает. Если бы она называлась #x0754AB34, вряд ли тебе было бы легче запомнить её смысл.

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

Я ничего никуда не возводил, но в информационных системах поля, как правило, называются в соответствии со смыслом содержимого. Иное бывает, но для этого нужна какая-то веская причина. Из этого вовсе не следует, что я не буду смотреть код. Но опять же, это удобнее, чем назвать поля f1 … f6.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

намекают

В этом вся суть. Не надо путать намёк и факт.

именами e1,e2,e3,…e10, тебе вряд ли станет удобнее

Конечно неудобнее. Названия должны легко запоминаться и отличаться друг от друга. А вот совпадать с нативным языком программиста совсем не обязаны уже. Твои примеры на каком-то странном языке, кстати, мне бы было некомфортно дорабатывать как раз по это причине: эти слова слишком длинные, слишком похожие друг на друга и их сложно произнести даже про себя - они плохо подходят в качестве ярлыков. А вовсе не потому что я не знаю их словарный перевод.

Видимо, замеряет время, в течение которого тред выполнялся, если тред передан.

намекает

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

в информационных системах поля, как правило, называются в соответствии со смыслом содержимого

Только это мало чем поможет программисту. Ему часто вообще нет дела до содержимого, особенно если оно не влияет на алгоритм.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Только это мало чем поможет программисту. Ему часто вообще нет дела до содержимого, особенно если оно не влияет на алгоритм.

А вот совпадать с нативным языком программиста совсем не обязаны уже.

Да они вообще не обязаны ничем, могут быть и цифрами. Вопрос лишь в цене - насколько быстрее ты запомнишь эти функции, если они будут названы словами известного тебе языка, близкими по смыслу к тому, что они обозначают. Уверен, что нет разницы между словами известного тебе языка и произвольными этикетками? Ладно, не 8-значные, но ведь понятий не так много, допустим, 10000. Почему бы не назвать их 4-значными цифрами? Они короткие и все отличаются друг от друга. Произносятся тоже по-разному.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 3)
Ответ на: комментарий от firkax

Только это мало чем поможет программисту. Ему часто вообще нет дела до содержимого, особенно если оно не влияет на алгоритм.

Тебе всё равно, когда ты программируешь свои ядра, работать ли с тредами или со спинлоками? Для тебя они на вид так же мало отличаются, как opiskelija и etunami?

Программисту говорят: «нам нужно узнать средний возраст студента». Он знает, что в базе есть студенты и есть в них поле возраст, или дата рождения (это где-то в доке написано). Знает, как посчитать среднее. Но он заходит в базу, а там одни только sukunimi. Как в этом случае он решит свою задачу, игнорируя содержимое?

Кстати, зря придираешься. Может быть, функции и не особо хорошо названы, но имена таблицы и полей в ней прекрасно произносятся: «опискелия», «этунами», и «сукуними». Т.е. слова, которые хорошо отличаются друг от друга и могут служить метками.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 4)
Ответ на: комментарий от den73

Для тебя они на вид так же мало отличаются

Это алгоритмически разные сущности.

Но он заходит в базу, а там одни только sukunimi. Как в этом случае он решит свою задачу, игнорируя содержимое?

Должна быть документация, что дата рождения хранится в поле birthday (ну или в каком-нить ещё). А без документации это поле может с тем же успехом означать дату создания записи (например в struct stat в юниксах есть поле st_birthtime - очевидно это не время рождения студента, чьи данные хранятся в этом файле, а время «рождения» файла).

Да, конечно имеет место тактика «посмотрим на название, предположим что там находится, пишем на этом основании какой-нить черновой код и оставим как есть раз работает» когда не хочется тратить время на нормальную разработку, но это всё-таки черновик.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Да, конечно имеет место тактика «посмотрим на название, предположим что там находится, пишем на этом основании какой-нить черновой код и оставим как есть раз работает»

Ещё есть идеология «чистого кода», где предписывается давать сущностями понятные названия. Даже в твоём kern_thread_time оно частично соблюдается, ведь назвали же не release_spinlock, а могли бы.

Далее. когда ты ищешь, «как бы мне узнать время, которое тред работал или которое провёл в ядре», ты открываешь API и ищешь именно по словам. Ты не полезешь в документацию функции release_spinlock в ожидании того, что она вернёт время работы треда. Хотя опять же, я не видел код, с которым ты работаешь, может у вас там принято всё шифровать. Такое бывает, я вот на работе недавно предлагал называть виды тестирования по номерам задач, но почему-то не прокатило, хотя я и сейчас считаю, что test_45621 - это лучше, чем test_from_sa_to_da_e2e_comparing_statistics, при том, что есть трекер, в котором 45621 расшифровывается во вполне чёткое описание того, что там делается, в то время как e2e и comparing_statistics имеют неоднозначности смысла, которые непонятны, пока не заглянешь внутрь. Пока трекер не продолбали, мой подход будет работать, и можно продублировать комментариями в начале скрипта - тогда будет работать, пока исходник не продолбали.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от firkax

Естественно, всё это не означает, что по слову можно точно понять содержание функции. Но это и в жизни так. Представь себе, рядом с тобой стоит человек и говорит тебе «слева птичка». Если он стоит к тебе лицом, то неясно, в какую сторону смотреть. Сильно зависит от того, что это за человек. А если это какой-то чужак, то надо смотреть на него и ждать, что он собрался плохого сделать, а может и сразу бить уже пора. Тем не менее, «слева птичка» - это иная информация, чем «птичка сверху летит».

Неполнота передачи информации словами не отменяет их нужности.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.