LINUX.ORG.RU

а вам кажется странным поведение двойных кавычек в tcl?

 , ,


2

6

Принимая во внимание следующее:

  • списки в tcl не построены из консов
  • списки в tcl на печати изображаются с помощью фигурных скобок
  • при этом внешняя пара фигурных скобок при печати опускается
  • слова можно считать символами
  • {*} по смыслу есть ,@ (см. Википедию)

Получаем следующее:

# присвоим переменной v список из двух символов b и с
> set v {b c} 
b c 
; то же в лиспе
> (setq v '(b c))
(b c)

# построим двухэтажный список
> list a $v
a {b c}
; то же в лиспе 
> (list 'a v)
; то же в лиспе с помощью квазицитирования
> `(a ,v)

# вклеим содержимое v в список
> list a {*}$v
a b c
; то же в лиспе с помощью квазицитирования
> `(a ,@v)

# А вот это что и зачем? 
> puts "a $v"
a b c

# А так не работает:
> puts "a {*}$v"
a {*}b c

Здесь основной вопрос - зачем двойные кавычки ведут себя вот таким образом? Ведь, казалось бы, двойные кавычки по смыслу и являются аналогом квазицитирования, и поэтому должно быть так:

> "a $v"
a {b c}
> "a {*}$v"
a b c

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

★★★★★

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

my-atopacctd

grep \\satopacctd$

my\ atopacctd

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

Если принципиально, то ps -e | grep '^[^:]*:..:.. atopacctd$'

код станет огромным и write-only

Одна строка изменилась.

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

Не мог. Подумай, почему ни один shell на базе лиспов не стал популярен.

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

В рамках UNIX пробелы в именах процессов крайне не рекомендуются.

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

Подумай, почему ни один shell на базе лиспов не стал популярен.

Не знаю. Про SBCL могу сказать: потому что SBCL не умеет запускать сторонние программы. И, кроме того, shell живёт не в вакууме. UNIX - это комплекс программ. Если ps выдаёт человеко-читаемую таблицу, а не структурированные данные, то попадалово уже состоялось. Если бы все команды OS выдавали какой-нибудь поток JSON-выражений или s-выражений, всё было бы по-другому.

Одна строка изменилась.

Во-первых, тут и вообще всего одна строка, во-вторых, я искал проблемы только в команде grep, а не в остальных. Могу ещё один вариант предложить: представь, что команда называется 5264 или pts. Т.е. тут хрупкость практически в каждой точке. И далее в командной строке очень высокая плотность смысла: одна буква идёт за целое слово. Сложность команды grep выросла примерно в 10 раз. Ну в 5, если считать повторяющиеся конструкции за одну.

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

Ещё проблемка: слишком длинные имена команд обрезаются. Да и вообще, если посмотреть man sort, то мы видим там целый язык запросов, включающий, к примеру, сортировку. Если фильтрацию процессов (которая, кстати, решает твою задачу лучше) ещё можно обосновать требованиями быстродействия, то сортировку можно оправдать только тем, что напечатанный ps-ом текст уже нельзя так просто отсортировать с помощью штатной команды sort - его перед этим придётся парсить. Если идея юникса состояла в том, чтобы разбить задачу на простые подзадачи, соединяемые в конвейер, то здесь этот подход явно нарушен, и нарушен он именно по причине, что «всё есть строка».

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

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

Я всегда считал, что юникс - это говно. Точнее говоря, я не считал так короткое время, когда после убогих bat-файлов узнал, что есть могущественный баш. Но вонь ощутилась очень быстро. Мне пришлось написать для «Кворума» сервер сборки. Он был на батниках, но написан под влиянием UNIX и были какие-то аналоги юниксовых текстовых программ. Но уже тогда стало ясно, что вот эта школьного уровня идея «выведи всё в строку а потом распарсь её» для серьёзных вещей не годится. Вывод в строку предназначен для чтения человеком, а не компьютером! А уж окончательно это стало ясно, когда зимой то ли 2014, то ли 2015 году моих знакомых в Питере взломали через уязвимость в bash. За 24 года не смогли сделать нормальный bash, да.

Давайте разберём насчёт вложенных структур, читая man ps.

Во-первых, ps -ejH выводит дерево процессов. Уровень дерева выражается в виде отступов. Удобно, да? С учётом того, что имена программ обрезаются, вывод этой команды практически полностью безполезен. Но вопрос не в том, а в том, что внезапно «простейшие» программы могут выдавать информацию в виде вложенных структур, и с ней придётся как-то работать, если она нужна, а нет ни нормального представления, ни простых инструментов. В лиспе или JS Это было бы выражено как вложенная структура данных - и с ней было бы тривиально работать.

Во-вторых, ключ, к примеру, p. «These options accept a single argument in the form of a blank-separated or comma-separated list». Что мы видим из этой цитаты? Что, во-первых, среди аргументов команды ps таки встречаются как минимум линейные списки. Поскольку в shell строка запуска ps и её аргументы - это уже список, получается, что параметр ключа -p - это список в списке. Т.е. команда ps -p «1 2» - это ничто иное, как двухуровневый список. Поскольку в говношелле нет двухуровневых списков, которые якобы не нужны, как вы мне тут вещаете, авторам ps пришлось создавать свой частный формат, кодить его, вписывать в мануал, и заставлять пользователей знать его конкретно для одного ключа одной команды, что потребует от них умения писать и читать этот формат. Если бы вместо shell был нормальный язык, было бы написано просто «These options accept a list».

Опция --sort требует уже двухуровневой структуры. Требуется задать по каким колонкам сортировать, и для каждой колонки ещё и порядок. Итого команда ps jax --sort=uid,-ppid,+pid является ничем иным, как трёхуровневым списком, в починенном тикле он бы выглядел как-то так:

ps jax --sort{uid{- ppid}{+ pid}}
# vs
ps jax --sort=uid,-ppid,+pid
Да, букв стало чуть больше, зато единый формат с чётко видной структурой, который гораздо проще.

Вот до какой степени нужно не уметь думать, чтобы говорить, что это не нужно, если нужность видна на первом же примере?

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

потому что SBCL не умеет запускать сторонние программы

uiop:run-program

И, кроме того, shell живёт не в вакууме. UNIX - это комплекс программ. Если ps выдаёт человеко-читаемую таблицу, а не структурированные данные, то попадалово уже состоялось.

Вот это правильный ответ. То есть, чтобы сделать другой shell (не на базе строк) нужно отказаться от человекочитаемого вывода и вообще от половины UNIX.

Но вот аналогичный пример на Powershell (здесь вместо строк объекты):

$vapm = Get-Process -Name vapm # точно один

# а svchost много
$s = 0
$k = 0
foreach ($i in (Get-Process -Name svchost))
{
  $s = $s + $i.VM
  $k = $k + 1
}
Write-Host $k $s
# выводит 62 136348303527936

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

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

То есть, чтобы сделать другой shell (не на базе строк) нужно отказаться от человекочитаемого вывода и вообще от половины UNIX.

Юникс мне не жаль, а вот добавить один ключик и выдавать в какой-нибудь XML вполне было бы возможно. Описать схемы XML для всех команд. И сделать программу, к-рая превращает XML в человеко-читаемый вид, которую уже можно через конвейер вызвать. Что-то типа troff, но другое.

А если отказаться от идеи, что с элементом можно сделать всё, что со списком из одного элемента, то будет много преобразований (car ...) и (list ...)

Ну так я же предложил, как это починить в стиле тикля: $x - это элемент. {*}$x - подставить элемент как список. Можно ещё какой-нибудь значок изобрести для функции «список, если это список, или список из одного элемента, если это элемент». В 8-битных кодировках значков мало, но это отдельный вопрос.

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

Ну и что доказывает пример на Powershell? Объекты есть, сериализация вложенных структур как-то прошла мимо данного примера. Т.е. я не вижу, как этот пример мог бы обосновать ненужность чего-то подобного JSON или S-выражениям в языках типа shell или tcl.

Я читал одну из апологий за tcl, что вот можно написать некий конфиг:

hosts {
  ip 127.0.0.1
  name www.ya.ru
}
И, добавив пару команд, сделать этот конфиг исполняемым. Но ведь ясно, что это наколенная поделка, поскольку такой способ чтения конфига страдает от внедрения вредоносного кода, и бороться с этим требует неких усилий. Которые по умолчанию забудутся и в итоге останется дыра. Кроме того, невозможно статически (без риска произвольных побочных эффектов) сказать, что этот конфиг хотя бы грамматически корректен, что вместо ip не написали ir.

По сравнению с этим, JSON не позволяет ничего исполнять и его можно валидировать. В том же лиспе элементарно можно управлять тем, является ли конфиг исполняемым или в него даже нельзя внедрить никакого исполнения *read-eval* nil .

Кроме этого, ни tcl, ни баш не предлагают встроенного (без наколенных парсеров) способа создавать конфиги. Именно поэтому в мире JS все конфиги могли бы быть в JSON, если бы там были допустимы комментарии. Так-то многие *.js, с теми же последствиями для уязвимости. Только в лиспе толково - можно делать конфиги s-выражениями.

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

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

Описать схемы XML для всех команд. И сделать программу, к-рая превращает XML в человеко-читаемый вид, которую уже можно через конвейер вызвать. Что-то типа troff, но другое.

Теперь становится понятнее почему ты фейлишь все начинания. И да, юникс это не твоё, зачем себя мучить?

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

Ну и что доказывает пример на Powershell? Объекты есть, сериализация вложенных структур как-то прошла мимо данного примера.

PS > $a = (1,2),(3,4)
PS > $a.length
2
PS > $a[0]
1
2

Т.е. я не вижу, как этот пример мог бы обосновать ненужность чего-то подобного JSON или S-выражениям в языках типа shell или tcl.

Shell должен быть в первую очередь лаконичным, во вторую — легко читаемым, а уже в третью — позволять сложные конструкции

Ну так я же предложил, как это починить в стиле тикля: $x - это элемент. {*}$x - подставить элемент как список.

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

И что делать с конструкциями типа

Get-Process proc | Format-List

Format-List на входе ожидает список, Get-Process может вернуть один элемент, а может список.

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

Описать схемы XML для всех команд. И сделать программу, к-рая превращает XML в человеко-читаемый вид, которую уже можно через конвейер вызвать.

И будет PowerShell.

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

Только в лиспе толково - можно делать конфиги s-выражениями.

И чем их читать? Если read, то те же уязвимости.

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

read с *read-eval* nil неуязвим - возвращает просто данные и ничего не выполняет. Если бы лисп ещё не intern-ил символы было бы вообще хорошо (можно рассмотреть intern при чтении как ошибку проектирования)

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

И будет PowerShell.

Ага, раз то, что я хочу, воплощено, значит, я хочу правильно. А не то, в чём меня тут пытаются убедить.

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

Ну, по идее да, подумал, когда написал уже, что формат данных должен быть строго типизированным, и выражаться это может только с помощью значков. Я в своё время сделал формат, которым пользовался аж на 3 языках, подобный s-выражениям. У меня там было просто: первая буква определяет тип, а дальше идут данные, формат которых зависит от типа. Получилось очень легко парсить и мне лично мой формат нравится больше JSON, не говоря уже об XML. Но в нужных случаях можно добавить полиморфизма, допустив на вход «атом или список». В лиспе это легко, в typescript вроде тоже есть, по остальным языкам я не знаю, но в целом если нет спецификатора типа «А или Б», то это проблема данного языка, не более того :) Есть у Завалишина подобная идея с типизацией, что нет файлов, а есть только объекты. Соответственно, у объекта grep будет метод exec, который возвращает поток-из {атом или список} Свой смысл в таком подходе присутствует, на мой взгляд. При этом отказываться от подхода «всё есть строка» необязательно, но нужно его поменять на «всё может быть представлено строкой, возможно, с потерей полноты и однозначности». Получится не хуже юникса.

Значков, может быть, получается не так уж мало, но и в tcl их не так уж мало: фигурные скобки, кавычки, {*}, list, string cat, subst - всё это примерно про одно, но есть отличия. В наборе примитивов тикля не видно ни ортогональности, ни элегантности. При том, {*} и string cat были добавлены относительно недавно - это по сути означает признание серьёзности проблемы quoting hell и является попыткой её смягчить.

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

Format-List на входе ожидает список, Get-Process может вернуть один элемент, а может список.

По идее Get-Process должен возвращать поток описаний процессов. В этом потоке будет либо один элемент, либо N. Вернуть одно S-выражение нельзя, т.к. это приводит к ухудшению отзывчивости. При печати в поток первые элементы доступны рано. Хотя вроде в XML парсерах есть разные подходы - при одном подходе читаем весь XML файл и потом парсим, а при другом читаем каждую запись, просто некоторые недостроенные записи помечены как недостроенные, и вызывается событие в момент их достройки. В этом случае Format-List всегда возвращает список потоков.

И да, в этом случае мы попадаем в ту ситуацию, о которой ты сказал - внешние скобки оказываются «лишними». Но с философской точки зрения, они не такие уж и лишние, т.к. заставляют сразу подумать о том, что запрос может вернуть более одного объекта. Можно сделать ключ «вернуть только один процесс или сигнализировать ошибку» - это будет более безопасный вариант. При нём не будет ни накладных расходов на лишний car, ни возможности протупить наличие двух процессов - программа внятно обругается достаточно рано.

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

По идее Get-Process должен возвращать поток описаний процессов.

Но этот поток можно сохранить в переменную (при этом сохраняется на самом деле future). И уже из переменной передать куда-нибудь.

Кстати, в PowerShell ещё интересное обобщение есть

> $proc = get-process notepad
> $proc.length
2 # 2 элемента
> $proc.ID # вызываем свойство объекта Process на список объектов
6712
9412

так что кроме неявного car/list есть ещё неявный mapcar.

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

Кстати, в PowerShell ещё интересное обобщение есть

Мне не нравится, потому что легко заблудиться. Если полиморфизма недоложить, получается слишком многословно. Если переложить, получается помойка. На мой взгляд, лучше недоложить, чем переложить.

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

Типичный пример лишнего полиморизма, который не признаёт 99% программистов: арифметические операции. 1+1=11 - это уже всем ясно, что перебор. А вот 1+1.1 или там 2/3 почему-то протеста не вызывает, хотя по сути-то это нонсенс.

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

На мой взгляд, лучше недоложить, чем переложить.

На мой взгляд, для shell'а наоборот. Длинные скрипты там не бывают, а лаконичность крайне важна.

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

Ага, раз то, что я хочу, воплощено, значит, я хочу правильно.

В общем-то, да. Но к этому следует добавить «раз миллионы людей десятки лет используют sh+coreutils», значит и в этом есть рациональное зерно.

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

Рациональное зерно в том, чтобы ничего не менять, есть всегда. «Оно работает - не трогай его». Но вот мне больше нравится лозунг языка Zig: «Software should be perfect». И спрос на замену шеллов есть, и предложение есть (я так понял, некоторые используют python, к примеру).

Длинные скрипты там не бывают, а лаконичность крайне важна.

Ну вот например wc /etc/grub.d/10_linux :

  371  1423 12425 /etc/grub.d/10_linux
Много это или нет? На мой взгляд, 400 строк на плотном языке - это уже «длинный».

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

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

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

Вопрос не в том менять что-то или не менять. Вопрос в том почему шелл таким сделали и почему спустя 40 лет при наличии кучи альтернатив им всё ещё пользуются? Подумайте об этом.

Много это или нет?

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

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

И спрос на замену шеллов есть, и предложение есть (я так понял, некоторые используют python, к примеру).

Вообще то перлу 30 лет уже, например. Питону не сильно меньше. Но баш они не убили (а ты похоже всерьез веришь, что кто-то мечтает о сложном языке общего назначения в качестве шелла). Шелл вовсе не для программистов делали, не забывай об этом.

anonymous
()
Ответ на: комментарий от ugoday

Подумайте об этом

Думаю-думаю - никак не надумаю. Я готов всё списать на «работает - не трогай», «де-факто стандарт», «везде есть из коробки» и прочие вещи, которые исключают выбор как таковой.

В данном случае — нет, но вообще для скриптов со сложной логикой

Угу, вот был перл в BSD, потом выпилили. Можете назвать эти «прекрасные» языки? Я слышал про Питон. Недавно тут был вброс (или серьёзный вопрос) на эту тему, ничего, кроме Питона, не запомнилось, искать заново лень. Вот Монк назвал PowerShell - видимо, сделан покультурнее, и, оказывается, даже переносимый теперь. Я его, наверное, всерьёз рассмотрю, и, если найду его хорошим, буду даже продвигать на работе. Потому что для кроссплатформенного софта поддерживать скрипты - это довольно большой геморрой. Правда, доверия к MS мало.

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

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

Ну и вообще-то сейчас скачал с opennet ман в виде pdf. 146 страниц. Вовсе не так уж и мало, чтобы не назвать «сложным».

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

Думаю-думаю - никак не надумаю.

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

Можете назвать эти «прекрасные» языки?

Примерно в половине случаев, если надо скриптовать, то ansible/salt/puppet справятся гораздо лучше. В остальном, python/perl5/ruby/guile/что-угодно-не-слишком-экзотическое справятся достаточно хорошо. Собтвенно, на масштабах типичного скрипта разница между любой скриптотой просто не успеет проявиться. Лично мой выбор — питон, просто потому, что я его лучше знаю. Коллеги используют аммонит, потому что скала форева и вообще. Что характерно, на масштабах в пару десятков строк разницы между аммонитом и башем нет совсем, единственно в аммоните визуального мусора больше, но к этому можно притерпеться.

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

что если вы не понимаете почему реальность устроена так, а не иначе

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

Примерно в половине случаев,

Спасибо! Прямо познавательный тред получился.

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

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

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

У тебя своя версия-то есть?

Есть, конечно, но я понятия не имею как её вам объяснить. Все нужные аргументы были высказаны ещё до меня, но у вас профдеформация. ;-( Вот, пытаюсь намёками зародить сомнение.

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

ты хочешь dict

http://wiki.tcl.tk/5042

смотри «More examples» «Here is a useful example: an array of dicts»

вот, например:

#!/usr/bin/env wish

package require Tcl 8.5
package require Tk

set windowparams {
    title myPrograms
    minsize {800 600}
    resizable {1 1}
}

set userconfig {
    menubar yes
}

set menu {
    Connection {
        "Log in" {
            -command login
        }
        "Log out" {
            -command logout
        }
        Exit {
            -command exit
        }
    }
    Help {
        About {
            -command about
        }
        Help {
            -command help
        }
    }
    -name menu
}

proc setup-window {w params} {
    wm title $w [dict get $params title]
    wm resizable $w {*}[dict get $params resizable]
    wm minsize $w {*}[dict get $params minsize]
}

proc build-menu {menu w args} {
    set label ""
    dict with args {
        set options [dict filter $menu key -*]
        if {[dict exists $options -command]} {
            $w add command -command [dict get $options -command] -label $label
        } else {
            if {[dict exists $options -name]} {
                set name [dict get $options -name]
            }
            set m [menu $w.$name]
            foreach {k v} $menu {
                if {![string match -* $k]} {
                    build-menu $v $m label $k name [incr i]
                }
            }
            if {[llength $args]} {
                $w add cascade -menu $m -label $label
            } else {
                $w configure -menu $m
            }
            return $m
        }
    }
}

setup-window . $windowparams
if {[dict get $userconfig menubar]} {
    build-menu $menu .
}

anonymous
()
Ответ на: комментарий от ugoday

Есть, конечно, но я понятия не имею как её вам объяснить.

А ты постарайся :)

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

Начну издалека. Есть языки с бедным алфавитом идентификаторов (Си, Java, Js, Python) и с богатым (лисп, тикль, sql, файловая система). В богатых возникает нужда в quoted identifiers, поскольку алфавит идентификатора пересекается с множеством отделителей токенов языка.

В тикле, и кавычки, и {} - это лишь способы закавычивания, отличающиеся наличием или отсутствием интерполяции. И это значит, что в рамках этой модели нельзя отличить строку с пробелами от списка. Одного лишь сохранения {} недостаточно.

В том же лиспе есть литералы символа, «строки» и `квазицитаты. Символы бывают обычные и закавыченные, т.е. |foo bar|. Если делать таблицу соответствия с tcl, то получается, что {} и «» одновременно выполняют роль конструктора списка, ограничителей литерала строки, сломанной квазицитаты и ограничителей закавыченного символа. При этом обычное слово без кавычек может быть символом, строкой или числом. А определение того, чем является данный токен, происходит только в момент использования. Офигеть!

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

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

# литерал символа
'ls' 
# литерал строки
"*.sh"
# литерал числа
@64ui123 # 64-разрядное беззнаковое целое
# литерал списка
("a" "b" "c")
# литерал записи
{"a" "b"}
# литерал с отложенным определением типа
a
# литералы подстановки
[другая-команда $переменная]
Команда неявно является списком, т.е. окружается парой (). Соответственно,
ls -l "мой файл*.sh"
Это список из литералов с отложенным определением типа и начертаниями «ls», "-l" и одним типизированным (строкой). Командный интерпретатор интерпретирует первый из них как символ, потому что он стоит на том месте, где должна быть команда. Строка уже строкой и остаётся, а насчёт -l есть варианты.

А. -l передаётся в ls как нетипизированный, а уже ls им дальше занимается. Выглядит логично, до тех пор, пока мы не начинаем синтезировать команды с помощью [] и $.

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

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

Г. Наверное, есть ещё варианты.

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

Спасибо за пример, пришлось над ним подумать. Попробую так ответить: если попытаться так представить дерево (например, html-страницу), то будет проблема, поскольку нельзя отличить лист от ветки.

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

А ты постарайся :)

Я недавно три дня убил, пытаясь объяснить Айронбагу простейшие вещи. Результат — фрустрация у меня, гордое чувство собственного превосходство у неё. Ну и зачем?

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

  • Вы в магазине подходите к кассе. Перед вами находится один покупатель. Это один человек или очередь из одного человека?
  • Вы взяли с собой в командировку книгу. У вас книга или библиотека из одной книги?
  • Вопрос со звёздочкой для любителей bdsm-типизации. Положим, что кошелёк с баксами отличается от кошелька с рублями. Различаются ли между собой кошелёк без баксов и кошелёк без рублей?

Чтобы понять почему шелл такой, вам нужно начать думать по-другому. Это можете сделать только вы. Придётся постараться уж вам.

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

Ты пытаешься выдумать message passing and late binding Алана Кея.

Да нет, я вообще говорю только про синтаксис. Выдумывать его не нужно, т.к. я его знаю (и не очень жалую, т.к. late binding = debugging hell).

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

Это один человек или очередь из одного человека?

С точки зрения процедуры обслуживания в кассе, это очередь из одного человека. С точки зрения сцены - это один человек. С точки зрения зрительного анализатора это - поток кадров. Как связано с обсуждаемым вопросом?

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

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

Вопрос со звёздочкой для любителей bdsm-типизации.

Я не любитель bdsm типизации. Таковая в плюсах, а я на лиспе больше программирую :) Если бог даст, и не буду никогда ничего программировать на плюсах.

Чтобы понять почему шелл такой, вам нужно начать думать по-другому

Это пока просто декларация, т.к. не объясняется, как именно надо думать.

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

В свою очередь, всё же буду гнуть свою линию. Считаешь ли ты, что в баше не нужны вложенные списки? Я привёл пример: ключ --sort в ps, который принимает двухуровневую структуру данных, и ключ -p, принимающий одноуровневый. Поскольку в bash нет понятия вложенной структуры данных, имеем зоопарк: для каждой команды и даже для каждого ключа в рамках одной команды представление структур разное. Считаешь ли ты это оптимальным с т.з. производительности труда всех участвующих в процессе лиц (разработчика команд типа ps и пользователя этих команд)?

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

Если бы я умел объяснять как именно надо думать, я бы зарабатывал в 10 раз больше. ;-(

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

Считаешь ли ты, что в баше не нужны вложенные списки?

Это крутая, но не приоритетная фича. Если вы придумаете как её добавить и не ухудшить читаемость, будет очень здорово.

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

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

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

Вот был у нас posix shell и куча скриптоты на нём. Bash можно рассматривать как его улучшение, башизмы реально упрощают многие вещи. Переход на идеальный баш будет происходить так же (и так же неторопливо) как переход с sh на bash.

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

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

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

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

Вот это уже другой разговор :)

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