Re[4]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 28.09.23 15:05
Оценка:
Здравствуйте, Marty, Вы писали:

M>Начали да, потом наши подхватили


Не начали, а практически весь и сделали. После этого была главным образом косметическая доработка.
Ад пуст, все бесы здесь.
Re[4]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 28.09.23 15:08
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>1. От алгола-60 через виртовские язывки до Оберона-2


От оно как. То есть это не Алгол-60 важен, а оберон, который сделан на слямзенных из Алгола идеях.
Ад пуст, все бесы здесь.
Re[2]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 28.09.23 15:08
Оценка:
Здравствуйте, Baiker, Вы писали:

B>Где-то сейчас скулит один Влад — то ли от смеха, то ли от досады...


Влад очень радуется, что все заслуги приписали ему.
Ад пуст, все бесы здесь.
Re[3]: Сколько стоит создать ЯП?
От: Baiker  
Дата: 28.09.23 18:29
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Здравствуйте, Baiker, Вы писали:


B>>Где-то сейчас скулит один Влад — то ли от смеха, то ли от досады...


C>Влад очень радуется, что все заслуги приписали ему.


Пинать за "Нитру" тоже будут его.
Re[5]: Сколько стоит создать ЯП?
От: LaptevVV Россия  
Дата: 28.09.23 19:35
Оценка: :)
LVV>>1. От алгола-60 через виртовские язывки до Оберона-2
C>От оно как. То есть это не Алгол-60 важен, а оберон, который сделан на слямзенных из Алгола идеях.
"Огласите весь список, пожалуйста"(с)
Список идей, которые слямзены из Алгола-60.
Вы хотя бы сообщение об Алголе 60 читали ?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[6]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 28.09.23 21:06
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Вы хотя бы сообщение об Алголе 60 читали ?


О том, что оберон-прародитель важнее всего, включая те языки, из которых растут ноги самого оберона?
Ад пуст, все бесы здесь.
Re[7]: Сколько стоит создать ЯП?
От: LaptevVV Россия  
Дата: 30.09.23 18:32
Оценка: :))
LVV>>Вы хотя бы сообщение об Алголе 60 читали ?
C>О том, что оберон-прародитель важнее всего, включая те языки, из которых растут ноги самого оберона?
То есть не читал но осуждаешь.
Книжки надо читать, родной.
Тогда сойдешь за умного.
Я читал сообщение еще до твоего рождения.
Алгол-60 — первый язык, синтаксис которого был описан грамматиками Хомского.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[8]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 01.10.23 03:41
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Я читал сообщение еще до твоего рождения.


Не надо так раздуваться, а то лопнешь.
Ад пуст, все бесы здесь.
Re[2]: Сколько стоит создать ЯП?
От: Evgeny.Panasyuk Россия  
Дата: 01.10.23 03:43
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Далее, язык программирования в современном понимании — не только синтаксис ключевых слов, но также runtime (зачастую в форме виртуальной машины), стандартная библиотека, менеджер зависимостей и прочие на первый взгляд не относящиеся к языку вещи. Но без них язык никому не нужен.


Для нового языка необязательно всё лисапедить с нуля, можно пристроиться к любой существующей инфраструктуре.
Например именно так развивался C++ (он компилировался в C).
Да и сейчас есть много примеров, например Hy — Lisp построенный на рантайме Python.

Создать новый язык в одно рыло вполне возможно меньше чем за месяц, но имеет это смысл только для специализированных задач, так что скорей всего это будет DSL. И при грамотном подходе такой язык вполне может обходить другие языки по целевым метрикам, именно за счёт специализации.
Re[9]: Сколько стоит создать ЯП?
От: LaptevVV Россия  
Дата: 01.10.23 04:25
Оценка: :)
LVV>>Я читал сообщение еще до твоего рождения.
C>Не надо так раздуваться, а то лопнешь.
То есть, про Алгол-60 сказать нечего...
И поэтому нечего возразить Кернигану и Доновану, которые проводят генеалогию Go от Алгола-60 до Оберона-2 напрямую
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: Сколько стоит создать ЯП?
От: rudzuk  
Дата: 01.10.23 08:22
Оценка:
Здравствуйте, so5team, Вы писали:

s> Т.е. вы пропустили обвинения в сторону Java, которые около 20 лет назад любители Паскаля/Оберона выдвигали в сторону Java? Мол, разработчики Java внимательно изучали опыт Oberon-а и Component Pascal, даже кто-то к кому-то ездил в гости (уже не помню кто и куда), а потом бах! Выходит Java с байт-кодом , скомунизженным из Component Pascal, и ни одного благодарственного слова!


Это были не то чтобы обвинения, просто констатация факта, что жаба черпала идеи переносимого байт-кода в pascal-p (не обероне вовсе). Целая статья была на эту тему.
avalon/3.0.2
Re[10]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 01.10.23 20:03
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

LVV>И поэтому нечего возразить Кернигану и Доновану, которые проводят генеалогию Go от Алгола-60 до Оберона-2 напрямую


То есть ровно то, что я и сказал. Оберон — промежуточное звено, а не родоначальник.
Ад пуст, все бесы здесь.
Re[11]: Сколько стоит создать ЯП?
От: LaptevVV Россия  
Дата: 04.10.23 16:39
Оценка: :)
LVV>>И поэтому нечего возразить Кернигану и Доновану, которые проводят генеалогию Go от Алгола-60 до Оберона-2 напрямую
C>То есть ровно то, что я и сказал. Оберон — промежуточное звено, а не родоначальник.
Ты так и не ответил, что Оберон слямзил у Алгола-60.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[12]: Сколько стоит создать ЯП?
От: pagid_ Россия  
Дата: 04.10.23 18:08
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>>>И поэтому нечего возразить Кернигану и Доновану, которые проводят генеалогию Go от Алгола-60 до Оберона-2 напрямую

C>>То есть ровно то, что я и сказал. Оберон — промежуточное звено, а не родоначальник.
LVV>Ты так и не ответил, что Оберон слямзил у Алгола-60.
Оберон разве не "улучшенный" Паскаль, которому пришлось дать новое имя из-за отсутствия совместимости? А Паскаль прямой наследник Алгола-60. Немного "незаконнорожденный" потому как у папы слишком тяжелое отношение к законному ребенку — Алголу-68. И он родил вот такого вечного ребенка с названием Паскаль.
Re[12]: Сколько стоит создать ЯП?
От: Codealot Земля  
Дата: 04.10.23 21:10
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Ты так и не ответил, что Оберон слямзил у Алгола-60.


Кхм, ты уже начал отрицать свои же слова?
Ад пуст, все бесы здесь.
Re[13]: Сколько стоит создать ЯП?
От: LaptevVV Россия  
Дата: 07.10.23 06:05
Оценка: :)
LVV>>Ты так и не ответил, что Оберон слямзил у Алгола-60.
C>Кхм, ты уже начал отрицать свои же слова?
От каких ?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: стоит создать ЯП?
От: Sm0ke Россия ksi
Дата: 11.10.23 01:47
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вот если посмотреть популярные ЯП — то это дофига работы команд. Годы работы, годы доработок. Т.е. идея может быть вдохновлена одним человеком (на самом деле он эту идею где-то подсмотрел, как правило), а вот разработка языка — это уже только команда.


S>Получается хороший новый язык не может создать один человек и это всегда годы работы. Т.е. неожиданно новый ЯП возникнуть не может, в отличие от JS-фреймворка типа Vue.


S>Но бывают и исключения. Вот же наши как-то смогли создать тот же Nemerle вообще без особых затрат, силами энтузиастов. Как так?



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

PHP изначально сделал Расмус. Классов там не было, их добавили позднее (в 5-ой версии), когда появилась команда разработчиков. Енумы там появились вообще относительно недавно (версия 8.1). Кстати имена переменных в PHP начинаются с символа $
Квадратные скобки там служат не только для обращения к элементу по индексу, но и для создания массива. Все массивы в PHP ассоциативны (как ключ допустимо и целое число и строка текста).

Я думаю многие задумывались поменять что-то в уже существующих ЯП, с которыми они работали, или что-то туда добавить. А не лучше ли вообще сделать своё? — Примерно такая идея у меня возникла ещё когда я учился в Колледже. Вам же это знакомо?

Я действительно хочу учавствовать в разработке нового ЯП!

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

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

Фичи языка:

*- Ячейка — это может быть: локальная переменная, параметр функции, свойство модуля, и т.д.
*- Возможность работать с типом, как со значением. Тип такой ячейки будет $type
*- Имена системных типов начинаются к примеру с символа $ (но это можно указать в конфиге, как и другие начальные символы).

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

t1 = $int
t2 = $float
t1 <> t2

*- Императивный кусок кода помещается в фигурные скобки и имеет тип $seq (sequence).
do = {
  /* expression-list here */
}


Значение типа $seq можно передавать в функцию, присваивать в ячейку, и даже использовать как ключ в ассоциативном массиве.
Это позволит определять языковые конструкции как обычные функции.
Сами по себе фигурные скобки — действий внутри не выполняют без определённой команды. Это называется вычисление по требованию.

* По сути sequence — это как лямбда без параметров.
do = {
  local_var = { call_some_fn() }
  local_var()

  call_other_fn(local_var)
}


Приблизительный пример:
if_each!
[
  { a == b } : { /* действие 1 */ }
  { /* условие 2 */ } : { /* действие 2 */ }
]

if_first!
[
  { a == b } : { /* действие 1 */ }
  { /* условие 2 */ } : { /* действие 2 */ }
  $bool.true : { /* действие иначе */ }
]

Квадратные скобки — массив/мапа. Двоеточие — разделитель в паре ключ-значение.
hint: думаю нужно отделить типы $map от $array

Символ восклицательный знак после ячейки с функцией — применить её к последующему выражению (просто чтобы не писать круглые скобки if_first([])).
if_first — выполняет sequence каждого условия до тех пор, пока не встретит первое правдивое, и тогда выполнит sequence действие из значения пары.
if_each — будет проверять все условия, даже после того как встретит правдивое.

Такая штука ведь нагляднее, чем городить огород из if else if else ?

Функцию вывода на консоль или в файл можно сделать чтобы она принимала sequence. Так она итератором будет вычислять элементы $seq — выражения, и выводить их результат, пока не они не закончатся, или не возникнет ощибка вывода / исключение, при которой оставшиеся выражения не будут вычислены.

@main

do = {
  /* c-style function call */
  @std.write( {sinus(a), " ", cosine(b)} )

  /* Smarty style function call */
  {sin(a), " ", cos(b)} |write@std
}

Собачка — начало имени модуля. Файл программы начинается с указания модуля. Далее следуют ячейки модуля — его свойства.
Это декларативная часть. Императивная часть находится внутри фигурных скобок.
При запуске программы выполнится sequence из ячеки do модуля @main

Запятая — разделитель опциональный.

Вертикальная палка перед ячейкой с функцией — применить функцию как метод к результату предшествующего выражения.
Так можно вызывать функции по цепочке слева-направо. Эта идея подсмотрена в PHP библиотеке шаблонов Smarty
a |sinus |write@std(to: file)
/* аналог: */
write@std(sinus(a), to: file)

-- line-comment

a |sinus => x |write_line@std(to: file)
write_line@std( x = sinus(a), to: file )

Оператор "присвоить вправо" => в общем то под вопросом.

Определение структур как типов: команда #struct
Команда #fn определяет функцию
@lib

coords = #struct ( x y )

scale = #fn (pos, factor) {
  #ret = coords(pos.x * factor, pos.y * factor)
}

do = {
  pos = coords(10 20) |scale(5.5)
}

Ячейка результата вызова функции #ret
Если добавить в язык Возможность её-же принять как параметр функции, то:
scale = #fn (#ret, factor) {
  #ret = coords(pos.x * factor, pos.y * factor)
}

do = {
  pos_1 = coords(10, 20)
  pos_2 = pos_1 |scale(2)
  pos_2& |scale(0.5)
}

Строчка: pos_2& |scale(0.5) передать яцейку pos_2 как link на ячейку (функция сможет её изменить)
Строчка: pos_1 |scale(2) запись в ячейку #ret в этом случае не изменит ячейку pos_1

scale можно переписать по другому:
scale = #fn (#ret, factor) {
  (#ret.x, #ret.y) *= factor
}

do = {
  pos_1 = coords(10, 20)
  pos_1 |scale(2)
}

Тут будут изменены свойства (x y) у координат в pos_1
Ведь структуры передаются по указателю, как и прочие значения системной категории _compound
Все категории типов (значение $cat) произрастают из базовой _any, включённой во все типы по-умолчанию.
Категория — это просто категория, она не хранит в себе данных. Каждый тип может принадлежать своему набору категорий.
В программе можно проверить их принадлежность. Это может быть полезно при динамической типизации.
При строгой типизации $cat можно использовать как ограничение (например ограничить тип параметра функции).
@sample

squared = #fn(_plain_number: n) { #ret = n*n }

do = {
  i = 2 |squared
  f = 1.5 |squared
}

@global

/* exposition only */

#cat (
  _any /* base category */

  _compound /* values of _compound types are passed by pointer */

  _plain /* values of _plain types are passed by-value */
  _number

  _plain_number #includes( _plain _number )
)

_plain_number #refers_to ($int $float)

@lib

complex = #struct( re im )
complex #refers( _number )

Категории можно использовать как обычные значения в программе, их сравнивать, использовать как ключ в $map.
Ведь тип $cat пренадлежит категории _map_key

Естественно пользователь сможет определять и свои категории типов.
( _null / _undefined ) — пример для пустых значений при динамической типизации, возможно это системные категории.

Атрибуты

Например у всех типов есть атрибут initial — это начальное значение ячейки, которое будет использовано при неуказании инициализации.
Доступ к атрибутам происходит через оператор стрелка ->
range = #struct [$type: value_type] ( value_type: from, to )

range->initial(from: 0, to: value_type->max)
/* или */
range->initial.from = value_type->zero
range->initial.to = value_type->max

Что это? Да это же шаблон структуры. Параметр шаблона под именем value_type — тип.
А могло быть и число
#struct [$type: Type, $int: N] ()
А мог быть и тип с ограничением $type_refers[_number]
А могла быть и категория с ограничением $cat_includes[_plain]

Собственно нужны ли категории и шаблоны в языке — под вопросом.

Про типизацию и название языка
Мне нравится название ksi-lang (и строгая и динамическая типизация)
ksi-script (только динамическая типизация)
ksi-pl (только строгая типизация)

Я долгое время пилю интерпретатор для ksi-script
Дело в том, что я по разным причинам откладывал разработку и возвращался к ней снова.
В одиночку непросто это.

Назначение языка — для любых целей. Хотя кси скрипт скорее всего для web, и как скриптовый движок в game-dev

p/s
Вопрос: синглтон или набор статик свойств
Ответ: вид значений #nest (это команда определиния типа)
colors = #nest (
  red = 0h_ff0000
  black = 0
)

/* colors.red |write */

Попытка создания значения типа, который nest only, приводит к получению этого же типа.

К струткуре можно добавить статик свойства командой #add_nest
@sample

color = #struct ( r g b a )
color->initial.a = 255

color #add_nest (
  from_code = #fn($int: code) { /* вычисления */ }

  red_color = color.from_code(colors.red)
)


Перечисления — они для чёткого набора состояний ячейки.
У элемента перечисления я думаю можно добавить атрибут data, чтобы там что-то хранить.
Атрибут data для каждого элемента перечисления привязан к этому элементу. Сами элементы передаются по значению-номеру (их data не копируется при этом).
align_h = #enum (left center right)
align_h.left->data = /* да тут что угодно, хоть даже структура */

do = {
  a = align_h.center
  a->data = /* what? can we change it? */
  a->name |write_line@std
  /* align_h.center->name */
}

Можно сделать атрибуты ->name ->index ->next_wrap (обсуждаемо)
А сомому енуму атрибут align_h->elements
align_h->elements |each: #fn(it) { it->data |write }

Вот такую примерно можно придумать интроспекцию.

В нюансах все прелести и сложности. Как делать захват локальных ячеек в sequence, который внутри sequence ? Всё ли захватывать, или указывать конкретные, или автоматом по необходимости (как в javascript).

Нужна ли языку константность (read_only ячейки)
$int: (c# = 5, x = 4, y# = c + x)
c += 1 /* ошибка */

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

private public protected / friend — отдельная тема. Но я бы не тянул геттеры и сеттеры из си шарп

Наследование — сомнительно, но можно сделать команду #insert_struct
coords = #struct( x y )
game_object = #struct (
  name
  #insert_struct( coords )
  type
)

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

Доступ к под-объекту — как вариант в индексе [] тип
rabbit = game_object( coords:(1 1), name: "Vitalik" )
pos = rabbit[coords]


Ещё есть идея
std::optional аналог

#cat ( _yes )

range = #options (
  _any:
  from
  to
  
  $cat_exact[_yes]:
  exact_from
  exact_to
)
r = range(to: 5, exact_to: _yes)

Оно хранит только заданные опции. Чтение из незаданных — вопрос. (или _null / _absent; либо ошибка/exception)
В отличии от $map — имена допустимых ключей явно заданы в определении.
Способ хранения данных — implementation defined
(наверно для $cat_exact можно по битам опции разложить, или придумать свой #bit_set / #flags)

Для системных функций я бы ещё сделал префикс &
&if_first &each &loop &write &switch &catch &throw
Так мы освобождаем имя модуля @std для прочих штук.

--
Для исключений (если да) — атрибуты:
e->source.line
e->source.column
e->source.file

Получится собрать команду разработчиков нового языка программирования в этом году?
Какие идеи вам приглянулись?

pp/s Хотел сперва вкратце написать про ksi, чтож
Даже идею про #actions (аналог интерфейсам не показал)

do = {
  c = 0h_e3d7f5 !as[color]
}

color = #struct ($integer_unsigned[8]: r g b)

color #allow_actions( conversion_from[_integer] )

conversion_from = #actions [$hint: from_type] (
  as = #fn_params [$type: to_type] (from_type: this) : to_type
)

conversion_from[$int].as[color] = #fn (_integer: this) : color {
  [#ret.r #ret.g #ret.b] = (this !make_byte_array: [3 2 1])
}

Ещё можно придумать команду #allow_actions_only, исключающую применение повторябельной #allow_actions
$hint = #variant( $type, $cat ) -- или как ещё это лучше сделать?? Чтобы оно могло принимать и тип, и категорию

Отредактировано 11.10.2023 2:11 Sm0ke . Предыдущая версия . Еще …
Отредактировано 11.10.2023 2:07 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 2:03 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 1:58 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 1:56 Sm0ke . Предыдущая версия .
Re[2]: стоит создать ЯП?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.10.23 06:52
Оценка: +1
Здравствуйте, Sm0ke, Вы писали:

S>Я действительно хочу учавствовать в разработке нового ЯП!


Тогда давай начнёшь с определения целей.

1. Общая направленность — системный, прикладной на какой-то класс задач.
2. Процедурный, функциональный, что-то посредине.
3. Управление памятью: ручное (как в C, C++), автоматическое полностью (как в Java, C#), на владении ссылками (Rust), смешанное.
4. Уровень фиксации типизации — статическая, динамическая.
5. Уровень жёсткости типизации. Например, насколько разрешён integral promotion и по каким правилам.

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

S>Си++ хорош, но слишком переусложнён. Его стандартники делают с ним, то что хотят они — и это не всегда чего хотим мы.

S>Когда методы определяются внутри самого класса, то класс постепенно разрастается и превращается в монстра великана.
S>Мне кажется более наглядным, когда в программе данные определяются отдельно от действий над ними.

Для большинства это менее наглядно, но пусть. Что-то похожее есть в Rust с его impl-ами для типа. Смотрел это? Какие впечатления?

S>Я предлагаю создать свой язык вместе. У меня есть идеи, чтобы их обсудить.

S>Фичи языка:
S>*- Ячейка — это может быть: локальная переменная, параметр функции, свойство модуля, и т.д.

Смущает термин "ячейка", но пусть.

S>*- Возможность работать с типом, как со значением. Тип такой ячейки будет $type

S>*- Имена системных типов начинаются к примеру с символа $ (но это можно указать в конфиге, как и другие начальные символы).

Неееет!!!! Это однозначный путь к бардаку. Хватит нам и споров snake_case/CamelCase/mixedCase. Ты представляешь себе, что будет, если ты будешь подключать файл из одного такого режима к проекту с другим режимом?
Разрабатывая язык, сразу рассчитывай на то, что на нём будут писать что-то на миллион строк и половина авторов будут условными индусами, которым похер на всё, кроме зарплаты.
Подобные элементы синтаксиса обязаны быть жёсткими и безальтернативными!

S>Таким образом добавление системных типов не будет конфликтовать с уже написанным пользовательским кодом.


Для такого давно придумали пространства имён. Но редкие конфликты с автоматической переделкой — не проблема.

S>*- Императивный кусок кода помещается в фигурные скобки и имеет тип $seq (sequence).


Тогда надо сразу сказать, что будет в неимперативных кусках.

S>* По сути sequence — это как лямбда без параметров.


Только с автозахватом из внешнего контекста? Уточни.

S>Символ восклицательный знак после ячейки с функцией — применить её к последующему выражению (просто чтобы не писать круглые скобки if_first([])).


А зачем его вообще писать, ты ведь уже назвал "ячейку"?

S>if_first — выполняет sequence каждого условия до тех пор, пока не встретит первое правдивое, и тогда выполнит sequence действие из значения пары.

S>if_each — будет проверять все условия, даже после того как встретит правдивое.

S>Такая штука ведь нагляднее, чем городить огород из if else if else ?


Да. Но сравнимо с тем, если будет явное elif.

S>Функцию вывода на консоль или в файл можно сделать чтобы она принимала sequence. Так она итератором будет вычислять элементы $seq — выражения, и выводить их результат, пока не они не закончатся, или не возникнет ощибка вывода / исключение, при которой оставшиеся выражения не будут вычислены.


Пока что вижу закос под пачку современных языков — что-то среднее между Zig и Ruby.

S>Запятая — разделитель опциональный.


Вместо LF или вообще? Надо уточнить.

S>coords = #struct ( x y )


Я бы делал, что есть набор слов, которые по умолчанию опознаются как ключевые (например if, while, func), а если нужно их сделать идентификаторами, то поставить, например, $ впереди.

S>Ячейка результата вызова функции #ret


По-моему, этот подход в основном признан менее удачным, чем явное return как оператор.

S>Ведь структуры передаются по указателю, как и прочие значения системной категории _compound


Это плохо. Например, математики тебя побьют. struct complex { float real, imag; } — во многих ABI передаётся в двух регистрах. Это эффективно. А ты предлагаешь откатиться обратно.

S>Все категории типов (значение $cat) произрастают из базовой _any, включённой во все типы по-умолчанию.

S>Категория — это просто категория, она не хранит в себе данных. Каждый тип может принадлежать своему набору категорий.
S>В программе можно проверить их принадлежность. Это может быть полезно при динамической типизации.

Интерфейсы или типажи (traits)? Есть причина вводить новое слово для того же?

S>Категории можно использовать как обычные значения в программе, их сравнивать, использовать как ключ в $map.

S>Ведь тип $cat пренадлежит категории _map_key

Вообще обычно говорят более математически — hashable или linearly orderable.

S>Собственно нужны ли категории и шаблоны в языке — под вопросом.


Нужны. Только продумать надо.

Итого
У тебя нет killer feature. Без неё это не выйдет за пределы одного условного диссера.
The God is real, unless declared integer.
Re[3]: стоит создать ЯП?
От: Sm0ke Россия ksi
Дата: 11.10.23 12:57
Оценка: :)
Здравствуйте, netch80, Вы писали:

N>Тогда давай начнёшь с определения целей.


N>1. Общая направленность — системный, прикладной на какой-то класс задач.


Назначение языка — для любых задач.
И для gui, и для научных расчётов, и как встроенный скриптовый движок приложений/игр.

N>2. Процедурный, функциональный, что-то посредине.


Наверно это микс.

Структура файла:
* Имя модуля
* Декларативная часть (определение ячеек модуля, то есть свойств модуля)

Элемент декларативной части начинается с имени ячейки, или с разрешённой для декларативной части команды.
Ячейка может содержать что угодно. И тип, и функцию, и последовательность выражений (sequence), и просто значение

Таким образом не нужно писать как в си++ using type_alias = int;
А просто type_alias = $int
Аналогично для функций:
fn_alias = other_fn


S>>*- Императивный кусок кода помещается в фигурные скобки и имеет тип $seq (sequence).

N>Тогда надо сразу сказать, что будет в неимперативных кусках.

В декларативной части можно:
имя_ячейки = ( /* expression */ )
имя_ячейки = /* команда опеделения */
имя_ячейки = { /* последовательность выражений, тут императивная часть */ }
имя_ячейки /* команда-модификатор */

Вот некоторые команды для создания новых определений: (список не полный)

N>3. Управление памятью: ручное (как в C, C++), автоматическое полностью (как в Java, C#), на владении ссылками (Rust), смешанное.


Этот нюанс хорошо бы обсудить отдельно.
Для динамических объектов я думаю, что по умолчанию будет реализация optr (автоматическое освобождение ресурсов)

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

N>4. Уровень фиксации типизации — статическая, динамическая.


Все Три вида типизации: ~ по трём отдельным обработчикам
Можно сказать — три диалекта языка.

Динамическая типизация ~ ksi-script
Строгая типизация ~ ksi-pl
динамическая + строгая ~ ksi-lang

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

N>5. Уровень жёсткости типизации. Например, насколько разрешён integral promotion и по каким правилам.


СИ-шных ошибок в проектировании языка желательно избежать!

Есть шаблонный метод x !as[type] , который вызывается в программе-скрипте явно для преобразования типов.
В квадратных скобках указывается параметр шаблона — тип результата преобразования.
Методы в кси вызываются не через точку (а через воскл.знак перед методом).
Точка служит для обращения к элементам (свойствам).
А методы задаются отдельно в так называемом интерфейсе (команда #actions)

conversion_from = #actions [Source_type] (
  as = #fn_params [Target_type] (Source_type: src) : Target_type

  implicit_as = #fn_params [Target_type] (Source_type: src) : Target_type
  
  /* implicit_as = as */
  /* same params of function */
)

Рассмотрим на примере. Если мы хотим преобразование явного вида из $int в $float тогда в декларативной части:
$float #allow_actions( conversion_from[$int] )

conversion_from[$int].as[$float] = #fn ($int: number) : $float
{ #ret = /* какая-то системная функция */ }

do = {
 i = 5
 f = (i !as[$float])
}

Если действие implicit_as не задано, то неявное преобразование запрещено обработчиком.
Но мы можем при желании его задать одной строчкой:
conversion_from[$int].implicit_as[$float] = conversion_from[$int].as[$float]

Короче сделать алиас из уже написанной функции implicit_as = as
В этом случае будет работать неявное преобразование. Программист это может контролировать сам в том числе и для своих типов.

N>Ответы желательно развёрнуто. Это только для разгона, после этого можно будет выходить на второй круг.


S>>Мне кажется более наглядным, когда в программе данные определяются отдельно от действий над ними.

N>Для большинства это менее наглядно, но пусть. Что-то похожее есть в Rust с его impl-ами для типа. Смотрел это? Какие впечатления?

Надо будет посмотреть как там impl в Rust

S>>*- Имена системных типов начинаются к примеру с символа $ (но это можно указать в конфиге, как и другие начальные символы).


N>Неееет!!!! Это однозначный путь к бардаку. Хватит нам и споров snake_case/CamelCase/mixedCase. Ты представляешь себе, что будет, если ты будешь подключать файл из одного такого режима к проекту с другим режимом?


N>Подобные элементы синтаксиса обязаны быть жёсткими и безальтернативными!


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

S>>coords = #struct ( x y )


N>Я бы делал, что есть набор слов, которые по умолчанию опознаются как ключевые (например if, while, func), а если нужно их сделать идентификаторами, то поставить, например, $ впереди.


#struct — это системная команда.
Какой начальный символ для команд, а какой для системных типов лучше подобрать?
Я предлагаю для команд #
Для типов $
Для функций &
Это просто строчки в конфиге обоаботчика. С другой стороны нужен общепринятый формат)

Ключевые слова? keywords — нужны ли они вообще в кси? Если да, то какие?
Можно сделать bitwise методы для integer types (выглядят как именованные операторы bit_xor, bit_and, bit_shift +1 -1)

S>>Таким образом добавление системных типов не будет конфликтовать с уже написанным пользовательским кодом.


N>Для такого давно придумали пространства имён. Но редкие конфликты с автоматической переделкой — не проблема.


В кси — модули. Хотя пространства имён возможно тоже понадобятся (или нет). Есть #nest для nested штук.
@sys.int просто $int писать не так длинно
@sys.write_line или &write_line

S>>* По сути sequence — это как лямбда без параметров.

N>Только с автозахватом из внешнего контекста? Уточни.

Да, с автозахватом (closure)

Мб добавить возможность задания seq без захвата локального внешнего контекста через конструкцию #{ } ?

S>>Символ восклицательный знак после ячейки с функцией — применить её к последующему выражению (просто чтобы не писать круглые скобки if_first([])).


N>А зачем его вообще писать, ты ведь уже назвал "ячейку"?


Ячейка if_first хранит функцию. Способы вызова функции:

Функции if_first if_each принимают один параметр, с типом $seq
Я бы по хорошему их сделал системными.

Ключевых слов в кси стараюсь вообще избегать.
К примеру можно определить системную функцию &do_while цикл с пост-условием
@global /* exposition only */
&do_while = #fn($seq: loop_body, condition)

@main

do = {
  { /* loop body */ } |&do_while: { /* condition */ }
}

Или как метод в seq_actions
@main

do = {
  { /* loop body */ } !do_while: { /* post-condition */ }
  { /* pre-condition */ } !while_do: { /* loop body */ }
}

@global /* system exposition */

seq_actions = #actions ( do_while, while_do )

Вместо if можно сделать метод !then
{ a == b } !then: { seq }

Но тут нюанс с !else пока не решён)

S>>Запятая — разделитель опциональный.

N>Вместо LF или вообще? Надо уточнить.

LF и запятая — опциональные разделители, хотя LF оно как WHITEPSACE
А запятая с проверкой в парсере.

S>>Ячейка результата вызова функции #ret

N>По-моему, этот подход в основном признан менее удачным, чем явное return как оператор.

Добавить команду #return не проблема)

S>>Ведь структуры передаются по указателю, как и прочие значения системной категории _compound


N>Это плохо. Например, математики тебя побьют. struct complex { float real, imag; } — во многих ABI передаётся в двух регистрах. Это эффективно. А ты предлагаешь откатиться обратно.


Значит нужна возможность задать для структуры как она передаётся ( _by_value или _by_pointer )
Например через категории типов.
@math

complex = #struct ( $float: real imag )

complex #refers ( _by_value ) // привязали категорию для типа


S>>Все категории типов (значение $cat) произрастают из базовой _any, включённой во все типы по-умолчанию.

S>>Категория — это просто категория, она не хранит в себе данных. Каждый тип может принадлежать своему набору категорий.
S>>В программе можно проверить их принадлежность. Это может быть полезно при динамической типизации.

N>Интерфейсы или типажи (traits)? Есть причина вводить новое слово для того же?


Нет, это не интерфейсы. Про интерфейсы я ответил выше как #actions
Категории ещё могут быть абстрактными (с запретом к привязки для типов)
Для специальных значений, или сигналов об ошибке.
@sample

// returns: _key_absent or _ok
func1 = #fn (param) : $cat_options[_key_absent, _ok]
{ #ret = _ok }

// returns: subcategories of _null
func2 = #fn (param) : $cat_under[_null]
{ #ret = _ok }

@global

#cats (
  _null #includes ( _abstract )
  _null #subcat ( _undefined _key_absent _no_such_action _ok )
)

@maybe

void_type = $cat_exact[_ok]


S>>Собственно нужны ли категории и шаблоны в языке — под вопросом.

N>Нужны. Только продумать надо.

S>>Категории можно использовать как обычные значения в программе, их сравнивать, использовать как ключ в $map.

S>>Ведь тип $cat пренадлежит категории _map_key

N>Вообще обычно говорят более математически — hashable или linearly orderable.

Это похоже на набор методов для работы с данными.
ordering = #enum ( strong weak partial )

cmp_result = /* ? */

comparable = #actions [ordering: O, $type: left_type right_type] (
  cmp = #fn_params (left_type: left, right_type: right) : cmp_result

  (<) = #fn (left_type: left, right_type: right) : $bool
  { #return( (left !cmp: right) == cmp_result.less ) }
)


Стандыртные наборы действий (интерфейсы) для системных типов необходимо определить.
Желательно совместными усилиями, а не в одиночку.

N>Итого

N>У тебя нет killer feature. Без неё это не выйдет за пределы одного условного диссера.

А как-же работа с типами как с обычными значениями?
Вместо плюсовых <type_traits> std::is_same_v<> и using type =

А как же встроенная система атрибутов. Позволяющая в том числе и рефлексию (интроспекцию).
Работать со списком/мапой элементов перечисления, как с обычным массивом.
Так-же со списком свойств структуры / неста.
Атрибут type->name текстовая строка.

Возможность добавлять пользовательские конструкции над seq как функции.

--

Постораюсь ответить на вопросы, которые ещё остались неотвечены.

То что я написал — моё приблизительное представление.
На основе этого можно же сделать better language, как бы он не назывался
Отредактировано 11.10.2023 13:41 Sm0ke . Предыдущая версия . Еще …
Отредактировано 11.10.2023 13:39 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:32 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:26 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:23 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:21 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:19 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 13:18 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 12:59 Sm0ke . Предыдущая версия .
Отредактировано 11.10.2023 12:58 Sm0ke . Предыдущая версия .
Re[4]: стоит создать ЯП?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 14.10.23 06:21
Оценка:
Здравствуйте, Sm0ke, Вы писали:

N>>1. Общая направленность — системный, прикладной на какой-то класс задач.

S>Назначение языка — для любых задач.

Уже не бывает. Надо определиться.

S>И для gui, и для научных расчётов, и как встроенный скриптовый движок приложений/игр.




N>>2. Процедурный, функциональный, что-то посредине.


S>Наверно это микс.


S>Структура файла:

S>* Имя модуля
S>* Декларативная часть (определение ячеек модуля, то есть свойств модуля)

S>Элемент декларативной части начинается с имени ячейки, или с разрешённой для декларативной части команды.

S>Ячейка может содержать что угодно. И тип, и функцию, и последовательность выражений (sequence), и просто значение

S>Таким образом не нужно писать как в си++ using type_alias = int;

S>А просто type_alias = $int
S>Аналогично для функций:
S>
S>fn_alias = other_fn
S>


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

S>>>*- Императивный кусок кода помещается в фигурные скобки и имеет тип $seq (sequence).

N>>Тогда надо сразу сказать, что будет в неимперативных кусках.

S>В декларативной части можно:

S>
S>имя_ячейки = ( /* expression */ )
S>имя_ячейки = /* команда опеделения */
S>имя_ячейки = { /* последовательность выражений, тут императивная часть */ }
S>имя_ячейки /* команда-модификатор */
S>


Это просто вынесенная вперёд часть инициализаций, ничего пока особенного.

N>>3. Управление памятью: ручное (как в C, C++), автоматическое полностью (как в Java, C#), на владении ссылками (Rust), смешанное.


S>Этот нюанс хорошо бы обсудить отдельно.


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

Язык с ManMM это переносимый ассемблер (даже если это C++). Язык с AMM это то, что требует как минимум unsafe-слоя для реализации и связи с нижними слоями.
Попытка их совместить — см. про коня и лань.

S>Вообще неплохо-бы предусмотреть способ указания (в самой программе на кси) для желаемого поведения при конкретном случае (для low level штук).

S>Например чтобы не происходило автоосвобождение большого колличества мелких объектов по отдельности, а пачкой

Это речь про GC. Разные стили GC могут выбираться по реализации, но в этом нет ничего нового.

S>(ещё когда при закрытии приложении ОС сама освобождает выделенную память)


N>>4. Уровень фиксации типизации — статическая, динамическая.


S>Все Три вида типизации: ~ по трём отдельным обработчикам

S>Можно сказать — три диалекта языка.

S> Динамическая типизация ~ ksi-script

S> Строгая типизация ~ ksi-pl
S> динамическая + строгая ~ ksi-lang

Почему это динамическая+строгая?

S>Каждый обработчик может быть как компилятор, так и интерпретатор. А может быть два в одном.

S>Это уже нюанс реализации обработчика.

N>>5. Уровень жёсткости типизации. Например, насколько разрешён integral promotion и по каким правилам.


S>СИ-шных ошибок в проектировании языка желательно избежать!


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

S>Есть шаблонный метод x !as[type] , который вызывается в программе-скрипте явно для преобразования типов.


Всегда? Безопасные (без изменения характера типа и без потери точности) расширения вообще не допускаются?

S>Рассмотрим на примере. Если мы хотим преобразование явного вида из $int в $float тогда в декларативной части:

S>
S>$float #allow_actions( conversion_from[$int] )

S>conversion_from[$int].as[$float] = #fn ($int: number) : $float
S>{ #ret = /* какая-то системная функция */ }

S>do = {
S> i = 5
S> f = (i !as[$float])
S>}
S>


Я не понял, к чему '!' впереди "!as". В остальном — понятно на локальном уровне. Но мне кажется, что безусловный запрет расширяющих конверсий это диверсия.
Если нужно, их следует запрещать для определённых контекстов. Но я думаю, это будет редко использоваться.

Кстати, int->float для стандартных int32 и binfloat32 это не расширяющая конверсия, возможна потеря точности.

N>>Подобные элементы синтаксиса обязаны быть жёсткими и безальтернативными!


S>Согласен с этим утверждением. Я не точно сформулировал мысль.

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

Скорее жёстко, тут нечего конфигурировать.

S>#struct — это системная команда.

S>Какой начальный символ для команд, а какой для системных типов лучше подобрать?
S>Я предлагаю для команд #
S>Для типов $
S>Для функций &

А зачем выделять типы и функции? Это необычно.

S>Это просто строчки в конфиге обоаботчика. С другой стороны нужен общепринятый формат)

S>Ключевые слова? keywords — нужны ли они вообще в кси? Если да, то какие?

У меня такое впечатление, что вы их называете командами.

S>Можно сделать bitwise методы для integer types (выглядят как именованные операторы bit_xor, bit_and, bit_shift +1 -1)


Можно.

S>>>Таким образом добавление системных типов не будет конфликтовать с уже написанным пользовательским кодом.


N>>Для такого давно придумали пространства имён. Но редкие конфликты с автоматической переделкой — не проблема.


S>В кси — модули. Хотя пространства имён возможно тоже понадобятся (или нет).


Если хочется чего-то выше уровня песочницы — понадобятся, иерархические.

S>>>* По сути sequence — это как лямбда без параметров.

N>>Только с автозахватом из внешнего контекста? Уточни.
S>Да, с автозахватом (closure)

Если не регулируется — могут жаловаться.

S>Мб добавить возможность задания seq без захвата локального внешнего контекста через конструкцию #{ } ?


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

S>Ключевых слов в кси стараюсь вообще избегать.


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

S>К примеру можно определить системную функцию &do_while цикл с пост-условием


Есть такие стили, да. Можно посмотреть на Common LISP как образчик. Там макрами транслируется часть конструкций в другой код.

S>Значит нужна возможность задать для структуры как она передаётся ( _by_value или _by_pointer )


Да. И умолчание скорее by value.

N>>Интерфейсы или типажи (traits)? Есть причина вводить новое слово для того же?


S>Нет, это не интерфейсы. Про интерфейсы я ответил выше как #actions

S>Категории ещё могут быть абстрактными (с запретом к привязки для типов)
S>Для специальных значений, или сигналов об ошибке.

Ближе к типажам, наверно.

N>>Вообще обычно говорят более математически — hashable или linearly orderable.

S>Это похоже на набор методов для работы с данными.
S>
S>ordering = #enum ( strong weak partial )

S>cmp_result = /* ? */

S>comparable = #actions [ordering: O, $type: left_type right_type] (
S>  cmp = #fn_params (left_type: left, right_type: right) : cmp_result

S>  (<) = #fn (left_type: left, right_type: right) : $bool
S>  { #return( (left !cmp: right) == cmp_result.less ) }
S>)
S>


Ну да, дальше определяется, что например hashable должен поддерживать hash(), а linearly orderable — сравнение как минимум на "меньше" (и полезно на "равно", судя по <=> в новом C++).

S>Стандыртные наборы действий (интерфейсы) для системных типов необходимо определить.

S>Желательно совместными усилиями, а не в одиночку.

N>>Итого

N>>У тебя нет killer feature. Без неё это не выйдет за пределы одного условного диссера.

S>А как-же работа с типами как с обычными значениями?

S>Вместо плюсовых <type_traits> std::is_same_v<> и using type =

По сравнению с плюсами — может быть. По сравнению с более новыми языками — нет.

S>А как же встроенная система атрибутов. Позволяющая в том числе и рефлексию (интроспекцию).


Аналогично.

Глубоко изучи для начала Rust.

S>Возможность добавлять пользовательские конструкции над seq как функции.


S>--


S>Постораюсь ответить на вопросы, которые ещё остались неотвечены.


S>То что я написал — моё приблизительное представление.

S>На основе этого можно же сделать better language, как бы он не назывался

Можно. Но без хорошей теоретической подготовки шансы около нуля.
The God is real, unless declared integer.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.