Pull to refresh
22
0.1

Software Engineer

Send message

а вы ищите лом которые ее сломает.

Разумеется. Так работает примерно вся математика и в значительной мере тестирование ПО.

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

Вы утверждали, что модель не понимает как оно работает внутри. Но как раз это абсолютно неверно

У вас очень своеобразная интерпретация того, что такое понимание модели вычислений. Понимание это когда я 100 раз даю LLM на вход тот код, который я дал выше копилоту - вывод этого кода детерминированный - прошу её предсказать этот вывод, и она даёт корректное предсказание в 100 случаях, потому что берёт и исполняет код в этой модели, ну или хотя бы пытается организовать эту модель и действовать в её рамках. Иначе это правдоподобные рассуждения, вайбкодинг, гадание, но никак не понимание.

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

И если придираться, то решение с вектором тоже так себе. Если в инпуте миллион элементов, он аллоцирует вектор на миллион элементов, хотя можно обойтись обычным поэлементным циклом с условием.

А вы можете решить любую задчу?

Я-то нет, но вы вроде говорили, что LLM на это способна?

поверьте, эти дискуссии в самом начале.

Стандартный ответ. Ну что ж, я готов продолжить дискуссию, когда внутри LLM будет модель исполнения C++ кода и когда они не будут галлюцинировать.

Нет, неправильно, так как исходная задача (если убрать отладочную печать "pay for processing") выведет result: 2, result: 4, result: 6, а ваше изменение приводит к выводу: "result: 3, result: 5". Патч изменил наблюдаемое поведение. На сём предлагаю закончить дискуссию о волшебном умении ллм решить любую задачу.

Главная неэффективность: платная операция делается до фильтра

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

2-3 формально верно, но несущественно.

4 просто неверно. Второй раз уже это говорю. Static const это прямое указание как компилятору, так и читающему код человеку, что лямбда одна и та же при любом запуске, и во многих похожих случаях приводит к инлайнингу лямбды. Что хочет выразить автор кода, сделав run_paid_request неконстантной или нестатической? Она может измениться между запусками? Она может быть переприсвоена?

В целом рефакторинг конечно замечательный, но напомню, что в исходный вопрос входило также "Что напечатает данный конкретный код"?

Если скажете, что именно в реальном коде является “платной” операцией (I/O? сеть? CPU?)

Платной операцией является run_paid_request.

Поэтому нет никаких гарантий что даже дорогие модели смогут решить вашу задачу.

что ж, неплохой прогресс по сравнению с исходным посылом "попробуйте показать мне задачу, которую не решит LLM"

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

Нет там используемых классов с документацией. Там код в 10 строчек, 1 функция, вызывающая ranges::transform и ranges::filter. Весь нужный здесь контекст - это указание на возможную дороговизну ф-и run_paid_request. Никакой комплексный анализ не нужен, это не про ассемблерную оптимизацию вопрос. Там тупо дорогая функция вызывается больше раз чем надо.

а раз не помогают мне уровню мидл (правда на c/c++ я не писал уже много лет), то модели, тупее среднестатистического человека, хоть и эрудированной, тем более не поможет.

Говорят, помогает запустить код и проверить, правильно ли LLM его предсказала? https://godbolt.org/z/e783T6sq5 - дорогая функция вызывается для нечётных элементов 2 раза.

Я очень часто вижу такой ответ от апологетов llm. Не та модель, возьмите платную модель и всё получится, дайте больше документации... Какой документации??? Там #!!.* написан грёбаный автономный код в десяток строчек! У него вывод предопределён моделью данных STL. Модель или предсказывает его правильно или нет.

В платных моделях есть математическая модель среды исполнения C++ кода и они мне дадут правильный ответ на этот вопрос, особенно если я уберу из кода все толстые подсказки вида печати в cout в определённом месте? Или всё же там внутри всё тот же вероятностный механизм, просто чуть лучше работающий и с обвесом в виде агентов и полаганием на сайд-эффекты типа выхлопа тестов?

Что ж, разочарую вас:
https://copilot.microsoft.com/shares/9NoKwVTmdN8Uu1ADR3pME

Основная проблема с кодом не найдена, предсказание вывода неверное, понимания работы ranges не наблюдаю. Дан ряд несущественных замечаний, причём не всегда верных ("A normal local lambda would be clearer" - ллм буквально не понимает как работает static const).

Так вот, пока LLM не научатся моделировать математически точный процесс исполнения C++ (Python, Go...) кода, я бы не стал делать громких заявлений по поводу того, что LLM может сделать любую задачу.

tl:dr любой код, который требует понимания ментальной модели среды исполнения (aka модели мира) для корректной реализации. Ну вот классический и многим известный пример на c++, про который ни одна LLM мне не смогла ни правильно сказать, что с ним не так, ни предсказать правильный вывод - тк для этого надо понимать внутреннюю логику c++20 filters/ranges:

Дана C++ реализация функции process_data, имитирующей дорогую обработку входных данных (run_paid_request) и затем фильтрацию. Есть ли в ней архитектурные проблемы, проблемы производительности? Что выведет на экран запуск программы?

#include <iostream>
#include <ranges>
#include <vector>

void process_data(std::ranges::forward_range auto &&input) {
    static const auto run_paid_request = [](auto i) {
        std::cout << "pay for processing of " << i << std::endl;
        return i + 1;
    };

    auto output = input
        | std::views::transform(run_paid_request)
        | std::views::filter([](auto i) {
            return i % 2 == 0;
          });

    for(auto o : output) {
        std::cout << "result: " << o << std::endl;
    }
}

int main() {
    process_data(std::vector<int> {1, 2, 3, 4, 5});
    return 0;
}

блокировку в Rust-библиотеке

в оригинале lock contention, это не блокировка а соревнование за блокировку, несколько другая вещь

декомпрессию в сетевом потоке

што такое сетевой поток. В оригинале "decompressing in the same thread that was doing the networking transfers". Т.е. занятие распаковкой трафика в том же треде который шлёт пакеты в сеть

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

Верно, вмешиваться во ввод в eBPF можно только в сетевой подсистеме, в остальных частях ядра можно только наблюдать/фильтровать, в тч писать колбеки на вызовы клавиатурных функций.

Но если делать на уровне ядра, нужно написать какой-то модуль, потому что изменять само ядро — задача посложнее

eBPF же

Вот это настойчивость, моё увожение.

https://github.com/dermesser/uvco случайно не вашу задачу решает?

И где именно в этой системе используется свойство σ быть автоморфизмом? В ваш питон код можно закинуть любую композицию перестановок (не обязательно автоморфизмов) на Pm и всё, что этот код сделает, - это перебором вычислит орбиту любого элемента "state". Алгебраической содержательности в этом процессе нет, вы не делаете никаких математических утверждений по поводу каких-либо классов σ на Pm. Композиции разных σ или каких-то взаимодействий разных σ между собой тоже не видно.

Если что, устройство Aut(Pm) весьма нехитро, она изоморфна группе кольца Zm по умножению, а если m простое, то группа циклическая. Всё.

"Движок решает инженерно корректную задачу: подобрать отображение σ (переименование меток), которое лучше всего согласует наблюдения" - не всякое переименование меток является автоморфизмом, так что не понятно какие σ вы рассматриваете, то ли Sym(Pm), то ли Aut(Pm).

Какое-то шарлатанство с заваливанием аудитории умными терминами.

Если что, кроме Just и plain Make в мире есть с десяток систем сборки промышленного уровня, не считая гикосистем типа Tup, и чуть ли не каждая из них заявляет, что побеждает проблемы Make.

Вы проанализировали хотя бы самые известные из них, прежде чем писать свой велосипед? Если нет, то почему?

Баш скрипты внутри мейкфайлов писать кстати - это антипаттерн из антипаттернов.
Make часто критикуется за возможность вызвать $(shell...), но вообще если не вызывать всякую процедурщину, то система Target-ов и паттернов Make - это вполне себе чистая ФП система, просто мало кто ей пользуется правильно.

Ну так и сделали бы генератор в обычном смысле (функция (void)->кролик), или систему разных генераторов, и вокруг этого генератора - класс magicians_hat имитирующий корутину и хранящий генератор + копию возвращаемого им значения + ссылки на внутренние переменные генератора если они есть. Чтобы разделить где собственно функционал генератора, и где то что хранится во фрейме корутины.

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

struct Rabbit {};

const int STATE_DONE = 0;


template<class T>
concept RabbitGenerator 
= requires(T &t) {
    { t.gen_rabbit() } -> std::same_as<std::optional<Rabbit>>;
    { t.state() } -> std::same_as<int&>;
};



template<RabbitGenerator G>
class magicians_hat {
public:
    magicians_hat(G&& generator):
        generator_(generator) {}

    void pullout_rabbit() {
        if (generator_.state() == STATE_DONE) return;

        if (auto yielded_rabbit = generator_.gen_rabbit()) {
            yielded_rabbit_ = yielded_rabbit.value();
        }
    }

    // интерфейс coroutine_handle
    Rabbit& promise() { return yielded_rabbit_; }
    void resume();
    void destroy();
    //...
    
private:
    G       generator_;
    Rabbit  yielded_rabbit_;
};

Да вообще ужас, безумных вещей каких-то требую, например чтобы функция "достать кролика" возвращала объект кролик. А возвращаемое генератором значение у вас является частью состояния генератора. Вы уверены, что проблемы с пониманием генераторов у меня, а не у вас?

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

Если честно объяснение непонятное с самой первой структуры magicians_hat_base.

Int state_ - у структуры 4294967295 состояний? Или всё-таки какие-то из них недостижимые? Или структура сама не знает, какие состояния достижимые и какие нет? Подобные соглашения должны быть в описании класса.

" // Функция возобновления virtual void pullout_rabbit() " - мне казалось что таким именем будет названа функция вытаскивания кролика, а не функция "возобновления" чего-либо? Почему "возобновления"? Если я сделаю pullout_rabbit(); pullout_rabbit(); это 2 раза возобновить что-то? Это ошибка или нет?

Int current_rabbit_ - зачем заводить в структуре поле "вытащенный кролик" если "вытащенный кролик" это по смыслу возвращаемое значение, а не хранимое? В базовом классе нет никакой логики завязанной на это поле, просто взяли в стиле C завели поле без знания как им управлять и без гарантий что потомок это реализует.

Что такое состояния 1, 0, как пользователь должен догадаться что из них что означает? Pullout_rabbit() можно вызывать бесконечно много раз - это баг или фича? Разве pullout_rabbit не должен вести себя по-разному в зависимости от done()?

Ну если вы уж хотите полной аутентичности, то привязываться к языкам дварфов Средиземья следует только если у вас сеттинг по Средиземью. :) В противном случае имхо ничего страшного если вы возьмёте имя из дварфского языка из любого постороннего сеттинга, если язык там достаточно проработан и круто звучит. Можете взять дварфский из Dwarf Fortress https://dfwk.ru/Dwarven_language, это не настоящий язык тк в нём нет грамматики и морфологии (только слова некоторых частей речи), но имена собственные там есть, и фонетика в нём ничего так, а у имён собственных есть значения. Стандартное имя гнома в этом языке будет Urist.

1
23 ...

Information

Rating
3,348-th
Location
Ирландия
Registered
Activity