1. Алфавит. Ассоциативные связи.
По поводу алфавита сказано так много, что я для начала процитирую работу Карла Бюлера «Теория языка»
«Алфавит — это ассоциативная цепочка (механическая последовательность), и больше ничего; но каждый выучивал и знает его. Поэтому отображения последовательностей каких-либо объектов на алфавит — это удобное соотнесение. Мы постоянно им пользуемся на практике для упорядочивания. Было бы не трудно доказать, что в системе знаков, из которых состоит естественный язык, встречается множество ассоциативных цепочек и переплетений, которые с психологической точки зрения находятся на одной ступени с алфавитной цепочкой, и которые оказывают нам такую же службу во всеобъемлющей задаче упорядочения нашего знания о предметах и сообщения этого знания другим».
Стало быть, каждому элементу алфавита можно и нужно поставить в соответствие значение (что собственно и делается сейчас ) и закрыть этот вопрос. Однако не все так просто. Логично считать алфавитом множество ассоциаций A. Если i не равно j и аi и аj: A, то AI пересеченное AJ = пустому.
Отображение T множества знаков S (объекты класса Symbol) на алфавит в языке l:L (где L множество языков) обозначим Tl. Они же (знаки) являются своего рода источником ассоциаций (через отношение Tl). Множество ассоциаций, порожденное отображением знаков Tl, обозначим Al (собственно алфавит языка l). Множество Al конечное, его можно пронумеровать, что и будет кодом ассоциации или алфавита, но будет категорически не правильно называть это кодом знака. Ассоциацию, порожденную знаком s в языке l обозначим Tl(s). Понятно, что Tl(s): Al. Несколько знаков могут порождать одну и ту же ассоциацию. Например, знак большая буква «А» и маленькая «а» порождает одну и ту же ассоциацию. Стало быть могут существовать s1:S, и s2:S такие, что Tl(s1) пересеченное с Tl(s2) не пусто. Это один момент. И второй момент то, что это ассоциация зависит от среды или для каждого языка свое множество ассоциаций. Т.е. у английской, французской и русской среды, один и тот же знак может вызывать разные ассоциации. Обычно для реализации отображения Tl достаточно построить таблицу ассоциаций (она же и есть отношение Tl), но могут применяться и более сложные алгоритмы как, например, в нотной записи, картографии или в построении электрических схем.
.
2. Группирование знаков.
Однако не для всех категорий знаков есть необходимость строить свою таблицу ассоциаций. Есть знаки, которые вызывают общие для всех языков ассоциации. Справедливо, даже более сильное утверждение: Различные ассоциации в разных языках вызывают только объекты, которые мы обычно называем буквами. Что бы подчеркнуть это свойство объединим их в группу Letter. А так как разбиение на группы уже произошло, разобьем множество знаков еще на несколько групп.
Группа цифра (группа Digital) в которую включены знаки 0,1,2,3,4,5,6,7,8 и 9 вызывающие очевидные и одинаковые ассоциации во всех современных языках.
Группа управляющих знаков (группа Command) в которую включены все знаки управления и форматирования. В современных стандартах ассоциации этой группы используются, однако не предусмотрены знаки, отображающиеся непосредственно в управляющие ассоциации. По какой-то странной логике отображение T знаков этой группы отсутствует, а для графического представления используются знаки использующие пустую ассоциацию и только в обратном отображении пустая ассоциация знак, имитирующий соответствующую управляющую ассоциацию. Т.е. знак, который отображается непосредственно в ассоциацию «перевод строки» (код 10 в стандарте KOI8) отсутствует, а знак изображающий перевод строки отображается «ассоциацией знака» с кодом 182 в стандарте KOI8.
Группа Mark включает в скобки, кавычки, запятые и прочее. Принципиальное отличие этой группы знаков, что они не принимают участие в лексическом разборе, а являются самостоятельными лексемами. Т.е. не формируют лексему, участвуя в какой-то последовательности знаков, а участвуют собственным наличием — отсутствием непосредственно в синтаксическом разборе.
Группа знаков Letter имеет еще одну особенность, которая и есть основное назначение знаков этой группы, последовательность этих знаков формирует собственную ассоциацию, которую назовем лексемой. Отделяются лексемы друг от друга знаками остальных групп, одним из которых является пробел.
После разделения знаков на группы можно соответственно разделить на соответствующие группы их ассоциации. Заметим, что для любого iи j:L, если s:Letter, то Ti(s)= Tj(s)=As. Этот факт позволяет для знаков этих групп создать единую таблицу ассоциаций для всех языков. И, кроме этого для всех групп кроме Letter, не имеет смысла свойство «регистр» (большой, маленький).
3. Ввод данных.
Все выше перечисленные группы объединяет одно спорное качество все их можно вводить с клавиатуры. Для того клавиатуру и изобретали, а так же и стандарты как кодировок знаков так и раскладок клавиатур. Подчеркнем здесь, что с клавиатуры вводятся именно знаки, а не ассоциации. И попытки подогнать в соответствие коды клавиатуры и коды ассоциаций наталкиваются на упорное сопротивление реального положения вещей. Но предусмотреть ввод всех необходимых на практике знаков, конечно, не возможно. Поэтому мы просто обязаны расширить возможности клавиатуры. Назначением клавиатуры является прямое соответствие нажимаемой клавише знаку, но поступать так всегда значило бы увеличение размеров клавиатуры до не разумных. Потому применяется метод комбинирования клавиш (одновременное нажатие нескольких клавиш) удобен для управляющей группы знаков. И тут же возникает вопрос, а не пора ли расширить стандарт знаков для функций уже ставших стандартными (копирование, удаление и т.д.) и добавить новых знаков для редактирования (новый раздел, примечание и т.д.)? Думаю вполне реально. А к этому придумать для каждого из них графическое изображение (которое зачастую уже придумано). Комбинирование знаков возможно еще специальными последовательностями. Так называемые композиционные знаки. Этот прием широко используется для смайликов (последовательность двоеточия и круглой скобки) или знака ® и.т.п. Применение для ввода знаков композиционных знаков дает широкие возможности для пользовательских знаков и смайлов.
Хорошей идеей считаю менять соответствие знаков и клавиш клавиатуры в зависимости от среды. Клавиатура Лебедева способная изменять изображение знаков на клавишах хорошо согласуется с нашими принципами.
4. Знаки как объекты.
4.1. Кодировка. Наборы знаков.
Это пошло со времен, когда мониторы и принтеры не отличались графическими возможностями, и каждая буква кодировалась «железно». Получилось так, что например, буква «а» английская и русская кодируется по-разному, хотя это же один знак. Таких примеров достаточно много. Я не вижу в этом много смысла. Притом что многих, действительно нужных знаков не хватает. Кроме того условное разделение на английские и русские буквы явно не выдерживает критики если мы будем кроме русского и английского использовать другие языки. Например, латинский или французский. Кто тогда мне скажет, какому языку принадлежит буква «p»?.. А веду я к тому, что это просто знак, и если считать этот знак объектом, то у него нет свойства «Язык». А это уже принципиально. Рассуждая логически данное свойство «Язык» должен иметь объект Word! Т.е. последовательность (группа) букв! Да и то это свойство не однозначно определяется последовательностью знаков. Вполне возможно одна последовательность знаков может иметь разный смысл в разных языках. А может и одинаковый. Пример: «petitio principii». Вот какие это буквы, и какой это язык? Или что б совсем было очевидно, какому языку принадлежит пробел " " или двоеточие ":"?. Отсюда следует только одно. Знак должен быть знаком. А если он и принадлежит, в силу своей исключительности, к какому-то алфавиту языка это не больше чем такой вот факт. Обычно если мы применяем прилагательное «Английский» или «Русский», то не к знаку, а к звуку, что бы конкретизировать именно изображение знака. Отсюда следует, что общепринятый подход с различными кодировками знаков по языкам не правильный. Наборы знаков, отличающихся или совпадающих написанием с другими языками, касаются только группы Letter, потому их можно кодировать внутри группы выделив для этого байт и имея разноязыкие наборы. А возможно достаточно и одного набора для всей группы индоевропейских языков.
4.2. Большие буквы. Сортировка.
Первые мониторы и принтеры были с ограниченными графическими возможностями, поэтому для больших букв предусматривалась отдельная кодировка, и на этом вопрос был закрыт. Значение этого кода служит параметром для операций сравнения, и остаются легко решаемые проблемы сортировок с учетом регистра и без. Если считать знак объектом возникает вопрос, как поступать с регистром? То ли это свойство, то ли это новый знак? Фактически вопрос стоит так: Считать ли большие буквы тем же знаком или это отдельный знак? Ответ: Это разные знаки обозначающее одно и то же. Само собой напрашивается объединить их в группу. Вопрос только что будем объединять? Вот здесь опять возникает вопрос, что такое знак? Только ли изображение? Или нас интересует смысловая нагрузка? Скорее смысловая нагрузка интересует. Тогда под это смысловое содержание надо и объединять варианты изображения. А если все-таки изображение? Тогда от изображения надо выходить на смысловую нагрузку. Так вот реально знак это изображение и не больше (вспомним иероглифы). Какой смысл мы вкладываем в это изображение это вопрос второй. Ну, а если это знак, то создание нового объекта вполне логично и создатели стандартов кодировок очень даже правильно поступили, определив отдельный код для каждого большого и маленького знака.
Давайте вдумаемся, какой смысл имеет это свойство? Или это не свойство, а отдельный знак? Ведь про отдельно стоящую букву мы не сможем сказать большая она или маленькая, кроме случаев отличимых графическим изображением. Т.е. фактически большая она или маленькая это понятие относительное и зависит от рядом стоящих букв или размера шрифта по умолчанию. Стало быть, это самостоятельное свойство, которое очевидно влияет на графическое изображение (и на сортировку) основываясь на размере шрифта или рядом стоящих букв. Сейчас размер буквы можно изменять как угодно, поэтому в отдельной кодировке для больших букв нет необходимости, а предусмотреть такое свойство (регистр) для букв необходимо. Здесь же заметим что ни управляющие знаки, ни знаки группы Mark, ни тем более пользовательские знаки этого свойства не имеют. Оно не имеет для них смысла. Время задуматься, а не наследуемый ли это класс от знаков?
4.3. Сортировка.
Необходимость сортировок знаков обычно сомнения не вызывает. А вот вызвало. Во-первых: Если считать знак объектом, то решение этого вопроса частный случай сортировки объектов, и по существу является вопросом определения операций сравнения на классе объектов. Допустим, мы этот вопрос решили, но нужен критерий для определения операций сравнения. При существующей на сегодняшний день ситуации код символа и служит таким критерием. Этот же код является параметром для формирования изображения, а это совершенно разные функциональные нагрузки.
Во-вторых, сами по себе знаки уже отсортированы. В той ситуации как это принято в данный момент, код символа и является порядковым номером положения его в таблице связанных с этим символом. В нашем случае объект Symbol определен в какой то группе, и тоже имеет свой индекс расположения, который вряд ли может быть аргументом для операций сравнения.
Таким образом, код символа несет в себе три различные функции: Является индексом массива, одним из параметров для графического изображения, и одним из параметров для операции сравнения. Если осуществлять динамическое и пользовательское формирование знаков, то это три разных свойства, а не одно. Стало быть, для операций сравнения к ассоциациям
Но кроме вопроса как выполнять операцию сравнения с учетом регистра или без, есть еще коварный вопрос. Если нет у буквы свойства «язык», то, как их сравнивать буквы из разных языков? И тут же напрашивается ответ. А ведь необходимость сортировок возникает при сортировке лексем. Сортировать отдельные буквы не имеет смысла. А в лексемах и свойство язык есть, и принадлежность лексемы какому-то классу!!! То есть мы пришли к тому, что сортировка применяется не к знакам, а к смыслу. То же самое можно сказать и о группе Digital. Мы сортируем не по знакам, а по значениям!
5. Обратное отображение .
Обратное отображение необходимо от ассоциации к знаку. Как мы заметили, одна ассоциация может быть порождена разными знаками. Но, дело в том, что как таковая ассоциация применяется только для внутренних нужд, и всегда порождена каким-то знаком. При современном подходе такая необходимость возникает при необходимости использовать управляющие ассоциации, так как они не имеют своего знака. Т.е. там, где надо сделать переход на новую строку или каким-то образом отформатировать информацию для вывода приходится сочинять что-то на тему chr(10) как в VB или /n как в C. Мы же смело можем поставить необходимый знак там, где он необходим. Как ожидается, он своим появлением вызовет изменение в тексте. Однако необходимо сделать только одно замечание, если управляющий знак является текстовой константой, то его управляющие функции не действуют. Т.е. взятый в текстовые кавычки управляющий знак теряет свои управляющие свойства.
6. Группа Mark.
6.1. Знак "=".
История этой проблемы, в общем, то старая и мне не понятно, почему до сих пор не появились стандарты на разные знаки применительно к логическим отношениям и собственно присваиванием значения. В принципе, можно сконструировать транслятор, который будет отличать по контексту различное применение этого знака. Но это влечёт за собой, как накладные расходы по ресурсам во время трансляции, так и ограничения для некоторых синтаксических конструкций, для того, что б транслятор однозначно опознавал контекст. В разных языках этот вопрос решают по-разному. В языках класса C принято присваивание обозначать знаком равно "=", а логическое отношение двойным знаком "==". В языках класса Pascal присваивание обозначают двойным знаком ":=" а, логическое отношение одним знаком "=". Язык VB пользуется одним знаком "=" для обоих применений приняв некие ограничения и умолчания. Одним, из которых является разделение двоеточием операторов в одной строке.
Думаю, и мы бы придумали нечто из этого, если бы не третье назначение для того же знака. Вопрос возник в связи с единым форматом, заявленным в системе Lada и дальнейшим развитием объектной парадигмы. Знак "=" используемый для определения значения (или даже выражения) свойства объекта имеет совсем другой смысл в операции присвоении значения динамически создаваемому объекту (оператором Dim). Фактически разница в том, что когда мы создаем объект в редакторе (например, как сейчас делается графическими мастерами, но это же присвоение имеет текстовый вид) и присваиваем ему свойство, например, Top=2, то это значение 2 сохраняется в формате хранения созданного элемента, и при загрузке этого элемента в соответствующем месте памяти уже будет находиться именно это значение. Нет никакой необходимости использовать команду Move, для занесения этого значения, т.е. непосредственно выполнять команду присвоения Top=2, а, следовательно, и генерировать транслятором соответствующий код. С аналогичной ситуацией сталкиваемся в HTML. Там присвоение не превращается в команду присвоения, а является, каким-то значением. Если считать что там тегами создаются объекты, то никаких команд для присвоения свойств транслятором не генерируется. Соответствующие значения просто уже находятся в соответствующих местах в двоичном формате после трансляции.
В концепции .Net это некий аналог статического свойства. Т.е. свойства для доступа, к которым не обязательно создавать объект. Но в концепции .Net речь идет о программах, т.е. только об объектах, которые создают классы. И языки программирования, не создают (в том смысле как пишут программы) объекты. А в концепции Lada создание объекта такой же процесс, как и написание программы (программа тоже объект). Более того, объекты могут находиться внутри программы, как во время написания, отладки так и выполнения. Это очень полезно для сопровождения, как для процесса проектирования программы, так и эксплуатации. Поясним на примере.
Пример 1. Создание в тексте программы объекта «Срок сдачи программы».
Tag «Срок сдачи программы»: Date
{
Value=Pointer «Поступление Т.З.»: Data. ¤Value+2Месяц
}
Допустим, где-то есть тег с датой поступления Т.З… В данном примере выполняется присвоение значения срока выполнения программы. Присвоение технологически произойдет на этапе трансляции (при создании объектов), и именно тогда выполнится операция сложения, и результат этого сложения сохранится в значении свойства Value объекта «Срок сдачи программы». Этот значение и будет служить информацией для управления проектом. Никакого запуска программы, и создания классов для доступа к объекту «Срок сдачи программы» нет необходимости. Достаточно что бы исходный текст хранился в сопровождаемом месте. Понятно, что для такого присвоения нет необходимости генерировать команды сложения и присвоения, формировать адреса для данных, выделять для них место при создании объекта, как это делается в программе. Новое значение даты формируется и присваивается во время трансляции, а не во время выполнения программы. Не говоря уже о том, что создаваемый объект может вообще не быть программой. А вот как нечто аналогичное происходит в программе.
Пример 2. Вычисление даты сдачи программы.
Dim DateTZ: Date
……
Dim Value: Date
Value= Date. ¤Value+2Месяц
Совсем иная картина в данном примере. Здесь обычная ситуация. Где-то определена переменная с датой поступления Т.З. (DateTZ). В результате трансляции создадутся объекты Dim и объекты присвоения и выражения с адресами операндов. При выполнении программы для данных выделится область памяти (операторами Dim), и когда наступит время выполнять данную последовательность команд, выполнится сложение, и потом присвоение.
Можно опять оставить задачу определения назначения на контекстный анализ транслятором, но тогда мы лишим себя возможности анализировать недопустимые присвоения в статических классах. А можно пойти дальше и отказаться от такой парадигмы как статические классы. Собственно их роль выполнение функций или методов, в какой-то области определения. Не вижу смысла отказываться от интуитивно более понятных категорий, ради того что бы породить новое понятие, да еще и попытаться объяснить его назначение.
Таким образом, мы просто вынуждены вводить новые знаки, что б опознать три различных назначения знака "=". Хотелось бы иметь две стрелочки для различных видов присваивания и знак "=" оставить для логических отношений.
Хотелось бы добавить операцию определяемого равенства (или тождества) для ссылочных объектов после, которого в фигурных или круглых скобках список свойств, по которым сравниваются два ссылочных объекта. Например
A B {Location, Size}
Даже если объекты разного класса они могут иметь одинаковые свойства.
Присваивание. Тогда присваивание правое можно определить как
Или можно пойти дальше с определяемыми отношениями вообще.
6.2. Знак обмена. "><".
Нет такого знака. Мы его сконструировали из двух знаков ">" и "<". А ведь полезный оператор. При необходимости поменять значения двух переменных необходимо определять третью переменную для сохранения промежуточного значения. Конечно, машинной команды такой нет. А ведь мы давно знаем, что формат процедуры (и программы) имеет в запасе место, которым пользуется именно по этому назначению (для сохранения промежуточных результатов) при вычислении выражений. Почему бы его не использовать для этой операции. Да. Отсутствие соответствующего знака это большая проблема!!! А двунаправленная стрелочка очень подошла бы. Или вот так.
6.3. Операции отношения. "=>", "<=", "!=".
Просто слов нет. Моделист конструктор какой-то. А ведь пора бы придумать соответствующие знаки. Особенно меня восхищает подход в языке C, где восклицательным знаком обозначили отрицание. Читать тексты, перегруженные знаками не соответствующими смысловой нагрузке очень увлекательное занятие. Неужели такие бедные графические возможности? Ведь давно есть сложившиеся обозначения для обозначения меньше и равно знак меньше и внизу черточка. Для обозначения больше и равно знак больше и внизу черточка. Неравенство обозначать принято перечеркнутым знаком равно
Здесь уместно применить так называемые композиционные знаки. Если знаки рассматривать как объекты, то при лексическом разборе (или даже до лексического разбора при редактировании) можно объединять составные знаки в один. Например знаки ":" и "=", в ":=". Или три точки "." в "…", Таким же путем получать смайлики или другие графические элементы так или иначе являющиеся знаками. Композиционные знаки добавлять в группу алфавит, и они могут наравне со стандартными участвовать в синтаксическом разборе.
6.4. Операция & и |. Кванторы.
Этим знаком принято обозначать логическую операцию в одних языках и конкатенацию текста в других. Как поступить если есть необходимость в обоих знаках? Или оставить и определиться с операцией по типу данных. Операция Или применяет знак |. Надо определиться. Знаки, которые давно используются в математической логике очень бы подошли. И ( или ( отрицание (¬), импликация () и два знака эквивалентности (,≡). Хотя, так как операции + и * определяются для каждого типа вполне можно обойтись ими для операций и или.
Традиционно в логике употребляется два вида кванторов: всеобщности () и существования (). Если F некоторая формула, содержащая единственную переменную x, то (x: F) — предложение утверждающее, что F выполняется для всех рассматриваемых объектов, а (x: F) — по крайней мере, для одного из них. Таким образом, появляется возможность описывать взаимосвязи между предикатами. Например, делать такие знаменитые утверждения, как (x: человек(x) смертен(x)) или (x: y: управдом(x) человек (у) друг(x, у) ).
6.5. Прогрессивные операции.
Сложились стандартные обозначения, для выполнения многих операций. Это суммирование и произведение по индексу, интеграл, дифференциал и многие другие. Выполнить эти операции, определив их какими-то (а они уже давно сложились) знаками не есть большая проблема, если язык позволяет функции высокого порядка. Наш язык таков.
Пример 3. Прогрессивное суммирование.
i=n∑mA[I]2 или
Пример 4. Прогрессивное произведение.
I=0n-1A[I2 или
Аналогично можно поступить и с интегралом, и не забыть про дифференциал и с прочими делами.
7. Группа Mark.
С тех же «железных» времен тянутся коды «перевода строки» и «возврат каретки». Это имело смысл, когда автоматизировали печатные машинки. Тогда это было актуально. Но сейчас, то зачем эти два управляющих кода? Вот табуляция пригодилась бы. Только не как управляющий код, а как лексема, содержащая количество пробелов (а может не только пробелов) и, конечно, с каким-то значением (количество) по умолчанию. Вообще-то табуляция должна иметь длину отступа в пикселях, или относительных единицах, а не количество пробелов. А то выравнивание текста становится невозможным. Для визуализации табуляции вполне подходит стрелочка, для перевода строки то, что и применяется в Word. Вообще управляющие знаки должны иметь визуальное представление, открывающееся в режиме просмотра управляющих кодов. Ведь не совсем логично иметь отдельно код перевода строки, и отдельно код знака визуализирующего перевод строки. Собственно это касается всех управляющих кодов, а не только тех, о которых я упомянул. Ведь какой смысл заложен в управляющие коды? Да редактирование и форматирование текста! И если сейчас мы имеет возможности редактировать не на уровне печатной машинки, то почему мы остановились в стандартизации управляющих кодов не только для перевода строки и перевода страницы но и нового раздела, примечания, комментариев и прочего. Почему не расширить возможности до уровня графического редактирования?
О пробеле. Были времена, когда это был знак со своей позицией и стандартными размерами, под которые подгоняли все буквы. Но теперь вполне можно иметь не знак, а размер не занятого пространства. Пусть с минимальным значением для каждого шрифта и размера шрифта.
Я бы подумал еще о пробеле, который не допускает переносов и форматирования. Если необходимо записать выражение с запретом форматирования. Например, формулу или пример, который должен выглядеть специальным образом там, где форматирование может нарушить задумку автора, изменив вид (а может и смысл) текста. Или пригодилось бы там, где мы используем знак “_” обозначая единый смысл несколькими словами. Например: Обращение_к_функции. По сути дела это обозначение единого понятия или объекта. Конечно, удобнее было бы применять вместо подчеркивания пробел, который вроде буквы не позволяет разорвать эту последовательность знаков при форматировании. Т.е. хотелось бы иметь пробел, который скорее буква, но выглядит как пробел (т.е. никак не выглядит).
Таким образом, предлагается 4 пробела. Один выполняющий функции табуляции. Второй служащий разделителем слов и позволяющий форматировать (изменять размеры пробела в сторону увеличения от некого минимального значения). Третий пробел, допускающий изменение размера только при редактировании, и не изменяемый при форматировании, и четвертый, который похож на третий, но не являющийся разделителем. Отличать функционально пробелы можно с помощью цвета фона.
Если мы применим такой подход к знакам, и управляющие коды будут иметь графическое представление, то нам не нужны будут хитрости с функциями, превращающими букву в код и наоборот (извиняюсь за рифму), для текстовых переменных, а использовали бы именно их графическое изображение в качестве управляющих знаков для форматирования текста. И не только в редакторе.
8. Желательные знаки.
Знаки из теории множеств:
Знак принадлежности.
Знак не принадлежности
Знак пусто .
Знак включения
Знак включения с замыканием
Знак включения справа
Знак включения с замыканием справа
Знак не включения
Знак бесконечность как максимальное значение
Объединение
Пересечение
Знак угол
Корень квадратный √
Тождественно
Приблизительно
Если то
То если
Тогда и только тогда
Знак принадлежности можно реализовать как логическое выражение вместо цикла с вложенной проверкой на наличие данного объекта в массиве или в коллекции.
Идя далеко вперед можно рекомендовать для булевских значений True и False отдельные знаки.
Например, True и False.
Было бы неплохо сделать отдельный знак для указателя.
По поводу алфавита сказано так много, что я для начала процитирую работу Карла Бюлера «Теория языка»
«Алфавит — это ассоциативная цепочка (механическая последовательность), и больше ничего; но каждый выучивал и знает его. Поэтому отображения последовательностей каких-либо объектов на алфавит — это удобное соотнесение. Мы постоянно им пользуемся на практике для упорядочивания. Было бы не трудно доказать, что в системе знаков, из которых состоит естественный язык, встречается множество ассоциативных цепочек и переплетений, которые с психологической точки зрения находятся на одной ступени с алфавитной цепочкой, и которые оказывают нам такую же службу во всеобъемлющей задаче упорядочения нашего знания о предметах и сообщения этого знания другим».
Стало быть, каждому элементу алфавита можно и нужно поставить в соответствие значение (что собственно и делается сейчас ) и закрыть этот вопрос. Однако не все так просто. Логично считать алфавитом множество ассоциаций A. Если i не равно j и аi и аj: A, то AI пересеченное AJ = пустому.
Отображение T множества знаков S (объекты класса Symbol) на алфавит в языке l:L (где L множество языков) обозначим Tl. Они же (знаки) являются своего рода источником ассоциаций (через отношение Tl). Множество ассоциаций, порожденное отображением знаков Tl, обозначим Al (собственно алфавит языка l). Множество Al конечное, его можно пронумеровать, что и будет кодом ассоциации или алфавита, но будет категорически не правильно называть это кодом знака. Ассоциацию, порожденную знаком s в языке l обозначим Tl(s). Понятно, что Tl(s): Al. Несколько знаков могут порождать одну и ту же ассоциацию. Например, знак большая буква «А» и маленькая «а» порождает одну и ту же ассоциацию. Стало быть могут существовать s1:S, и s2:S такие, что Tl(s1) пересеченное с Tl(s2) не пусто. Это один момент. И второй момент то, что это ассоциация зависит от среды или для каждого языка свое множество ассоциаций. Т.е. у английской, французской и русской среды, один и тот же знак может вызывать разные ассоциации. Обычно для реализации отображения Tl достаточно построить таблицу ассоциаций (она же и есть отношение Tl), но могут применяться и более сложные алгоритмы как, например, в нотной записи, картографии или в построении электрических схем.
.
2. Группирование знаков.
Однако не для всех категорий знаков есть необходимость строить свою таблицу ассоциаций. Есть знаки, которые вызывают общие для всех языков ассоциации. Справедливо, даже более сильное утверждение: Различные ассоциации в разных языках вызывают только объекты, которые мы обычно называем буквами. Что бы подчеркнуть это свойство объединим их в группу Letter. А так как разбиение на группы уже произошло, разобьем множество знаков еще на несколько групп.
Группа цифра (группа Digital) в которую включены знаки 0,1,2,3,4,5,6,7,8 и 9 вызывающие очевидные и одинаковые ассоциации во всех современных языках.
Группа управляющих знаков (группа Command) в которую включены все знаки управления и форматирования. В современных стандартах ассоциации этой группы используются, однако не предусмотрены знаки, отображающиеся непосредственно в управляющие ассоциации. По какой-то странной логике отображение T знаков этой группы отсутствует, а для графического представления используются знаки использующие пустую ассоциацию и только в обратном отображении пустая ассоциация знак, имитирующий соответствующую управляющую ассоциацию. Т.е. знак, который отображается непосредственно в ассоциацию «перевод строки» (код 10 в стандарте KOI8) отсутствует, а знак изображающий перевод строки отображается «ассоциацией знака» с кодом 182 в стандарте KOI8.
Группа Mark включает в скобки, кавычки, запятые и прочее. Принципиальное отличие этой группы знаков, что они не принимают участие в лексическом разборе, а являются самостоятельными лексемами. Т.е. не формируют лексему, участвуя в какой-то последовательности знаков, а участвуют собственным наличием — отсутствием непосредственно в синтаксическом разборе.
Группа знаков Letter имеет еще одну особенность, которая и есть основное назначение знаков этой группы, последовательность этих знаков формирует собственную ассоциацию, которую назовем лексемой. Отделяются лексемы друг от друга знаками остальных групп, одним из которых является пробел.
После разделения знаков на группы можно соответственно разделить на соответствующие группы их ассоциации. Заметим, что для любого iи j:L, если s:Letter, то Ti(s)= Tj(s)=As. Этот факт позволяет для знаков этих групп создать единую таблицу ассоциаций для всех языков. И, кроме этого для всех групп кроме Letter, не имеет смысла свойство «регистр» (большой, маленький).
3. Ввод данных.
Все выше перечисленные группы объединяет одно спорное качество все их можно вводить с клавиатуры. Для того клавиатуру и изобретали, а так же и стандарты как кодировок знаков так и раскладок клавиатур. Подчеркнем здесь, что с клавиатуры вводятся именно знаки, а не ассоциации. И попытки подогнать в соответствие коды клавиатуры и коды ассоциаций наталкиваются на упорное сопротивление реального положения вещей. Но предусмотреть ввод всех необходимых на практике знаков, конечно, не возможно. Поэтому мы просто обязаны расширить возможности клавиатуры. Назначением клавиатуры является прямое соответствие нажимаемой клавише знаку, но поступать так всегда значило бы увеличение размеров клавиатуры до не разумных. Потому применяется метод комбинирования клавиш (одновременное нажатие нескольких клавиш) удобен для управляющей группы знаков. И тут же возникает вопрос, а не пора ли расширить стандарт знаков для функций уже ставших стандартными (копирование, удаление и т.д.) и добавить новых знаков для редактирования (новый раздел, примечание и т.д.)? Думаю вполне реально. А к этому придумать для каждого из них графическое изображение (которое зачастую уже придумано). Комбинирование знаков возможно еще специальными последовательностями. Так называемые композиционные знаки. Этот прием широко используется для смайликов (последовательность двоеточия и круглой скобки) или знака ® и.т.п. Применение для ввода знаков композиционных знаков дает широкие возможности для пользовательских знаков и смайлов.
Хорошей идеей считаю менять соответствие знаков и клавиш клавиатуры в зависимости от среды. Клавиатура Лебедева способная изменять изображение знаков на клавишах хорошо согласуется с нашими принципами.
4. Знаки как объекты.
4.1. Кодировка. Наборы знаков.
Это пошло со времен, когда мониторы и принтеры не отличались графическими возможностями, и каждая буква кодировалась «железно». Получилось так, что например, буква «а» английская и русская кодируется по-разному, хотя это же один знак. Таких примеров достаточно много. Я не вижу в этом много смысла. Притом что многих, действительно нужных знаков не хватает. Кроме того условное разделение на английские и русские буквы явно не выдерживает критики если мы будем кроме русского и английского использовать другие языки. Например, латинский или французский. Кто тогда мне скажет, какому языку принадлежит буква «p»?.. А веду я к тому, что это просто знак, и если считать этот знак объектом, то у него нет свойства «Язык». А это уже принципиально. Рассуждая логически данное свойство «Язык» должен иметь объект Word! Т.е. последовательность (группа) букв! Да и то это свойство не однозначно определяется последовательностью знаков. Вполне возможно одна последовательность знаков может иметь разный смысл в разных языках. А может и одинаковый. Пример: «petitio principii». Вот какие это буквы, и какой это язык? Или что б совсем было очевидно, какому языку принадлежит пробел " " или двоеточие ":"?. Отсюда следует только одно. Знак должен быть знаком. А если он и принадлежит, в силу своей исключительности, к какому-то алфавиту языка это не больше чем такой вот факт. Обычно если мы применяем прилагательное «Английский» или «Русский», то не к знаку, а к звуку, что бы конкретизировать именно изображение знака. Отсюда следует, что общепринятый подход с различными кодировками знаков по языкам не правильный. Наборы знаков, отличающихся или совпадающих написанием с другими языками, касаются только группы Letter, потому их можно кодировать внутри группы выделив для этого байт и имея разноязыкие наборы. А возможно достаточно и одного набора для всей группы индоевропейских языков.
4.2. Большие буквы. Сортировка.
Первые мониторы и принтеры были с ограниченными графическими возможностями, поэтому для больших букв предусматривалась отдельная кодировка, и на этом вопрос был закрыт. Значение этого кода служит параметром для операций сравнения, и остаются легко решаемые проблемы сортировок с учетом регистра и без. Если считать знак объектом возникает вопрос, как поступать с регистром? То ли это свойство, то ли это новый знак? Фактически вопрос стоит так: Считать ли большие буквы тем же знаком или это отдельный знак? Ответ: Это разные знаки обозначающее одно и то же. Само собой напрашивается объединить их в группу. Вопрос только что будем объединять? Вот здесь опять возникает вопрос, что такое знак? Только ли изображение? Или нас интересует смысловая нагрузка? Скорее смысловая нагрузка интересует. Тогда под это смысловое содержание надо и объединять варианты изображения. А если все-таки изображение? Тогда от изображения надо выходить на смысловую нагрузку. Так вот реально знак это изображение и не больше (вспомним иероглифы). Какой смысл мы вкладываем в это изображение это вопрос второй. Ну, а если это знак, то создание нового объекта вполне логично и создатели стандартов кодировок очень даже правильно поступили, определив отдельный код для каждого большого и маленького знака.
Давайте вдумаемся, какой смысл имеет это свойство? Или это не свойство, а отдельный знак? Ведь про отдельно стоящую букву мы не сможем сказать большая она или маленькая, кроме случаев отличимых графическим изображением. Т.е. фактически большая она или маленькая это понятие относительное и зависит от рядом стоящих букв или размера шрифта по умолчанию. Стало быть, это самостоятельное свойство, которое очевидно влияет на графическое изображение (и на сортировку) основываясь на размере шрифта или рядом стоящих букв. Сейчас размер буквы можно изменять как угодно, поэтому в отдельной кодировке для больших букв нет необходимости, а предусмотреть такое свойство (регистр) для букв необходимо. Здесь же заметим что ни управляющие знаки, ни знаки группы Mark, ни тем более пользовательские знаки этого свойства не имеют. Оно не имеет для них смысла. Время задуматься, а не наследуемый ли это класс от знаков?
4.3. Сортировка.
Необходимость сортировок знаков обычно сомнения не вызывает. А вот вызвало. Во-первых: Если считать знак объектом, то решение этого вопроса частный случай сортировки объектов, и по существу является вопросом определения операций сравнения на классе объектов. Допустим, мы этот вопрос решили, но нужен критерий для определения операций сравнения. При существующей на сегодняшний день ситуации код символа и служит таким критерием. Этот же код является параметром для формирования изображения, а это совершенно разные функциональные нагрузки.
Во-вторых, сами по себе знаки уже отсортированы. В той ситуации как это принято в данный момент, код символа и является порядковым номером положения его в таблице связанных с этим символом. В нашем случае объект Symbol определен в какой то группе, и тоже имеет свой индекс расположения, который вряд ли может быть аргументом для операций сравнения.
Таким образом, код символа несет в себе три различные функции: Является индексом массива, одним из параметров для графического изображения, и одним из параметров для операции сравнения. Если осуществлять динамическое и пользовательское формирование знаков, то это три разных свойства, а не одно. Стало быть, для операций сравнения к ассоциациям
Но кроме вопроса как выполнять операцию сравнения с учетом регистра или без, есть еще коварный вопрос. Если нет у буквы свойства «язык», то, как их сравнивать буквы из разных языков? И тут же напрашивается ответ. А ведь необходимость сортировок возникает при сортировке лексем. Сортировать отдельные буквы не имеет смысла. А в лексемах и свойство язык есть, и принадлежность лексемы какому-то классу!!! То есть мы пришли к тому, что сортировка применяется не к знакам, а к смыслу. То же самое можно сказать и о группе Digital. Мы сортируем не по знакам, а по значениям!
5. Обратное отображение .
Обратное отображение необходимо от ассоциации к знаку. Как мы заметили, одна ассоциация может быть порождена разными знаками. Но, дело в том, что как таковая ассоциация применяется только для внутренних нужд, и всегда порождена каким-то знаком. При современном подходе такая необходимость возникает при необходимости использовать управляющие ассоциации, так как они не имеют своего знака. Т.е. там, где надо сделать переход на новую строку или каким-то образом отформатировать информацию для вывода приходится сочинять что-то на тему chr(10) как в VB или /n как в C. Мы же смело можем поставить необходимый знак там, где он необходим. Как ожидается, он своим появлением вызовет изменение в тексте. Однако необходимо сделать только одно замечание, если управляющий знак является текстовой константой, то его управляющие функции не действуют. Т.е. взятый в текстовые кавычки управляющий знак теряет свои управляющие свойства.
6. Группа Mark.
6.1. Знак "=".
История этой проблемы, в общем, то старая и мне не понятно, почему до сих пор не появились стандарты на разные знаки применительно к логическим отношениям и собственно присваиванием значения. В принципе, можно сконструировать транслятор, который будет отличать по контексту различное применение этого знака. Но это влечёт за собой, как накладные расходы по ресурсам во время трансляции, так и ограничения для некоторых синтаксических конструкций, для того, что б транслятор однозначно опознавал контекст. В разных языках этот вопрос решают по-разному. В языках класса C принято присваивание обозначать знаком равно "=", а логическое отношение двойным знаком "==". В языках класса Pascal присваивание обозначают двойным знаком ":=" а, логическое отношение одним знаком "=". Язык VB пользуется одним знаком "=" для обоих применений приняв некие ограничения и умолчания. Одним, из которых является разделение двоеточием операторов в одной строке.
Думаю, и мы бы придумали нечто из этого, если бы не третье назначение для того же знака. Вопрос возник в связи с единым форматом, заявленным в системе Lada и дальнейшим развитием объектной парадигмы. Знак "=" используемый для определения значения (или даже выражения) свойства объекта имеет совсем другой смысл в операции присвоении значения динамически создаваемому объекту (оператором Dim). Фактически разница в том, что когда мы создаем объект в редакторе (например, как сейчас делается графическими мастерами, но это же присвоение имеет текстовый вид) и присваиваем ему свойство, например, Top=2, то это значение 2 сохраняется в формате хранения созданного элемента, и при загрузке этого элемента в соответствующем месте памяти уже будет находиться именно это значение. Нет никакой необходимости использовать команду Move, для занесения этого значения, т.е. непосредственно выполнять команду присвоения Top=2, а, следовательно, и генерировать транслятором соответствующий код. С аналогичной ситуацией сталкиваемся в HTML. Там присвоение не превращается в команду присвоения, а является, каким-то значением. Если считать что там тегами создаются объекты, то никаких команд для присвоения свойств транслятором не генерируется. Соответствующие значения просто уже находятся в соответствующих местах в двоичном формате после трансляции.
В концепции .Net это некий аналог статического свойства. Т.е. свойства для доступа, к которым не обязательно создавать объект. Но в концепции .Net речь идет о программах, т.е. только об объектах, которые создают классы. И языки программирования, не создают (в том смысле как пишут программы) объекты. А в концепции Lada создание объекта такой же процесс, как и написание программы (программа тоже объект). Более того, объекты могут находиться внутри программы, как во время написания, отладки так и выполнения. Это очень полезно для сопровождения, как для процесса проектирования программы, так и эксплуатации. Поясним на примере.
Пример 1. Создание в тексте программы объекта «Срок сдачи программы».
Tag «Срок сдачи программы»: Date
{
Value=Pointer «Поступление Т.З.»: Data. ¤Value+2Месяц
}
Допустим, где-то есть тег с датой поступления Т.З… В данном примере выполняется присвоение значения срока выполнения программы. Присвоение технологически произойдет на этапе трансляции (при создании объектов), и именно тогда выполнится операция сложения, и результат этого сложения сохранится в значении свойства Value объекта «Срок сдачи программы». Этот значение и будет служить информацией для управления проектом. Никакого запуска программы, и создания классов для доступа к объекту «Срок сдачи программы» нет необходимости. Достаточно что бы исходный текст хранился в сопровождаемом месте. Понятно, что для такого присвоения нет необходимости генерировать команды сложения и присвоения, формировать адреса для данных, выделять для них место при создании объекта, как это делается в программе. Новое значение даты формируется и присваивается во время трансляции, а не во время выполнения программы. Не говоря уже о том, что создаваемый объект может вообще не быть программой. А вот как нечто аналогичное происходит в программе.
Пример 2. Вычисление даты сдачи программы.
Dim DateTZ: Date
……
Dim Value: Date
Value= Date. ¤Value+2Месяц
Совсем иная картина в данном примере. Здесь обычная ситуация. Где-то определена переменная с датой поступления Т.З. (DateTZ). В результате трансляции создадутся объекты Dim и объекты присвоения и выражения с адресами операндов. При выполнении программы для данных выделится область памяти (операторами Dim), и когда наступит время выполнять данную последовательность команд, выполнится сложение, и потом присвоение.
Можно опять оставить задачу определения назначения на контекстный анализ транслятором, но тогда мы лишим себя возможности анализировать недопустимые присвоения в статических классах. А можно пойти дальше и отказаться от такой парадигмы как статические классы. Собственно их роль выполнение функций или методов, в какой-то области определения. Не вижу смысла отказываться от интуитивно более понятных категорий, ради того что бы породить новое понятие, да еще и попытаться объяснить его назначение.
Таким образом, мы просто вынуждены вводить новые знаки, что б опознать три различных назначения знака "=". Хотелось бы иметь две стрелочки для различных видов присваивания и знак "=" оставить для логических отношений.
Хотелось бы добавить операцию определяемого равенства (или тождества) для ссылочных объектов после, которого в фигурных или круглых скобках список свойств, по которым сравниваются два ссылочных объекта. Например
A B {Location, Size}
Даже если объекты разного класса они могут иметь одинаковые свойства.
Присваивание. Тогда присваивание правое можно определить как
Или можно пойти дальше с определяемыми отношениями вообще.
6.2. Знак обмена. "><".
Нет такого знака. Мы его сконструировали из двух знаков ">" и "<". А ведь полезный оператор. При необходимости поменять значения двух переменных необходимо определять третью переменную для сохранения промежуточного значения. Конечно, машинной команды такой нет. А ведь мы давно знаем, что формат процедуры (и программы) имеет в запасе место, которым пользуется именно по этому назначению (для сохранения промежуточных результатов) при вычислении выражений. Почему бы его не использовать для этой операции. Да. Отсутствие соответствующего знака это большая проблема!!! А двунаправленная стрелочка очень подошла бы. Или вот так.
6.3. Операции отношения. "=>", "<=", "!=".
Просто слов нет. Моделист конструктор какой-то. А ведь пора бы придумать соответствующие знаки. Особенно меня восхищает подход в языке C, где восклицательным знаком обозначили отрицание. Читать тексты, перегруженные знаками не соответствующими смысловой нагрузке очень увлекательное занятие. Неужели такие бедные графические возможности? Ведь давно есть сложившиеся обозначения для обозначения меньше и равно знак меньше и внизу черточка. Для обозначения больше и равно знак больше и внизу черточка. Неравенство обозначать принято перечеркнутым знаком равно
Здесь уместно применить так называемые композиционные знаки. Если знаки рассматривать как объекты, то при лексическом разборе (или даже до лексического разбора при редактировании) можно объединять составные знаки в один. Например знаки ":" и "=", в ":=". Или три точки "." в "…", Таким же путем получать смайлики или другие графические элементы так или иначе являющиеся знаками. Композиционные знаки добавлять в группу алфавит, и они могут наравне со стандартными участвовать в синтаксическом разборе.
6.4. Операция & и |. Кванторы.
Этим знаком принято обозначать логическую операцию в одних языках и конкатенацию текста в других. Как поступить если есть необходимость в обоих знаках? Или оставить и определиться с операцией по типу данных. Операция Или применяет знак |. Надо определиться. Знаки, которые давно используются в математической логике очень бы подошли. И ( или ( отрицание (¬), импликация () и два знака эквивалентности (,≡). Хотя, так как операции + и * определяются для каждого типа вполне можно обойтись ими для операций и или.
Традиционно в логике употребляется два вида кванторов: всеобщности () и существования (). Если F некоторая формула, содержащая единственную переменную x, то (x: F) — предложение утверждающее, что F выполняется для всех рассматриваемых объектов, а (x: F) — по крайней мере, для одного из них. Таким образом, появляется возможность описывать взаимосвязи между предикатами. Например, делать такие знаменитые утверждения, как (x: человек(x) смертен(x)) или (x: y: управдом(x) человек (у) друг(x, у) ).
6.5. Прогрессивные операции.
Сложились стандартные обозначения, для выполнения многих операций. Это суммирование и произведение по индексу, интеграл, дифференциал и многие другие. Выполнить эти операции, определив их какими-то (а они уже давно сложились) знаками не есть большая проблема, если язык позволяет функции высокого порядка. Наш язык таков.
Пример 3. Прогрессивное суммирование.
i=n∑mA[I]2 или
Пример 4. Прогрессивное произведение.
I=0n-1A[I2 или
Аналогично можно поступить и с интегралом, и не забыть про дифференциал и с прочими делами.
7. Группа Mark.
С тех же «железных» времен тянутся коды «перевода строки» и «возврат каретки». Это имело смысл, когда автоматизировали печатные машинки. Тогда это было актуально. Но сейчас, то зачем эти два управляющих кода? Вот табуляция пригодилась бы. Только не как управляющий код, а как лексема, содержащая количество пробелов (а может не только пробелов) и, конечно, с каким-то значением (количество) по умолчанию. Вообще-то табуляция должна иметь длину отступа в пикселях, или относительных единицах, а не количество пробелов. А то выравнивание текста становится невозможным. Для визуализации табуляции вполне подходит стрелочка, для перевода строки то, что и применяется в Word. Вообще управляющие знаки должны иметь визуальное представление, открывающееся в режиме просмотра управляющих кодов. Ведь не совсем логично иметь отдельно код перевода строки, и отдельно код знака визуализирующего перевод строки. Собственно это касается всех управляющих кодов, а не только тех, о которых я упомянул. Ведь какой смысл заложен в управляющие коды? Да редактирование и форматирование текста! И если сейчас мы имеет возможности редактировать не на уровне печатной машинки, то почему мы остановились в стандартизации управляющих кодов не только для перевода строки и перевода страницы но и нового раздела, примечания, комментариев и прочего. Почему не расширить возможности до уровня графического редактирования?
О пробеле. Были времена, когда это был знак со своей позицией и стандартными размерами, под которые подгоняли все буквы. Но теперь вполне можно иметь не знак, а размер не занятого пространства. Пусть с минимальным значением для каждого шрифта и размера шрифта.
Я бы подумал еще о пробеле, который не допускает переносов и форматирования. Если необходимо записать выражение с запретом форматирования. Например, формулу или пример, который должен выглядеть специальным образом там, где форматирование может нарушить задумку автора, изменив вид (а может и смысл) текста. Или пригодилось бы там, где мы используем знак “_” обозначая единый смысл несколькими словами. Например: Обращение_к_функции. По сути дела это обозначение единого понятия или объекта. Конечно, удобнее было бы применять вместо подчеркивания пробел, который вроде буквы не позволяет разорвать эту последовательность знаков при форматировании. Т.е. хотелось бы иметь пробел, который скорее буква, но выглядит как пробел (т.е. никак не выглядит).
Таким образом, предлагается 4 пробела. Один выполняющий функции табуляции. Второй служащий разделителем слов и позволяющий форматировать (изменять размеры пробела в сторону увеличения от некого минимального значения). Третий пробел, допускающий изменение размера только при редактировании, и не изменяемый при форматировании, и четвертый, который похож на третий, но не являющийся разделителем. Отличать функционально пробелы можно с помощью цвета фона.
Если мы применим такой подход к знакам, и управляющие коды будут иметь графическое представление, то нам не нужны будут хитрости с функциями, превращающими букву в код и наоборот (извиняюсь за рифму), для текстовых переменных, а использовали бы именно их графическое изображение в качестве управляющих знаков для форматирования текста. И не только в редакторе.
8. Желательные знаки.
Знаки из теории множеств:
Знак принадлежности.
Знак не принадлежности
Знак пусто .
Знак включения
Знак включения с замыканием
Знак включения справа
Знак включения с замыканием справа
Знак не включения
Знак бесконечность как максимальное значение
Объединение
Пересечение
Знак угол
Корень квадратный √
Тождественно
Приблизительно
Если то
То если
Тогда и только тогда
Знак принадлежности можно реализовать как логическое выражение вместо цикла с вложенной проверкой на наличие данного объекта в массиве или в коллекции.
Идя далеко вперед можно рекомендовать для булевских значений True и False отдельные знаки.
Например, True и False.
Было бы неплохо сделать отдельный знак для указателя.