Тривиль — как лучше?

Меня малость удивляет, что язык получился красивый, несмотря на задачу сделать «тривиально». Видимо, опыт имеет значение — все таки, это 5-й проектируемый мной язык.

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

1) Оператор «надо»

Это прямой аналог Swift guard.

Пример: надо x # 0 иначе авария(«деление на ноль»)

См. формат:167 или формат:195.

Насколько понятно слово ‘надо’ и есть ли лучше? ‘требую’? Что-то другое?

2) Оператор выбора

Пример: когда х {  есть 1: хорошо() есть 2: неплохо() иначе плохо() }

См. формат:79

Собственно, сначала я сделал очевидный синтаксис: выбор х {  |1: хорошо() |2: неплохо() иначе плохо() }

Но это приводит к неоднозначности в контексте:

выбор х {  |1: х := а | б …

Операцию условное-или я хочу писать коротко — ‘|’, поэтому этот синтаксис я отмел, и позаимствовал слово ‘когда’ из Котлина, впрочем только его. Котлин в операторе when совсем не тривиален.

Собственно, то, что получилось, мне нравится. Есть некая однородность операторов: если, когда, пока, надо.

Но может быть вместо есть использовать это?

когда х {  это 1: хорошо() это 2: неплохо() иначе плохо() }

Замечу, что выбор по типу (Go: switch x.(type) {}) я собираюсь добавить, когда понадобится, поэтому учитывать надо еще и: когда … { это Тип1: … это Тип2: … }

3) Посмотрите решение для unsafe

См. формат — ключевое слово «осторожно», в подсветке выделено красным, так что сразу видно. См. , например, формат:81.

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

4) Строка формата

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

 

14 комментариев


  1. Оператор «надо» — это прямая аналогия assert. Для условий, имхо, не очень.
    Оператор выбора предлагаю традиционный «если». Всегда стоит следовать принципу наименьшего удивления — мыслетопливо разработчика есть ограниченный ресурс.
    В комментариях к предыдущей записи уже написал: та часть языка, что разрушает инварианты памяти должна быть подвалом. Подвал — это ни хорошо, ни плохо. Но это точно опасно, подвал должен быть явным, работа с подвалом должна быть сведена к минимуму и контролируема. Чем меньше подвал, тем лучше язык. В идеальном случае — подвала быть не должно вообще. Увы, но таких языков в массовом использовании пока нет. К этому был близок «Кронос» и «Эльбрус-3». Но где все эти проекты мы знаем, а кое-кто знает непонаслышке.

    Ответить

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

      Кроме оператора «надо», это же задачу — линеаризации и выделения главного, решают операторы «вернуть» и «прервать». Читаю сейчас статью Бертрана Мейера «Right and wrong: ten choices in language design» и тихо ругаюсь по поводу «one-entry, one-exit blocks».

      Ответить

  2. Строка формата как в Го — как по мне, вполне приличный приличный вариант. Да, в питоняке строка формата развита, на насмерть зашитый «принт» в язык (и в Го, кстати, тоже) — это порочный путь.

    Ответить

  3. Может быть вообще не использовать «есть» или «это», но оставить «иначе»? Например: когда х { 1: хорошо() 2: неплохо() иначе плохо() }

    Ответить

    1. В большинстве языков для варианта оператора выбора используются префиксы, например, «case» (Си, Go, Swift, и много еще), в Обероне/Модуле-2 префикс «|». И этому есть обоснование.

      Если посмотреть на языки c выбором без префикса, например, when в Котлине или match в Расте, то видно, что в них приходится использовать дополнительные синтаксические фокусы.
      Например, в Расте конец варианта обозначается символом «,». В Котлине, если в варианте несколько операторов, надо ставить {}. На мой взгляд, это менее наглядно. Что еще важно, что префикс, четко обозначает структуру, облегчая понимание.

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

      Ответить

      1. На мой субъективный взгляд, как раз варианты Котлина и Раста выглядят достаточно гармонично и читабельно.
        Знак препинания типа запятой (если это упрощает парсинг), мне кажется, тоже логично вписывается в конструкцию, как и фигурные скобки для выделения блока операторов. В Расте тоже используются фигурные скобки когда в условии не один оператор, что строже и нагляднее чем только пробелы и табуляции. Но тут наверное кому что более привычно. Тем кто пишет на Питоне, наверное наоборт фигурные скобки глаз режут :)

        Ответить

  4. Несколько раз пересмотрел файл «формат» из предыдущего сообщения понял, что названия функций добавляют дополнительные (ненужные) мысли при прочтении кода.

    Например определение: фн (р: Разборщик) добавить аргумент(аргТ: Слово64, арг: Слово64) {}

    Можно прочитать как «добавить аргумент», а можно подумать что «аргумент» это самостоятельный идентификатор/функция/оператор или другое зарезервированное слово. Может быть мне просто не привычно видеть подобную запись, но все таки язык программирования, на мой взгляд, и должен быть более утрирован нежели обычный язык. Может стоит рассмотреть использование нижнего подчеркивания для определений функций и других цельных идентификаторов вместо пробельных символов?

    Ответить

    1. Полагаю, что вы смотрели без подсветки синтаксиса. Подсветка существенно упрощает понимание. Именно для этого Вирт делал ключевые слова заглавными: IF … THEN END. С подсветкой в этом нет смысла. Подсветка превращает ключевые слова в «руны» (иероглифы), которые воспринимаются целиком и становятся опорными точками для понимания.

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

      Наверное, для вас это непривычно. Я написал свой первый компилятор на Эль-76 на русском языке, хотя и без пробелов в идентификаторах. А рядом народ писал на ЯРМО, а вот там были пробелы в идентификаторах. А потом Вир — в котором тоже русские и с пробелами, например: «Разослать уведомление до запуска».

      Давайте просто сравним:

      • фн (р: Разборщик) добавить аргумент(…
      • фн (р: Разборщик) добавить_аргумент(…
      • фн (р: Разборщик) добавитьАргумент(…
      • фн (р: Разборщик) ДобавитьАргумент(…
      • фн (р: Разборщик) ДобАрг(…

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

      Ответить

      1. Согласен, что подсветка очень помогает, но не всегда есть возможность иметь инструмент с подсветкой. И на счет книжек согласен, но язык программирования и «естественный язык», все же, несколько разные области.

        Мои замечания связаны исключительно с выделением (не подсветкой) определенных _законченных_/_цельных_ конструкций (идентификаторов). Исключительно во избежании возможных примесей других смыслов. Потому, лично мне кажется допустимым и логичным, использование в определениях символа подчеркивания «_». В таком случае разделитель на месте и сходство с «естественным языком» тоже очень близко.

        В своем предыдущем комментарии я не упомянул еще один момент, за который цепляется мой глаз. Из того же файла с форматом:

        р.добавить целое10(арг(:осторожно Цел64))

        Вот тут даже более наглядно чем в определении функции.
        Здесь можно задуматься что «целое10» может нести свой смысл, а «добавить» свой. Более того, далее есть «арг», который тоже несет свою смысловую нагрузку. Но у нас есть функция «добавить аргумент». Тогда, например, вот такая конструкция обрастает дополнительными смыслами:

        р.добавить аргумент(арг(…), нечто(список[№-арг]))

        Кстати, а что если в определениях функций оставить доступным использование символа «_» в дополнение к пробелу и интерпретировать «_» тоже как пробел? Тогда каждому, будет возможно писать как ему удобнее :)

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

        Ответить

        1. Подчерки тоже разрешены.

          Идентификатор: Слово ((‘ ‘ | ‘-‘) Слово)* Знак-препинания?
          Слово: Буква (Буква | Цифра)*
          Буква: Unicode-letter | ‘_’ | ‘№’
          Знак-препинания: ‘?’ | ‘!’

          Ответить

          1. Действительно. Я не внимательно смотрел grammar.txt
            Тогда это снимает мои опасения :) Спасибо!


  5. У нас есть чатик в телеграми «Русский язык в ИТ», в нём аж целых 14 человек. Заходите. Понятно, что NIH-синдром — это святое и учиться на чужих ошибках неинтересно для настоящего хоббийщика, для которого процесс важнее результата. Но я вижу, что Алексей наступил на те грабли, на которых я уже давно (4 года назад) плясал, но потом слез.

    Ответить

    1. Ну что же, поговорим о граблях. Первый компилятор на русском (на Эль-76) я написал в 1993-1994, потом был большой перерыв до Вира. А дальше, весь Вир, кроме малой части на Дельфи, написан на Вир/а0 — на русском. Потом разработка Вир/а1 — тоже, естественно на русском. И теперь Тривиль.

      Почему русский? Потому что я ленив. Есть простой факт — хоть я и свободно спикаю, но часовой разговор на английском меня утомляет гораздо больше, чем такое же на русском. То же самое с чтением/пониманием/письмом. И это верно не для меня одного, так на работе — мы немедленно переключаемся на русский, как только это возможно.

      Понятно, что я малость выпендрился, написав «ленив». В действительности, я хочу за те годы, которые мне еще остались для творческой и производительной работы, сделать очень много. Поэтому, мне лично надо работать очень экономично. Поэтому это не С++ (слишком много уходит в пустоту), и не Оберон (мало выразительный язык) и не Го (много ошибок в дизайне языка) и так далее.

      Тривиль достаточен выразителен и очень экономичен — компилятор размером 10 тысяч строк и описание языка на 45 страницах. Далее bootstrap Тривиля, который выявит ошибки, и даст мне основу для следующих компиляторов, и вперед — к языку, пригодному для интенсивного программирования. Если кто-то подключится к работе — прекрасно, если нет, у меня есть опыт работы над Виром.

      А наступать на грабли я делегирую всем желающим…

      Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *