Hacker News Digest

Тег: #cpp

Постов: 5

The Expression Problem and its solutions (2016) (eli.thegreenplace.net)

Проблема выражений и её решения

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

Пример на C++
Базовый класс Expr с двумя методами: Eval() и ToString().
Новый тип — просто новый класс-наследник.
Новая операция — правим базовый класс и все наследников, нарушая OCP.

Функциональный подход (Haskell)
Типы данных и функции разведены:

data Expr = Constant Double | BinaryPlus Expr Expr
eval (Constant x) = x
eval (BinaryPlus a b) = eval a + eval b

Добавить операцию легко: пишем новую функцию.
Добавить вариант Expr — правим сам тип и все функции, pattern-match’и которых его затрагивают.

Как быть

  • Визитор (ООП) — двойная диспетчеризация, но код всё равно растёт.
  • Мультиметоды (CLOS, Clojure) — выбор по типу всех аргументов, код не трогается.
  • Type-class / протоколы (Haskell, Clojure) — «открытые» функции, реализуемые вне исходного модуля.
  • Tagless-final / finally-tagless — выразить язык как набор операций, интерпретаторы добавляются без изменения AST.

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

by andsoitis • 07 сентября 2025 г. в 06:28 • 95 points

ОригиналHN

#cpp#haskell#rust#swift#object-oriented-programming#functional-programming#type-class#visitor-pattern#multiple-dispatch#tagless-final

Комментарии (69)

  • Суть проблемы: нужно добавлять новые типы данных и новые операции без переписывания старого кода и без потери статической безопасности.
  • Классический подход: O·T матрица — каждая операция реализуется для каждого типа; при росте O или T взрывается boilerplate.
  • Языковые решения:
    – трейты/impl в Rust, typeclass в Haskell, протоколы в Swift позволяют добавлять операции «сбоку»;
    – enum (суммарные типы) упрощают добавление операций, но затрудняют новые варианты данных.
  • Продвинутые техники: tagless-final, object algebras, data types à la carte, multiple dispatch, visitor-pattern.
  • Ограничения: «сиротское правило», отсутствие виртуальных extension-методов, необходимость заранее знать все комбинации при раздельной компиляции.
  • Вывод: идеального языка нет; выбор зависит от того, что важнее — расширять типы или операции — и насколько нужна статическая типизация.

Forking Chrome to render in a terminal (2023) (fathy.fr)

  • Рисование
    Терминал умеет только моноширинные символы и escape-последовательности. Используем нижний полублок , задавая цвет фона (верхний пиксель) и символа (нижний).

    fn print_pixels_pair(top, bottom, (x, y)) {
        println!("\x1b[{};{}H\x1b[48;2;{t}m\x1b[38;2;{b}m▄", y+1, x+1, t=top, b=bottom);
    }
    
  • Текст
    Создаём TextCaptureDevice в Skia: перехватываем onDrawGlyphRunList, преобразуем glyph → Unicode, вызываем Rust-функцию draw_text.
    Добавляем очистку текста при заливке прямоугольников:

    if (paint.getStyle() == kFill_Style && paint.getAlphaf() == 1.0)
        clear_text(rect);
    
  • Ввод
    Читаем stdin, парсим escape-коды клавиш/мыши, передаём их в Chromium через DOM-события.

  • Pipe-режим
    carbonyl --pipe рисует в stdout, позволяя встраивать браузер в скрипты.

  • Mojo
    Заменяем GPU-процесс на заглушку, отключая лишние сервисы.

  • Layout
    Подгоняем device_scale_factor и viewport под размер терминала, чтобы 1 px = ½ клетки.

  • LoDPI
    На 1×-экранах включаем сглаживание, чтобы символы не «дребезжали».

  • Цвет
    Палитра 6×6×6 или 24-бит truecolor; приводим цвета к ближайшему доступному.

  • Заголовок
    ESC-операторы меняют заголовок окна и вкладки tmux.

  • Итог
    Carbonyl запускает весь веб в терминале без X11/Wayland: cargo install carbonyl.

by riddley • 05 сентября 2025 г. в 00:54 • 140 points

ОригиналHN

#rust#cpp#skia#chromium#mojo#terminal#unicode#pdf#podman#youtube

Комментарии (17)

  • Carbonyl — терминальный браузер на движке Chrome, удивительно шустрый и юзабельный, особенно с --zoom=300 --bitmap.
  • Пользователи просят добавить Kitty Graphics Protocol, sixel/chafa для нормального вывода картинок без ASCII-арта.
  • Проект вдохновлён browsh, но работает быстрее; автору даже помог получить работу.
  • Запускается в podman, показывает YouTube «кубиками» и почти справляется с капчей (могут помочь мультимодальные LLM).
  • Под капотом — Skia и Mojo из Chromium, что позволяет рендерить всё, включая PDF.

A review of Nim 2: The good and bad with example code (miguel-martin.com)

Плюсы Nim 2

  • Память: по умолчанию ORC/ARC (RAII, деструкторы, move/copy), а не трассирующий GC. Можно --mm:none или --mm:atomicArc.
  • Компилируется в C/C++/Obj-C/JS; выбираем компилятор (gcc, nvcc, …).
  • Лёгкая интеграция: {.importc.}, {.importcpp.}, {.importjs.}, {.compile.} для сторонних файлов.
  • Метапрограммирование: макросы, static исполнение кода на этапе компиляции, генерация CUDA.
  • Краткость: мало шаблонного кода (чат на 70 строк).
  • Производительность ≈ C/C++/Rust; поддержка SIMD, CUDA.

Минусы и подводные камни

  • Генерируемый C/C++ код нечитаем — не цель проекта.
  • Нет атомарных счётчиков в ORC по умолчанию (требуется флаг).
  • Некоторые старые статьи/комментарии описывают Nim 1.x (GC по умолчанию).
  • Синтаксис чувствителен к отступам и регистру (но это субъективно).

Мини-пример: простой key/value формат

import std/[tables, strutils]

type Config = object
  host*: string
  port*: int

proc loadConfig(path: string, T: typedesc): T =
  let data = readFile(path).splitLines()
  var kv = initTable[string, string]()
  for line in data:
    let parts = line.split('=')
    if parts.len == 2:
      kv[parts[0].strip()] = parts[1].strip()

  result.host = kv.getOrDefault("host", "localhost")
  result.port = parseInt(kv.getOrDefault("port", "8080"))

let cfg = loadConfig("app.conf", Config)
echo cfg.host, ":", cfg.port

Файл app.conf:

host = 0.0.0.0
port = 9000

Всё компилируется в один бинарник без GC-задержек.

by miguel_martin • 28 августа 2025 г. в 22:25 • 216 points

ОригиналHN

#nim#c#cpp#rust#cuda#javascript#webassembly#metaprogramming

Комментарии (51)

  • Пользователи отмечают редкую, но полезную возможность Nim — определять собственные операторы.
  • Хвалят макросы, интегрированные в систему типов и перегрузку, сравнивая язык с «статически типизированным Lisp».
  • Критика: сложности с Windows (Nimble-зависимости тянут GCC, Defender блокирует бинарники) и неоднозначная «фантастическая» интеграция с C++.
  • Обсуждают объём JS-артефактов: для мелких примеров — десятки килобайт, но без оптимизации могут быть мегабайты.
  • Для WASM рекомендуют компилировать в C и прогонять через Emscripten, но стандартные JS-биндинги не работают.
  • Вопросы IDE: есть nimsuggest и быстрая настройка для Neovim, но плагинов для JetBrains почти нет.

Mistral Integration Improved in Llama.cpp (github.com)

  • Добавлена поддержка моделей Mistral-Small-3.1-24B-Instruct-2503 и Mistral-Small-24B-Instruct-2501
  • Улучшена работа с Mamba-2 и Sliding Window Attention
  • Новые правила конвертации: convert-hf-to-gguf.py теперь корректно обрабатывает sliding_window, mamba2, attention_bias, tie_word_embeddings
  • Обновлён llama_model_loader и llama_model: добавлены поля mamba2 и sliding_window, упрощена логика KV-cache
  • Поддержка mamba2 в llama_context и llama_decode
  • Удалены устаревшие llama_model и llama_vocab
  • Добавлены тесты test-mistral.py и test-mistral-vision.py

by decide1000 • 11 августа 2025 г. в 10:10 • 79 points

ОригиналHN

#mistral#llama.cpp#mamba-2#sliding-window-attention#python#fastapi#c++#github#cpp

Комментарии (11)

  • Mistral предлагает mistral-common как официальный токенизатор, но пока только через Python-библиотеку и временный REST-обвязанный FastAPI.
  • Сообщество жалуется: «cpp-бинарь, зависящий от Python-сервера — временное и грустное решение», ждут нативный C++ порт.
  • Пользователи расстроены, что Mistral, выпуская веса, не сразу поддерживает llama.cpp, на котором держится большинство «домашних» запусков.
  • Некоторые замечают, что llama.cpp и так тянет Python для шаблонов, но это не отменяет желания увидеть полноценную C++ реализацию.
  • Сторонники Mistral отвечают: компания маленькая, пока не ясно, какие именно инференс-фреймворки поддерживать, зато открыли собственный mistral-inference.

C++26 Reflections adventures and compile-time UML (reachablecode.com)

by ibobev • 03 августа 2025 г. в 00:12 • 139 points

ОригиналHN

#c++#reflection#uml#metaprogramming#cpp

Комментарии (112)

Whenever I start to feel like a real programmer making games and webapps and AI-enhanced ETL pipelines, I inevitably come across the blog post of a C++ expert and reminded that I am basically playing with legos and play-doh. I had to do a UML thing for the first time in years for