Pull to refresh

Comments 44

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

Не знаю как ситуация была 2019, но есть struct - ваши классы; [что такое подтипы?]; интерфейсы с помощью функций внутри структур, которые принимают структуру как первый аргумент(тут правда проблемка - почему-то нельзя сделать приватными поля, не понял причин этого пока что);
В одной из статей по Zig написано, что он скорее антимодульный, чем модульный. Как я понял, он сделан с целью быть простым как Си, при этом исправить его недостатки. Я думаю с этой целью он хорошо справляется.

Все эти быстрые пороги вхождения уже проходили, раст хоть заявляется что решает проблемы с памятью, а тут больших киллер-фич не видать.
Так что там по киллер-фичам? Go — просто как топор, в Rust потокобезопасная концепция владения, и copiler-driven-development. Ну типа незнаю… должно же быть хоть что-то типа «гляди как могу!». )

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

Компилятор пока что написан на C++, хотелось бы чтобы портировали на Zig. Тогда дальнейшее развитие будет легче идти.

А в каких компилируемых языках дженерики не компайл тайм?
generic — общий, обобщенный, имеется ввиду, что среда даписания кода программы и среда компаил компиляции гомогенны по отношению к коду. Проще говоря, вы можете взять код написанный для рантайма и переместить в компаил тайм и наоборот не подвергая его изменениям. А теперь отвечая на ваш вопрос, нет такого понятия как компилируемый язык или интерпритируемый язык. В терминах виртуальной машины (хорошо описанно у Таненбаума) любой язык может быть как скомпилирован так и интерпритирован. Ну и вообще, если честно я не знаю языков кроме Java, где есть языковые конструкции (generic), хотя это скорей блоки кастов, вроде там исползуется техника которую они почему то называют стиранием типа. Вообщем дженерик выше это прилагательное.

Под дженериками aka generic types и generic functions обычно подразумеваются некоторые шаблонные типы и функции, которые имея на входе другие типы могут исполниться в некоторой шаблонной функции.
То бишь вместо


fn add(a: int, b: int) -> int { a+b }
fn add(a: float, b: float) -> int {a+b}

можно написать просто


fn<T> add(a: T, b: T) -> {a+b}

и скармлвать в такую функцию хоть int, хоть float, хоть сложный тип у которого оператор сложения реализован/перегружен.
В C++ их обычно шаблонами зовут, например.
Собственно исполнение генериков подразумевает, что шаблон необходимо разернуть и вывести типы, что обычно проворачивает компилятор. Генерики в интепретируемых языках вроде не встречаются, поэтому я утверждаю что не компайл-тайм genericов не существует. Поэтому и спросил про альтернативные женерики в существующих языках программирования.

Снова теже грабли habr.com/ru/sandbox/54131, есть еще cling. C джава также есть джит интерпритаторы есть компилятор(мне один известен). И того ваша утверждение неверно просто по причине того что нет такого понятия как компилируемый язык или интерпритируемый язык. Нет ну если вы настаиваете я поишу среди тысяч маленьких языков и найдут уверен не один где они интерпритируются. Нет вот именно это и не делают, нет их так не зовут, смешивать шаблоны и дженерики (название которых как механизма языка я встречал только в Java) концептуально неправильно. Поищите в интеренете есть куча статей template vs generic. Конечно и то и то, есть примеры обобшенного программирования, и да их можно назвать generic function, но подразумивают под ними шаблоны с++ программисты или программисты языкма где они есть, вообшем конкретный механизм. Олсо мне не понятен термин скармливаете тип, а если не тип) То уже не шаблон? Сложный тип, для меня тоже вешь загадочная. Простите я пока знаю Rust недостаточно что бы обсуждать его возможности. Вторая ошибка, шаблоны не исполнеются, как вы сами написали же они сначала инстанцируются (термин возможно не верен ну да ладно), таже ошибка про развернуть, разворачиваются макросы и это обычно называется экспанд макроса. И да мой основной язык с++. Предлагаю остановить на этом тред, дженерик лично я понимаю как обобшенный, то что в отдельном языке вида Java есть механизм названный generic function не должен был ввести вас в заблуждение.
65535 — это ограничение 16 бит, возможно отсюда.
А насчет срезов. Не знаю есть ли они в GO, но они точно есть в Python.
Возможно оттуда и взято.
А вообще интересно конечно, спасибо за обзор :)
Именно 65535 бит. Почти 8К (без одного бита). Тут интересно почему не 65536, куда бит дели:)
UFO just landed and posted this here
Не, все правильно.
16 бит — это 65536 значений.
А эти значения в диапазоне:
от 0 до 65535.
А 65535 — это именно максимальное значение, которое можно представить в 16-битном целом числе.
Ну а число с 0 бит — то странное число было бы :)
В Python использование синтаксиса слайсов на самом деле не создает слайс, а создает «настоящий» новый list.
Срез — это невладеющая структура данных, отображение настоящего массива. Т.е. изменения элементов среза также должно изменять оригинальный массив. В именно го так, а в Python не так.
да, согласен с вами, не обратил внимание что влияние идет на исходный массив.
Очень интересный язык. Надо посмотреть поближе.
ps: есть такой тупой мультик
image
Корутины, судя по вашему описанию, fullstack. Во второй диаграмме с ними подразумеваются некие глобальные переменные (a_promise)? Использование final_result вообще не видно. Она тоже глобальная?
Union в такой реализации вообще какие-то бесполезные получаются.
Понравилось перечисление как пространство имен. Но все равно хочется для переменной A типа enum вызвать A.isSomething(). В D это решается передачей A в качестве параметра в функцию isSomething насколько я помню.
Понравился подход к обработке ошибок.
P.S. А почему «идеологически верно» писать тип переменной после ее имени?
P.S. А почему «идеологически верно» писать тип переменной после ее имени?

Мне вот тоже интересно.
С давних времен привык что везде тип переменной перед ее именем, и как-то совсем не понял почему перевернули наоборот.
UFO just landed and posted this here
Парсить проще потому что двоеточие после идентификатора есть что ли?
Как я понимаю современные тенденции, удобнее парсить когда в начале известное, а за ним новое имя. В c++ на это напоролись и пришлось вводить typename перед именами типов в некоторых случаях в шаблонах. Во всех языках последнего поколения пишут обычно
var x: type = value

Здесь var/let/const — всегда известное ключевое слово, дальше имя, а тип опционален ибо в тренде автоматический вывод типов.
Ну кроме C, также идет в:
C++, Objective C, Java.
Ну а насчет того что так читается проще — довольно субъективное утверждение, дело привычки, возможно и так наверно.

Идиоматически верно, потому что в большинстве случаев можно написать что-то вроде const a = 3 или let a = vec.map(Impl::doStuff).collect() и иже с ними и тип будет выведен компилятором автоматически.

На картинке только часть кода, непосредственно относящаяся к корутинам. Переменные a_promise и final_result глобальные, функция seq выводит строку на экран, в отличие от оригинального примера, где она заполняет массив буквами, соответствующими точками вызова.
Да он практически идеальный для миграции с С++. Ну всё, теперь можно валить :)
умножение — я все ждал пока кто-то это реализует, и вот дождался:) В Ассемблере(!) есть такая операция dup, которая позволяет формировать повторяющиеся данные. Теперь и в Zig:

В Perl это давно есть:


print( "xxxaaa"x3 )  # выведет   xxxaaaxxxaaaxxxaaa

Слайсы (Срезы)
Вроде бы это взято из Go, не уверен.

Снова очень похоже на Perl:


@a[ 1, 2, 7, 3 ]        # Достать елементы массива. Вернёт значения в индексах 1,2,7,3
@x{'key1', 'key2'}     # Достать елементы хеша. Вернёт значения ключей key1, key2

while,for
for (items[0..1]) |value| {
sum += value;
}

Думаю, что в далёком 2006 вот именно по этой причине я ушел с РНР на Perl:


for my $item ( @items[ 1..3, 7 ] ) {
    print $item;
}

Оператор unreachable

Perl Yada-Yada operator?


...

Исполнение кода во время компиляции
В Zig предусмотрена мощнейшая возможность — выполнение кода, написанного на zig, во время компиляции.

Видимо всё новое — это хорошо забытое старое


Очень приятно что такие проекты появляются и развиваются.

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


Спасибо за статью.

Спасибо за комментарий! Похоже Perl это действительно неисчерпаемый кладезь идей для языков программирования, а я как-то про него и забыл:)
Будет прикольно, если напишите статью про Perl ;-)

Вот фича ( 2002год), которую я в других языках не видел: позволяет вешать событие ПЕРЕД/ПОСЛЕ выполнения блока: [Sub::ScopeFinalizer](https://metacpan.org/pod/Sub::ScopeFinalizer)

в python такое делается декораторами

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

Я правильно понял, что это пока динамической загрузке?
в Ptrhon умножение массивов(и строк) есть
[1,2,3] * 5
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
Кстати, хочется напомнить что три основные революции в языках программирования были вызваны не дополнительными возможностями языка программирования, а введение ограничений на возможности написания кода:
1. структурированное программирования (ограничило прямую передачу управления — запрет goto куда попало)
2. объектно ориентированное прогр. (ограничило косвенную передачу управления)
3. функциональное прогр. (ограничело на присваивание)
Даже модели MVC ограничивают то что может происходить в модели, представлении и контроллере.
Пока в языке в явном виде не появятся объявления ограничений, за которыми будет следить компилятор, очередной революции не будет.
UFO just landed and posted this here
Правда. И причина фундаментальная, и не зависит от языка программирования. Сложность всегда возрастает, все эти ограничения были призваны именно для борьбы с ростом сложности.
А чем такая запись:
fn foo(condition: bool, b: u32) void {
    const a = if (condition) b else return;
    @panic("do something with a");
}

лучше чем эта:
fn foo(condition: bool, b: u32) void {
    if (!condition) return;
    const a = b;
    @panic("do something with a");
}
?
Это просто общий принцип из функциональных языков: операторные блоки могут возвращать значения. Унификация, чуть больше компактности, возможность использовать блоки в выражениях — почему бы и нет?
Так я ж не против. Возможно, такая запись и правда очень полезна.
У меня претензия к примеру — он совершенно не раскрывает пользу такой записи.
В идеале, пример должен быть из реального проекта. И неплохо бы показать не только код, использующий данную возможность, но и код, который приходится писать без такой возможности.
Return в качестве такого значения в блоке это что-то достаточно странное. Хотя, если оно понимается в стиле throw, то ещё можно понять логику…

Действительно интересная замена для си. Судя по официальной странице, автор выбил финансирование и работает над языком в полную смену. Для меня самыми интересными фичами оказались поддержка 80-точности чисел с плавающей точкой, длинная арифметика, арифметика с насыщением и векторные типы. Первая попытка скомпилировать dll и вызвать функцию из c# прошла удачно, но вот скомпилировать именно для 32-х битной платформы не получилось. Попозже может доберусь до более полноценных испытаний.

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

Где-то в доках есть другое объяснение. В каждой строке кода есть всё необходимое для её токенизации, нет зависимости от контекста. Отсюда многострочные комментарии сделаны однострочными и по этой же причине raw-строки также однострочные :| Видимо разработчик языка озабочен эффективностью компилятора. Имхо, можно было и поступиться в части комментов и строк этим правилом. С другой стороны, вставки комментов/строк решаемы поддержкой в IDE, а на читабельности это не скажется.

Sign up to leave a comment.

Articles