[Я так и не смог написать хороший вводный текст к данной статье, поэтому начну просто с примеров.]
(Попробуйте угадать значения зарезервированных букв, а также мысленно переписать этот кусочек кода на языках программирования, которые вы знаете.)
А вот пример побольше (это перевод Python-кода из моей предыдущей статьи).
F calculate_sacred_number()
A results = []
L(hash_algorithm) hashlib:algorithms_available // Обходим все доступные хэш-алгоритмы
\\ (список включает в себя MD5, SHA...)
I.unlikely "shake" C hash_algorithm // Пропускаем алгоритмы SHAKE, так как ...
L.continue
L(uppercase) 0B..1B // Проверяем варианты написания как строчными, так и ПРОПИСНЫМИ
L(space) 0B..1B // Проверяем варианты написания с дефисом и через пробел
L(n) 10..99 // Проверяем все двузначные числа
A nw = :numbers[n] // Получаем текущее число, записанное словами на англ.
I uppercase
nw .= upper()
I space
nw .= replace(‘-’, ‘ ’)
A ns = String(n)
// Считаем хэш от записанного словами числа,
A digest1 = hashlib:(hash_algorithm, nw.encode()).hexdigest()
// а также от этого же числа, преобразованного в строку.
A digest2 = hashlib:(hash_algorithm, ns.encode()).hexdigest()
L 2 // Проверяем целый хэш, а также первую половину хэша
// Оба хэша должны начинаться на первую цифру текущего числа
// и заканчиваться на вторую цифру.
I digest1[0] == ns[0] & digest1[@-1] == ns[1]
& digest2[0] == ns[0] & digest2[@-1] == ns[1]
results [+]= ns
// Берём первую половину хэша
digest1 = digest1[0.<@/2]
digest2 = digest2[0.<@/2]
assert(results.len == 1) // Должно быть только одно "выигравшее" число
R results[0] // Возвращаем это число
// Based on [https://stackoverflow.com/a/8982279/2692494 ‘How do I tell Python to convert integers into words’]
A numbers = "zero one two three four five six seven eight nine".split()
numbers [+]= "ten eleven twelve thirteen fourteen fifteen sixteen".split()
numbers [+]= "seventeen eighteen nineteen".split()
L(tens) "twenty thirty forty fifty sixty seventy eighty ninety".split()
L(ones) numbers[0..9]
numbers [+]= I ones == "zero" {tens} E tens‘-’ones
print(calculate_sacred_number())
Как можно заметить, импорт модулей осуществляется неявно — можно просто обращаться к нужной функции пиша
имя_модуля:имя_функции(...)
. То есть, простое обращение к fs:path:dirname()
, re:compile()
\рв:компил()
, math:log()
\матем:лог()
, time:sleep()
\время:спи()
, json:load()
, html:escape()
автоматически импортирует все необходимые модули (fs
, fs:path
\фс:путь
, re
, math
, time
, json
, html
).Для сырых строк можно использовать одиночные парные кавычки — на мой взгляд строки в таких кавычках выглядят понятнее. [Ещё варианты для сырых строк:
'"строка"'
, ''""строка с "'""''
, `строка`.]Согласен, что этот пример
"http://...?rev=" + revision
).Буквы | Слова | Пояснение | ||
---|---|---|---|---|
A | автоматический тип (аналог auto из C++11) |
|||
C | in | С | contained in\содержится в | |
I | Е | if | если | |
E | И | else | иначе | |
exception | исключение | |||
F | Ф | fn | фн | объявление функции |
L | Ц | loop | цикл | замена for, while и do-while |
N | Н | null | нуль | |
R | Р | return | вернуть | вернуть результат функции |
S | В | switch | выбор | switch/select |
T | type | тип | объявление нового типа | |
T() | typeof | тип() | получить тип выражения (typeof в GCC, decltype в C++11) | |
X | для дополнительных зарезервированных подслов |
(Исходные файлы на языке должны быть оформлены единообразно — либо используя зарезервированные слова, либо используя буквы.)
Данный/предлагаемый язык дополнительно отличается от других тем, что зарезервированные слова языка идут не в виде списка слов (как принято в[о всех[?]] других языках программирования), а структурированы в иерархию, на верхнем уровне которой располагаются 11/12/13 корневых/базовых зарезервированных букв/слов.
I\Е | I.likely\Е.часто I.unlikely\Е.редко |
Е\И | E.try E.throw E.catch E.try_end (аналог try-else в Python) |
F\Ф | F.args\Ф.арг F.virtual.new\Ф.виртуал.новая F.virtual.override\Ф.виртуал.переопр F.virtual.final\Ф.виртуал.финал F.virtual.abstract\Ф.виртуал.абстракт F.destructor\Ф.деструктор |
L\Ц | L.break\Ц.прервать L.continue\Ц.продолжить L.again — перейти к началу цикла L.index — номер текущей итерации цикла (начиная с 0) L.next\Ц.след — следующее значение переменной цикла L.prev\Ц.пред — предыдущее значение переменной цикла |
S | S.break S.fallthrough |
T | T.super — для доступа к базовому типу T.enum\Т.переч — объявление перечисления |
Два вида деструкторов
- Вызывается при выходе из области видимости (как обычный деструктор в С++ и других языках с поддержкой RAII) —
F.on_scope_exit
(также эту запись можно использовать как аналог defer в Go). - Объект разрушается сразу после последнего использования/обращения —
F.destructor
.
Основным я предлагаю сделать второй вариант.
Это позволит удалять временный файл сразу после работы с ним без явного вызова close():
tmpfile, fname = tempfile.mkstemp(text=True)
tmpfile = open(tmpfile)
r = subprocess.call(cmd, stdout = tmpfile, stderr = tmpfile)
tmpfile.seek(0)
print(tmpfile.read(), end = '')
tmpfile.close() # этот вызов можно не делать, если tmpfile будет разрушен в предыдущей строке
os.remove(fname)
А также избавит от необходимости писать move() в случаях:
Person p
p.name = ...
p.age = ...
persons.append(p) // в С++ здесь пришлось бы писать persons.push_back(std::move(p)) для оптимальности
А также позволит избежать копирования при вызове функции sorted()\сортй():
for root, dirs, files in os.walk(path):
for file in sorted(files): # в C++ бы пришлось писать что-то вроде (files.sort(), files) для избежания копирования массива files
...
Развивая идею вывода типов (type inference)
Для начала скажу про такой момент, что в предлагаемом языке есть такие служебные функции как copy() и share().
Тип умного указателя я предлагаю определять по его использованию (также как тип массива или словаря в Nemerle определяется по типу первого добавленного в него элемента). Получается эдакий autounishared_ptr — гибрид unique_ptr и shared_ptr из C++11. Если где либо в коде встречается share(p), тогда p становится shared_ptr-ом, иначе остаётся unique_ptr-ом.
Функция copy()\скоп() используется для копирования тяжелых объектов, которое, как я считаю, должно быть обозначено явно в коде (просто через
оператор =
можно копировать только лёгкие объекты).(Более подробное описание предлагаемого мной механизма работы с памятью — это тема для отдельной статьи, но вкратце скажу, что я предлагаю модель памяти несколько отличную от C++ и Rust (но также без сборщика мусора).)
Задумывались ли вы над тем, что флаги открытия файла можно не указывать явно, а выводить из его использования?
A fstr = File(fname).read() // А фстр = Файл(имя).прочти()
File(fname).write(contents) // Файл(имя).запиши(содержимое)
I File(fname) // заменяется компилятором на I fs:file_exists(fname)
File(fname).size // заменяется компилятором на fs:stat(fname).size
Единая/одна конфигурация сборки
Сталкивались ли вы с проблемой отладки Release/Optimized сборок? Или низкой производительностью Debug сборки? Или с различным поведением в Debug и Release/Optimized? Возможно, проблемы от такого разделения возникают не так уж часто, но когда/если они возникают, это становится большой головной болью для программистов. Я считаю, что стоит попробовать избавить программистов-пользователей языка от такой боли путём отказа от этого разделения, добавив полноценную отладку в Release/Optimized build. К примеру, взять gdb, он выдаёт optimized out в случае когда переменная не хранится в стеке. Но если переменная используется, то где-то же (в регистре или где-либо в памяти) она хранится! Почему в отладочной информации это не предусмотрели — для меня загадка. Ведь посмотреть значение регистров можно на каждом шаге отладки, а значения переменных, хранящихся в регистрах, уже нельзя.
Теоретически, это предложение возможно реализовать и в существующих компиляторах, но, предполагаю, что это слишком сложно, так как это не закладывалось в существующие компиляторы в начале их разработки.
Явное обозначение области видимости переменных при обращении к ним (синтаксическая соль)
Глобальные переменные я предлагаю обозначать префиксом
:
(смотри :numbers
в примере выше).Переменные объектов — префиксом
.
(так, например, .x
означает обращение к переменной[/члену] объекта с именем x
), переменные типов (или статические\static в терминологии C++) — префиксом .:
.Префикс @ (символ похож на объединение двух букв C и a — Capture\Схватить) — для захвата внешних переменных внутри локальных функций, аналог nonlocal из Python.
Префикс
^
— для доступа к переменным из внешней ‘области видимости’\scope, это может быть полезно во время отладки (например, есть цикл по i
, внутри него ещё какой-то цикл, внутри которого ещё маленький цикл по i
, находясь в котором хочется получить текущее значение переменной i
верхнего уровня, это можно сделать посредством записи ^i
). Также ^ можно использовать для возврата из внешней функции внутри локальной функции:F outer_func(...)
F local_func(...)
^R // (or ^(outer_func)R) return from outer_func
В данной статье я коротко описал наиболее интересные черты нового языка (а также некоторые возможности, которые могли бы перенять уже существующие языки). Если кого-либо заинтересовал данный проект, напишите мне личное сообщение.
T Person
String name
Int age
F (name, age)
.name = name // or (.).name = name, because (.) is this/self
.age = age
A persons = []
persons [+]= Person("Name", 17)
// Translation of Python's `def parenthesize(s: Union[str, bytes]) -> Union[str, bytes]: ...` from [http://neopythonic.blogspot.com]:
F parenthesize(T C (String, Bytes) s)
...
// Doubly linked list
T DLListItem[T Type]
Type& prev // ‘unsafe pointer’/‘unowned reference’ [true weak pointer/reference `Type??` is much more expensive]
Type? next
F is_in_list // if method is defined without parentheses, than it must be called also without, i.e.: I it.is_in_list {...}
R next != N
T DLList[T Type(DLListItem)] // Type(DLListItem) means that Type must be derived from DLListItem
Type? first
Type& last
F.destructor // destructor is needed/necessary because some list item may be shared, and in that case it will not be removed from the list and also all following items will not be removed
.clear()
F clear()
Type? p = move(first) // this also sets `first` to N
L p
p.prev = N
Type? n = move(p.next) // this also sets `p.next` to N
p = n // move(n) is not needed here as the compiler put `move` automatically at all places of last use of variable
last = N
F append, [+]=(Type &item) // define both method `append()` and operator [+]=
item.prev = .last
I .last {.last.next = item} E .first = item
.last = item
F calc_len()
Int len = 0
L (.)
len++
R len
F L
F () -> Type& // returns iterator to the first element of this container
R .first
F next(it) -> Type&
R it.next
F prev(it)
R it.prev
Т ЛичныеДанные
Строка имя
Цел возраст
Ф (имя, возраст)
.имя = имя // или (.).имя = имя, так как (.) это this/self
.возраст = возраст
А массив_лд = []
массив_лд [+]= ЛичныеДанные("Имя", 17)
// Перевод Python-кой записи `def parenthesize(s: Union[str, bytes]) -> Union[str, bytes]: ...` из [http://neopythonic.blogspot.com]:
Ф заключить_в_скобки(Т С (Строка, Байты) с)
...
// Двусвязный список
Т ЭлДССписка[Т Тип]
Тип& пред // небезопасная ссылка/указатель [честный слабый указатель `Тип??` значительно дороже]
Тип? след
Ф в_списке // если метод объявляется без скобок, то вызывать его необходимо также без скобок, например: Е эл.в_списке {...}
Р след != Н
Т ДССписок[Т Тип(ЭлДССписка)] // Тип(ЭлДССписка) означает, что Тип должен быть производным от ЭлДССписка
Тип? первый
Тип& последний
Ф.деструктор // деструктор нужен, так как какой-то элемент списка может быть shared\разделён, и в этом случае он не будет удалён из списка также как и последующие элементы
.очистить()
Ф очистить()
Тип? п = перем(первый) // это также сбрасывает `первый` в Н
Ц п
п.пред = Н
Тип? с = перем(п.след) // это также сбрасывает `п.след` в Н
п = с // перем(с) здесь не обязательно, так как компилятор вставляет `перем` автоматически в места последнего использования переменной
последний = Н
Ф добавить, добавь, [+]=(Тип &эл) // также может быть полезно для "локализованных" исходных файлов: F append,добавить ...
эл.пред = .последний
Е .последний {.последний.след = эл} И .первый = эл
.последний = эл
Ф вычисл_длину()
Цел длина = 0
Ц (.)
длина++
Р длина
Ф Ц
Ф () -> Тип& // возвращает итератор контейнера (в данном случае — указатель на первый элемент списка)
Р .первый
Ф след(эл) -> Тип&
Р эл.след
Ф пред(эл)
Р эл.пред
Ещё вот код по рисованию диаграммы, которая помогла мне определить оптимальное время для публикации данной статьи: сетевая часть (на Python и новом языке программирования) и сохранение файла изображения [диаграммы] (на C++ и новом языке программирования).
Комментарии (131)
alhimik45
07.03.2018 17:50+1По поводу "единой конфигурации сборки". Писать свой компилятор это сложно. А хороший компилятор (оптимизации там/разные платформы) ещё сложнее. Кажется легче взять тот же LLVM и попытаться втащить эту возможность в него (в случае успеха пользу будет принесена многим пользователям нескольких уже существующих языков). В крайнем случае можно его форкнуть и перепилить как нужно. По крайней мере всяко проще чем пилить с нуля.
Zenitchik
07.03.2018 17:53+2Однобуквенные имена нельзя резервировать: они нужны для локальных переменных.
alextretyak Автор
07.03.2018 21:49Тогда используйте полные версии зарезервированных слов, представленные в 3 и 4 столбцах таблицы базовых слов.
aamonster
07.03.2018 18:25Плакал. С чего вы взяли, что optimized out переменная где-то хранится? Возможно даже, соответствующее численное значение ни в какой момент времени не появляется в регистрах.
Более того — и использующего её куска кода может не быть. Или, к примеру, нам фактически нужен один бит из неё, который и вычисляется в релизной сборке — и код этого вычисления не очень-то похож на наш исходник.
В общем, неплохо бы изучить теорию и чужой опыт до создания своего языка. Во всяком случае, языка с оптимизирующим компилятором, скриптовой-то язык проще...
alextretyak Автор
07.03.2018 21:41Это вы верно подметили, но ради краткости статьи я не стал разбирать данный случай.
В подобных ситуациях я хочу предложить:
- constant unfolding — "деоптимизация", выполняемая отладчиком во время отладки, которая позволяет по шагам показать вычисление констант, которые в реальности вычисляются на этапе компиляции. Например: в
A -c = max(1, 2, 3)
можно заглянуть в функцию max и виртуально пройти по шагам в этой функции, хотя реально значениеc
вычисляется на этапе компиляции и во время выполнения функцияmax
не вызывается. - loop counter deoptimization — в случае если компилятор как-то оптимизировал работу со счётчиком цикла, при отладке выполняется обратное вычисление, позволяющее посмотреть актуальное текущее значение переменной-счётчика цикла.
Собственно, я как раз хотел сделать акцент на том, что обратное вычисление для "живой" переменной (ещё не вышедшей из области видимости) сделать возможно всегда.
Реальная проблема только с переупорядочиванием операций компилятором, но от него можно отказаться, я считаю.aamonster
08.03.2018 09:05+4На минуточку, создатели gcc и llvm, да и msvc в курсе этого. Это — мощные команды профессионалов высокого класса. Однако ж они не реализовали формат отладочной информации, обеспечивающий "обратное вычисление". Как вы думаете, почему?
Призовой вопрос: почему вы не сможете сделать это в одиночку?
Насчёт отказа от переупорядочивания — посмеялся. Это базовая операция, обеспечивающая возможности для других оптимизаций. Как без этого, к примеру, выносить код из цикла?
alextretyak Автор
08.03.2018 09:31-1Однако ж они не реализовали формат отладочной информации, обеспечивающий "обратное вычисление". Как вы думаете, почему?
Legacy code.
Призовой вопрос: почему вы не сможете сделать это в одиночку?
Я верю, что смогу собрать команду профессионалов (и да, это не смотря на тот факт, что в данный момент времени над этим языком работаю я один), причём, надеюсь, что Хабр в этом сыграет не последнюю роль. :)(:
Как без этого, к примеру, выносить код из цикла?
Выносить код из цикла можно не нарушая порядок.
Можете привести конкретный пример?
- constant unfolding — "деоптимизация", выполняемая отладчиком во время отладки, которая позволяет по шагам показать вычисление констант, которые в реальности вычисляются на этапе компиляции. Например: в
lair
07.03.2018 18:33+1Какую задачу решает ваш язык программирования?
alextretyak Автор
07.03.2018 21:55-1Такую же, какую решают Python и C++. Только в более компактной форме и с лучшей производительностью и безопасностью по сравнению с Python.
lair
07.03.2018 21:59+1Такую же, какую решают Python и C++
Если такую же, то зачем он нужен? (это не говоря о том, что Python и C++ решают немного разные задачи)
Только в более компактной форме
Зачем это нужно?
с лучшей производительностью и безопасностью по сравнению с Python
Без потерь других характеристик Python?
KirEv
07.03.2018 18:37в потугах кодо-оптимизаций легко забыть: программный код пишет программист для программиста (человека), а не для машины, последним занимается компилятор.
зачем лишний раз программирование усложнять?
alextretyak Автор
07.03.2018 22:01-1Не знаю, что вам ответить. На ум приходит только такой [мной собранный] стишок:
Hardware and software
Require each other
And neither can be
Without the other.
Вот также программист и машина — не могут друг без друга. :)(:
Akdmeh
07.03.2018 22:33Это что, какой-то эзотерический язык, чтобы усложнить разработку в команде?..
Напомнило какую-то ужасную смесь непонятности Ассемблера и кириллицу 1С.
Задача кода быть понятным, а тут какая-то непонятная экономия, чтобы меньше печатать ключевые слова и увеличивать количество опечаток.alextretyak Автор
07.03.2018 23:24Я вдохновлялся языками программирования Python и C++.
А какой язык программирования вы считаете образцом для подражания?
Вообще глобальная задумка такова, чтобы вместо букв были символы (большие).
Насчёт
увеличивать количество опечаток
прошу, приведите хотя бы один пример кода, где возможно перепутать символы (то есть, вместо одного зарезервированного словосимвола использовать другой, и при этом код останется корректным с точки зрения синтаксиса).alextretyak Автор
07.03.2018 23:38Ответ ‘заменить L.break на S.break’ прошу не предлагать, так как я считаю, что следует заменить одно из этих подслов на другое (например: L.exit).
alextretyak Автор
07.03.2018 23:48Это что, какой-то эзотерический язык, чтобы усложнить разработку в команде?
Это дело вкуса. Чтож, вам не понравилась такая запись. Кому-то может понравится…
Для меня скорее Perl — эзотерический язык, но это [моё мнение о Perl] не помешало ему завоевать популярность и найти своих сторонников.
lair
08.03.2018 00:37… к разговору, значит, об опечатках:
Префикс ^ — для доступа к переменным из внешней ‘области видимости’ [...] например, есть цикл по i, внутри него ещё какой-то цикл, внутри которого ещё маленький цикл по i, находясь в котором хочется получить текущее значение переменной i верхнего уровня, это можно сделать посредством записи ^i
Вот, значит, у меня пять вложенных циклов (ну по пятимерному массиву я хожу), и в каждом из них индексация по
i
. Как мне обратиться к индексу второго массива сверху?
… или, скажем, статическая типизация и работа с памятью.
A persons = [] persons [+]= Person("Name", 17)
Какого типа
persons
, и что конкретно произошло с памятью во второй строчке?alextretyak Автор
08.03.2018 01:00По первому вопросу: прошу назовите хотя бы один язык программирования, в котором возможно ‘обратиться к индексу второго массива сверху’ или приведите код на любом (в том числе несуществующем) языке программирования более красивый, чем в предложенном в статье языке.
По второму вопросу: это успешно реализовано в языке Nemerle, о чём я уже говорил в статье:
< также как тип массива или словаря в Nemerle определяется по типу первого добавленного в него элементаlair
08.03.2018 01:16По первому вопросу: прошу назовите хотя бы один язык программирования, в котором возможно ‘обратиться к индексу второго массива сверху’
Любой язык, в котором возможны вложенные циклы:
foreach(var i in someArray) foreach(var j in i) foreach(var k in j) foreach(var l in k) foreach(var m in l) { DoSomethingTo(j); }
приведите код на любом (в том числе несуществующем) языке программирования более красивый
Код чего?
По второму вопросу: это успешно реализовано в языке Nemerle
Что успешно реализовано? Я задал два конкретных вопроса: какого типа
persons
, и что конкретно случилось с памятью в моментpersons [+]=
.
Еще кстати, бонусный вопрос про типизацию: как выглядит сигнатура функции, которая принимает в себя один аргумент, являющийся перечислимым (enumerable) множеством от любого типа, на котором определена операция сложения?
alextretyak Автор
08.03.2018 01:39Код чего?
Вы и правда не понимаете. Или притворяетесь, что непонимаете? :)(:
Скрытый текстВы предлагаете:
пять вложенных циклов (ну по пятимерному массиву я хожу), и в каждом из них индексация по
‘Индексация поi
.i
в каждом’ означает ‘индексация по i во всех пяти массивах’, а именно:
foreach(var i in someArray) foreach(var i in i) foreach(var i in i) foreach(var i in i) foreach(var i in i) { DoSomethingTo(i); // как здесь обратиться ‘к индексу второго массива сверху’ }
В предлагаемом языке ваш код можно записать так:
L(i) someArray L(i) i L(i) i L(i) i L(i) i DoSomethingTo(^^^i)
А можно так:
L(i) someArray L(j) i L(k) j L(l) k L(m) l DoSomethingTo(j)
lair
08.03.2018 10:55+2foreach(var i in someArray) foreach(var i in i) foreach(var i in i) foreach(var i in i) foreach(var i in i) { DoSomethingTo(i); // как здесь обратиться ‘к индексу второго массива сверху’ }
К счастью, никак. Более того, в определенных языках этот код даже не скомпилируется, потому что variable shadowing — это зло.
L(i) someArray L(i) i L(i) i L(i) i L(i) i DoSomethingTo(^^^i)
… и, собственно, получить то, о чем шла речь. Во-первых, опечататься в количестве
^
и не заметить этого — как нефиг делать, особенно если там окажется индекс, а не элемент. Во-вторых, стоит скопипастить эту строчку на уровень выше, как она начнет обращаться не ко второму сверху, а к верхнему — что не то, что было нужно разработчику.
Type inference для словаря и массива.
Type interference для словаря и массива — это как раз легко. Только мой вопрос был не про это.
Я предлагаю взять реализацию из Nemerle, поэтому ваши вопросы следует задавать разработчикам Nemerle.
Э нет, так не взлетит. Это ваш язык, ваши примеры, и вы должны знать, как он себя ведет.
Более того, в Nemerle type interference (в этом месте) сделан для generic parameter, а окаймляющий класс задан явно.
alextretyak Автор
08.03.2018 01:54как выглядит сигнатура функции, которая принимает в себя один аргумент, являющийся перечислимым (enumerable) множеством от любого типа, на котором определена операция сложения?
Не очень понял о чём именно вы спросили, можете привести пример кода?
Я смог изобразить только вот этот код пиша ответ на ваш вопросT.enum Shape // or T.enum Shape {BOX, CUBE; SPHERE} (`BOX, CUBE` means here that BOX = CUBE and CUBE = BOX) BOX, CUBE SPHERE F func(Shape s) ... func(BOX) F +(Shape s1, Shape s2) // just like in Ruby def +(...) Shape r ... R r
lair
08.03.2018 11:01+1fun sum set -> if set |> empty None else r = set |> first for x in set |> skip 1 r += x Some(r) sum []: None sum [1, 2, 3]: 6 sum [0.1, 0.5]: 0.6 sum [30m, 30s]: 30,5m sum set(1, 3): 4 [1, 2, 3] |> filter odd |> sum : 4
KirEv
08.03.2018 06:46+1хорошо, много коментариев за несколько часов
вот первый пример кода из начала статьи
что мне нужно сделать, чтобы скомпилировать этот код в бинарник и выполнить его?alextretyak Автор
08.03.2018 08:47-1В данный момент проект находится на очень ранней стадии и до полноценного компилятора [тем более в бинарник (планируется поддержка только двух архитектур: x86-64 и ARM)] ещё далеко. Лично я отвечаю за трансляцию нового языка в C++17. Данный код странслируется в:
while (true) { switch (instr[i]) { case '[': nesting_level++; break; case ']': if (--nesting_level == 0) goto break_; break; } i++;
Comdiv
08.03.2018 16:55+1Если транслятор корректно генерирует код на С++, то и исполняемый двоичный файл получить не проблема. В конечном итоге транслятор должен брать на себя возню со сторонним компилятором, но если это сейчас не так, то можно так и написать, что нужно выполнить примерно следующее:
$ newlangtrans booboo.nl > booboo.cpp && g++ booboo.cpp -o booboo
alextretyak Автор
08.03.2018 20:48-2Благодарю за разъяснение, но вы знаете, какая самая популярная операционная система среди программистов? Почему вы пишете только ответ для менее распространённой операционной системы?
[Говоря по простому, приведите пример крупных проектов, кто в "продакшн" использует gcc под Windows?]Comdiv
08.03.2018 23:05Среди программистов GNU/Linux + Mac OS X +(WSL | cygwin ), для которых этот пример верен, не менее популярны. Сам я Windows не пользуюсь.
dopusteam
08.03.2018 10:47+4Лично я считаю, что многие обозначения операторов языков выбраны неправильно, например ^ у новичков в программировании ассоциируется с операцией возведения в степень.
Префикс ^ — для доступа к переменным из внешней ‘области видимости’
Не находите, что это немного странно?alextretyak Автор
08.03.2018 13:59-2Обе эти возможности [крайне] редко используемые, просто мне хотелось сразу перечислить все префиксы, обозначающие "области видимости переменных".
dopusteam
08.03.2018 14:43+2Вы про возведение в степень и обращение к области видимости?
Вообще, [судя по Вашей манере писать], Вы бы и пунктуацию, синтаксис и прочие правила и у русского письменного поменяли бы :)
Кстати, где можно ознакомиться со спецификацией Вашего письменного языка? Не совсем понятны подобные вставкиalextretyak Автор
08.03.2018 14:52-1Вы про возведение в степень и обращение к области видимости?
Да. (И я ведь указал это в подсказке к "Обе эти возможности", или вы заходите с планшета или смартфона? [Почему-то в Android практически нет браузеров показывающих всплывающие подсказки при долгом тапе/нажатии.])
К русскому ‘в данный период времени ’|у меня|‘ пока’ лишь две претензии:
Почему запятая не всегда означает паузу и почему не с глаголами пишется раздельно.dopusteam
08.03.2018 15:07Ваша правда, я с телефона.
Мне кажется, что возведение в степень — достаточно частая операция.
Обращение к области видимости — тоже, это обычный вложенный цикл.
Но даже если были бы редкими, то я её понимаю, как это оправдывает неочевидное использование символа ^
lair
08.03.2018 15:18+1Почему запятая не всегда означает паузу и почему не с глаголами пишется раздельно.
Потому что это естественный язык, и такова его логика.
alextretyak Автор
08.03.2018 20:53-2Потому что это естественный язык, и такова его логика.
А вы можете формализовать?
Было бы здорово увидеть грамматику запятой в EBNF/ABNF. :)(:alextretyak Автор
08.03.2018 21:44-'‘запятой’'+'‘русского языка’'
lair
08.03.2018 23:07А вы можете формализовать?
Берете Розенталя или Мильчина, там правила описаны.
Было бы здорово увидеть грамматику запятой в EBNF/ABNF
Естественный язык.
alextretyak Автор
09.03.2018 00:52> Берете Розенталя или Мильчина, там правила описаны.
Я имел в виду точно формализовать (: в БНФ[‘или EBNF/ABNF’] :).
> *Естественный* язык.
Я правильно понимаю, что вы под естественным языком понимаете язык, на котором говорят люди?
А как вы относитесь к идее создания нового формализованного языка (имеющего точную БНФ форму), на котором можно и программировать и разговаривать людям одновременно?
И еще. Вы слышали про языки эсперанто и авелидо?lair
09.03.2018 01:00Я имел в виду точно формализовать
Повторяю еще раз: естественный язык.
Я правильно понимаю, что вы под естественным языком понимаете язык, на котором говорят люди?
Под естественным языком я понимаю то, что понимает под ним лингвистика: "язык, используемый для общения людей и не созданный целенаправленно".
А как вы относитесь к идее создания нового формализованного языка (имеющего точную БНФ форму), на котором можно и программировать и разговаривать людям одновременно?
Плохо.
И еще. Вы слышали про языки Эсперанто и Авелидо?
Про первый — да, про второй — нет. Эсперанто — сконструированный язык.
stgunholy
08.03.2018 13:50+1Любой язык разрабатывается с целью решения широкого или наоборот узкого круга проблем. За мои 18 лет опыта никогда не было острой необходимости ‘обратиться к индексу второго массива сверху’. Так что изобретать велосипедный синтакис (который сразу и не понять.) для решения такой редкой проблемы странно как минимум
alextretyak Автор
08.03.2018 13:52-2Это нужно для отладки. Просто будет странным, если такой синтаксис будет работать при отладке, а в коде программы уже не будет работать.
stgunholy
08.03.2018 13:57+1Ну во время отладки (в известных мне отладчиках) можно же просто указать какие переменные/значения выводить… Даже можно прерывать выполнение по изменению значения иногда. И какой смысл дебаг функциональность делать «фичей» нового языка? Как правило, сборки и различают на дебаг/прод именно потому, что задачи запуска сборок разные совсем.
alextretyak Автор
08.03.2018 14:06-1В MS Visual Studio 2013 в C++ это не работает, то есть если навести курсор на внешнюю переменную `i`, то показывается всё равно значение внутренней `i`. [-Хотелось бы таблицу, показывающую в каких IDE показывается верное значение при наведении, а в каких — нет.-]
stgunholy
08.03.2018 14:10+1Intellij… Chrome :) Но опять таки… Как мне кажется сомнительная причина городить язык новый. ПС. Опрос смотрю со мной согласен… :)
lair
08.03.2018 14:08+1Задумывались ли вы над тем, что флаги открытия файла можно не указывать явно, а выводить из его использования?
И как вы это предлагаете делать, если файл используется за пределами того юнита, где он открывается?
Или вот, скажем, один программист думал, что открывает файл для чтения (и у него код на это оптимизирован), а другой попозже написал операцию записи в тот же файл — что должен сделать язык?
alextretyak Автор
08.03.2018 14:40-1И как вы это предлагаете делать, если файл используется за пределами того юнита, где он открывается?
Тип файла будет шаблонным. Что-то вроде:
T File[T.enum { READ WRITE READ_WRITE } mode]
Или вот, скажем, один программист думал, что открывает файл для чтения (и у него код на это оптимизирован), а другой попозже написал операцию записи в тот же файл — что должен сделать язык?
Открываться файл автоматически и для записи и для чтения в таком случае, скорее всего, не будет.
Но вы согласны с тем, что при таком использовании:
флаги открытия файлов можно однозначно не указывать?A fstr = File(fname).read() File(fname).write(contents)
Вообще, такие вопросы будет решать комитет по разработке языка. Я не достаточно компетентен, чтобы ответственно отвечать на ваши вопросы. Свою главную задачу я вижу в том, чтобы собрать ядро комитета.lair
08.03.2018 15:16+2Тип файла будет шаблонным.
И как вам это поможет сделать его автовывод в описанных мной случаях?
Открываться файл автоматически и для записи и для чтения в таком случае, скорее всего, не будет
… и что же случится?
флаги открытия файлов можно однозначно не указывать?
Нет, не согласен. В каком режиме открыт файл во втором случае? Write? Append? Shared atomic append? А в первом — sequential read или random access read?
Вообще, такие вопросы будет решать комитет по разработке языка. Я не достаточно компетентен, чтобы ответственно отвечать на ваши вопросы.
Ну то есть вы понаделали кучу громких заявлений, а отвечать на них должен кто-то другой?
alextretyak Автор
08.03.2018 21:22-2И как вам это поможет сделать его автовывод в описанных мной случаях?
Затрудняюсь ответить. Переадресую этот вопрос комитету, когда он будет собран.
… и что же случится?
Ошибка компиляции (: очевидно :).
В каком режиме открыт файл во втором случае?
В таком же как в Python "w"|"wt".
open(fname, "w").write(contents)
Ну то есть вы понаделали кучу громких заявлений, а отвечать на них должен кто-то другой?
Отвечать будем все вместе. Я как раз и ищу тех, с кем можно будет разделить ответственность.
Мои личные переживания по поводу ответственности [за создание сильного ИИ] изложены здесь:http://archive.li/hMGCi:
Мне долгое время было плохо физически от осознавания того, к чему приведёт результат моей деятельности в будущем.lair
08.03.2018 23:11Затрудняюсь ответить.
Ну то есть ваш "каркас" ничего не стоит, на самом деле.
Ошибка компиляции (: очевидно :).
Нет никакого "очевидно" в данном случае.
В таком же как в Python "w"|"wt".
… а если мне нужен append, или, того хуже, atomic append?
Отвечать будем все вместе. Я как раз и ищу тех, с кем можно будет разделить ответственность.
А зачем кому-то может быть нужно отвечать за ваши высказывания?
alextretyak Автор
09.03.2018 04:23… а если мне нужен append, или, того хуже, atomic append?
‘Это’[‘подобное’], скорее всего, лучше делать через специальное имя файла, например:
open(‘ram:myfile’)
открывает файл в оперативной памяти (файл доступен до закрытия [приложения или файла] всем подпрограммам/подприложениям, запускающимся из данного приложения/программы). Или так:open(‘memory:myfile’)
илиopen(‘sharedmemory:myfile’)
[в первом случае файл виден только данному приложению и всем приложениям, запущенным из данного, а во втором — файл виден всем сторонним приложениям].
Открытие в режиме append я предлагаю заменять дополнительным вызовом функции-члена/метода
seek()
:
A f = File(fname) f.seek(END)
lair
09.03.2018 11:19+1Это’[‘подобное’], скорее всего, лучше делать через специальное имя файла
Вы, похоже, даже не понимаете, что мне нужно.
Открытие в режиме append я предлагаю заменять дополнительным вызовом функции-члена/метода seek():
То есть то, что файлы (точнее, потоки) бывают без seek, вы даже еще и не думали? И про то, что atomic append так сделать нельзя? Впрочем, вы вообще про потоки, похоже, не думали, вы только о файлах говорите.
Comdiv
08.03.2018 16:38+4Я не достаточно компетентен, чтобы ответственно отвечать на ваши вопросы. Свою главную задачу я вижу в том, чтобы собрать ядро комитета.
Комитет должен собирать достаточно компетентный человек, иначе некомпетентность такого комитета, может оказаться даже выше.alextretyak Автор
08.03.2018 21:33-2Не соглашусь, [достаточно] разумный — да. Но не обязательно вникать в детали того, как работает компилятор.
Comdiv
08.03.2018 22:32Понимание деталей влияет на понимание реализуемости и полезности. Отвлечённое языкотворчество прагматического инструмента — это ошибка.
lair
08.03.2018 23:12А мы пока что до компилятора не дошли, мы пока только наблюдаемое поведение обсуждаем.
alextretyak Автор
09.03.2018 04:29Вы не согласны с тем, что компилятор неразрывно связан с ‘наблюдаемым поведением’?
lair
09.03.2018 11:19+2Нет, конечно. Можно иметь два компилятора и одно поведение. Можно вообще не иметь компилятора, но иметь спеку на поведение.
Comdiv
08.03.2018 16:34+3Я так и не смог написать хороший вводный текст к данной статье, поэтому начну просто с примеров
Это, скорее всего, означает, что Вам нечем обосновать создание этого языка, кроме как потому что хочется. Обоснование — это и был бы хороший вводный текст.alextretyak Автор
08.03.2018 21:38У меня нет другого обоснования [в данный момент времени] кроме как ‘время пришло’.
Comdiv
08.03.2018 23:08Это, кстати, нормальный ответ. Хуже было бы, если «так велели голоса».
Но надеяться под это собрать комитет, на мой взгляд, наивно.alextretyak Автор
08.03.2018 23:36так велели голоса
Ну почти так и есть. :)(: Только я их называю ‘смысловыми импульсами [из будущего [посредством квантовой телепортации]]’.
32bit_me
09.03.2018 09:41+1Отсюда: http://archive.li/hMGCi
Всё дело в том, что исходный код ДЕйВОСи[с] написан на [совершенно] новом языке программирования.
И [мне[?]] необходимо собрать команду для разработки компилятора под этот язык для того, чтобы можно было выполнить/запустить [полученный/принятый из будущего] исходный код [на этом языке].
Разумеется, команду разработчиков компилятора я буду собирать не здесь (: [не в этом месте/сайте/форуме] :).
Не хотите ли сообщить дополнительные подробности по поводу этого?
vdem
09.03.2018 20:45Представьте себе минималистичный язык, синтаксиса которого было бы достаточно для того, чтобы именно (и только) средствами языка можно было создать тип данных «бит», на основе которого теми же средствами языка можно было бы построить «байт», «слово», «двойное слово», «длинное слово». Само собой, потребуются встроенные классы для функций, завязанных на хранение данных (в зависимости от ОС). Очень близко к Форт, но объектно-ориентированное (для объектов, которые «живут» долго и завязаны на систему и как правило зависят от ее реализации, но имеют общий интерфейс, — «дисплей», «накопитель») и функциональное (для объектов, которые многократно создаются и уничтожаются в процессе).
И запрет на использование Unicode в идентификаторах, зато можно использовать разные ASCII символы типа +, -, /, etc.
Это был бы язык, отличающийся от других.vdem
09.03.2018 20:55И, конечно, минимальный минимум зарезервированных идентификаторов. Например:
class lang.Bit { events: { on: { send switchedOn; switch off; }, off: { } } }
vdem
09.03.2018 21:00Упс, время истекло.
И, конечно, минимальный минимум зарезервированных идентификаторов. Например:
class lang.Bit { states: { on: { setOn: { // Handle setOn signal }, setOff: { switch off; send switchedOff; } }, off: { setOn: { switch on; send switchedOn; }, setOn: { } } } }
vdem
09.03.2018 21:06А для языка, основанного на данных и правилах их обработки (типа Пролога) можно вообще не выдумывать никакого особого синтаксиса, и использовать самый обычный JSON или XML, — т.о. парсер не нужен, а AST строится как в Лего.
Hvorovk
Код на этом «языке» сложноват. Чем сложно написать fun, def или что то в этом роде? Зато более понятно и глаз не режет
alhimik45
Согласен, нет смысла экономить на размере ключевых слов. Код должен быть понятен (хотя бы немного, на структурном уровне) даже программисту не знакомому с этим языком.
Новые языки должны создаваться, если есть новые концепции, которые хочется реализовать. При этом совершенно не обязательно коверкать базовый синтаксис. Можно просто взять знакомый всем си-подобный или питоно-подобный и немного изменить/докинуть ключевых слов. Это вполне может увеличить аудиторию заинтересованных (хотя бы на процент тех людей, которые закрыли статью, ужаснувшись от кода на первой картинке)
alextretyak Автор
А если нет новых концепций [не лично у меня, а вообще/‘в принципе’ не осталось больше новых концепций (вы ведь допускаете такой вариант в будущем?)], но хочется структурировать уже имеющиеся концепции.
Верно, можно. Но это могут[/должны] делать разработчики соответствующего языка программирования (того же Python). А что делать мне и тем, кто хочет создать новый язык программирования?
alhimik45
Ну структурируйте, только зачем синтаксис то свой, никому не понятный, придумывать?
Создавайте, используя модифицированный синтаксис уже существующих языков.
alextretyak Автор
Есть замечательная фраза ‘‘критикуешь — предлагай’’. Какой конкретно язык вы предлагаете взять за пример образцового синтаксиса?
и при этом нет ни одного достойного языка программирования с русскими ключевыми словами?И к тому же, предполагается поддержка русского языка хотя бы на уровне проверки жизнеспособности идеи о том, что ‘Программирование на кириллице может повысить производительность [труда [русских программистов]]’.
Вам не обидно, что
А на русском многие ключевые слова при прямом переводе с английского звучат не очень. Как бы вы перевели, к примеру,
this
на русский?этот
?alhimik45
Я уже говорил, си-подобный или питоно-подобный, для императивного ооп языка самое то.
Нет, я наоборот очень рад что для меня конструкции языка программирования не имеют дополнительного смысла, как это было бы, если бы язык был моим родным.
alextretyak Автор
Ну хорошо. А если посмотреть с точки зрения не вас, как уже имеющего опыт программирования человека, а точки зрения нового поколения детей. Какому языку программирования вы бы стали их учить?
Лично я считаю, что многие обозначения операторов языков выбраны неправильно, например ^ у новичков в программировании ассоциируется с операцией возведения в степень.
Я понимаю, что операция возведения в степень используется крайне редко, но… если и вводить в язык оператор для её обозначения, то это должно быть соответствующее обозначение (и я предполагаю, что основной причиной отказа от
^
в качестве оператора возведения в степень является использование этого символа для операции поразрядного XOR (исключающего ИЛИ), что я считаю неудачной идеей — ну, во всяком случае новичков в программировании это точно сбивает с толку)Хотя я могу понять разработчиков языка Си… у них просто не было времени на качественный выбор символов для операторов языка [другими словами, в их время это была неприоритетная операция, гораздо важнее были другие задачи]. Но я бы взял обозначение операции исключающего ИЛИ как (+), так как эти три символа похожи на символ ?, который используется в алгебре логики\Boolean algebra для обозначения операции ‘исключающего или’/сложения по модулю 2: . И хотя ? используется чаще для одноразрядных значений, в Википедии встречается его применение для указателей и для массивов из байт
lair
… а почему, учитывая, что вне программирования этот символ так не используется?
Но если вам очень хочется, то вот: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/exponentiation-operator
Соответствующее чему?
Zenitchik
Вычисления в Excel — это вне программирования?
lair
Нет (в контексте обсуждения).
alextretyak Автор
Просто соответствующее (или можно сказать консистентное).
lair
Не бывает "просто соответствующего", соответствовать можно только чему-то. Не бывает "просто консистентного", бывает консистентной в рамках чего-то или с чем-то.
Так вот, обычно в рамках языков, которые вводили этот оператор, это было консистентно.
alextretyak Автор
Консистентно с чем или в рамках чего? :)(:
lair
С другими операторами в рамках языка.
vdem
По поводу символов русского/любого другого языка (кроме общепринятого латинского алфавита) в качестве допустимых в идентификаторах:
1. А что делать с подобной программой, поддержку или развитие которой собираются передать индусам, бразильцам или китайцам? Фактически, над ней смогут работать только те, кто 1) хотя бы знаком с кириллицей и 2) имеет клавиатуру с соответствующими символами и 3) в ОС кириллица поддерживается и установлена.
2. Видите разницу между идентификаторами «myVar» и «myVаr»? А она есть :) P.S. Так что или делать чисто русский язык программирования (без латиницы в идентификаторах ВООБЩЕ), или забыть про эту неумную идею ВООБЩЕ :)
alextretyak Автор
Использовать русскую версию языка предполагается [если говорить серьёзно] в основном в отечественных военных разработках. (Я как раз думаю над тем, как сформулировать предложение для военных.)
lair
… это чтобы опыт на военке и на гражданке вообще несовместим был, да?
vdem
А зачем, Вы можете объяснить? Назовите ту самую главную причину, по которой НЕОБХОДИМО поддерживать кириллицу в идентификаторах? Незнание английского у программистов, работающих на МО? Так их в шею гнать надо, т.к. по программированию материалов на английском языке на порядки больше и по качеству часто лучше, чем на русском, таким образом программист, который не может этими материалами пользоваться из-за незнания языка необходимым образом оказывается ограниченным программистом. Или причина — «чтоб враг не догадался»?
Когда и если этот Ваш язык программирования завоюет хоть какую-то заметную популярность (не говоря уже о военном применении), [если говорить серьезно] я оставлю программирование и пойду работать подсобником на стройку :D
alextretyak Автор
Это привлечёт дополнительное внимание к языку у патриотично настроенных граждан, особенно незнающих/‘плохо знающих’ английский язык.
kAIST
Я вот патриотично настроенный гражданин, который достаточно плохо знает английский. А когда учился программированию, его (английский) вообще не знал. И это никоем образом не мешало учиться программированию. Разве что только над переменными вида otvet, itog и пр, некоторые смеялись )
Создавать язык, которым будут пользоваться лишь «избранные», извините, бред.
Comdiv
Мотивация автора странная, но поддержка кириллицы и не только давно есть даже в Си, не говоря про более новые языки. Делается это очень просто и нет причин в языке ограничивать идентификаторы латиницей.
vdem
1) Причин ограничивать в языке, действительно, нет. Ну кроме «myVar» и «myVаr» ;) Только незачем отсутствие подобного ограничения выставлять как некую офигенную фичу, отличающую данное поделие от других языков, тем более что
2) Ничего особенного, никакой особой идеи, никакого решения неких проблем предложенный язык не несет. Ну вот кроме этой самой «фичи» и зарезервированных слов длиной в один символ.
Comdiv
А мой ответ был на следующее:
Здесь поддержка кириллицы была преподнесена как что-то позорное для идиотов, которых нужно гнать в шею.
alextretyak Автор
А почему вы так решили? Можете привести конкретную цитату?
Comdiv
Цитату чего? Весь ответ vdem пропитан этим. Вы не заметили в нём злого сарказма?
alextretyak Автор
Хм, я не заметил.
vdem
Не было там никакого сарказма, тем более злого. Я действительно полагаю, что программист обязан знать английский. Не на разговорном уровне, но достаточно, чтобы понимать документацию. Ну и переменные называть не «pochta», а «email». Так исторически сложилось, что английский более международный, чем русский, а от глобализации особо не спрячешься. И, как я уже отметил, документации на английском на порядки больше, чем на других языках, — здесь же на Хабре и на ГТ чуть ли не половина статей — переводы, т.е. контента для разработчиков и вообще технарей больше генерируется на английском.
vdem
По поводу поддержки Unicode для идентификаторов. Я тут немного подумал, и решил что это зло. Сам пару раз с UTF-8 в коде встречался — пока в хексе не глянешь, не найдешь где ошибка.
AnutaU
Код на кириллице — смешная помеха для иностранных шпиёнов (если я правильно поняла причину, по которой вы хотите предложить свой язык именно этой аудитории).
Comdiv
lair
Нет такого, потому что разные вкусы и разные задачи.
Нет, не обидно. А почему должно быть?
Comdiv
Но если хочется сосредоточиться на одном базовом, то лучше спросить у потенциальных пользователей.
alextretyak Автор
< используйте полные версии зарезервированных слов, представленные в 3 и 4 столбцах таблицы базовых слов.
(Вариант fn[‘как в Rust’] обсуждается [возможные варианты: fun[‘как в Kotlin’], func[‘как в Swift’], function[‘как в JavaScript’]]. Вообще такие возможности языка будут отданы на откуп сообществу в процессе его разработки. И определятся результат будет простым большинством голосов. Я уже давно планирую систему голосования через GitHub (один коммит — один голос), но боюсь, что GitHub не выдержит "хабраэффекта".)
alhimik45
Если в язык добавлена возможность, то ей кто-то обязательно воспользуется. И человеку, который ни разу не сталкивался с этим языком будут непонятны все эти L F S, в отличии от общепринятых while/functuon/switch
alextretyak Автор
Как вы оцениваете сложность операции чего-то вроде
replace_all('F', 'function', WHOLE_WORD).replace_all('S', 'switch', WHOLE_WORD)...
?Предполагается, что новая среда разработки будет позволять показывать код в удобном пользователю виде.
alhimik45
Вот только код смотрят не только в своей IDE, бывает нужно подойти, показать что-то коллеге. Или просто кто-то пишет в блоге/делает презентацию на конференцию. Какой стиль ему выбирать? То же самое и со stackoverflow.
alextretyak Автор
Ладно, согласен. Пусть стиль для хранения файлов выбирается большинством голосов. Но я бы попробовал попрограммировать в предложенном мной однобуквенном стиле.
Comdiv
Если уж хочется программировать «однобуквенно», то для этого логичней использовать поддержку в IDE, а не наоборот.
alextretyak Автор
Я именно это и имел в виду.
Вообще, как я это себе представляю, будут отдельные голосования:
Comdiv
Что именно Вы имели ввиду? Я говорил приблизительно о следующем:
Пишите L, жмёте на <Чего-то> и буква раскрывается в полновесную конструкцию с понятными ключевыми словами. То есть на уровне транслятора нет поддержки сокращений. В этой же заметке это представлено именно как возможность языка.
alextretyak Автор
[В том числе] для этого и предназначено Правило одной кнопки.
Как
возможностьфича языка представлена иерархичность служебных/ключевых/зарезервированных слов. Просто идея использовать однобуквенные зарезервированные слова послужила отправной точкой к идее иерархичности слов языка.Операторы, состоящие из одной буквы, могут показаться странными на первый взгляд, но такая краткость даёт возможность полностью отказаться от (полностью дублирующего функциональность) тернарного оператора ?: (например, в Ruby также можно использовать оператор if и в выражениях, но это не так кратко как с ?:, в противном случае (как в данном языке) в операторе ?: не было бы смысла), а также это стимулирует использовать ‘более понятные’\‘more descriptive’ имена переменных вместо кратких однобуквенных.
Также, это в значительной степени сужает поле для выбора имён ключевых слов, частично решая проблему выбора, например: function, func, fun или fn.
К тому же, некоторые ключевые слова на русском языке в неоднобуквенной форме могут звучать довольно глупо, например: авто.
Ну и должна же быть у языка какая-то [фишка/]отличительная черта, сразу бросающаяся в глаза, и возможно даже чем-то отпугивающая. :)(: [Если честно, я боюсь делать слишком хороший[/совершенный] язык, так как это слишком большая ответственность.]
[[Национальная причина: русский язык для однобуквенных ключевых слов обладает преимуществом перед английским и многими другими, так как в русском языке больше букв! ]]
Но для новичков я согласен что полная форма читаться будет легче.
lair
Только вы ей не пользуетесь. Можно с успехом выкинуть однобуквенные префиксы, и ничего не изменится.
Нет, возможно отказаться от тернарного оператора дает только
if
-как-выражение (expression). И в ту же корзинкуswitch
-как-выражение, он же pattern matching (которого у вас тоже нет). Длина радикального значения не имеет.А вы знаете, да, что есть языки, в которых это ключевое слово вообще не используется?..
Обычно это все-таки что-то полезное.
Особенно прекрасны буквы Щ и Ъ. И удачи вам в отличении Ы от ЬI.
alextretyak Автор
.
после F/fn/fun/func/function выводится список/дерево вариантов’ достаточно полезной для новичков.И как вы предлагаете быть с ключевыми/зарезервированными словами для циклов? Резервировать prev, next, index глобально?
А почему вы так решили? Я просто не написал про
S.match
. Или вы хотите сразу всё изучить про новый язык? Тогда подождите хотя бы годик.Приведите список новых языков программирования где бы функции объявлялись в стиле Си.
Я не планирую отказ от
моноширногомоноширинного шрифта.А буква Ы рассматривается как вариант замены В/вЫбор, так как она располагается на одной клавише с латинской буквой S/switch.
Если вы не любите русский язык, так и скажите.
lair
А для этого тоже не нужны однобуквенные префиксы, для этого нужен синтаксис "сначала определимое, потом определение". Иными словами, вместо
public class
—class public
, тогда IDE после набораclass
может подсказать видимость. Только это же не читаемо.Ну да.
Потому что он нигде не упомянут. И еще потому, что отдельное ключевое слово для него, на самом деле, не нужно — что наводит меня на мысли, что вы не очень понимаете, как это устроено.
А откуда внезапно взялось ограничение "новых"? Я вроде бы не про новые языки говорил.
А при беглом чтении лучше не станет.
Я как раз люблю русский язык.
Zenitchik
Почему? Я лично не вижу разницы с т.з. читаемости.
lair
Потому что в английском языке, который я знаю, первая форма естественна, а вторая — нет.
Zenitchik
Ммм… А при чём тут английский? У английского же синтаксис совсем другой, сходство только в лексике.
lair
Совсем другой нежели что? Нежели словосочетание "public function", которое в английском совершенно валидно?
Zenitchik
Нежели любой язык программирования.
lair
Понимаете ли, просто не надо сравнивать язык программирования целиком, надо сравнивать фрагменты текста (которые вполне могут читаться).
for element in array
например.Zenitchik
Зачем сравнивать фрагменты текста? Я считаю, что не надо сравнивать ни язык целиком, ни фрагменты. Язык программирования не обязан быть похож на естественный язык.
Кстати говоря, в процитированном Вами примере, можете объяснить, почему оператор цикла называется «для»? Где логика?
Если бы я знал английский язык, когда начинал программировать, эта особенность помешала бы мне читать программный код.
lair
Не обязан, конечно. Но когда он уже похож, лучше эту похожесть сохранять, иначе будет много обманутых ожиданий.
Потому что это вполне себе существующее выражение: "for every something do that". Например, "for every in-text citation of the publication, list the name of the first author".
Zenitchik
С большим трудом можно притянуть за уши смысл этой конструкции к поведению оператора for в любом известном мне языке программирования.
lair
Мне вот для этого не нужно вовсе никакого труда. Возможно, это вопрос понимания английской конструкции.
lair
Кстати, если воспринимать
for
не как "оператор цикла", а как оператор перечисления, все становится логичнее (а в качестве "оператора цикла" намного лучше ложитсяwhile
/until
).lair
(забыл ответить) потому что мы их читаем, когда читаем программу. Чем меньше дискомфорта они вызывают, тем лучше.
Comdiv
Условное выражение, она же троичная операция, он же «тернарный оператор» тоже не нужны, как и безумная краткость.
В этом есть маркетинговый смысл, но, похоже, Вы перестарались, судя по реакции.alextretyak Автор
Перестарался или нет… время покажет.
YemSalat
Вы как себе это вообще представляете?
vdem
Все будут в восторге от русского языка программирования, тем более там одним символом можно функции определять. И военка ну просто вообще кипятком ссать будет от такого дела. Но GitHub точно не выдержит.