Pull to refresh

Comments 17

Напрашивается вариант повторить это на чем то чуть менее известном/популярном (ну там - KMP/Qt/Tauri/Fluttter).

и внезапно - R1 - терпимо но к ответам будут вопросы.

А вот o3-mini (что обычная что high) очень очень неплохо. При этом если использовать o3-mini через Kagi Assistant напрямую - там качество на уровне R1, а вот code assistant в Kagi Assistant (там Sonnet но с хитрым prompt) - вполне себе сравнимо уже с o3 и лучше R1. Промпт тоже важен получается?

А вот откровенное издевательство с запросом - Create Windows app using only C and WinAPI for list of countries by categories. Use API from World Bank to get information - висело долго, потом сказало что JSON это сложно, наш путь - XML и парсер будет очень примитивный. Результат на первый взгляд корректный.

Предложение написать вообще на ассемблере для Windows - ответ дан но с кучей комментариев про NASM-style pseudocode, calling convention. Для Linux на ассемблере - ИИ решил упростить себе задачу - захардкодил IP-адрес(не факт что правильно - у меня другой резолвится) и решил вывести на stdout (ну правильно - про Xorg/Wayland в задаче не было), если добавить требование что GUI App и нельзя хардкодить - думает больше минуты, но выдает что то на первый взгляд отдаленно похожее на правду(я не знаю Xlib на таком уровне) с использованием Xlib (ну правильно - Wayland? А что это?), при этом теперь захардкожен уже 8.8.8.8 в качестве DNS-сервера(системный резолвер - а что это?). Если прямо сказать что надо Wayland - сделает под Wayland. Ну и Ассеблер по мнению бота это ассебмлер x86-64

Предложение написать тоже самое для MSX-2 или ZX-Spectrum - долго думает и говорит что не запустится там , вот вам на Python'е с Tkinter в стиле старого железа.

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

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

Вот только чуть усложняем задачу

Промпт: Create Kotlin Multiplatform app for android, windows, macos and web for download books or fanfics as epub from ficbook.net. Use Compose Multiplatform as GUI library. . Use separate gradle modules/source sets if you feel it's necessary. Write full source code of each relevant file, add all plaform-specific dependencies

Результат: https://chatgpt.com/share/67ab385c-553c-8008-963a-ae4d04224739

Вот только не учтено например:

  • без авторизации и подписки сайт не отдаст epub - надо по главам читать

  • там вообще то еще и Cloudflare есть

  • нету сохранения файлов

  • про обложки - не знает

Если прямо уточнить где сохранения - добавит (причем грубейшим хардкодом). Про остальное - фиг.

Ну или смотрим что выходит если попросить таки сделать игру про корованы даже с несколькими уточнениями - https://chatgpt.com/share/67ab41cc-bdec-8008-b211-49dea3bd6753 - вообщем самый нубский учебник Unreal 5 за 21 час - позволит сделать такое (это если код вообще компилируется).... да, по крайней мере не так плохо как раньше.

Очередная сказка про 8 летнюю девочку которая создала 3д игру и собирает донаты?

Мне с помощью армии ллм с большим трудом удалось сделать для андроида калькулятор с фонариком (калькулятор скорее нерабочий чем рабочий получился) и еще одно столь же несложное приложение. Продолжать не хочется вообще.

Сделать простейший плагин для фаирфокса не получилось, там как обычно у опенсорса в прошлую пятницу обновили полмира и теперь надо самому читать новые и старые доки и и еще кучу всего что бы простой хелоуворлд написать.

8 летние девочки не задают prompts c concurrency. Как бы вам это не представлялось, задания (prompts) задаёт квалифицированный программист и ответы оценивает он же. Так что ВЫ ведете ИИ и туда, куда ВАМ нужно. Так вот ChatGPT o3-mini очень хорошо отвечает на правильно поставленные вопросы, как и DeepSeek, но он чаще ошибается и его приходится "подталкивать" в нужном направлении, он неплохо "слушается" и это сокращает ВАШЕ время написания iOS приложения. И в этом их прелесть.

Нет никаких иллюзий, что за вас кто-то напишет приложение.

При написание кода, особенно на таких прогрессирующих языках программирования, как Swift, есть очень большая вероятность, что вам предоставят решение с устаревшей версией. И так оно и было с Claude 3.5 sonnet и ChatGPT 4o1, не говоря уже о Gemini 1.5, который выдаёт позавчерашнюю версию языка.

Но ситуация с ChatGPT 4o3-mini и DeepSeek существенно изменилась в лучшую сторону.

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

Для андроида и фаирфокса делал примерно так же.

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

я просил возможно еще более простую вещь - нарисовать 2 view с эффектом blend (смешивание) в UIKit. Визуально это отдаленно похоже на 2 соединенные капли.
До сих пор все модели или пытаются смешать 2 цвета в один и закрасить им все, или придумывают несуществующий фильтр "blend", с которым приложение даже не скомпилируется.

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

Первоначально был запрос общего характера: к моему любимому ИИ - Claude 3.5 Sonnet "Создай iOS приложение, которое показывает страны Мира по категориям. Используй информацию Всемирного Банка". Просто хотелось понять, сможет ли он найти сайты, понять, как устроен JSON, создать Модель Данных, декодировать её и создать хоть какой-то UI для сгруппированных стран.

И тут же получаю iOS приложение с кодом, который НЕ РАБОТАЕТ. Вроде сайт Всемирного Банка ИИ нашел, Модель данных создал, UI тоже нормальный, а Decode не может выполнить. Да, JSON - нестандартный, но не такой уж и сложный, но как я "не упрашивала" Claude 3.5 Sonnet - не хочет, не натренирован, не обучен, не знаю. Пришлось этот частный вопрос декодирования конкретных JSON данных решать c ChatGPT, в результате получаю правильные 3 строчки кода, которые и предлагаю Claude 3.5 Sonnet, с которым продолжаю работать, так как код для UI у него всегда замечательный.

И тут появляется DeepSeek, а затем и ChatGPT 4.o3-mini.

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

Хочу добавить дополнительную информацию о населении и ВВП страны ( как оказалось выборки с других endpoints) - ChatGPT 4.o3-mini практически сразу великолепный результат, DeepSeek чуть запутался, но не смертельно, чуть "пнула" - всё понял и исправился.

Аппетит приходит во время еды,

Прошу перейти к новому и очень сложному Swift 6 strict concurrency - оба справляются.

Хочу страну на карте Мира - все работает, но оба пытаются подсунуть мне старый API. Прошу новый - оба "слушаются" и выдают правильный результат, но по-разному.

Так что - ДА, понадобилось 8 Prompts, чтобы получить окончательное приложение.

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

старый CGD (Central Grand Dispatch), так что приходилось дополнительно рефакторить код до современного async / await.

Использовал современную async / await систему работы с многопоточностью

Выборка данных из сети выполнена с помощью современной async / awaitсистемы работы с многопоточностью.

И дальше еще несколько раз упомянуто, что "swift concurrency современный". Соответственно:
1)вы писали, что генерируете код с помощью нейросетей, но у вас и сама статья сгенерирована в chatGPT?
2)если статья все-таки не сгенерирована, то чем конкретно в вашем примере GCD хуже, чем Structured Concurrency, да еще со strict concurrency? Код вам уже сгенерировали. Сложность кода при переходе на strict concurrency растет в геометрической прогрессии.

Ну, вы загнули насчет того, что статья сгенерирована в ChatGPT. Да, в ней дословно приводятся "рассуждения" ChatGPT, но они скрыты, чтобы не загромождать текст статьи - кто хочет, тот прочитает, а обычным читателям может и не понадобится.

Что касается старого  CGD (Central Grand Dispatch), то на работоспособность приложения это, конечно, не влияет, но на читабельность кода влияет очень сильно. одна  Pyramid of doom чего стоит, впрочем посмотрите статью Swift async/await. Чем он лучше GCD?. Там все очень подробно написано.

Что касается меня, то я очень люблю CGD и владею им в совершенстве (Многопоточность (concurrency) в Swift 3. GCD и Dispatch Queues), с трудом перешла на async / await, но сейчас вижу его огромные преимущества. Даже на примере этой статьи код с async / await намного лаконичнее и он линейный - не надо думать, что сработает раньше, а что позже.

Что касается Swift 6 strict concurrency, то это борьба с "гонкой данных" на уровне компиляции. Вы когда-нибудь сталкивались с "гонкой данных"? В статье Многопоточность (concurrency) в Swift 3. GCD и Dispatch Queues) приводится такой пример: на UI пользователь задаёт url и ждет изображение, оно долго не приходит и пользователь меняет url, для которого изображение тут же приходит, но спустя некоторое время приходит предыдущее изображение, уже не соответствующее заданному пользователем url и "забивает" ваще правильное изображение. В случае  CGD нужно обнаружить "гонкой данных" и бороться с ним на уровне кода.

Кстати, никакой сложности кода в геометрической прогрессии нет : ставишь @MainActor перед class ViewModel и помечаешь fetch функции как nonisolated. Смотри пост Многопоточность по шагам:  Сетевой запрос.

Но использование Swift 6 strict concurrency конкретно в этом тестовом приложении была в том, чтобы "дожать" ChatGPT, понять границу, где он "сломается". К сожалению, а может быть к счастью, ChatGPT, а также DeepSeek, на сложных вещах "не ломаются", они "ломаются" на очень простых вещах, например, на "человеческих" ошибках проектирования API Всемирного банка.

Спасибо за статью про эксперименты с GCD я ее читал и перечитывал несколько раз.
Я еще не читал последнюю статью, но если в первых двух у вас playground и отдельные функции, где обработка retain cycle особо не имеет значения, то в последней она нужна, а вы ее игнорируете. Получается, что вы заморочились на то, чтобы у вас изображение не подтянулось старое (хотя это можно предусмотреть и в GCD отдельно), но проигнорировали то, что у вас структура остается висеть в памяти.
Другими словами если у вас есть код:

DispatchQueue.main.async {

   self....
}

То DispatchQueue настолько "мощно" удерживает self в памяти, что без `[weak self]` этот класс/структура могут быть созданы в фоновом потоке, а уничтожиться в главном.

Насколько я понимаю, с Task будет аналогичная ситуация - объект будет удерживаться в памяти в лучшем случае до тех пор, пока этот Task не закончится. А это кроме утечек может привести к другим приколам, например, если класс внутри Task посылает сообщения другим классам. Кстати нигде в документации не описано, что делать с Task в таких случаях.

По поводу @MainActor и nonisolated - я вас правильно понимаю, вы сначала включили strict concurrency, а потом с помощью nonisolated вручную отключили проверки? Но какой тогда смысл в strict concurrency?

Дальше тут я недавно читал эту статью https://habr.com/ru/companies/yandex/articles/879078/ и там есть кусок кода:

@MainActor
func testMainActor() {
  Task { print(“a”) }
  Task { print(“b”) }
  Task { print(“c”) }
}

До Swift 6 (на который еще не все перешли) буквы в лог выводятся в произвольном порядке, хотя казалось бы - главный поток, и каждая Task должна "наследовать контекст".


В итоге оказывается, что structured concurrency до сих пор сырой. А если предусматривать все-все его особенности, то сложность кода окажется похлеще, чем у Pyramid of doom. И кстати почему-то предыдущий Combine в этом плане оказался более продуманным.

Но опять же может я и ошибаюсь - по особенностям работы Task я не всегда нахожу информацию. А chatGPT вряд ли поможет в этом - я использую Perplexity, который аргументирует свои ответы ссылками на источники, откуда берет информацию - и эти источники часто неверные.

Спросила ChatGPT ваш вопрос:

Нам необходим [weak self] в коде:

Task {
            do {
                let fetchedCountries = try await WorldBankService.shared.fetchCountries()
                DispatchQueue.main.async {
                    self.countries = fetchedCountries
                    self.isLoading = false
                }
            } catch {
                DispatchQueue.main.async {
                    self.error = error
                    self.isLoading = false
                }
            }
        }

Вот что он ответил:

Нет, в этом случае вам не нужен [weak self]. Вот почему:

1️⃣ Задача Task захватывает self stronlgy, но это не Retain Cycle

Поскольку задача Task не сохраняется (это эфемерный асинхронный блок), она завершит и освободит свои ссылки, включая self.
2️⃣ DispatchQueue.main.async не вызывает Retain Cycle
Замыкание DispatchQueue.main.async также захватывает self stronlgy, но поскольку оно выполняется асинхронно и завершается немедленно, оно не вызовет Retain Cycle.

А вот ответ Gemini 2.0 Flash Thinking Experimental

Почему [weak self] технически не нужен в вашем фрагменте кода:

Задача Task привязана к жизненному циклу View: задача запускается при появлении View (из-за .task) и отменяется при исчезновении View.
Операции связаны с UI: выборка стран и обновление @State — это операции, напрямую связанные с UI .
Нет долгоживущей фоновой задачи: это не фоновая задача, предназначенная для выполнения независимо от View в течение длительного периода.

Вкратце:

Для типичного использования модификатора .task SwiftUI для асинхронных операций, связанных с View, таких как выборка данных, [weak self] обычно не требуется для безопасности памяти из-за управления жизненным циклом задач SwiftUI. SwiftUI разработан для безопасной обработки этих случаев.

Однако добавление [weak self] также не нанесет никакого вреда в этом сценарии. Некоторые могут посчитать это немного более защитным кодированием или вопросом личных предпочтений, чтобы быть явным в отношении семантики захвата. Но для общих шаблонов SwiftUI с .task это часто считается излишней многословностью и не идиоматичным.

Поэтому в предоставленном вами коде вам не нужно использовать [weak self]. .task SwiftUI разработан для правильной обработки жизненного цикла без необходимости вручную добавлять weak self, чтобы избежать утечек памяти в этих типичных сценариях.

Современным студентам Стэнфорда читают только async /await.

Лекция 14. Многопоточность. Обработка ошибок.

Насчет Swift 6 все таки очень очень -очень советую статью Concurrency Step-by-Step: A Network Request или её русскоязычный перевод пост Многопоточность по шагам:  Сетевой запрос.

Что ж Apple, конечно, намудрила с Swift6 strict concurrency, но после этой статьи голова реально просветлеет. Мне она очень помогла - автор великолепный.

Спасибо за детальный ответ, но меня смутило немного другое. Perplexity мне тоже выдал, что [weak self] использовать не нужно, но запрос:

you use Structured Concurrency in swift. Task { ... } means using of swift blocks. Should you always write [weak self] and "guard let self else" (or other code) to prevent retain cycles

Ответ:

When using Structured Concurrency in Swift with Task { ... } blocks, you don't always need to write [weak self] and guard let self else to prevent retain cycles45. Here's why:

  • Swift Concurrency and Memory Management: Swift’s concurrency model, introduced in Swift 5.5, includes features like async/await, actors, and tasks, designed to avoid traditional multithreading pitfalls such as race conditions and deadlocks1.

  • Sendable Closures: When you create a new task, the work it performs is within a @Sendable closure. These closures are restricted from capturing mutable variables in their lexical context, ensuring that captured values are safe to share5. This is achieved because the values are either value types (like Int and String) or objects designed to be accessed from multiple threads, such as actors5.

  • Structured Concurrency Benefits: Structured concurrency manages the lifecycle of concurrent tasks in a hierarchical manner, ensuring tasks are created, executed, and terminated within a clear scope7. This helps in automatic resource management and makes code more predictable7.

  • When to Use [weak self]: The primary reason to use [weak self] is to prevent strong reference cycles when capturing self in a closure, especially if the closure might outlive the object it's capturing46. However, with Swift Concurrency, the need for [weak self] is reduced because asynchronous callbacks are guaranteed to run exactly once, eliminating the possibility of permanent reference cycles4.

  • Unnecessary [weak self] Overhead: Reflexively adding [weak self] can increase runtime overhead and code complexity, as it requires handling the possibility of self being nil4. This can make the code harder to reason about, as arbitrary amounts of code might be skipped if self is nil4.

In summary, while [weak self] and guard let self else are crucial in many traditional closure scenarios to prevent retain cycles, Swift's structured concurrency and the nature of asynchronous tasks often eliminate the need for them145. You should focus on using actors and @Sendable closures to manage state and ensure data safety in concurrent code57.

Выглядит правильно и логично, но ссылается сюда (здесь вообще ничего, просто примеры swift concurrency):
https://toxigon.com/swift-concurrency-best-practices
и сюда (список proposals, которые не обязательно вошли в релиз swift):
https://forums.swift.org/t/swift-concurrency-roadmap/41611

Т.е. рассуждения вроде как верные, но некоторые источники невалидные/нерелевантные.

Да, странные ссылки, вторая ссылка вообще 2020 года. Не пользовалась Perplexity, хотя его вроде хвалят.

Sign up to leave a comment.

Articles