Panzerschrek[CN]
> Это синонимы, или их значение различно?
let заявляет константу. скорее всего как в Rust (или где?) значение можно перебить ниже, но это не изменение предыдущего значения, а сокрытие ранее введённого имени чисто лексически.
Panzerschrek[CN]
> На счёт let/var не понял. Это синонимы, или их значение различно?
var это let mut.
Насчёт того, что в с++ вы читаете код слева-направо или справо-налево. Всё намного хуже в плюсах. Вот хорошая иллюстрация:
Нижний вариант это не Carbon, а Specs (древний пропозал для С++). Не зацикливайтесь на крышечках. Это лишь иллюстрация, что консистентно сделать можно.
Alprog
Крестовая типосрань давно известна. Почти везде лучше сделано.
В Ü, например:
i32 // integer type [i32, 4] // array of 4 integers [[i32, 3 ], 4] // array of 4 array of 3 integers $(i32) // raw pointer to integer fn() -> i32 // function pointer to function, returning integer fn(i32 x, i32 y) : $(i32) // function pointer to function, accepting two integers and returning raw pointer to integer tup[i32, f32, bool] // tuple of 3 elements tup[] // empty tuple
Alprog
> Это лишь иллюстрация, что консистентно сделать можно.
Консистентно это будет если имплементация функции без параметров возвращающей указатель на int будет выглядеть так:
(void -> ^int param) func_name { // implementation ... }
=A=L=X=
> Консистентно это будет если имплементация функции без параметров возвращающей
> указатель на int будет выглядеть так:
Там так:
func fn1 : (void -> ^int);
https://users.monash.edu/~damian/papers/HTML/ModestProposal.html
Но это не принципиально. Это ж просто иллюстрация была.
Alprog, блин, да ты пример паскаля скинул. )))
По моему даже визуально понятнее когда определения идут слева-направо.
=A=L=X=
> (void -> ^int param) func_name
Тип до имени функции - так себе.
В Ü, например, тип полностью задаётся после имени:
fn foo(i32 x, f32& y) : &mut bool
Кстати, частью типа ещё может быть соглашение о вызове, unsafe флг и соглаения о связывании ссылок (чисто Ü-шная хрень).
Alprog
> Но это не принципиально. Это ж просто иллюстрация была.
Не, мне понятна претензия к тому, что у C сложное определение типа гуляет влево-вправо, но это как раз консистентно с тем как выглядит объявление функции или массива. Парсер единый, а не расслаивается на два варианта.
И действительно есть языки где реализации функций выглядят как то так:
type1 (type2 param1, type3 param2, ... ) function_name =
{
... code ...
};
И это... QuakeC от Кармака, игродела от Бога.
Он уже давно всё понял.
Удачно замёл все вообще реализации и объявления переменных и типажи в один единый структурированный, логичный и проработанный формат.
Вообще, Carbon выглядит интересно. Я буду щупать, когда будет более живой. С++ с адекватным (ок, более адекватным) синтаксисом и без легаси звучит очень заманчиво.
Rust это не преемник С++, а его конкурент. Он сильно меняет парадигму и майндсет и не может рассматриваться как апгрейд для плюсовиков. Про D и Go вообще молчу. Одно сдохло, другое — вообще про другое. Carbon же это попытка рефакторинга крестов в правильном (для меня) направлении. Не утверждаю, что она успешная. Это мы ещё поглядим. Но выглядит очень интересно.
=A=L=X=
Не понимаю поинта. Чем это лучше, чем это, например?
fn function_name(param1:type1, param2:type2, ... ) : type3 { /*.. code ..*/ };
Возвращаемый тип слева в крестах работает только до тех пор, пока не захочешь возвращать какой-нибудь decltype(auto). Так и смысл две нотации иметь?
Panzerschrek[CN]
>
> [i32, 4] // array of 4 integers
начерта смешивать тип и количество элементов, хотя мне нравится как в csharp'e где количество идет сразу после типа, а не название. Ну это из-за особенности массивов в C# и C. В C все же мы объявляем несколько переменных под одним именем, а в CSHARP'e мы создаем тип Array с заданным типом и количеством
Alprog
> Всё намного хуже в плюсах. Вот хорошая иллюстрация:
ты же знаешь что это все c-style, тебя же в зад выебут эстеты за использование c-style-array. В C++ уже массивы через std::array<int, 3> a1 объявляются . Указатели же через аж целых 3 обертки на выборы
Я правильно понимаю, что в Карбоне все также осталось ручное управление памятью и протухающие ссылки/указатели?
Alprog
> Возвращаемый тип слева в крестах работает только до тех пор, пока не захочешь
> возвращать какой-нибудь decltype(auto). Так и смысл две нотации иметь?
Наоборот это одна нотация, а не две разных:
void (int param) func = // процедура принимающая int { ... }; void ( int param) *func_ptr = &func; // указатель на процедуру принимающую int
Абсолютно одинаково записывается суть, а не скачут скобки то налево, то направо в зависимости от намерений сделать функцию или указатель на неё.
Так что если говорить про консистентность, то идеал - вот он.
Panzerschrek[CN]
> fn() -> i32
> fn(i32 x, i32 y) : $(i32)
Так стрелка или двоеточие?
_
Вообще, раз уж заговорили про после. В хорошем языке, если есть тип-конструкторы-операторы - они все должны быть либо префиксными, либо постфиксными. Например, если мы комбинируем массивы и указатели:
int^[10] -- хорошо, понятно, очевидно "массив указателей на инт" int[10]^ -- хорошо, понятно, очевидно "указатель массив на интов" [10]^int -- хорошо, понятно, очевидно "массив указателей на инт" ^[10]int -- хорошо, понятно, очевидно "указатель массив на интов" ^int[10] -- какая-то хренотень ^(int[10]) -- костыли (^int)[10] -- костыльчики