Дело в том, что этот алгоритм нельзя увидеть, если ваше мышление сосредоточено на коде, на типах, исключениях, циклах while и прочем, а не на математических свойствах чисел.
Ну не совсем так. В языках с достаточно развитой системой типов, типы и их ограничения специфицируют поведение программы (то есть алгоритм). Да, к этому примешиваются и детали реализации (вроде спецификации поведения при переполнении), но особенности целевой платформы тоже имеют значение, а значит должны быть отражены в спецификации.
Спасибо! Вы озвучили и мои мысли тоже относительно этого фильма. Как ни странно, на Хабре оказалась самая трезвая аудитория, в сравнении с другими ресурсами, где также обсуждается "Чернобыль".
Дело в том, что типы (по крайней мере в Rust) — это объекты времени компиляции. Тут нужен способ некоего "структурного запоминания", если таковой возможен.
В Rust по идее можно развить функционал ассоциированных типов для достижения нечто подобного. Собственно, первый вариант "замыкания" пытался их использовать, но ограничения системы типов текущего Rust не позволили.
значит ли данное ограничение, что составить дерево из произвольного количества компонент на основе, например, пользовательского input'а с таким подходом будет невозможно?
Можно даже кастить функциональные указатели напрямую. Они одного размера, так что по идее с этим не должно быть проблем, хотя я на 100% не уверен в безопасности такого кода.
Ну, 'static-типы — это такие типы, определение которых не содержит ссылок или содержит только статические ссылки (с лайфтаймом 'static). Да, это касается только лайфтаймов, никаких ограничений на задание самих значений полей нет.
В простейшем случае добавляется по одному полю-указателю на каждый метод, который должен оперировать "захваченным" типом. Но можно сделать и по-другому, например, так:
возможно этой логикой должен обладать какой-то другой класс/объект/модуль
Конечно, можно использовать аггрегацию. И в Rust, где нет наследования, так в основном и делают. Но часто при этом еще возникает необходимость пробрасывать вызовы методов. Вручную писать такое — это бойлерплейт, поэтому в Rust ведется работа по добавлению в язык делегатов.
Иначе обстоит дело в ООП языках. Там есть соблазн просто унаследоваться. И так делают достаточно часто — используют наследование именно для расширения, а о том, что при этом еще и полиморфизм подтипов начинает работать, не думают. Иногда это приводит к проблемам.
Square даже по определению подтипом Rectangle не является
И почему это? Квадрат — частный случай прямоугольника. То есть там, где мы ожидаем прямоугольник, всегда должно быть можно подставить квадрат. Вы с этим спорите?
Наследование удобно использовать для синтаксического расширения существующего класса: когда потомок имеет те же поля и методы, что и предок + свои. Далеко не всегда желательно, чтобы при этом потомок был подтипом предка. И наоборот, часто для образования подтипа приходится использовать наследование и тянуть в потомка все содержимое предка, хотя это и не нужно.
Вот вам пример для иллюстрации проблемы: есть класс Rectangle и Square. Ясно, что Square должен быть подтипом Rectangle, но наследование реализации при этом не желательно. Эффективная реализация Square должна хранить только поле a, вместо двух полей a и b, которые она получила бы в наследство от Rectangle.
Это вряд ли. Проблема ООП (в том виде как оно реализовано в мейнстримовых языках) как минимум в том, что в нем смешивается наследование с образованием подтипов.
Ну, через текст статьи уже проступает некоторая "ржавчина" ) В Rust нет ООП (в смысле наследования данных и образования подтипов с помощью наследования), нет культуры обязательного наличия геттеров/сеттеров, уровень доступа к полям можно ограничивать видимостью в модуле и т.п. Rust снимает большинство претензий автора.
Можете предоставить ссылку на то, что стандарт utf16 как-то ограничивает значение второго числа из пары.
10 разряд обоих слов пары используется для указания признака лидирующего или последующего слова. А пять старших разрядов у обоих слов должны содержать 11011. Так что для кодирования символа в паре используется только 20 разрядов:
Насколько я знаю utf-16 поддерживает суррогатные пары (если лидирующее слово содержит 11011 в старших разрядах). При этом последующее слово обязательно должно содержать 110111 в старших разрядах. Если это не так, то последовательность невалидна.
В языках типа C/C++ или Rust используется ручное управление памятью, поэтому программисты тратят больше времени на написание кода, управление временем жизни объектов, а затем на отладку.
Вообще-то в Rust автоматическое управление памятью и за соответствием времен жизни ссылок и объектов следит компилятор.
Для определения того, какой из двух данных цветов светлее, это и не важно )
Ну не совсем так. В языках с достаточно развитой системой типов, типы и их ограничения специфицируют поведение программы (то есть алгоритм). Да, к этому примешиваются и детали реализации (вроде спецификации поведения при переполнении), но особенности целевой платформы тоже имеют значение, а значит должны быть отражены в спецификации.
Надо было
Gray50
,Gray66
иGray75
назвать, тогда проблемы бы не было :)Эмм… Это в какой, не подскажете? )
Спасибо! Вы озвучили и мои мысли тоже относительно этого фильма. Как ни странно, на Хабре оказалась самая трезвая аудитория, в сравнении с другими ресурсами, где также обсуждается "Чернобыль".
Дело в том, что типы (по крайней мере в Rust) — это объекты времени компиляции. Тут нужен способ некоего "структурного запоминания", если таковой возможен.
В Rust по идее можно развить функционал ассоциированных типов для достижения нечто подобного. Собственно, первый вариант "замыкания" пытался их использовать, но ограничения системы типов текущего Rust не позволили.
На первые вопросы ответил ниже
Нет, не значит )
Вариант с вектором методов:
Запустить
Можно даже кастить функциональные указатели напрямую. Они одного размера, так что по идее с этим не должно быть проблем, хотя я на 100% не уверен в безопасности такого кода.
Ну,
'static
-типы — это такие типы, определение которых не содержит ссылок или содержит только статические ссылки (с лайфтаймом'static
). Да, это касается только лайфтаймов, никаких ограничений на задание самих значений полей нет.В простейшем случае добавляется по одному полю-указателю на каждый метод, который должен оперировать "захваченным" типом. Но можно сделать и по-другому, например, так:
Запустить
У личного домика с двориком — тоже много преимуществ. Но попробуйте-ка заведите себе такой не в деревне, а в крупном городе, поближе к центру.
Так значит все-таки будет коммунизм?
0xDC00 = 1101110000000000
0xDFFF = 1101111111111111
Конечно, можно использовать аггрегацию. И в Rust, где нет наследования, так в основном и делают. Но часто при этом еще возникает необходимость пробрасывать вызовы методов. Вручную писать такое — это бойлерплейт, поэтому в Rust ведется работа по добавлению в язык делегатов.
Иначе обстоит дело в ООП языках. Там есть соблазн просто унаследоваться. И так делают достаточно часто — используют наследование именно для расширения, а о том, что при этом еще и полиморфизм подтипов начинает работать, не думают. Иногда это приводит к проблемам.
И почему это? Квадрат — частный случай прямоугольника. То есть там, где мы ожидаем прямоугольник, всегда должно быть можно подставить квадрат. Вы с этим спорите?
Наследование и полиморфизм подтипов
Наследование удобно использовать для синтаксического расширения существующего класса: когда потомок имеет те же поля и методы, что и предок + свои. Далеко не всегда желательно, чтобы при этом потомок был подтипом предка. И наоборот, часто для образования подтипа приходится использовать наследование и тянуть в потомка все содержимое предка, хотя это и не нужно.
Вот вам пример для иллюстрации проблемы: есть класс
Rectangle
иSquare
. Ясно, чтоSquare
должен быть подтипомRectangle
, но наследование реализации при этом не желательно. Эффективная реализацияSquare
должна хранить только полеa
, вместо двух полейa
иb
, которые она получила бы в наследство отRectangle
.Это вряд ли. Проблема ООП (в том виде как оно реализовано в мейнстримовых языках) как минимум в том, что в нем смешивается наследование с образованием подтипов.
Ну, через текст статьи уже проступает некоторая "ржавчина" ) В Rust нет ООП (в смысле наследования данных и образования подтипов с помощью наследования), нет культуры обязательного наличия геттеров/сеттеров, уровень доступа к полям можно ограничивать видимостью в модуле и т.п. Rust снимает большинство претензий автора.
10 разряд обоих слов пары используется для указания признака лидирующего или последующего слова. А пять старших разрядов у обоих слов должны содержать 11011. Так что для кодирования символа в паре используется только 20 разрядов:
UTF-16, an encoding of ISO 10646 — 2.1 Encoding UTF-16
Насколько я знаю utf-16 поддерживает суррогатные пары (если лидирующее слово содержит 11011 в старших разрядах). При этом последующее слово обязательно должно содержать 110111 в старших разрядах. Если это не так, то последовательность невалидна.
Вообще-то в Rust автоматическое управление памятью и за соответствием времен жизни ссылок и объектов следит компилятор.