Pull to refresh
5
Филипп@Filipp42

Лисп-программист

1,6
Rating
4
Subscribers
Send message

Ура!
Я так ждал! Я использовал Gemma 3 12b когда отключали интернет. Вот не знаю, будет ли эта версия лучше, чем предыдущая. С одной стороны, она лучше обучена, а с другой, она сильно меньше.

Хм... Возможно, сложность может уменьшиться, если программист искусен? Например, он может применить хорошие паттерны, а то и вообще монады и моноиды...

Нужно всё-таки признать, что способы чуть-чуть уменьшить сложность всё-таки есть.
Языки более высокого уровня могут уменьшить сложность. Использование библиотек позволяет перенести сложность с того, кто пишет продакшен код на автора библиотеки.

Есть хитрые техники, которые сокращают код, если их уметь применять.

Добрый день!
Спасибо вам за статью!
Я когда-то писал парсер-комбинаторы на Лиспе. Похоже, что подходящей оптимизации не было, комбинаторы работали очень медленно.
В языке программирования Lean комбинаторы чуть ли не в стандартную библиотеку встроены.
Скажите, может быть, вы не против посмотреть язык Lean, и немного попрограммировать на нём?
Он вообще имеет двоякую природу. С одной стороны он язык программирования общего назначения, похожий на Haskell, только там гораздо более мощная система типов - зависимые типы.
С другой - средство доказательства теорем. Мне было забавно сегодня доказать теоремы про алгоритм Евклида. Правда, на индуктивном доказательстве я застрял. Но это нормально. Математику я только изучаю.

В любом случае, штука интересная.

Каноническая IDE для Lean - это VSCode. Там работает языковой сервер, который даёт очень много различных подсказок.

Вообще мне кажется, что в таких случаях могут помочь программы проверки моделей. Они позволяют смоделировать дизайн программы, и посмотреть, есть ли у него нужные свойства!
Может быть, если предварительно написать модель на Alloy (Вот по нему книжка), а потом заставить ИИ работать по этой модели, удастся хоть немного повысить качество?

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

Может быть, тут есть синьёры, которые могли бы проверить этот подход на своих пет-проектах? Мне было бы интересно посмотреть на результат.

Мне вот интересен Lean 4. Это одновременно и язык программирования, и помощник для доказательств. Он помогает изучать математику. Если ты доказал теорему, и верифицировал доказательство в Lean, можно быть практически уверенным, что доказательство правильное.

Я для работы с Unicode использую вот эту библиотеку:
https://codeberg.org/atman/zg

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

И да, он безопаснее, чем C. Стандартная библиотека на порядок лучше, чем в Си. На счёт того, кто быстрее... Тут, наверное, Си немного выиграет, потому что в нём есть оптимизации на основе UB и отсутствуют многие проверки. Зато в Zig гораздо проще работать с SIMD! Но в любом случае, Zig - это очень быстрый язык. Хотя правильно написанный код на Julia может оказаться быстрее неправильно написанного кода на Zig...

Самое любимое преимущество Zig - это алгебраические типы данных. А именно, маркированное объединение (tagged union) - тип сумма. В C есть union, но он не хранит информации о том, какой именно вариант сейчас активен. В Zig union(enum) хранит тег, и его можно красиво сочетать со switch
```

const Res = union(enum) {
    node: *Node,
    fail,

    pub fn success(node: *Node) Res {
        return .{ .node = node };
    }
};
pub fn next(self: *Parser) anyerror!*Node {
        switch (try self.readInteger()) {
            .node => |node| return node,
            .fail => {},
        }
        switch (try self.readSymbol()) {
            .node => |node| return node,
            .fail => {},
        }
        switch (try self.readList()) {
            .node => |node| return node,
            .fail => {},
        }
        return ParsingError.CantParse;
    }

Это очень помогло мне, когда я писал компилятор, представлять абстрактное синтаксическое дерево. Тип сумма - это один из базовых способов описания мира.То, что его нет в большинстве популярных языков - это какое-то кошмарное недоразумение. Тут уже не понятно, кто виноват.

Другой большое преимущество - это comptime - вычисления во время компиляции. Он позволяет, например, делать регулярные выражения, которые оптимизируются во время компиляции. Хотя тут возникает проблема, что само регулярное выражение должно быть известно во время компиляции. Но это проблема библиотеки регулярных выражений. Можно написать и обычным образом.

А ведь в comptime можно производить вычисления над типами... Так реализованы обобщённые типы:

fn Gen(ty: type) type {
    return struct {
        first: ty,
        second: i32,
    };
}

const GenUsize = Gen(usize);

Если сравнивать безопасность Си и Zig, то побеждает конечно же Zig.
В нём все указатели, которые могут содержать Null обязательно помечаются, и если мы хотим из разыменовать, нам нужно будет их проверить, что они не Null.


fn foo(a: ?*GenUsize) void {
    if (a) |gen| { // Вот тут мы проверяем, что указатель не null, и кладём его значение в gen, если он таки не null.
        std.debug.print("First: {}, Second: {}\n", .{ gen.first, gen.second });
    } else {
        std.debug.print("No value\n", .{});
    }
}

Работа с памятью заметно улучшена, по сравнению с Си. Для выделения памяти используется специальный объект - аллокатор. Если функция решила выделить память, она должна принимать аллокатор в качестве параметра:

const std = @import("std");

/// Создаёт динамический массив целых чисел от 0 до n-1,
/// возвращает срез (slice). Вызывающий отвечает за освобождение памяти.
fn createRange(allocator: std.mem.Allocator, n: usize) ![]u64 {
    // Выделяем память под n элементов
    const slice = try allocator.alloc(u64, n);

    // Заполняем значениями
    for (slice, 0..) |*item, i| {
        item.* = @intCast(i);
    }

    return slice;
}

pub fn main() !void {
    // Используем GeneralPurposeAllocator для отслеживания утечек
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const status = gpa.deinit();
        if (status == .leak) {
            std.debug.print("Обнаружена утечка памяти!\n", .{});
        }
    }

    const allocator = gpa.allocator();

    // Вызываем нашу функцию
    const numbers = try createRange(allocator, 10);
    defer allocator.free(numbers); // освобождаем при выходе из scope

    // Печатаем результат
    for (numbers) |num| {
        std.debug.print("{} ", .{num});
    }
    std.debug.print("\n", .{});
}


Этих аллокаторов есть несколько видов, самые полезные - это GeneralPurposeAllocator и аллокатор арена.

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

Арена же позволяет на сначала выделить много-много кусков памяти, но очищаем мы их все разом! Это очень удобно, и решает множество проблем с утечками и двойным освобождением памяти.

Замечательно, что аллокаторы имеют один интерфейс, так что для выделения памяти функцией можно использовать как арену, так и GPA, в зависимости от того, чего мы хотим добиться!

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

Ещё одно прекрасное преимущество Zig - это обработка ошибок. Начнём с того, что в отличие от Си она тут хотя бы есть! То, что есть в Си - не считается, это костыли и прошлый век.

В Zig под обработку ошибок выделена отдельная система. Функция может быть помечена как способная вернуть ошибку. Ошибку можно либо прокинуть вверх при помощи try, либо отловить при помощи catch. Эти ключевые слова в Zig действуют не так, как в других языках.

const MyError = error {
    Ploho, // Возможноые варианты ошибки
    Ujasno,
};

fn baz(a: usize) MyError!void { // Помечаем, что функция вернёт либо ошибку типа MyError, либо void
    if (a % 2 == 0) {
        return error.Ploho;
    } if (a % 3 == 0) {
        return error.Ujasno;
    }
}

pub fn main() void {
    try baz(1); // Просто выполнится, так-как baz не возвращает ошибку. try ничего не сделает
    baz(2) catch |err| { // Перехватываем ошибку, и что-то с ней делаем
        std.debug.print("Error: {}\n", .{err});
    };
    try baz(4); // Так-как baz вернёт ошибку, оператор try просто вернёт её из функции.


Короче говоря, Zig побеждает C по многим параметрам. Это я ещё не все перечислил. Составить ему конкуренцию могут только Rust и C++. Что же он противопоставит им? Простоту. Zig очень простой язык. Говорят, его реально, без шуток можно выучить за 21 день, если вы уже умеете программировать. Я слышал отзыв одной компании, которая использовала Zig, что ей не нужно было нанимать тех, кто его уже знает. Они могли просто научить ему программиста сами.

C++ он побеждает ещё и тем, что в Zig нет такого адского количества неопределённого поведения. А ещё в C++ куча легаси, оставшегося за пятьдесят лет развития, и он унаследовал множество недостатков Си! Его очень трудно знать хорошо.

Rust, наверное, самый сильный противник. Думаю, что многим он подойдёт больше. С другой стороны, в Zig управление памятью полностью ручное, а в Rust оно автоматическое. Часто это плюс, но я могу представить ситуацию, когда это минус. Хотя не знаю, что это за ситуацию.

И вообще, тут много вкусовщины. Мне Zig нравится больше всего. Rust я не осилил. C++ мне категорически не нравится.

Очень советую попробовать написать на Zig достаточно большую программу, чтобы почувствовать, ваш это язык, или не ваш. Если вы любите C, то скорее всего полюбите и Zig.

Скажите пожалуйста, а какое влияние на вашу операционную систему оказала Plan-9?
Я слышал, что она была эталоном архитектурной изящности, но к сожалению, не сумела завоевать популярности.

Добрый день!
Очень заинтересовал ваш проект.
Я сам написал на Zig игрушечный интерпретатор: https://github.com/Filipp-Druan/berlisp
И сейчас вернулся к написанию компилятора: https://github.com/Filipp-Druan/ftorlisp
Скажите пожалуйста, я могу что-нибудь написать для вашей ОС?
Я никогда разработкой ОС не занимался. Мне было бы интересно с этим разобраться.
Скажите, чтобы немного поучаствовать в вашем проекте, нужно ли предварительно перелопатить кучу книг?

У меня есть безумная идея.
Чем больше людей получит образование - тем лучше.

Но бывает так, что человек идёт на какую-то специальность просто потому, что надо куда-то пойти. И получает бесполезную для него специальность.

В средние века были тривиум (Грамматика, Логика, Риторика) и квадривиум (Арифметика, Геометрия, Астрономия, Музыка).

Вот мне и пришла мысль: может быть, для тех, кто не определился с тем, что они хотят, организовать что-то вроде тривиума и квадривиума? Учить их универсальным вещам. В наше время выбор предметов должен, конечно, быть другим. Например, логика, математика (не очень сложная), история, теория принятия решений.

Ещё могут очень помочь науки о тексте, только я не знаю, какие конкретно выбрать. Работа с источниками наверное. Логику уже назвал. Обязательно информатика! И не такая, где учат тыкать кнопки в Word, а такая, которая давала бы понимание работы современной инфраструктуры.

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

Я встречал критику мозгового штурма у Генриха Альтшуллера. В качестве альтернативы он предлагал выделить закономерности развития техники, и применять их целенаправленно. На этой основе была создана Теория решения изобретательских задач (ТРИЗ). Кто-то говорит, что она решает кучу проблем и очень полезна. Кто-то говорит, что она бесполезна. Я склоняюсь к тому, что это довольно интересная эвристика, которую не плохо бы знать. Хотя я не применял её на практике... Говорят, в программировании её применить не получалось. Есть свидетельства, что сам Альтшуллер утверждал: чтобы освоить ТРИЗ, нужно много часов лекций и куча решенных задач. Так по книгам учить не особо полезно.

Есть ещё такой интересный эффект как гроконие (Grokking). Это когда модель обучается на маленьком датасете, полностью его выучивает, но тестовая точность остаётся очень низкой. Но потом, если оставить модель обучаться очень и очень долго, то качество тестовой выборки подскакивает почти до ста процентов. Модель обобщает после долгого запоминания.

Интересно, а они выпустят Gemma 4? Я вот этого очень жду.

Хм... Интересно. А если рисовать перед генерацией шаблон-аниматик, который задаёт темп, повороты камеры, тому подобное. А диффузия после этого генерирует основное видео.

Мне хочется очень высокого качества.
Эх, мечты...
Хотя, с другой стороны, у нас довольно много авторской анимации.
Хотя её в основном делают люди причастные к ремеслу.

Спасибо!
Мне бы узнать конкретные приёмы.
Тут дело в том, что мне хотелось бы достичь достаточно реалистической рисовки. И консистентность очень важна. Хотелось бы достигнуть студийного уровня картинки. Мечты мечты...
Другое дело, что у меня нет режиссёрского образования. И я мало смотрю сериалы. Да что там, вообще не смотрю.

Это мне сказал один режиссёр.
А у вас есть другие данные?

1
23 ...

Information

Rating
1,889-th
Registered
Activity