Pull to refresh
32
0.1
Николай Меркин @nickolaym

User

Send message

Как бы не получился комикс "брошу яваскрипт и стану проституткой". С вот этим вот преобразованием чисел в строки (или строк в числа). Потому что тут рядом тусуются проблемы локалей.

Кажется, что вопрос не по теме поста. Как это соотносится с бимапами?

И, собственно, в чём проблема? В мемоизации функции f? Зачем нужен словарь, на что должна влиять монотонность и, тем более, линейность? Какой прикладной смысл этого всего?

Такую штуку делали в каком-то очень дремучем году, например, Microsoft ATL/WTL.

160 элементов - это всё ещё "мало". Были бы сотни тысяч, можно было бы подумать об эффективном хранении и из-за этого - об эффективном доступе. А тут...

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

Но кстати, быстрое-и-грязное решение - это напихать ключи в один словарь

def make_bimap(src):  # src - dict
    dst = {}
    dst.update(src)
    dst.update((v, k) for (k, v) in src.items())
    return dst

Но при этом надо удостовериться, что нет конфликта ключей в обратном направлении.

Ну и не забываем про наследие предков. Бимапы люди делали издревле, и быстрый поиск даёт, например, PyPy.bidict.

Преимущества начинаются, когда у наследников есть полиморфные

  • статические члены: обычными виртуальными функциями их уже не пробросить, нужен механизм словарей/фабрик (в шарпе и яве это сделано на дженериках - ну или ручками, ручками всё)

  • свойства времени компиляции: типы, константы и всё такое - тут уже даже дженерики не спасут

template<class Impl> class Vehicle {
  // пример статической функции
  static Impl* create_road_train() {
    if (!Impl::can_tow() || !Impl::can_be_towed()) return nullptr;
    Impl* tow = Impl::create();
    Impl* trailer = Impl::create();
    return Impl::bind(tow, trailer);
    // или, может быть
    return tow->bind(trailer);
  }

  // пример свойств времени компиляции
  Impl::WheelType wheels_[Impl::number_of_wheels];
};

Это уже отмазки пошли. Я сказал, зачем нужно делать new const T, вы сказали, что чаще бывает static T, я привёл сценарии - более чем рабочие! - а вы отделываетесь какой-то совершенно пустой фразой "главное, чтобы программист знал..."

Ну вот пусть программист и знает, что константы на куче размещать можно и нужно.

Это читерство и антипаттерны.

Если некий тип задуман как состоящий из константной (ключевой) и неконстантной частей, то лучше эти неконстантные части объявить как mutable.

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

const_cast, снимающий константность - это всегда звонкий колокол.

Плохая статья.

В ней просто названы несколько взятых наобум мусорных языков и показаны случайные примеры на них.

Что мы видим? Что это write-only языки, код на которых больно читать. И больше ничего не видим.

Какие идеи заложены в эти языки, помимо минимального синтаксиса и нечитаемости? Можете рассказать?

Давайте-ка я сделаю это за вас. Начну с "традиционных" вырвиглазок.

  1. Старый добрый брейнфак. Это - разновидность машины Тьюринга. (В которую добавили бесконечное количество состояний ячеек и откуда убрали goto).

  2. Unlambda. Комбинаторная логика на традиционном базисе SKI.

  3. Йот. Довели КЛ до абсурда-и-предела, базис из единственного комбинатора i.

  4. APL, J, K, Q. Это промышленные языки, которые работают с произвольными тензорами, а синтаксис упрощён в пользу тацитной (безымянной) нотации. Упор там сделан на очень быстрый парсер и очень быстрый интерпретатор.

  5. Лисп. Лямбда-исчисление, код-как-данные, сам себя интерпретатор.

  6. Форт. Стековая машина, ПОЛИЗ, и опять же сам себя интерпретатор.

А теперь посмотрим на то, что в статье.

  1. Malbolge. Просто упоротая машина Тьюринга. (Но не брейнфак).

  2. Whitespace. Брейнфакнутая версия форта.

  3. Chef. Коболизированная версия форта с множеством стеков.

  4. INTERCAL. Коболизированная версия бейсика.

  5. Коболизированная версия брейнфака.

Скушно! Просто потрахать мозг. Никакой красивой математической идеи за ними не стоит.

А ещё есть const_cast и его помощники - функции std::move и std::as_const.

Большое количество больших константных объектов в принципе не создают в статической памяти.

А если эти константы времени исполнения?

Например, строки. Например, содержимое конфиг-файла.

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

1 клетка принимает 3 состояния и влезает в 2 разряда.

2 клетки - 3^2 = 9 состояний, 4 разряда.

3 клетки - 3^3 = 27 состояний, 5 разрядов.

Это значит, мы можем построить функции

using table = unsigned short;  // 15 bit
using row = unsigned char;  // 5 bit
using cell = unsigned char;  // 2 bit

row encode_row(cell c0, cell c1, cell c2) {
  return c0 + (c1 + c1*2) + (c2 + c2*8);
  // на сдвигах, если хочется умножения экономить
}

const cell decode_row[27][3] = {
  {0,0,0},{1,0,0},{2,0,0},
  {0,1,0},...............,
  ...............,{2,2,2},
};
// что-то сходу лень думать, можно ли арифметическим колдовством
// обойтись без деления и при этом - без таблицы

В общем, дальше лень писать :)

Что будет быстрее работать, - деления или нудная работа с таблицами, - хз. Бенчмарки тоже лень писать.

В функции set_cell ошибка, там сигнатура должна быть `void set_cell(state* s, .....)`

Правда, динамические константные объекты можно отнести к большой экзотике, какой-нибудь полезный пример привести трудно.

Элементарно! Если объект достаточно велик, чтобы жить на стеке.

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

Интегральные схемы - это не совсем рассыпуха :))

У светодиодов нет инерции, надо бы её добавить - чтобы было какое-никакое послесвечение. Может быть, rc-цепочки на каждый столбец?

  • Кодировка UTF-16: он состоит из двух байтов (то есть 16 бит). Это означает что один символ весит 16 бит. В данную кодировку вмещается 2 ^ 16 = 65536 различных символов.

Ну вот нет. UTF-16 и UCS-2 - это разные кодировки. И та и другая используют двухбайтные слова, только у UCS-2 - на один символ ровно одно слово, поэтому она вмещает 65536 символов, а UTF-16 - это кодировка переменной длины! Почитайте про суррогатные пары самостоятельно, пожалуйста.

До кучи, ещё есть UTF-7.

Практический смысл разных UTF-n в том, что для ASCII (наиболее расхожий набор символов) UTF-8 кодируется 1 байтом, и для европейских алфавитов и всякой популярной графики UTF-16 кодируется одним словом (но китайцы уже страдают!), а UTF-32 хватит для всего UCS-4 - и вот это уже кодировка фиксированной длины.

Этак при желании можно ломануть и зеркало дистрибутива, и даже сам дистрибутив. Потом будет скандал, но это когда ещё будет...

Кроме того, сторонний софт на то и сторонний, что в дистрибутив не вошёл. И что теперь, исповедовать подход эппла, "чего нет в нашем апсторе, то вам и не нужно!"

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

А практика ставить недостающий софт (которого не положили в репу дистрибутива) из сторонних реп - это нормально. Репа производителя - куда уж официальнее-то?

И сырцы не панацея. Автор прекрасно может насрать в свои собственные сырцы - на гитхабе такие истории уже были.

Вы каждый пакет вычитываете и верифицируете? Вам делать больше нечего?

Вы ради браузера поднимаете докер? Ну вы-то, допустим, можете...

Осталось главной интригой - какие люди-Х и как инфицировали сайт FDM? Засланные казачки, или извне ломанули?

Information

Rating
3,313-th
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity