2025-03-01

vak: (Украина)
Майкл Макфол, політичний аналітик, дипломат, професор Стенфордського університету, екс-посол США в РФ:

Зеленський багато разів дякував Трампу, Конгресу та американському народу. Але давайте прояснимо: коли Трамп і Венс заявили, що це ВОНИ зараз допомагають Україні і що Зеленський має особисто подякувати їм, є причини сумніватися в цьому:
  1. Команда Трампа заявила Україні, що вона має віддати частину територій Росії.
    Зеленський має подякувати їм за це?
  2. Трамп заявив, що Україна не може вступити в НАТО.
    Зеленський має подякувати їм за це?
  3. Трамп сказав, що якщо в Україні будуть міжнародні миротворчі сили, американські солдати в них брати участь не будуть.
    Зеленський має подякувати їм за це?
  4. Команда Трампа заявила, що планує скоротити кількість американських військових у Європі. Це величезний подарунок Путіну.
    Зеленський має подякувати їм за це?
  5. Відносини між США та Росією були офіційно відновлені без жодних попередніх умов під час зустрічі держсекретаря Рубіо та міністра закордонних справ РФ Лаврова в Саудівській Аравії. Чиновники Трампа натякнули на можливе пом’якшення санкцій проти Росії. Трамп запросив Росію знову приєднатися до G7.
    Зеленський має подякувати їм за це?
  6. США проголосували «проти» резолюції ООН, яка засуджує вторгнення Росії в Україну. Таким чином, Трамп порвав із демократичними союзниками США та став на бік Росії, Білорусі, Північної Кореї та інших диктатур.
    Зеленський має подякувати їм за це?
  7. А допомога, за яку Венс сьогодні вимагав подяки від Зеленського? Але ж Венс сам голосував «проти». Республіканська партія затримувала її шість місяців. А Трамп заявив, що Байден був «дурнем», коли надав цю допомогу.
То за що саме Зеленський має дякувати Трампу та Венсу? Конгресу — так. Американським платникам податків — безумовно. Але Трамп наразі не зробив нічого для України.

Усе, що робить команда Трампа, — це дарує подарунки Путіну. І якщо хтось має висловлювати їм подяку, то це російський диктатор.
vak: (Знайка)
Продолжаю двигаться по списку: изучаю базовые примитивы языка Rust. Сегодня рассмотрим Cell<T>, RefCell<T> и, на десерт, Option<T>.

Cell это простой контейнер на одно значение произвольного типа. С одной хитрой фичей: если значение неизменяемое (то есть имеет атрибут const), Cell позволяет обходить это ограничение и всё-таки изменять его. Аналогично ключевому слову "mutable" в Си++. Спросим у grok.com.

Question: Please show me how type Cell<T> can be implemented in C++.

Let’s dive into how we might implement Rust’s Cell<T> in C++. Rust’s Cell<T> is a fascinating type - it provides interior mutability, allowing you to mutate its contents even when you only have a shared reference, all while being safe in a single-threaded context. It’s lightweight, with no runtime overhead beyond the mutation itself, and it doesn’t involve locks since it’s not thread-safe (that’s what RefCell or atomics are for in Rust). In C++, we don’t have the exact same ownership and borrowing rules, so we’ll need to adapt the concept while preserving its spirit.

The core idea of Cell<T> is simple: it wraps a value of type T and provides methods to get and set that value, bypassing C++’s usual const-correctness restrictions in a controlled way. Rust uses it to allow mutation through shared references, so in C++, we’ll aim for something that lets us modify a value even when we might otherwise be constrained, like through a const reference, while keeping the implementation straightforward.

Here’s a basic implementation in C++: cell.cpp.
#include <utility>
#include <iostream>

template <typename T>
class Cell {
private:
mutable T value; // Mutable to allow mutation even when Cell is const

public:
// Constructor
explicit Cell(T initial) : value(std::move(initial)) {}

// Get a copy of the value
T get() const {
return value;
}

// Set a new value
void set(T new_value) const {
value = std::move(new_value);
}

// Replace the value and return the old one
T replace(T new_value) const {
T old_value = std::move(value);
value = std::move(new_value);
return old_value;
}
};
vak: (Украина)
(ещё полезный текст, сохраню для истории)

Зеленский, Трамп и орущий с дивана в Овальном кабинете.

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

Подробно. )
vak: (Знайка)
Тип RefCell<T>, аналогично Cell<T>, тоже контейнер на одно значение произвольного типа. Но к самому значению нельзя достучаться прямо, а надо сначала получить ссылку на него методами borrow() или borrow_mut().

Метод borrow() даёт константную ссылку. Значение можно получить методом get(), но нельзя изменить. Таких константных ссылок можно насоздавать сколько угодно - при условии, что не существует мутабельной ссылки.

Метод borrow_mut() даёт мутабельную ссылку. Значение можно изменить методом set(). Но мутабельную ссылку можно получить только одну-единственную, и при отсутствии константных ссылок.

Question: Please show me implementation of type RefCell<T> in C++.

Let’s tackle implementing Rust’s RefCell<T> in C++. This is an exciting challenge because RefCell<T> takes interior mutability a step further than Cell<T>. While Cell<T> allows mutation through a shared reference with a simple copy or swap, RefCell<T> provides borrowed access—either immutable (shared) or mutable (exclusive)—with runtime checks to enforce Rust’s borrowing rules: you can have many immutable borrows or one mutable borrow, but never both at once. In Rust, this is all about safety without locks, and we’ll aim to replicate that dynamic enforcement in C++.

In C++, we don’t have a borrow checker, so we’ll use a runtime mechanism to track borrows, similar to how RefCell uses a counter in Rust. The implementation will involve:
  • A container for the value.
  • Counters for active immutable and mutable borrows.
  • Methods to borrow the value immutably (borrow) or mutably (borrow_mut), returning smart pointers that enforce the borrowing rules.
  • Runtime checks to panic (or throw, in C++ terms) if the rules are violated.
Here’s the implementation: refcell.cpp.
#include <iostream>
#include <memory>
#include <stdexcept>
#include <utility>

template <typename T>
class RefCell {
private:
T value;
mutable size_t borrow_count; // Tracks immutable borrows
mutable bool borrowed_mut; // Tracks if there's a mutable borrow

public:
explicit RefCell(T initial) : value(std::move(initial)), borrow_count(0), borrowed_mut(false) {}

class Ref {
private:
const RefCell<T>* cell;
friend class RefCell<T>;

Ref(const RefCell<T>* c) : cell(c) {
if (cell->borrowed_mut) {
throw std::runtime_error("Already mutably borrowed");
}
cell->borrow_count++;
}

public:
~Ref() {
if (cell) {
cell->borrow_count--;
}
}

Ref(const Ref&) = delete;
Ref& operator=(const Ref&) = delete;
Ref(Ref&& other) noexcept : cell(other.cell) { other.cell = nullptr; }

const T& get() const { return cell->value; }
};

class RefMut {
private:
RefCell<T>* cell;
friend class RefCell<T>;

RefMut(RefCell<T>* c) : cell(c) {
if (c->borrow_count > 0 || c->borrowed_mut) {
throw std::runtime_error("Already borrowed");
}
c->borrowed_mut = true;
}

public:
~RefMut() {
if (cell) {
cell->borrowed_mut = false;
}
}

RefMut(const RefMut&) = delete;
RefMut& operator=(const RefMut&) = delete;
RefMut(RefMut&& other) noexcept : cell(other.cell) { other.cell = nullptr; }

T& get() { return cell->value; }

void set(T new_value) {
cell->value = std::move(new_value);
}
};

Ref borrow() const { return Ref(this); }
RefMut borrow_mut() { return RefMut(this); }
};
объяснения )
vak: (Знайка)
Устав от сложных концепций, глянем что-нибудь простое, скажем тип Option<T>. Это контейнер на одно значение произвольного типа, которое может отсутствовать. В Си++17 появился практически идентичный класс std::optional. Но мы попросим Грок состряпать нам решение, максимально близкое к Rust.

Question: Please implement type Option in C++, making it as close to Rust as possible, but still convenient for C++.

Let's create a C++ implementation of Rust's Option type. In Rust, Option is an enum that represents either Some(value) or None, used for handling cases where a value might be absent. Here's a C++ version that mimics this behavior while adapting to C++ idioms:
#include <utility>
#include <stdexcept>

template <typename T>
class Option {
private:
bool has_value;
union {
T value;
};

public:
// Constructors
Option() : has_value(false) {}

explicit Option(const T& val) : has_value(true), value(val) {}

explicit Option(T&& val) : has_value(true), value(std::move(val)) {}

// Copy constructor
Option(const Option& other) : has_value(other.has_value) {
if (has_value) {
new(&value) T(other.value);
}
}

// Move constructor
Option(Option&& other) noexcept : has_value(other.has_value) {
if (has_value) {
new(&value) T(std::move(other.value));
other.has_value = false;
}
}

// Destructor
~Option() {
if (has_value) {
value.~T();
}
}

// Assignment operators
Option& operator=(const Option& other) {
if (this != &other) {
if (has_value) {
value.~T();
}
has_value = other.has_value;
if (has_value) {
new(&value) T(other.value);
}
}
return *this;
}

Option& operator=(Option&& other) noexcept {
if (this != &other) {
if (has_value) {
value.~T();
}
has_value = other.has_value;
if (has_value) {
new(&value) T(std::move(other.value));
other.has_value = false;
}
}
return *this;
}

// Static methods to create Some and None
static Option Some(const T& val) { return Option(val); }
static Option None() { return Option(); }

// Check if contains value
bool is_some() const { return has_value; }
bool is_none() const { return !has_value; }

// Access value (unsafe - throws if None)
T& unwrap() {
if (!has_value) {
throw std::runtime_error("Called unwrap on None");
}
return value;
}

const T& unwrap() const {
if (!has_value) {
throw std::runtime_error("Called unwrap on None");
}
return value;
}

// Access with default value
T unwrap_or(const T& default_value) const {
return has_value ? value : default_value;
}

// Get value or compute default
template <typename F>
T unwrap_or_else(F&& func) const {
return has_value ? value : func();
}
};

// Helper function to make creation more convenient
template <typename T>
Option<T> some(const T& value) {
return Option<T>::Some(value);
}

template <typename T>
Option<T> none() {
return Option<T>::None();
}