Нестандартный подход к построению современного языка программирования

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

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

В современных языках программирования что-то не так


Чтобы не было скучно, речь пойдёт именно о недостающих тонкостях языков, а не о недостатках существующих инструментов (зачастую язык сильно связан с конкретной средой разработки). Итак, ниже я отобрал 5 самых «ненужных и бесполезных» пунктов, о которых «никто не говорит», а я расскажу. Да, автор человек и любит холивары в комментариях, но просит воздержаться.

1. Нормальные программисты хотят писать более короткий и более понятный для всех код. Эта тенденция очень заметна с приходом Python. Посмотрите Swift по сравнению с Objective-C, D по сравнению с C++, и остальные языки, появившееся в последнее время. Все они стремятся визуально облегчить конструкции языка, сохранив их смысл и предназначение. Конечно же это получается не везде.

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

3. До сих пор программисты наблюдают низкую переносимость ранее написанного кода. С библиотеками/фреймворками всё хорошо, но вот модули и классы потерялись в тоннах кода. Никакой ООП, АОП и функциональный подход не улучшают переиспользование такого кода. Эта задача решаема комплексно: легкость языка, функции среды разработки и окружение для конкретного разработчика. Словно портфель знаний Ваш код однажды станет переносим как папка с документами. Вы сможете легко их объединять, разделять, копировать, формировать из их сочетания новые пакеты. Словом всё то, что не было доделано до конца с классами java и много где ещё.

4. В современных языках наблюдается недостаточная прозрачность кода. Речь идёт о Вашем коде, даже без подключенных библиотек. Насколько Вы точно знаете, что происходит под капотом этого зверя? К счастью, проблемы возникают крайне редко. Но когда они возникают, люди лезут в самые дебри байт-кода, устройства стека и трансляции классов java, чтобы найти причину проблемы в нормальном на первый взгляд коде. Эта проблема редкая, комплексная (язык конечно же не самый виновник) и в целом не исправима. Но глубина кода, до которого Вы можете дотянуться в поисках проблемы, не достаточна. Самые хитрые нюансы устройства типов данных и их расположения в памяти скрыты за пределами кода. С этим и следует бороться, повышая прозрачность кода от высокоуровнего вызова до каждого бита.

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

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

Язык программирования ΣL


В начале несколько фактов о том, почему было выбрано такое название. Первоначально язык назывался WL (от white light), но кто-то известный занял это сокращённое название своим грандиозным проектом Wolfram Language. Поэтому я развернул W на 90 градусов, и это мне понравилось. После же, спросив Интернет, пришло осознание, что повернул я букву не в ту сторону. Несмотря на то, что язык с названием «Сигма» существовал с 1965 до самых 90-ых годов, переименовывать проект ещё раз не было желания.

«Сигма» — язык программирования общего назначения.

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

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

Базовый набор носит классическое название source, от него наследуются все остальные наборы.

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

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

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

Перейдём к числам. Обычно все числовые значения распознаются компилятором в процессе компиляции, в «Сигма» же числа являются базовыми структурами языка, наличие которых, как наличие набора source, неоспариваемо. Это активно используется как преимущество языка. Для обозначения чисел используется символ подчёркивания:

_ - это множество целых беззнаковых чисел,
__ - множество целых знаковых чисел,
__._ - знаковое, с фиксированной точкой
__,_ - знаковое, с плавающий точкой
_._ - беззнаковое, с фиксированной точкой
_,_ - беззнаковое с плавающей точкой

Есть возможность указывать диапазон значения, например, __[-10:10] — это целое число, которое принимает значение от -10 до 10 включительно.

В языке присутствует необычное ключевое слово «me». Оно является заменой this, но об этом расскажу позже.

Пример кода на языке «Сигма»:

@binary
//это базовый модуль типов для двоичных машин

binary {
  signed {
 //…
  }
  unsigned {
  //описание бита - минимальной единицы данных для двоичной машины
  bit: source { //source - это базовый тип, основа всех наборов
    _[0:1] value;
    state True is { //название состояния регистро-независимо: true, TRUE, True, tRUE, ...
      me.value == 1;
    }
    state False is {
      me.value == 0;
    }
    // операторы, методы и их внутренности опущены для наглядности
    operator := {}
    alloc(){}
    init(){}
    dealloc() {}
  } //bit
} //unsigned

  alias bit signed.bit;
  alias ubit unsigned.bit;
}

Обратите внимание на описание значения бита и его состояния. А так же запомните этот код, мы к нему ещё вернёмся.

Причина такого решения многим не понятна, зато программист сразу привыкает к такому решению и просто использует его. Кажется, что здесь нет проблемы, но на самом деле их было очень много. Чтобы сделать описание состояния настолько понятным и прозрачным ушли месяцы. Можно долго рассказывать о реализациях типов в каждом из языков и о работе условного оператора if, но это утомительно.

Приведённое выше описание явно вводит состояние, которое становится прозрачно описано для программиста, а не скрытно прибито к типу ключевым словом. Грубо говоря, этот код документирует сам себя. В любой момент Вы можете увидеть, что означает то или иное состояние, вследствие чего у Вас отпадает надобность запоминать выдержки документации. Помните такие значения как Infinity, NaN? Теперь их можно явно прописать такой конструкцией.

Состояние набора — это соответствие определённых элементов набора нужным значениям.

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

state False is {
    me.value == 0;
}

Слева у нас подставляется значение в процессе выполнения (me.value), справа заданное описанием статическое множество (0). Таких выражений может быть несколько (разумеется противоречить нельзя, писать второй раз me.value не допустимо).

Делается разность двух множеств. Если они равны, то множество вычитается само из себя (результат пустое множество). У Вас должен возникнуть вопрос, как с этим работает условный оператор (и другие операторы тоже). Оператор if проверяет пустое множество или нет. В случае положительного ответа выполняется последовательность инструкций.

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

Главный минус такого решения: нельзя в состоянии прописать условие отличные от тождественных. Например: нельзя писать «me.value >= 0;».

В коде это выглядит достаточно привычно. Ниже показано 4 варианта записи сравнения и 4 варианта присваивания состояния. Все валидны для текущей версии языка ΣL.

use binary;
alias bit binary.unsigned.bit;

bit b := 1;
if (b == 1) { b := 0; }
if (b == True) { b := False; }
if (b is True) { b := binary.unsigned.bit.state.False; } 
if (b.state is True) { b.value := 0; }

В наборе binary.unsigned.bit должны быть реализованы операторы сравнения и присвоения (последний как для числа, так и для состояния). Правила указания их приоритета отдельный разговор.

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

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

Все остальные типы языка для двоичных машин выводятся на основе модуля binary. Например, описание типов под архитектуру х86 начинается так:

@x86

use binary;

x86: binary {
    signed {
        byte {

Аналогично сделано и для десятичной и для троичной архитектуры.

Так же обратите внимание на ключевое слово «use», после его использования привычные «import», «using» и «include» выглядят как «begin» и «end» после сишных скобок. Автор обленился печатать, и его прёт. На самом деле автор видел много людей-программистов, которым это решение очень понравилось.

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

Ключевое слово me заменит self/this и т.п.


В этой части мы поверхностно поговорим о том, как замена привычного ключевого слова this (или self) на слово me влияет на скорость набора кода и ощущения, в процессе программирования.

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

Любую замену для ускорения ввода текста можно довести до абсурда, и в случае языка программирования получить что-то похожее на BrainFuck. По этой причине использование различных иероглифов, символов решётки и тому подобного является абсурдом для замены ключевого слова this. Важное примечание: для кого-то сама такая замена может казаться абсурдом, просто эта статья не для них. Более того ввод подобных символов на наших клавиатурах не всегда предусмотрен и удобен.

Выражения языка программирования должны быть максимально понятны, чётки, коротки (а затем лаконичны и элегантны для восприятия). По возможности следует использовать человекочитаемые фразы. Это помогает запомнить конструкции и быстрее адаптироваться в новом языке. Никлаус Вирт показал успешные примеры таких строгих, чётких и человекочитаемых языков программирования. Но в них были серьёзные недостатки в скорости написания и чтения кода. Простым примером служит конструкция begin end в языке Pascal. Думаю все согласятся, что после фигурных скобок {} языка C, писать begin end просто изнурительно. Новые языки программирования помимо технологий, прошлых наработок и современных падигм должны учитывать вышесказанное.

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

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

Если кто-то будет разрабатывать свой язык программирования в нашем веке я крайне рекомендую попробовать развить i-метод. С ним можно попытаться убрать точку обращения к методу или полю, получив проблемы с венгерской нотацией и похожие на продукты Apple названия iValue.

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

В замере на скорость непрерывной печати (в течении первых 6 секунд от начала эксперимента) наша команда продемонстрировала следующие усреднённые результаты:

3 this.
3 self.
5 me.

В последующие секунды скорость набора me значительно опережала this и self.
Значение скорости набора текста, к тому же непрерывного набора одной и той же фразы, слабо связано с реальной работой программиста. Поэтому был сделан более важный замер, уже в спокойной обстановке и в момент написания осмысленного кода. В этот раз никто не спешил, обстановка была приближена к повседневной рабочей.

Результаты показали, что в среднем self и this затрачивают одинаковое время в процессе работы программиста. Таким образом, self и this вряд ли могут быть конкурентом друг другу. Если создаваемый набор (класс/объект) редко вызывает собственные методы в реализации и редко обращается к своим полям данных, то использование me не даёт никаких преимуществ. При написании кода в иных наборах (преимущественно с частым обращением к собственным полям данных) на каждые напечатанные 10 self или this приходилось до 16 me, напечатанных за то же самое время. Некоторые коллеги отметили, что при использовании me они больше фокусировались на имени метода или поля, то есть выражение:

me.valueResult += me.valueOne * me.valueTwo;

в момент печати читалось словно me нет совсем:

valueResult += valueOne * valueTwo;

По их словам, такого не происходило с self и this, но я им не верю. На мой взгляд, self и this конечно же съедают больше места в строке кода, чем и обращают на себя внимание при чтении. Кстати, для кого-то это может быть плюсом. Забавный минус — падает скорость чтения кода: «сэлф» и «зис» читается миллисекунды дольше «ми». Вся забава в том, что это правда влияет на быстроту понимания кода человеком.

Важно, что такая маленькая замена, не вызвала проблем. Все испытуемые очень легко переключились на использование ключевого слова me, никто не ощутил дискомфорта. Напротив, всем понравилась такая замена.

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

В любом случае Вы вряд ли испортите свой проект: сочетание Ctrl+H плюс заменить все « me.» (с пробелом в начале) на « this.» вернёт всё как было.

Спасибо, что дочитали.
Пусть терпение и сила прибудет с Вами!
Поделиться публикацией

Комментарии 87

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

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

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

      P.S. А пробовали "me." заменить на "I."? Может, будет ещё прирост?
        0

        Надо на просто точку заметь! "." быстрее чем "i."

          –1
          Плюсую за интерес к весёлым темам!
          На мой взгляд «I.», i-метод и просто точка не подходят по причине уставшего взгляда программиста. Кто долго засиживается с кодом просто не увидит эту точку.
          За me, как и за this, глаза цепляются лучше.
            0

            Вот так намного заметнее будет
            ⬤getValue

              0
              использование геттеров не очень хороший метод. Например, в с++ для доступа к закрытым данным-членам визуально удобнее использовать метод с именем члена. При этом имя члена содержит либо префикс, либо суффикс. Выглядит это? например, следующим образом
              class T {
              int @rows;
              int @cols;
              public:

              int rows() {return @rows;}
              int cols() {return @cols;}

              }
                0

                Не очень хороший визуально или логически? Если вам нужно менять свойство, есть, фактически, два способа. Делать свойство публичным (и не иметь потом простой возможности перехватить изменения) или делать геттер+сеттер.

                  0
                  Речь шла о том, так ли необходимы геттеры.
                  Насчет сеттеров — другая ситуация. В подавляющем большинстве случаев защищенные данные могут модифицироваться собственными методами класса, нагруженными основным функционалом. Например, при моделировании, скажем, эволюции некоторого объекта, его состояние вполне может изменять тот метод или друг, который его, собственно, и рассчитывает. Необходимость в каких либо сеттерах в таких случаях отсутствует. Ну и, собственно, почему именно get(), а не clone(), например? set(), а не put()? Вообще get() в естественном языке предполагает перемещение, а не клонирование.
                    0

                    Если речь непосредственно про то, писать ли "getValue", "value" или "cloneValue" — то я просто пользуюсь соглашениями. В питоне пользуются паблик-свойствами вместо геттеров/сеттеров (потому что можно декоратор @property навесить), а в java или php код с cloneValue просто не пройдет ревью.


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

                      0
                      Потому в ряде рекомендаций по форматированию поля имеют префикс, а геттер его не имеет. Так доступ к полю получается более интуитивным.

                      А вообще, это дикий оффтоп. Язык не должен указывать, как назвать тот или иной метод. Это не его работа. Язык должен позволять получать копию, неизменяемую и изменяемую ссылку, адрес, монопольное, разделяемое право владения и Страуструп знает что ещё. А как должен называться конкретный метод получения — не его собачье дело. Не ему, в итоге, писать исходники.
                        0
                        однако будет лучше, если написанный на ЯП код будет соответствовать тем же гайдлайнам, в рамках которого разрабатывается стандартная библиотека этого языка.
                          0
                          Так доступ к полю получается более интуитивным.

                          Горизонтальная палка делает доступ более интимным. :-)

                      0
                      Так ваши rows() и cols() это тоже геттеры.
                  0
                  или голая стрелка, если речь идет об указателе, для которого возможна арифметика. Кстати, стрелка не будет выпадать из «уставшего взгляда».
                  +1
                  Ага, я так надеялся увидеть новую абстракцию «наборы», а тут полстатьи про то чем «me» лучше «this». В итоге автор убрал два символа из в общем-то нечасто используемого символа, зато навалил фигурных скобок вместо отступов. Хотя это всё имеет мало отношения к читаемости языка. Плюсы сложнее питона не из-за фигурных скобок.
                  0

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

                    –1
                    Спасибо за интерес!
                    В статье я пояснил и по сути привёл пример, что мы стремимся к прозрачности кода (текущей нам не всегда достаточно), но не возводим её в абсолют. Независимость/абстракция от железа более важна — на неё спрос выше.
                    Сейчас есть проблемы, встроенные типы данных для Вас чёрный ящик, за который можно переступать только в ассемблер. И если тип содержит сложную архитектуру или введены спец. состояния (такие как Null, NaN), в случае проблемы Вы пускаетесь в исследования этой скрытой структуры или поиски документации от разработчика компилятора или человека, уже исследовавшего этот механизм. Архитектура таких типов имеет абстракцию над железом, но увидеть её Вы не можете. Моё предложение (выкинуть чёрные ящики и) описать эти абстракции в коде.
                    В результате переход от высокоуровнего кода до ассемблерных команд конкретного железа будет сглажен. Эти структуры станут задокументированы в коде (по сути будут прозрачны в высокоуровневом коде). Увеличится понимание устройства типов и протекающих с ними процессов.
                      +2
                      Вы пытаетесь скрестить ежа (системный уровень) и ужа (прикладной уровень). Как в старом анекдоте, получится 2 метра колючей проволоки, которой вы отгородите свой синтаксис от любых посягательств на его использование.
                      встроенные типы данных для Вас чёрный ящик
                      Перед вами две архитектуры: на одной биты копчёные, на другой триты кипячёные. Какую себе возьмёте, за какую тимлида посадите?
                        –1
                        Вы пытаетесь скрестить ежа (системный уровень) и ужа (прикладной уровень).

                        Вы же не хотите сказать, что С++ плохой язык и такой же как Вы описали выше?
                        Если нет, то совершенно не понятно почему Вы против ΣL?

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

                        Это не проблема языка, это проблема людей — микроскопом тоже гвозди можно забивать.

                        Да даже, если и возникла беда в организации у людей, то среда разработки объединяя код сможет сгладить этот конфликт. Теоретически возможно, практически пока не реализовано.
                          –1
                          Вы же не хотите сказать, что С++ плохой язык и такой же как Вы описали выше?
                          Он особенный. С архитектурной точки зрения он ужасен: не даром уже дцать лет подряд выходят его убийцы. Но у него есть фишка, которой нет у других, и которая ещё долго будет держать плюсы сверху. Огромная кодовая база, своя и унаследованная от Си, и потрясающая гибкость. Вот и получается, что дозволено Юпитеру, не дозволено быку.
                          Это не проблема языка, это проблема людей — микроскопом тоже гвозди можно забивать.
                          Нет, это ваша проблема, потому как вы создаёте инструмент. И это была ваша заявка «сделать инструмент для всего».
                          Да даже, если и возникла беда в организации у людей, то среда разработки объединяя код сможет сгладить этот конфликт. Теоретически возможно, практически пока не реализовано.
                          Тогда зачем бросать привычные инструменты, если ваш не лучше? Извините, но платформу я могу и по
                          #if defined(__LP64__) || defined(_M_IA64)
                          цеплять, лишние 10 символов не критичны. А вот что будет на выходе вашей сигмы — это уже большой вопрос.
                    +1
                    Я считаю, что код должен минимально отличаться от литературного текста, так как код — это не программа, но лишь документация для компилятора. Поэтому me — крайне плохое решение: оно не вяжется с английским языком.
                    > This value is one — привычно, но не совсем понятно
                    > Me value is one — просто криво
                    > My value is one — звучит гладко

                    И да: как писали выше, основная проблема современных языков — архитектура, а не синтаксис. С последним мы кое-как разобрались, в конце концов, всегда можно разработать своё подмножество языка, транслирующееся в оригинал. Если уж так хочется заменить this)

                    А вот как связать обработку данных с архитектурой ясно не до конца. Или как запретить дублирование кода на уровня языка.
                      0
                      А можно поподробнее про разработку подмножества языка?
                        0

                        Для C++ хватит


                        #define me this
                        ```))
                          +1

                          Please, get value of property Money from object MyObject and add to variable Total :)

                          0
                          Странное впечатление
                          Конечно троичная логика это не проблема вообще, просто потому что в реальном мире железок с троичной логикой нет; а если кто и осилит создание троичного микропроцессора, то уж разработать модификацию Си для него точно сможет.
                          Ну и проблема ключевого слова «this/self/me» это тем более не проблема. Я сам разрабатываю язык программирования, с гораздо более высоким уровнем детализации в исследовательском процессе (сейчас получается довольно объемная книга с подробнейшим рассмотрением различных возможностей и решений в различных языках программирования, их сравнением, выбором оптимальных решений и разработкой собственных оригинальных возможностей с нуля). Я задумывался в том числе и над эстетичесими вопросами, и кажется что оптимальная длина ключевых слов 2..5 символов, когда длинее 6 это уже некомфортно. Разница между 4 и 2 для редкоиспользуемых слов (таких как this) несущественна.
                            0

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

                          0
                          язык с названием «Сигма» существовал с 1965 до самых 90-ых годов...

                          Это вот этот имелся в виду — "Сигма" от Thant Tessman?

                            0
                            _ — это множество целых беззнаковых чисел,
                            __ — множество целых знаковых чисел,
                            __._ — знаковое, с фиксированной точкой
                            __,_ — знаковое, с плавающий точкой
                            _._ — беззнаковое, с фиксированной точкой
                            _,_ — беззнаковое с плавающей точкой


                            Разрешите догадку, у вас отличное (ну или не очень плохое) зрение :)
                            ИМХО, нечитабельно.
                              –2
                              Верно, но я предполагаю, что Вы не будете использовать эти базовые конструкции повседневно. Для любого языка существуют правила хорошего тона в оформлении кода.
                              Этот инструмент в первую очередь для тех, кто создаёт привычные для Вас типы (такие как byte, int, short). К тому же в языке есть алиасы, Вы сможете его гибко подстроить под себя.
                              Почти все современные языки не используют такие возможности, так как их основа другая и не всегда это позволяет, а числа предоставлены компилятору.
                                +1

                                Лучше уж знакоместа обозначать решёткой:


                                #### — это множество целых беззнаковых чисел (число решёток — максимальное число разрядов)
                                ?#### — множество целых знаковых чисел (число решёток — максимальное число разрядов)
                                ?##.## — знаковое, с фиксированной точкой (число решёток — максимальное число разрядов)
                                ?#.###e## — знаковое, с плавающий точкой
                                ##.## — беззнаковое, с фиксированной точкой (число решёток — максимальное число разрядов)
                                #.###e## — беззнаковое с плавающей точкой (число решёток — максимальное число разрядов)

                                  –1
                                  Мысль определённо правильная, хорошая.
                                  В мой язык она из-за поддержки разных архитектур неочень подходит, но я подумаю. В первую очередь решётка лучше различима, чем подчёркивание.
                                  Спасибо за комментарий и активный интерес к разработке языков (раз уж тема поспособствовала чат создать)!
                                  0

                                  А можно поподробнее про вещественную арифметику в вашем языке?

                                    –1
                                    Можно и нужно. Не обещаю, что скоро, но напишу в отдельном посте.
                                    0

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

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

                                      Да, это редко нужно. Об этом не хотят говорить, что я отметил в статье.

                                      Видимо Вы не сталкивались с упомянутыми проблемами. Сейчас не найду подходящего примера, но как пример рекомендую послушать это с 16:50. Миф документации чуточку развеется.
                                        –1
                                        Идея в том, чтобы Вы смогли заглянуть ниже (в момент, когда будет интересно или когда понадобится) и понять это устройство, даже если документации нет

                                        Идея хороша, но магический компилятор сводит ее на нет. Мы смотрим на me.state := someState, и у нас нет никакого способа понять, какие же операции на самом деле происходят.

                                          +1

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


                                          Вот у вас используется слово state. Где оно определено? С ним намного больше будет проблем, чем с байтом или boolean. Или только в компиляторе смотреть, что же это слово на самом деле делает?

                                    0
                                    Я не совсем программист, K&R на стройке нашёл, но…
                                    В начале работы на программой у нас в голове есть абстрация предметной области и абстракция исполняющего устройства, наша задача заполнить разрыв между этими двумя границами; если быть более точным, то абстракции абстракций: чтобы иметь собственные модели надо 5 лет отработать по профессии, а потом еще лет 5 разрабатывать процессоры с обвязкой.

                                    Чем более подробны эти абстракции, тем дороже программист, а это заказчику нафиг не надо. Программисты это понимают и строят слои абстракций, дальше которых не лезут в 99% случаев. Если мы абстрагируемся от предметной области, то программа не закрывает потребностей заказчика, и он не даёт денег. Плохо. Значит, пытаемся отдалиться от железа; для начинающего пышника или JSника компьютер может быть вообще волшебный коробкой, но его тривиальный код таки будет работать, благодаря программистам, тоже не волшебникам, но у которых другой продукт и следовательно сдвинутый, но не более широкий, диапазон абстракций

                                    Чтобы разменять дорогого программиста на много дешёвых, между кодером и клиентам стоят аналитики и тим-/техлиды, а между кодером и железом — сисадмины и тестировщики. А язык… От него достаточно быть понятным, однозначным и бьющим по рукам в рамках своих абстракций, а за границами языка — обращайтесь к другим программистам, чтобы они написали вам инструмент: анализатор или компилятор. Или к тестировщикам, чтобы полезли в дампы памяти и сказали, в чем затык.
                                      0
                                      Как уже написали me, my и i — это «кто», т.е. одушевленное.
                                      Логичнее:
                                      it — “это”, перекликается со «штукой» ( ‘item’ ) и с итерацией;

                                      можно использовать артикли типа ‘a’ и ‘the’,
                                      если развивать дальше то ‘the’ === ‘z’
                                      получаем пару:
                                      ‘A’ — нечто неопределенное,
                                      ‘Z’ — нечто определенное.

                                      диапазон A <—> Z и т.п.
                                      заглавными даже будет более визуально определимо, да и набирать удобно, обе рядом с левым шифтом )
                                        0
                                        Пару лет назад, тоже были идеи по созданию нового языка программирования. Так и осталось на уровне концепта github.com/sms-system/Programming-Language-Concept. Увидел схожий момент с символом @ — который использовал для обозначения неймспейсов. Заменой слову `this`, я в свое время выбрал `it`
                                          +1
                                          Итак, ниже я отобрал 5 самых «ненужных и бесполезных» пунктов, о которых «никто не говорит», а я расскажу.

                                          Как ваш язык решает описанные вами же проблемы?


                                          Каким человекочитаемым и коротким ключевым словом можно заменить современное this, чтобы не исказить его смысл? [...] Мне же в голову приходит два перспективных варианта: очень короткое i и более длинное me.

                                          С одной стороны, замена this на me, очевидно, меняет смысл — это разная семанткика (хотя, надо заметить, что в каком-то VB использовалось именно Me для обращения к текущей форме).


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


                                          В последующие секунды скорость набора me значительно опережала this и self.
                                          выражение me.valueResult += me.valueOne * me.valueTwo; в момент печати читалось словно me нет совсем

                                          Вы не поверите, но самое простое решение — это не писать this (или me) вообще. Есть языки, которые это позволяют, почему бы вам просто не последовать их примеру?

                                            0
                                            Есть языки, которые это позволяют, почему бы вам просто не последовать их примеру?

                                            И в таких языках появляются нотации вида mName, чтобы не путать их с локальными переменными вида name.

                                              +1

                                              Да. Но такая нотация все равно короче, чем [любой идентификатор].name.

                                                –2

                                                Ещё короче — именовать поля объекта с большой буквы, а локальные переменные с маленькой.

                                                  0

                                                  Так тоже можно (собственно, так и делают), но теряется возможность различать поля и свойства объекта. Другое дело, что не всегда эта возможность нужна...

                                            +1
                                            Основой языка «Сигма» являются наборы, которые объединяют в себе большинство существующих парадигм программирования. Наборы значительно более мощный и гибкий инструмент, чем объекты. Наборы были с программистами всегда и в каждом языке программирования до этого. Массив это набор однотипных элементов. Функция это набор инструкций. Структуры/записи это набор полей данных. Класс/объект это набор из полей данных и методов-функций. Пространства имён в модулях это тоже наборы, которые содержат в себе всю эту начинку: функции, классы и т.д. Наборы подобно мат. множествам могут объединяться и обладают рядом свойств.

                                            А, да, кстати. Можно, пожалуйста, услышать определение понятия "набор", которое вы используете в этом абзаце, и какими именно свойствами "набор" обладает?


                                            Базовый набор носит классическое название source, от него наследуются все остальные наборы.

                                            Что вы вкладываете в понятие "наследуются"?

                                              –2
                                              Набор — это совокупность элементов. Будет вернее сказать, что набор — это интерфейс для совокупности элементов. Елементами является всё вышеперечисленное в приведённой Вами цитате.

                                              Внутреннее устройство набора по факту является математическим множеством. За исключением некоторых нюансов (описания не для комментария), набор обладает свойствами множества. Или, если будет понятнее, набор является контейнером элементов. Описание набора визуально напоминает классы. Отсюда возможность применить термин «наследование». Наследованием является включение совокупности элементов в новый набор. Множественное наследование это объединение наборов.

                                              P.S. Множества есть во всех языках, но как контейнеры на уровне классов и объектов они не использовались. По крайней мере в популярных языках, я такого не наблюдал.
                                                0
                                                Будет вернее сказать, что набор — это интерфейс для совокупности элементов.

                                                Что значит слово "интерфейс" в этом предложении?


                                                Внутреннее устройство набора по факту является математическим множеством.

                                                Считайте, что я ничего не знаю про математические множества. Что же такое "набор"?


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

                                                Элементы в наборе упорядочены или нет? Один и тот же элемент может быть дважды или нет — и если нет, то как определяется, что элемент "один и тот же"? Тип элементов набора ограничен? Тип самого набора определен?


                                                Множественное наследование это объединение наборов.

                                                Если вы объединяете два набора в которых есть "один и тот же" элемент, что происходит?


                                                Множества есть во всех языках, но как контейнеры на уровне классов и объектов они не использовались.

                                                А зачем? Какую задачу это выполняет?

                                                  0

                                                  Будет понятнее, если вы не будете предлагать три разных определения в одном комментарии. То "набор" напоминает массив, то интерфейс, то объект (итерируемый, видимо).

                                                    0
                                                    Множества есть во всех языках, но как контейнеры на уровне классов и объектов они не использовались.

                                                    В PHP объекты примерно так и устроены.

                                                  +1
                                                  Обратите внимание на описание значения бита и его состояния.

                                                  А что такое "состояние", что оно заслужило отдельного ключевого слова state, и как это используется на практике потребителем класса?

                                                    –2
                                                    Состояние это очень важно: установлена ли у Вас галочка True или нет False. Разные типы имеют разные состояния (так принято в современном программировании), и не всегда True это отдельный булев тип, когда-то он целое число строго = 1, а когда-то любое целое >= 0. Сначало с этим были ошибки, сейчас программисты привыкли использовать такое знание как хаки в разработке.
                                                    Благодаря этому
                                                    что такое «состояние», что оно заслужило отдельного ключевого слова state
                                                    упрощается описание РБНФ. Добавление одного «state» убрало из языка ряд ключевых слов, таких как: float, int, byte, bool, true, false и т.д.
                                                      0

                                                      Вот только вы так и не объяснили, чт оже такое "состояние" для типа.


                                                      установлена ли у Вас галочка True или нет False.
                                                      … это — состояние галочки.

                                                      Разные типы имеют разные состояния (так принято в современном программировании)
                                                      Я не встречал "в современном программировании" понятия "состояние" у типов — только у объектов. А у типов обычно есть допустимое множество объектов. Вы о нем сейчас говорите?

                                                      Добавление одного «state» убрало из языка ряд ключевых слов, таких как: float, int, byte, bool, true, false и т.д.
                                                      Ээээ… нет.

                                                      float, int, byte, bool — это названия (а в некоторых языках — и вовсе алиасы) встроенных типов. У вас они тоже есть (тип bit вы создаете в примере, про остальные пишете в комментариях).


                                                      true и false — это, в зависимости от реализации, либо литералы (если есть специальный тип bool), либо константы. И они у вас тоже есть.


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

                                                        0

                                                        Там в середине сбилось форматирование, читать так:


                                                        установлена ли у Вас галочка True или нет False.

                                                        … это — состояние галочки.


                                                        Разные типы имеют разные состояния (так принято в современном программировании)

                                                        Я не встречал "в современном программировании" понятия "состояние" у типов — только у объектов. А у типов обычно есть допустимое множество объектов. Вы о нем сейчас говорите?


                                                        Добавление одного «state» убрало из языка ряд ключевых слов, таких как: float, int, byte, bool, true, false и т.д.

                                                        Ээээ… нет.


                                                        (далее по тексту)

                                                          0
                                                          Нет, это не состояние галочки.
                                                          Если в «Сигма» Вы подключите к своему проекту только decimal модуль, то Вы не найдёте у меня True и False. Сам язык о них ничего не знает, он работает с числами и множествами. Состояния для привычки, удобства и по тому, что они нужны людям.

                                                          Подробнее о состоянии с примером Вы найдёте в статье.
                                                            0
                                                            Если в «Сигма» Вы подключите к своему проекту только decimal модуль, то Вы не найдёте у меня True и False.

                                                            Ну то есть это такие очень странные константы. Термин "состояние" здесь некорректен.


                                                            Так как же это работает? В той части, где "Состояние — это зафиксированная совокупность определённых элементов из набора, его статическое подмножество."? Предположим, у вас есть тип, описывающий рациональную дробь с числителем и знаменателем, и "состояние" Invalid, где знаменатель равен нулю. Как конкретно работают


                                                            • проверка smth is Invalid
                                                            • присвоение smth := Invalid
                                                              0
                                                              Давайте накидаем Ваш пример:
                                                              smth {
                                                                 int Numerator;   //числитель
                                                                 int Denominator; //знаменатель
                                                                 state Invalid is { //Ваше состояние
                                                                    me.denominator == 0;
                                                                 }
                                                                 init() { //конструктор без параметров
                                                                    me.Numerator := 0;
                                                                    me.Denominator := 0;
                                                                 }
                                                                 operator.right := (state s){ //более верно писать: smth.state s
                                                                    me.state := s; //присвоение состояния претерпит изменения в следующей версии, но пока так можно
                                                                 }
                                                              }
                                                              
                                                              
                                                              smth s;
                                                              if (smth is Invalid) { smth := Invalid; }
                                                              
                                                              //в оптимизированном коде это превратиться в привычное:
                                                              if (smth.denominator == 0) { smth.denominator := 0; }
                                                              

                                                              Другие более сложные моменты так же будут оптимизированы компилятором в простые asm-коды под целевую платформу.

                                                              Без оптимизации хранится набор статичных значений(элементов) справа. В нашем примере это 0. В момент работы с состоянием формируется активный набор из указанных слева значений. В нашем случае в такой набор попадёт значение me.denominator, у нас оно было проинициализировано 0-ём. При выполнении оператора is произойдёт вычитание из активного набора статичного набора по правилам математического множества (тождественные элементы исчезнут из активного набора). Условный оператор проверит получилось ли пустое множество или нет. Если получилось, выполнит код инструкций в фигурных скобках.
                                                              Присвоение определяется пользователем, кроме случая для набора — содержимое которого пропадает, а новая совокупность элементов связывается с именем этого набора. При стандартной реализации присвоения это и происходит. Наборам левой части (из описания состояния) присваивается значение статического набора (из правой части).
                                                                0
                                                                При выполнении оператора is произойдёт вычитание из активного набора статичного набора по правилам математического множества (тождественные элементы исчезнут из активного набора).

                                                                Как проверяется тождественность? (собственно, я уже задавал вам этот вопрос)


                                                                Присвоение определяется пользователем

                                                                А каким чудом me.state := s превратилось в me.denominator := 0? Какая волшебная логика распарсит сложное состояние (с несколькими логическими ветвлениями) и превратит его в присвоения?

                                                                  0
                                                                  Наборы тождественны, если состоят из одинаковых элементов.

                                                                  Очевидно, что вложенные наборы сравниваются так же, путём вычитания. Речь об элементах, являющихся вложенными наборами.

                                                                  В конечном итоге такого разбора всё упирается в элементы-числа. Числа тоже являются базовыми наборами. Это может быть одно число или диапозон.
                                                                  После компиляции под целевую платформу они превратятся в определённые структуры, подстраиваясь под разрядную сетку нужной архитектуры. На x86 для числового набора _[0:255] (целое беззнаковое со значениями от 0 до 255 включительно) будет байт.

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

                                                                    Хм. Тождествены ли a, b и b, a?


                                                                    BTW, а вы понимаете, что ваше "равенство" не транзитивно?


                                                                    a := {Numerator := 1, Denominator := 0}
                                                                    b := {Numerator := 2, Denominator := 0}
                                                                    c := Invalid
                                                                    a == Invalid //true
                                                                    b == Invalid //true
                                                                    a == b //false
                                                                    a == c //?

                                                                    Правда, здорово?


                                                                    Очевидно, что вложенные наборы сравниваются так же, путём вычитания.

                                                                    Полное структурное сравнение по дереву? Стоимость себе представляете?


                                                                    Про второй вопрос: волшебная логика компилятора, это не сложно.

                                                                    state Invalid is {Denominator == 0}
                                                                    state Valid is {Denominator != 0}
                                                                    
                                                                    smth := Valid
                                                                      0
                                                                      Вы перепутали сравнение наборов со сравнением состояний.
                                                                      a == b сравнивает наборы одного пользовательского типа
                                                                      a == Invalid сравнивает состояние в рамках набора а

                                                                      По второму случаю я где-то уже писал текущий минус: пока описываются только тождественные условия в состояниях. То есть неравенства сейчас не принимаются. Я над этим работаю.
                                                                        0
                                                                        Вы перепутали сравнение наборов со сравнением состояний.

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


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

                                                                        … и как же будет работать присвоение в этом случае?

                                                                          0
                                                                          Если видите проблему, то где Ваши предложения?

                                                                          Можно оставить для состояний только is и добавить какое-либо ключевое слово для перевода набора в нужное состояние. Например, in. Как на Ваш взгляд это повлияет на читаемость?

                                                                          Можете предложить и свои варианты реализации наборов и операций над ними.

                                                                          На мой взгляд это направление перспективно для развития языка программирования. Как минимум что-то новое и не топтаться на месте.
                                                                            0
                                                                            Если видите проблему, то где Ваши предложения?

                                                                            Выкинуть "состояния" вовсе, потому я не вижу профита, которые они бы приносили (в той реализации, которую вы предлагаете). Они прекрасно заменяются предикатами.


                                                                            добавить какое-либо ключевое слово для перевода набора в нужное состояние. Например, in.

                                                                            нельзя сделать перевод в (любое) нужное состояние.


                                                                            Можете предложить и свои варианты реализации наборов и операций над ними.

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


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

                                                                            Перспектива — это когда видна цель. А пока видно только


                                                                            что-то новое и не топтаться на месте.

                                                                            Я не люблю новое ради нового.


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

                                                              0
                                                              Если в «Сигма» Вы подключите к своему проекту только decimal модуль, то Вы не найдёте у меня True и False.

                                                              Только в голову пришло: если у вас нет встроенных булевых операций, то как же делать not, or и and?

                                                                0
                                                                Вместо bool теперь будет использоваться bit для работы с двоичной архитектурой. Для набора bit определены булевы операции (подобно операциям присвоения, то есть можно будет код посмотреть). Аналогично для других архитектур.
                                                                  –1

                                                                  Какого типа выражение a == b?

                                                                    0
                                                                    Это операция, она может быть переопределена программистом. Если a и b — наборы одного пользовательского типа, то и результат набор пользовательского типа.
                                                                      –1

                                                                      … и поскольку это наборы, над ними не определены логические операции, и сделать банальное a == b and c == d я не могу. Восхитительно.


                                                                      Что еще интереснее, если эта операция возвращает bit, я не могу просто запихнуть ее в if (потому что тот проверяет, пустое ли множество), я должен написать if ((a == b) is True).

                                                                        0
                                                                        Где другие могут видеть дорогу, у Вас полная шляпа.
                                                                        Всё не так плохо, на крайний случай if может принимать несколько множеств. Выглядеть это может примерно так:
                                                                        if ( a == b, c == d ) {}

                                                                        До конца ещё не проработал, но проблемы нет. Приведённый вариант не самый лучший.
                                                                          0
                                                                          Всё не так плохо, на крайний случай if может принимать несколько множеств. Выглядеть это может примерно так:
                                                                          if ( a == b, c == d ) {}

                                                                          Это and или or?


                                                                          До конца ещё не проработал, но проблемы нет

                                                                          Так как же решается проблема с использование bit в if?


                                                                          А, вот еще, кстати:


                                                                          x := {a, b, c}
                                                                          y := {a, b}
                                                                          z := {c}
                                                                          
                                                                          x == y //false
                                                                          y == z //false
                                                                          (x == y) == z //true
                                                                            0
                                                                            Продолжаем Вас вербовать.
                                                                            Это будет аналог and, теперь начинайте кричать «пропал or». Уже жду.

                                                                            Так как же решается проблема с использование bit в if?

                                                                            В bit реализовано сравнение с числом, с состоянием и с bit'ом. Лучший существующий аналог это перегрузка оператора в С++.

                                                                            Про последний пример кода: а чего Вы ожидаете от сравнения наборов, тем более разных типов? Если нужна булева алгебра, сделайте a, b и c наборами типа bit и тогда сравнивайте их между собой.
                                                                            Вы же в других языках не сравниваете строку и число напрямую?

                                                                            Темы затронуты хорошие, но я же в самом верху статьи написал, что не преуспел в этом вопросе. Есть вопросы, на которые я пока тоже не знаю ответа, но это не повод говорить стоп для исследователя. Концепция отличная от всего имеющегося есть, базис есть, я поделился идеей с комьюнити. Зря большинство, вместо развития, подводит к мысли выкинь и забудь.
                                                                              0
                                                                              В bit реализовано сравнение с числом, с состоянием и с bit'ом.

                                                                              Вот только if ничего ни с чем сравнивает — по вашим словам, — он проверяет, что множество пустое.


                                                                              Про последний пример кода: а чего Вы ожидаете от сравнения наборов, тем более разных типов?

                                                                              Я ожидаю, что код будет вести себя предсказуемо. А понятие "типа" набора у вас то появляется, то пропадает, и тоже пока что не определено.


                                                                              Если нужна булева алгебра, сделайте a, b и c наборами типа bit и тогда сравнивайте их между собой.

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


                                                                              Вы же в других языках не сравниваете строку и число напрямую?

                                                                              Вы не поверите, но сравниваю.


                                                                              Концепция отличная от всего имеющегося есть

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


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

                                                                              Не всякая концепция заслуживает развития только потому, что она отличается от всего имеющегося.


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

                                                                                +1
                                                                                а чего Вы ожидаете от сравнения наборов, тем более разных типов?

                                                                                Я например ожидаю, что сравнение возвращает логический тип, а не тип сравниваемых значений. Потому что иначе это то же самое, что (x-y).


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

                                                                                Большинство подводит к мысли, а в чем это поможет, что в этом полезного, чтобы его развивать? Зачем что-то развивать только чтобы догнать существующее?

                                                                                  0

                                                                                  … на самом деле, проблема с отсутствием встроенных логических типов прекрасно видна и на другом примере. Вот хочу я написать функцию (метод, не важно): IsSystemConfiguredThisWay, чтобы, значит, делать так:


                                                                                  if (IsSystemConfiguredThisWay()) {DoThat()}

                                                                                  Какой тип должна возвращать эта функция? "Любой" набор, и если он пустой, то if пройдет? А если мне надо, чтобы не прошло, вернуть "любой" непустой? А как это выразить в типе функции? В итоге мы получаем все те же самые #DEFINE FALSE {} и падение читаемости/самодокументируемости — строго противоположно тому, что вы хотели.

                                                                                    0
                                                                                    Можно использовать Лябмда-исчесление для булевой логики! )
                                                                                    Church Booleans

                                                                                    true  = \a b -> a
                                                                                    false = \a b -> b
                                                                                    
                                                                                    not p = p false true
                                                                                    
                                                                                    p `and` q = p q p
                                                                                    p `or`  q = p p q
                                                                                    
                                                                                    ifThenElse p a b = p a b
                                                                                    
                                                                                      0

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

                                                                                        0
                                                                                        ))) Да, лябда-исчисление то ещё программирование!
                                                                                        Хаскель красивей и лучше. Примерно так определено:
                                                                                        data Bool = False | True
                                                                                        
                                                                                        not True  = False
                                                                                        not False = True
                                                                                        
                                                                                        True `and` True = True
                                                                                        _    `and` _    = False
                                                                                        
                                                                                        False `or` False = False
                                                                                        _     `or` _     = True
                                                                                        
                                                                                        class Eq a where
                                                                                           (==) = not . (/=)
                                                                                           (/=) = not . (==)
                                                                                        
                                                                                        instance Eq Bool where
                                                                                           True  == True  = True
                                                                                           False == False = True
                                                                                           _     == _     = False
                                                                                        
                                                          +1
                                                          вроде как не так часто используется this чтобы экономия двух символов прям решала
                                                            0
                                                            В Ява — всё объекты.
                                                            В вашей Сигым — всё «наборы». Это чем-то лучше?

                                                            Кстати, можете заглянуть в мою старую статью, может что найдёте интересное для Сигмы:
                                                            Развитие пользовательских типов данных в программировании
                                                              +1
                                                              Спасибо за хорошую статью!

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

                                                              Наборы глубже пронизывают весь язык, чем объекты в Java или C#. В последних языках есть базовые типы (например, byte), посмотреть и контролировать реализацию которых Вы не можете (обычно это не минус, когда речь об одной архитектуре). Все числа преобразуются к этим типам в процессе компиляции. Нередко отдельно рассказывают устройство стандартного массива в языке. В Сигма стремимся убрать эти чёрные ящики, есть числа и наборы. Вместе они описывают всё — от самого приложения до самого базового типа интересующей нас архитектуры.
                                                              В теории появляются новые возможности. Например, применяя аспектно-ориентированное программирование прямо в процессе работы приложения возможно убирать и добавлять инструкции в специальных точках соединения (определённых срезом). На практике всех интересует как это будет реализовано на определённой архитектуре, чтобы после оптимизации не выглядело хуже уже существующих решений. Выполнить такие оптимизации возможно, но тогда наборы для людей выглядят тем чёрным ящиком, стыкующим логику и железо. Этого можно избежать, позволив описывать архитектурный код в языке.
                                                                0

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

                                                                  0
                                                                  Наборы немного лучше объектов и дают больше свободы.

                                                                  Чем лучше? В чем конкретно выражается "свобода"?


                                                                  Наборы глубже пронизывают весь язык, чем объекты в Java или C#.

                                                                  В чем конкретно это выражается?


                                                                  В Сигма стремимся убрать эти чёрные ящики, есть числа и наборы.

                                                                  А числа и наборы в Сигме — не черные ящики разве? Как я могу посмотреть реализацию _[0:1] или набора source?


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

                                                                  А если я всегда пишу для одной архитектуры, какой мне профит от необходимости ее определять?


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

                                                                  Эмм, а какие конкретно преимущества наборов позволяют это сделать легче по сравнению с другими АОП-инструментами для других языков?

                                                                    +1
                                                                    Вместе они описывают всё — от самого приложения до самого базового типа интересующей нас архитектуры.

                                                                    А если я всегда пишу для одной архитектуры, какой мне профит от необходимости ее определять?

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

                                                                    0
                                                                    Пока я не совсем понял, отличается ли «набор» от объекта или нет.
                                                                    Возможно, «наборы» — это объекты с предикатами?

                                                                    Единственное ваше изобретение — типы как классы/объекты/наборы.
                                                                    Правда, какие возможности это даёт — я не совсем понял из ваших примеров
                                                                      0
                                                                      Ага, кроме типов — функции и операторы — тоже объекты/наборы.
                                                                      Это веселее.
                                                                      Но, почему-то именно это вы и не описали: "// операторы, методы и их внутренности опущены для наглядности"

                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                Самое читаемое