LINUX.ORG.RU

Ключи, записи с атрибутами и как всё это получше сделать

 , ,


0

2

Упёрся. Есть такая простая вещь, как синтаксис.

Вот примеры:

ключ используется сам по себе, без значения
ls -l *.c

в лиспе ключ почти всегда используется в паре со значением
(make-foo :a 1 :b 2) 

<img src="siski.png" alt="UML-диаграмма">

Но ведь есть и «синтаксис»

for i in a do 
Во всех примерах есть общность в том, что есть имена атрибутов и их значения, которые иногда есть, а иногда их нет. Их же можно назвать «ключевыми словами». Хотелось обобщить это так, чтобы было легко и приятно.

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

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

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

В языках с гомоиконностью, или просто в расширяемых языках так не получается. Сегодня я завёл переменную finally, а завтра в языке появилось ключевое слово finally и вот мы приехали.

В лиспе традиционно используются кейворды, например

(defsystem 
  :serial t
  :description "Some utilities by Budden, mostly public domain"
  :depends-on 
  (:alexandria :cl-fad :split-sequence :cl-utilities :named-readtables
   :cl-ppcre		
   :iterate-keywords :swank :decorate-function :closer-mop)
  )

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

(defsystem 
  serial t
  description "Some utilities by Budden, mostly public domain"
  depends-on 
  (alexandria cl-fad split-sequence cl-utilities named-readtables
   cl-ppcre		
   iterate-keywords swank decorate-function closer-mop)
  )
И стало меньше мусора в тексте. Вот. Тут надо принять стратегическое решение, которое потом вряд ли удастся исправить. Посоветуйте что-нибудь.

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

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

объект хрень
 имя1 
  очень-длинное-значение-1
 имя2 значение2 
 имя3 значение3 имя4 // здесь нас подстрахует парсер
 имя5 значение 5 // несмотря на эту вторую ошибку
кно
★★★★★

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

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

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

Ты уверен что это именно от синтаксиса? Язык с идеальным синтаксисом тоже может быть нечитаем.

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

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

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

А чем особым хорош Perl?

Лаконичность и понятность:

next LINE if /^#/;

Возможность писать функции-операторы:

    sub try (&@) {
	my($try,$catch) = @_;
	eval { &$try };
	if ($@) {
	    local $_ = $@;
	    &$catch;
	}
    }
    sub catch (&) { $_[0] }
    try {
	die "phooey";
    } catch {
	/phooey/ and print "unphooey\n";
    };

Читабельность:

pretty_print({
    filename      => 'filename',
    text          => $long_text,
    text_width    => 80,
    justification => 'full', sentence_lead => 1});
на мой взгляд читается легче, чем
(pretty-print
  :filename "filename"
  :text long-text
  :text-width 80
  :justification :full :sentence-lead 1)

Я про то, что в CL :bla-bla не всегда обозначает имя параметра. Это ещё может быть значение перечисления.

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

Возможность писать функции-операторы.

Ок.

(pretty-print
  :filename         "filename"
  :text             long-text
  :text-width       80
  :justification    :full :sentence-lead 1)
Так уже тоже ничего читается. Но да, проблема кейвордов есть, над ней-то я и начал ломать голову перед этой темой Но ничего так и не смог придумать. А нельзя в перле поставить $key_name слева от => ?

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

Так уже тоже ничего читается

Читается в первую секунду как «justification => :full :sentence-lead 1». То есть ":justification '(:full :sentence-lead 1)".

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

(pretty-print
  #:filename         "filename"
  #:text             long-text
  #:text-width       80
  #:justification    'full #:sentence-lead 1)

Но там совсем другая идея модулей/пакетов.

А нельзя в перле поставить $key_name слева от =>

Можно.

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

Здесь-то у меня есть явные предпочтения. Если параметров мало, они обязательные и функция используется часто, то эти параметры должны быть неименованными.

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

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

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

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

Я имею в виду не только функции, но и любые синтаксические конструкции. Например, представь себе в Паскале формальный параметр функции:

function a(x:integer, y:string); 

А теперь представь, что мы рассахариваем этот сахар и делаем всё явным. Что получается?

function a(argument name = x type = integer, argument name = y type = string)
Получается XML. Думаю, было немало попыток сделать языки программирования на базе XML. С одним из них (ant) я даже имею несчастье сталкиваться по работе. Повбывал бы!

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