LINUX.ORG.RU

А какие сейчас есть актуальные замены (da|ba|k|)sh для скриптов?

 , скриптинг


1

4

Пишу сейчас очередной sh-скрипт с кучей вызовов awk, grep и sed. В связи с чем задумался об альтернативах. Попытался сформировать список черт, которые делают sh до сих пор актуальным инструментом:

  • Возможность легко и просто скомпилировать под любой утюг.
  • Отсутствие развесистой библиотеки, которую интерпретатор таскает с собой, а также как следствие — нет слома совместимости между версиями библиотеки.
  • Минимальное время инициализации интерпретатора.
  • Малое потребление памяти.
  • Простой параллелизм через fork.
  • Возможность удобно и просто вызывать внешние команды и пайплайны команд.
  • Возможность прозрачно миксовать внешние команды и собственные функции. (В sh мы делаем command1 | command2, и это работает одинаково, независимо от того, являются ли эти команды собственными функциями или внешними командами.)

Если обобщить, то главным отличием sh от ЯП типа perl, ruby, python и т.п. является композиция программы как совокупности исполняемых модулей, запускаемых как отдельные процессы, в противовес композиции библиотечных модулей, слинкованных в единый процесс.

Главным минусом sh является то, что в нём не развиты средства работы с какими-либо структурами данных, кроме строк. Да и для самих строк средства не развиты.

То есть потециальная альтернатива sh должна обладать всем перечнем указанных черт, но дополнительно иметь развитые средства работы со структурами данных такими как списки, хэш-массивы и т.д.

★★

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

Угу. :(

Building from git master currently requires:

Rust (version 1.70 or later)
CMake (version 3.19 or later)
a C compiler (for system feature detection)
PCRE2 (headers and libraries) - optional, this will be downloaded if missing
gettext (headers and libraries) - optional, for translation support
an Internet connection, as other dependencies will be downloaded automatically
For tests: a C++11 compiler
dataman ★★★★★
()
Последнее исправление: dataman (всего исправлений: 1)

Не в тему, но просто увлёкся. Ничего интересного просто операторы перегружаются, но всё равно прикольно, некое подобие пайпов и перенаправлений можно соорудить на коленке. Но детский сад конечно :)

Луа как шелл :)

    -- тройная "типа пайповая" труба"
    ls '/' | grep 'lib' | grep '32' | wc '-l',
    -- перенаправление в файл
    (ls '/' | wc '-l') >> 'out_1.txt',
    -- чтение из файла
    cat 'out_1.txt' | wc '-c',
    -- прост вывод. Без перенаправления сейчас не получить, дальше мне лень :)
    ls '-la /' | grep 'usr'

Хотя на самом деле вот…

#!/usr/bin/env lua5.3
-- или 5.4 такак в меньших нету >> и <<
-------------------------------------------------------------------------------
local function lua_shelol(...)
   for _,v in pairs({...}) do
      assert(type(v) == 'table','Нотатабле')
      print(v[1])
   end
end
-------------------------------------------------------------------------------
local function regapp(v,p_is_data)
    local tc = table.concat
    assert(not _G[v],
    [[Ааааааа нинада перезаписывать глобалки, уууулюлюлюлюлю!]])
   _G[v] = setmetatable({[1]=v},{
       __bor = function(a,b)
           local x
           if a[0] == 'data' then
              x = io.popen('echo -n "'..a[1]..'" | '..tc(b,' '),'r'):read('*a')
           else
              a[0]='application'
              b[0]='application'
              x =  io.popen(tc(a,' ')..' | '..tc(b,' '),'r'):read('*a')
           end
           x = regapp(x) x[0]='data'
           return x
       end;
       __shr = function(a,b)
            if a[0]=='data' and type(b) == 'string' then
               local x=io.open(b,'w')
                     x:write(a[1])
                     x:flush()
               return
            end
            if a[0]=='application' and type(b) == 'string' then
               io.popen(tc(a,' ')..' >> "'..b..'"','r'):read('*a')
               return
            end
            error('Слева команда >> справа файл, абоooлтуууус :)')
       end;
       __call = function(a,b)
           a[2]=b return a
       end
   })
   return _G[v]
end
-------------------------------------------------------------------------------
regapp 'ls'
regapp 'grep'
regapp 'wc'
regapp 'cat'
regapp 'pwd'

-- дабы на каждую строку не писать print((a | b)[1]) всё в одну впиховаем
lua_shelol(
    -- тройная "типа пайповая" труба"
    ls '/' | grep 'lib' | grep '32' | wc '-l',
    -- перенаправление в файл
    (ls '/' | wc '-l') >> 'out_1.txt',
    -- чтение из файла
    cat 'out_1.txt' | wc '-c',
    -- прост вывод. Без перенаправления сейчас не получить, дальше мне лень :)
    ls '-la /' | grep 'usr'
)
-------------------------------------------------------------------------------

dron@gnu:~/Рабочий-стол/lh$ ./main.lua 
2

3

lrwxrwxrwx   1 root root     7 сен 13  2021 bin -> usr/bin
lrwxrwxrwx   1 root root     7 сен 13  2021 lib -> usr/lib
lrwxrwxrwx   1 root root     9 сен 13  2021 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 сен 13  2021 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 сен 13  2021 libx32 -> usr/libx32
lrwxrwxrwx   1 root root     8 сен 13  2021 sbin -> usr/sbin
drwxr-xr-x  16 root root  4096 июл  6  2023 usr

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от dataman

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

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

Там до сих пор наркомания в виде конфигурации браузером?

Да, но можно и так:

$ fish_config prompt list
$ fish_config prompt show

И т. д. Темы тоже можно менять без браузера.

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

А чево сразу бредом, на ruby как и на lua пишут свои DSL часто под задачи вместо написания нового языка. Но всё имеет свои разумные границы, это да. (Но не в рамках веселья и домашних поделочек, там границ нету и можно всё уууууууууу!)

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

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

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

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

Всё, что есть в браузере можно выбрать через команды fish_config, либо можно вручную править fish_variables - там лежит приветственное сообщение, режим ввода, цвета и аббревиатуры (это как алиасы, но не говно). Мне хватило просто поправить функцию вывода промпта и убрать приветствие.

fumanchez
()
Ответ на: комментарий от wandrien

но только если это заворачивать во что-то, чтобы отделять от обычного кода.

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

Но так то да, у любого DSL свои границы и в применении и в выражении, а при смешивании кода ещё и в понимании где, кто, кого и куда :D Всё зависит от комбинации всяких разных границ, это да.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Переопределённое поведение будет работать только с зарегистрированными именами внешних команд.

Хотелось бы скорее не так, а чтобы вводилось неким префиксом и до конца выражения работало как пайплайн.

Можно этого добиться как-то так:

pipe | 'cat' 'out_1.txt' | 'wc' '-c'

Кстати, надо попробовать реализовать.

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

Ну можно и так, хотя нет, два подряд строковых преранда/лиртерала между | в луа не сделать, имя cat должно быть перегруженной таблицей или функцией. Вот так можно

pipe = cat 'out_1.txt' | wc '-c'
print(pipe[0]) -- тип это программа или данные
print(pipe[1]) -- имя программы или результат

Ну или вот так совсем, если прям всё оборачивать (придётся оборачивать)

pipe 'cat' 'out_1.txt' '|' 'wc' '-c'
print(pipe[0]) -- тип это программа или данные
print(pipe[1]) -- имя программы или результат 

Есть всё же некоторые синтаксические ограничения и порядки. Но как там в руби не знаю, может там попроще ибо Японец там всё объектами заделал что надо и что не надо :)

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)
Ответ на: комментарий от wandrien
ну{и} {
  будешь {всё} {вот так} 
  return {пейсать}
}

Он тоже мощный, да, порой даже слишком. Но у него тоже свои неизбежные синтаксические приколы

Сами пайпы там считай из коробки конечно, но хрен знает… Ой да ща все языки переберём. Один хрен даже в тикле придётся своё городить дабы выглядела работа +/- более похода как на обычные кусочки shell внутри общего кода определяющего всякую логику.

А так да, вот бы в shell`aх был и текущий развитый командный режим который есть и адекватные механизмы организации данных и логики через чуть более человеческий синтаксис родной. Если бы это было изначально python бы и подобные языки просто умерли бы не родившись ибо в них не было бы никакого смысла. Но, нет шеллы для интерактивного взаимодействия топчик и тихий ужас для скриптов с логикой и данными, тоже самое, но наоборот у других языков, с логикой и данными топчик, а с взаимодействием с другими программами либо геморой и лапша из самодельных подпорок либо зависимости в пол терабайта :D

Ой, всё. У меня винегрет. И меня тут уже неееееееееет…

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от wandrien

Поставлю, пощупаю.

Ну собственно дочитал https://elv.sh/ref/language.html

По первой трети документа всё кажется достаточно стройным. Затем создаётся впечатление, что всё несколько оверинженернуто, и могло быть проще.

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

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

тулзу на Go, то скорее всего это окажется продуманная и полезная штука

Главное, под капот не смотреть.

тулзу на Rust, то скорее всего это будет невнятная оверинженернутая хреновина

От тебя это почти что комплимент. Примеры невнятных хреновин в студию?

intelfx ★★★★★
()

То есть потециальная альтернатива sh должна обладать всем перечнем указанных черт, но дополнительно иметь развитые средства работы со структурами данных такими как списки, хэш-массивы и т.д.

Звучит как перл, причем ведь есть psh. Можно ещё вспомнить старину tclsh.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от wandrien

Не, в lua получится вот такое

bla "con" "cat" "en" "at" "ion"

Тут можно сделать так что bla это функция которая может принимать строку «con» без указания скобок(``) обработать и вернуть саму себя или функцию которая примет «cat» и так далее до и включая «ion». А как всё это интерпретировать дело десятое.

А вот такое нельзя

bla "con" "cat" | "grep" "lala" | "grep" "lolo"

Тут bla это отметатабленная таблица, которая может быть вызвана как функция и принять «con» обработать и вернуть функцию которая примет «cat» вернёт отметатабленную таблицу которая изменит поведение (только в случае наличия себя) ‘|’ а вот дальше всё «grep» примется и будет обработан отметатабленным ‘|’ но вот на «lala» всё дрёпнется ибо оно ни к селу ни к городу.

Вот у тебя в рубях всё склеит, а у меня заругает мол это твоё «lala» это вообще куда? Всё получится если grep будет перегруженной таблицей.

Либо, делать вереницу возвратов функций и всё в строки облрачивать

  • bla "a" "|" "blu" "ble" "|" "e"

Либо, делать как со строками но с таблицами явными

  • bla {"a"} {"|"} {"blu"} {"ble"} {"|"} {"e"}

Или так, тут шило/мыло

  • bla {"a"} | blu {"ble"} | e

Либо, делать вызовы таблиц как функций с переопределённым оператором, как выше изначально

  • bla "a" | blu "ble" | e"

Может ещё как можно, но там будет своё но. В целом достаточно вариативно и гибко, но не в абсолюте конечно. А у тебя, ну значит тебе придётся какой то синтаксический разделитель на уровне языка использовать. Так же как и тут в луашке, просто выглядеть будет по другому.

Ну тут видишь как, у тебя конкатенация строковых литтералов прям как в Сишке, на этапе компиляции

printf("%s","hello\n"
            "world\n");

Но вот такой побочный эффект для твоей текущей задаче что эта конкатенация мешает, а у меня наоборот вот так в луа нельзя

  • print("hello""world")

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

И вообще, можно просто сделать как дед волосатый, прямолинейно, просто и понятно и на любом языке

resultat = pipe(command_a,command_b)

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

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 5)
Ответ на: комментарий от wandrien

Надо бы попробовать что-нибудь на этом запрограммировать и посмотреть, как пойдёт.

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

Опыт применения elvish по первым впечатлениям мне не понравился. Многословно, неудобно, неэргономично.

Завтра до конца перепишу и покажу, что получилось. Сон рубит.

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

Зачем?

потомучто это удобно, допустим в памяти хранится n элементов и если считаем с 0 указатель в памяти будет равен n*размер и в прочей математике считать с 0 очень удобно. Это только удобно в первоклашке удобно считать с 1, те кто освоил 7 классов удобно иметь линейку начинающюся с 0 и в формулах 0 элемент очень удобен в отличии от 1. Более того во всех языках кроме некоторых древних версий бейсика и луа принято считать с 0.

local a = {"0","1","2","3"}
print(a[1])
print(a[2])
print(a[3])
print(a[4])
output
0
1
2
3

s-warus ★★★
()
Ответ на: комментарий от LINUX-ORG-RU

В пистоне тоже можно с помощью __xor__ пайпы эмулировать. Создать какой объект с динамическими свойствами типа:

c = ShellCommand()
contents = (c.grep('abc', 'file') | c.sort('-r')).getoutput()

Так же можно >, >> и тп реализовать, но чето это бредом пахнет, раз никто готового не родил, значит тащем-то и не нужно

rtxtxtrx ★★
()
Ответ на: комментарий от s-warus

Роберту Иерузалимски вошёл в чат пояснить за единичку :D

Ох люблю писать стены текста конечно, но воздержусь хехе. На самом деле это самая незначительная часть в Луа на которую обращаешь внимание, даже постоянно параллельно используя Си. В Си тоже надо помнить что в данных размером 5 для доступа к символу 3 нужно взять индекс номер 2 :D Это странно звучит из за слова индекс которого в си нет, а есть смещение. Вот у тебя с луа тоже когнитивное искажение, там хеш табля и всё.

В любом случае если есть возможность избегать неудобный для себя язык просто делай это, как по мне так нормально я вот всячески избегаю C++, просто люто избегаю.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)

Я пробовал как-то писать системные скрипты на php и lua. Вот как раз из-за развиты средств работы со сроками и структура и данных, но быстро бросил, ибо шелл, при всех его недостаткх, на порядок удобнее для этого

pihter ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Вот у тебя с луа тоже когнитивное искажение, там хеш табля и всё.

Нету когнитивного искажения, а есть математически естественный и удобный способ адресации массива, а есть неестественный и неудобный. Вариант с единицы относится ко второму.

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

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

с помощью xor пайпы эмулировать

Давайте признаем, что лучший язык для таких извращений — это ЛNCП, и закроем тему.

Только проблема, что ЛNCП — не лучший язык для написания и чтения человеком.

Вот если ты программный код, тогда другое дело.

wandrien ★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Роберту Иерузалимски вошёл в чат пояснить за единичку :D

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

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

И это пример того, как можно хороший проект испортить мелким косяком.

В любом случае если есть возможность избегать неудобный для себя язык просто делай это, как по мне так нормально я вот всячески избегаю C++, просто люто избегаю.

А если возможности нет? Вот sh и python примеры неудобных языков. И куда от них деваться — они буквально везде.

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

В паскале только в одном случае индекс с 1, только в короткой олд строке, потому что в 0 байте хранится длина строки. А так классическом виртовской и борлондовском всегда с 0.

s-warus ★★★
()
Ответ на: комментарий от wandrien

Опыт применения elvish по первым впечатлениям мне не понравился. Многословно, неудобно, неэргономично.

Вот так выражение парсится корректно:

put (and a b)

А вот так — нет:

put (and
	a
	b)
exec: "a": executable file not found in $PATH

И как прикажете сложные выражения тогда записывать? Все переводы строк внутри одного выражения необходимо ВСЕГДА экранировать через ^.

Я, конечно, из принципа сейчас допишу код до рабочего состояния, но уже понятно, что пользоваться этим я не буду.

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

Да, такой вот недолисп получается.

Использование нотации в стиле S-expression входит в противоречие с тем, последовательность команд представляет собой команды, разделённые символом новой строки.

В этом случае нужно либо до конца S-expressions вкручивать, либо как минимум сделать ; обязательным разделителем команд вместо перевода строки.

Это несогласованность дизайна синтаксиса. «Ни так, ни сяк».

Еще одной проблемой является отсутствие аналога set -x. Код printf-ами отлаживать?

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

В общем, синтаксис имеет ряд болячек, схожих с TCL, но при этом он еще хуже.

В обмен на сломанный синтаксис мы получаем… ничего.

В TCL мы метапрограммирование получаем взамен. А здесь только боль и страдание. Потому что эти псевдо-S-expression не являются гомоиконными.

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

Я, конечно, из принципа сейчас допишу код до рабочего состояния,

Да хрен с ней не буду. Выглядит это всё примерно вот так:

fn list_all_windows {|regexp|
	set _ = ?(
		xwininfo -tree -root | grep $regexp | grep -o '^[[:space:]]\+0x[0-9a-fA-F]\+' | grep -o '0x[0-9a-fA-F]\+'
	)
}

fn check_xfdesktop {
	var @ids = (list_all_windows xfdesktop)
	for id $ids {
		var props = (xprop -id $id | slurp)
		if (and ^
			(str:contains $props 'WM_CLASS(STRING) = "xfdesktop", "Xfdesktop"') ^
			(str:contains $props '_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DESKTOP')
		) {
			put $true
			return
		}
	}
	put $false
}

fn set_wallpaper_xfdesktop {|path|
	if (and (has-external xfconf-query) (check_xfdesktop) ) {
		var @workspaces = (
			xfconf-query --channel xfce4-desktop --list ^
			| grep -o '/backdrop/screen[^/]*/monitor[^/]*/workspace[^/]*/' | sort | uniq
		)
		for workspace $workspaces {
			xfconf-query --channel xfce4-desktop --property {$workspace}last-image --set $path
		}
		put $true
		return
	}
	put $false
}

В языке нет встроенной функции для того чтобы «вернуть результат вычисления, если в вычислении не было исключения, в ином случае вернуть исключение как результат». А написать её сами вы не можете из-за отсутствия гомоиконности и средств метапрограммирования. (UPDATE: Ладно, вру. Можете на лямбах.)

Максимум вы можете заглушить бросок исключения:

  set _ = ?(
    xwininfo -tree -root | grep $regexp | grep -o '^[[:space:]]\+0x[0-9a-fA-F]\+' | grep -o '0x[0-9a-fA-F]\+'
  )

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

Далее отсутствие гомоиконности и метапрограммирования приводит к тому, что такие функции как and, or, coalesce и т.п. являются «специальными». Использовать вы их можете, а вот написать собственный аналог с контролем потока управления — нет.

В качестве замены вам предлагают программировать на first-class лямбдах. Единообразие синтаксических средств не соблюдено.

Вот и получается, что синтаксически TCL лучше.

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

Да, про самую главную фичу не рассказал.

Выражения не «возвращают» значения, а выводят их в порт вывода.

Выражение может вернуть произвольное количество значений.

Выводимые значения могут быть двух видов:

  • Вывод в структурный порт с помощью put. Значение сохраняется как есть, включая его тип.
  • Вывод в обычный побайтовый stdout. Поток байт разбивается на lines и каждая line возвращается как отдельное значение типа «string». (Тот случай, когда приходится вставлять английские слова, потому что line и string на русский переводятся одинаковым словом.)

Бросок исключения, как я уже сказал выше, является ОТДЕЛЬНЫМ механизмом возврата, независимым от «вывода значений». И работает привычным для императивных ЯП образом.

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

Вся математика отсчитывает с 0 не просто так, линейки ни кто с 1 не делает, и километры тоже с 1 не начинают, это только детям не знакомым с абстактным понятием 0 удобно с 1 считать, удобно где математики нет, вроде этажей, да и то не удобно когда например нужно посчитать потенцальную энергию гири на 9 этаже E=(9-1)*h*g*m.
Это небинарным не могущим в математику и физику не знакомым с понятием 0 это может кажется удобным.

s-warus ★★★
()
Ответ на: комментарий от wandrien

Категорически не согласен с такой постановкой твоих слов. Сейчас нет времени стену текста писать к сожалению, но это заявление сводится к нравится, не нравится, удобно, неудобно. Это вообще отношение к делу не имеет. В Сишечке с нуля потому что там адресация и точка, холодный расчёт и ничего более. В Луа не с нулика во первых потому что на это нет технических причин, во вторых если хочется с нулика делай с нулика, в третьих львиная доля пользователей Луа не программисты от слова совсем. У Си ровно одна целевая аудитория системные и прикладные программисты высокопроизводительных программ. У Луа аудитории две программисты на Си и все остальные, все остальные это тётя в аэропорту которая научилась делать поиск билета не кнопочками, а набиранием кода. Замечу момент, половина пользователей Луа это сишники и кто угодно ругает эту единичку кроме них.

Нету когнитивного искажения

Ещё какое есть! Попытка воспринимать Сишные байтовые массивы как индексируемые ячейки, а не как адресуемые со всеми вытекающими. Попытка называть таблицы луа массивами со всеми вытекающими.

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

а есть математически естественный и удобный способ адресации массива

Во первых нет. Во вторых да, но только в одном единственном случае когда дело касается адресной арифметики, в Си это база, в Луа этого просто нет. Простые люди считают с 1рочки. И если в «массиве» один элемент он находится под номером один.

удобный способ адресации массива

У адресуемых массивов нет удобного варианта адресации, он просто один. Он просто есть и всё. Удобство это наживаемая мера выраженная в привычке. Это важно я не спорю. Но суть в том что это не тебе удобно у тебя выбора просто нет. Но это удобно да =)

а есть неестественный и неудобный. Вариант с единицы относится ко второму.

Когда ты работаешь пусь с луа табличкой, но данные абстрагируешь для себя не как ключ:значение то в этих рамках да может быть неудобно, но… даже если ты захочешь работать с луа в рамках адресной арифметики у тебя просто не получится, адресная арифметика это не индексы 0,1,2,3,4,5 это адрес+смещение 100+(0size),100+(1size),100+(2size),100+(3size),100+(4size),100+(5size) и никакого это отношения к 0,1,2,3 не имеет, ты в луа просто не сможешь применять настоящую адресную арифметику, там её нет, а называть вот это 0,1,2,3 адресацией такое себе это просто сахар, а не адресация.

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

То, что мы в жизни считаем с единицы, не имеет никакого отношения к математике.

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

Суть проста как палка, расчёт на то что обычному человеку проще так как в жизни, а луа для него инструмент для решения своих прикладных задач, цель языка сделать такому человеку жизнь проще и на деле так и есть. Касаемо остальных, а остальные это те кто не только программирует на Луа, а также ещё на Си как минимум, так вот касаемо остальных расчёт таков что программист на Си в состоянии учесть, понять и контролировать расхождение с тем что у него в Си и в луа, программисту это сделать проще чем простому человеку. Для обычного человека луа это просто конфиг на стероидах, для программиста это библиотека на си с коммуникацией через стек и рядом библиотечных функций полагающих взятие непрерывной последовательности из хеш таблицы с позиции ключа номер 1. Если этот программист хочет с нуля, то будет с нуля и никто ему не запретит и не помешает это сделать.

Я тут лишь кратко изложил всё ужав как смог, поэтому сумбурно, нет времени прям по пунктам всё расписать, но.

  • Си, адресная арифметика == единственный механизм работы с памятью. Он просто есть и всё.
  • В языках где с 0 всё, но нет адресной арифметики, это просто дань удобству программистам.
  • В Луа библиотечные функции полагаются на 1чку это дань удобству не программистам, а программисты уже в свою очередь сами разберутся в нюансах.

Всё,

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

Было бы удобнее если бы в луа тоже библиотечные функции ждал ключ и 0 в начале? Программистам да, не программистам нет. Может ли программист ровнять индексацию с нуля и адресную арифметику? Нет! Может ли он ссылаясь на адресную арифметику говорить про ноль в рамках луа где эта адресная арифметика невозможна применимельна к хеш мапам? Нееееет. Да ты можешь держать в ключах прям адреса, а в значениях чисто как бы байты и делать аналог sizeof и вычислять смещение по непрерывной последовательности целочисленных ключей, но это уже будет просто абстрактный тип данных, как и любой другой который ты придумаешь.

Так что нет в этой краткой записке я выражаю несогласие с твоей позицией! 😊 Твоя позиция не техническая и даже не часть дизайна языка, а просто «хоца вот так, я привык» В третий раз скажу, это важно, привычки это очень важная штука, но цель Луа переложить тяжесть груза специфики компуктер саенс вот на твои плечи как программиста, пусть простой человек просто в таблице описывает переплетающийся сценарий, а специалист по визуальным эффектам настраиваем пайплайн запросов на отрисовку, им так проще, а ты, ты программист и приоритет простоты для пользователя выше приоритета простоты для программиста! Пока пользователь решает прикладные задачи, программист решает задачи решающие прикладные задачи пользователя.

Единичка в луа это просто нюанс, несомненно жутко неудобный для тех кто всегда работал по другому. У луа есть проблемы, реальные проблемы и единичка не в их числе от слова совсем. Благо простые люди про них вероятно никогда и не узнают даже если каждый день что-то пишут на этом языке (библиотеке на сишечке обрабатывающим конфиг на стероидах)

В следующий раз в три раза больше ответ будет!!!!

LINUX-ORG-RU ★★★★★
()