Pull to refresh
221
Karma
6.6
Rating

Пользователь

В США по L-1: от первых собеседований до гринкарты

IT-emigration

Привет, Хабр.



Texas in July January


Периодически у тебя тут обсуждают иммиграцию в различные страны. Вспоминают и про Штаты: кто-то считает, что туда попасть очень легко, кто-то — что очень сложно. Я прошёл добрую часть этого пути (осталось только гражданство), так что, возможно, имеет смысл поделиться и своим опытом, и не только комментариями в обсуждениях, но и законченным и цельным текстом.


Да и вообще поделиться опытом хочется давно. Соответствующая статья уже успела поменять рабочее название с «пять лет тракторизма» на «шесть лет тракторизма», а затем и на «семь…», и, похоже, это не предел. Та статья действительно подробная, с описанием впечатлений, собеседований, поиска квартир, факапов, наблюдений и тому подобного. Однако воспринималка и ценности у всех разные, поэтому куда разумнее будет описать сухой опыт юридических аспектов переезда, возможно, упомянув связанные с релокацией бенефиты, а «N лет тракторизма» оставить на потом.


Под катом текста на примерно полчаса. Поехали?

Читать дальше →
Total votes 60: ↑58 and ↓2 +56
Views 21K
Comments 85

Следуй за денотацией

Programming *Mathematics *Functional Programming *
Translation


На самом деле ученые всегда стремятся к каким-то достижениям. Они думают только о том, удастся ли это им что-то совершить. И они почему-то никогда не задумываются — а стоит ли вообще совершать это «что-то»?
— Ян Малкольм, Парк Юрского Периода

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


Денотационный дизайн предназначен для формального описания этих предпочтений. Он позволяет посмотреть на эти интерфейсы и определить, являются ли они корректными.


Этот очерк — изложение прекрасной статьи Denotational design with type class morphisms от Conal Elliot.

Читать дальше →
Total votes 25: ↑25 and ↓0 +25
Views 5.6K
Comments 19

Разбираемся в рекурсии

Programming *Mathematics *Functional Programming *

Привет, Хабр.



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


Зачем это надо? Рекурсия — один из краеугольных камней ФП, а некоторые из функциональных языков (например, Idris или Agda) обладают достаточно мощной системой типов, чтобы использовать их для проверки доказательств. А чтобы проверенным доказательствам на самом деле можно было доверять, было бы неплохо, чтобы логическая система, которую представляет система типов языка, была консистентна — то есть, если упрощать, чтобы в ней нельзя было доказать ложь.


Один из главных источников неконсистентности — незавершающиеся вычисления (для примера см. КДПВ), поэтому вышеупомянутые языки очень стараются дать возможность убедиться, что вычисления завершаются — соответствующая их часть даже имеет отдельное название, «termination checker». Но, увы, по фундаментальным причинам у любой такой проверки всегда будут ложноположительные или ложноотрицательные срабатывания, поэтому приходится идти на компромиссы. В доказательствах лучше перебдеть, чем недобдеть, поэтому всегда есть завершимые функции, которые этими языками отвергаются. Однако, эти функции можно переписать так, чтобы termination checker был доволен, если можно доказать, что рекурсивный вызов всегда в каком-то смысле «меньше».


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

Читать дальше →
Total votes 73: ↑72 and ↓1 +71
Views 26K
Comments 92

Пора на свалку

Programming *C++ *IT career


Никогда не думал, что это случится со мной, но, похоже, я выгорел. А ещё мне стрёмно. Да, это ещё одна статья про выгорание.


Я тут на днях смотрел на свою RSS-читалку и заметил, что под тегом «C++» у меня где-то три сотни непрочитанных статей. Я не прочитал ни одной статьи по плюсам с прошлого лета, и мне офигенно. Я не написал ни строчки осмысленного кода на плюсах за последние три месяца, с тех пор, как распустили отдел, где я работал, и мне просто супер. Я позволил себе хотеть больше никогда не писать на плюсах, и у меня появились крылья.


Только стало страшно, потому что это давно уже стало куском моей самоидентификации. Я писал на плюсах лет 17, это почти две трети моей жизни, и как-то очень стрёмно всё это выкидывать. Всё моё сеньёрство-помидорство, львиная часть моего опыта — она там, в наступании на плюсограбли. Кто я без своего костюма?


Короче, да, я выгорел. И я не знаю, что делать дальше.

Читать дальше →
Total votes 397: ↑373 and ↓24 +349
Views 157K
Comments 1256

Радости и горести побед над C: делаем конфетку из прототипа wc на хаскеле

Programming *Haskell *Functional Programming *

Привет, Хабр.


Итак, в прошлый раз мы эмпирически доказали, что на хаскеле можно довольно легко написать этакий игрушечный wc, который при этом существенно быстрее реализации wc из GNU Coreutils. Понятное дело, что это не совсем честное сравнение: наша программа не умеет ничего, кроме подсчёта байт, строк и слов, тогда как настоящий wc куда мощнее: он имеет ещё несколько статистик, поддерживает опции, умеет читать из stdin… Короче, у нас действительно получилась всего лишь игрушка.


Сегодня мы это исправим. Наша главная цель — позволить пользователю выбирать конкретные статистики для подсчёта, при этом не считая то, что пользователю не нужно. А самое главное — мы будем стремиться к модульности, выделяя каждую статистику в отдельный изолированный юнит.


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



Основная функция С-версии не влезла на 4k-экран в портретной ориентации 4-м шрифтом.


Кроме этой модуляризации мы, среди прочего:


  • выразим идею, что некоторые статистики вроде подсчёта числа байт могут работать эффективнее на всём входе целиком, а другие должны смотреть на каждый байт;
  • реализуем ещё больше статистик, наслаждаясь возможностью рассуждать о каждой из них в отдельности (то, что называют local reasoning);
  • напишем немного тестов, наслаждаясь local reasoning'ом ещё раз;
  • испытаем некоторые почти зависимо типизированные техники, успешно получив корректно работающий, но феерически тормозящий код;
  • поиграем с Template Haskell;
  • полюбуемся (не)предсказуемостью и (не)воспроизводимостью производительности результирующего кода.
Читать дальше →
Total votes 39: ↑36 and ↓3 +33
Views 6.5K
Comments 34

Побеждая C двадцатью строками Haskell: пишем свой wc

Programming *Haskell *Functional Programming *

Привет, Хабр.


На днях Siemargl предложил мне перевести любопытную статью о победе над юниксовым wc при помощи хаскеля. Переводить её я, конечно же, не буду, и по нескольким причинам:


  • автор выжал из однопоточной версии далеко не всё, и однопоточная версия была существенно медленнее wc,
  • в той статье для победы потребовалось воспользоваться многопоточностью (что само по себе немного читерство и победа скорее над здравым смыслом, а не над wc),
  • для этого автору пришлось углубляться в трихомонады и моноиды — не, это отличная иллюстрация прелестей моноидального мышления, но ИМХО немного перебор для такой задачи, тем более, что из-за этого
  • код получился излишне объёмным,
  • да и вообще, соревноваться с wc, которая имеет кучу опций и фич, реализуя её ну очень игрушечный аналог, вообще как-то странно и даже немного глуповато.

Тем не менее, заниматься странными делами — дело хорошее, поэтому сегодня мы попробуем исправить первый из пунктов выше и улучшим результат Криса (так звать автора исходной статьи).


Опять же, как мы выяснили в прошлый раз, код на C я писать не умею, так что писать его и не буду, а в качестве конкурента хаскель-реализации у меня (как и у Криса) выступает сишный wc из GNU Coreutils. Те чуваки уж точно на C писать умеют, коду этому не один десяток лет, да и о производительности они позаботились, судя по таким кусочкам:


/* If the average line length in the block is >= 15, then use
   memchr for the next block, where system specific optimizations
   may outweigh function call overhead.
   FIXME: This line length was determined in 2015, on both
   x86_64 and ppc64, but it's worth re-evaluating in future with
   newer compilers, CPUs, or memchr() implementations etc.  */

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

Читать дальше →
Total votes 69: ↑61 and ↓8 +53
Views 17K
Comments 116

Стрелочка поворачивается: поговорим об обобщениях, или зачем программисту математика

Programming *Haskell *Functional Programming *

Привет, Хабр.


Прошло довольно много времени с публикации предыдущей статьи об обобщённой реализации паттерна Has, где мы успешно победили скуку и однообразный код при написании инстансов соответствующего класса, заодно поигравшись с дженериками и семействами типов одновременно, но давайте всё же добьём цикл и заодно лишний раз посмотрим, зачем программисту математика.


Итак, с обобщённой реализацией паттерна Has мы разобрались. Какой следующий интересный вопрос можно задать? Ну, например, можем ли мы обобщить наше решение, которое, к слову, является обобщением (Has Foo) обобщения (HasFoo) обобщения (MonadReader Foo) обобщения (Reader Foo) понятия параметра функции (Foo ->)? И, оказывается, что да, можем, и аж в двух ортогональных измерениях!


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

Читать дальше →
Total votes 21: ↑20 and ↓1 +19
Views 6.9K
Comments 2

Быстрее, чем C++; медленнее, чем PHP

Programming *Haskell *Functional Programming *

Привет, Хабр.


У меня тут случайно код на хаскеле получился быстрее аналогичного кода на C++. Иногда — на 40%.



(время работы, меньше — лучше, C++ снизу)


Что самое смешное — я собирал хаскель-код через LLVM-бекенд, но при этом сравнивал с GCC. Если сравнивать с clang (что вроде как логичнее), то всё становится ещё хуже для плюсов: почему-то на этой задаче clang проигрывает GCC в пару раз, и разница становится не 40%, а этак раза три. Впрочем, одна маленькая модификация C++-кода это поменяет.


Началось всё с того, что для одного моего проекта (который, естественно, делается на хаскеле, и о котором я тоже скоро напишу) нужно было быстро и эффективно считать расстояние Левенштейна между двумя строками. Расстояние Левенштейна — это такая метрика, которая говорит, сколько символов нужно удалить, добавить или заменить в одной строке, чтобы она стала равна другой строке. Я считал расстояния между довольно большими строками (масштаба десятков тысяч символов), поэтому эффективность была действительно важна.


А потом мне стало интересно, насколько быстро я вообще могу это расстояние считать (потратив разумное время на оптимизацию, конечно), так что я набросал вариант на С++ и взял его время работы за этакий идеал, к которому стоит стремиться. Впрочем, как уже понятно, идеал оказался превзойдён.


Посмотрим, как этого можно достичь?



В качестве бонуса — сравнение с некоторыми другими языками. Спойлеры:


  • Nim медленнее компилятора C двадцатилетней давности.
  • C# в пять раз медленнее Java, которая оказывается вполне на уровне Rust.
  • Go вровень с C.
  • PHP быстрее питона (что оправдывает вторую часть заголовка).
Читать дальше →
Total votes 133: ↑109 and ↓24 +85
Views 50K
Comments 415

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

Programming *C++ *

Привет, Хабр.


Пару дней назад мне на глаза попался вот этот твит:



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


Давайте разбираться, благо это будет недолго (по тексту Стандарта я прыгал не больше пары часов). И весело, ссылки на Стандарт — это всегда весело.

Total votes 169: ↑165 and ↓4 +161
Views 77K
Comments 543

Can I haz? Ударим программированием на типах по дженерикам

Programming *Functional Programming *

Привет, Хабр.


В прошлый раз мы описали Has-паттерн, обрисовали проблемы, которые он решает, и написали несколько конкретных инстансов:


instance HasDbConfig AppConfig where
  getDbConfig = dbConfig
instance HasWebServerConfig AppConfig where
  getWebServerConfig = webServerConfig
instance HasCronConfig AppConfig where
  getCronConfig = cronConfig

Выглядит неплохо. Какие тут могут возникнуть сложности?


image


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


instance HasDbConfig DbConfig where
  getDbConfig = id

Они позволяют нам легко писать отдельные тесты или вспомогательные утилиты, не зависящие от всего AppConfig.


Это уже скучновато, но таки продолжим. Легко представить, что некоторые интеграционные тесты проверяют взаимодействие какой-то пары модулей, и мы всё ещё не хотим зависеть от конфигурации всего приложения целиком, так что теперь нам надо написать шесть инстансов (по два на тип), каждый из которых будет сводиться к fst или snd. Например, для DbConfig:


instance HasDbConfig (DbConfig, b) where
  getDbConfig = fst
instance HasDbConfig (a, DbConfig) where
  getDbConfig = snd

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


Если интересно, как решить эту задачу в общем виде, причём тут зависимые типы, и как всё это в итоге будет выглядеть на хаскеле — велкам под кат.

Читать дальше →
Total votes 20: ↑18 and ↓2 +16
Views 4.6K
Comments 7

Can I haz? Рассматриваем ФП-паттерн Has

Programming *Functional Programming *

Привет, Хабр.


Сегодня мы рассмотрим такой ФП-паттерн, как Has-класс. Это довольно любопытная штука по нескольким причинам: во-первых, мы лишний раз убедимся, что паттерны в ФП таки есть. Во-вторых, оказывается, что реализацию этого паттерна можно поручить машине, что вылилось в довольно любопытный трюк с тайпклассами (и библиотеку на Hackage), который лишний раз демонстрирует практическую полезность расширений системы типов вне Haskell 2010 и ИМХО куда интереснее самого этого паттерна. В-третьих, повод для котиков.


image


Однако начать, пожалуй, стоит всё же с описания того, что же такое Has-класс, тем более, что какого-то краткого (и, тем более, русскоязычного) описания сходу не нашлось.


Итак, как в хаскеле решается проблема управления некоторым глобальным окружением, доступным только для чтения, которое необходимо нескольким различным функциям? Как, например, выражается глобальная конфигурация приложения?

Читать дальше →
Total votes 33: ↑31 and ↓2 +29
Views 5.4K
Comments 3

Тесты или типы

Programming *Functional Programming *
Translation

Привет, Хабр. На днях я искал, как сделать что-то в Idris, и наткнулся на неплохой пост, вольный перевод которого выглядит вполне уместным. Вольности и отсебятину, где необходимо, я буду обозначать ⟦вот такими закорючками в начале и в конце⟧.


Когда стоит использовать тесты, а когда — типы? Какую информацию и какие гарантии мы получаем в обмен на наши усилия по их написанию?


Мы рассмотрим простой и немного надуманный пример, выраженный на Python, C, Haskell и Idris. Мы также увидим, что можно сказать о реализации без каких-либо дополнительных знаний о ней, в каждом из случаев.


Мы не будем учитывать разнообразные чёрные ходы, позволяющие явно нарушать гарантии языка (например, расширения C, unsafePerformIO в Haskell, небезопасные приведения типов), иначе нельзя было бы сделать вообще никаких выводов, и этот пост получился бы довольно коротким. ⟦Кроме того, у того же хаскеля есть подмножество Safe Haskell, явно и транзитивно запрещающее использование этих и ряда других трюков, могущих нарушить целостность языка.⟧

Читать дальше →
Total votes 52: ↑51 and ↓1 +50
Views 7.6K
Comments 12

О новых стандартах C++

Programming *C++ *

Сегодня у меня довольно короткий пост. Я бы его и не писал, наверное, но на Хабре в комментах довольно часто можно встретить мнение, что плюсы становятся хуже, комитет делает непонятно что непонятно зачем, и вообще верните мне мой 2007-й. А тут такой наглядный пример вдруг попался.


Почти ровно пять лет назад я писал о том, как на C++ сделать каррирование. Ну, чтобы если можно написать foo(bar, baz, quux), то можно было бы писать и Curry(foo)(bar)(baz)(quux). Тогда C++14 только вышел и еле-еле поддерживался компиляторами, так что код использовал только C++11-фишки (плюс пара костылей для симуляции библиотечных функций из C++14).


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


Посмотрим?

Читать дальше →
Total votes 45: ↑39 and ↓6 +33
Views 17K
Comments 47

Как развернуть односвязный список на собеседовании

Abnormal programming *Programming *Functional Programming *

Привет, Хабр.


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


image

Читать дальше →
Total votes 208: ↑186 and ↓22 +164
Views 94K
Comments 475

Статически безопасная динамическая типизация à la Python

Programming *Haskell *Functional Programming *

Привет, Хабр.


На днях в одном моём хобби-проекте возникла задача написания хранилища метрик.


Задача сама по себе решается очень просто, но моя проблема с хаскелем (особенно в проектах для собственного развлечения) в том, что невозможно просто взять и решить задачу. Необходимо решить, расширить, абстрагировать, абстрагировать и потом ещё расширить. Поэтому захотелось сделать хранилище метрик расширяемым, чтобы не указывать заранее, какие они там будут. Само по себе это тема для отдельной статьи, а сегодня мы рассмотрим один маленький ингредиент: написание типобезопасной обёртки для неизвестных заранее типов. Что-то вроде динамической типизации, но со статическими гарантиями, что мы не сделаем ерунды.


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

Читать дальше →
Total votes 25: ↑24 and ↓1 +23
Views 4K
Comments 9

Этот ваш хаскель (не) только для факториалов и годен

Programming *Haskell *Functional Programming *

Когда речь заходит о любимых языках, я обычно говорю, что при прочих равных предпочитаю C++ для числодробилок и хаскель для всего остального. Полезно периодически проверять, насколько такое деление обосновано, а тут ещё недавно возник один праздный и очень простой вопрос: как себя будет вести сумма всех делителей числа с ростом этого самого числа, скажем, для первого миллиарда чисел. Эту задачу просто запрогать (аж стыдно называть получившееся числодробилкой), так что она выглядит как отличный вариант для такой проверки.


Кроме того, я всё ещё не владею навыком точного предсказания производительности хаскель-кода, так что полезно пробовать заведомо плохие подходы, чтобы посмотреть, как будет деградировать производительность.


Ну и вдобавок можно легонько выпендриться более эффективным алгоритмом, чем лобовой поиск делителей для каждого числа от $1$ до $n$.

Читать дальше →
Total votes 56: ↑52 and ↓4 +48
Views 15K
Comments 144

Как сделать ещё больше некорректных состояний ещё более невыразимыми

Haskell *Functional Programming *

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

Читать дальше →
Total votes 28: ↑28 and ↓0 +28
Views 4.8K
Comments 14

Вышел GHC 8.2

Haskell *
Вышла новая версия де-факто стандартного компилятора Haskell — GHC 8.2.1! Этот релиз является скорее итеративным улучшением, но вместе с тем имеет и ряд новых интересных фич, относящихся к удобству написания кода, выразительности языка и производительности скомпилированных программ. Рассмотрим же наиболее интересные, на мой взгляд, изменения!
Читать дальше →
Total votes 31: ↑30 and ↓1 +29
Views 4.6K
Comments 1

Передаем указатели на функции-члены в C API

C++ *
Энное время назад в одной XMPP-комнате, посвященной C++, один посетитель спросил, нет ли какого способа в современных плюсах без лишнего кода передать указатель на функцию-член класса в качестве коллбека в C API. Ну, что-то вроде:

// C API
void doWithCallback (void (*fn) (int, void*), void *userdata);

// C++ code
struct Foo
{
    void doFoo (int param);
};

int main ()
{
    Foo foo;
    doWithCallback (MAGIC (/* &Foo::doFoo */), &foo);
}

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

В этом посте мы попробуем (и, что характерно, у нас это получится) написать универсальную обёртку, а заодно посмотрим, как кое-какая фишка из C++17 поможет нам ещё сократить количество избыточного кода. Никаких крышесносных шаблонов здесь не будет, решение, на мой взгляд, достаточно тривиально, но, пожалуй, им всё равно имеет смысл поделиться (и заодно лишний раз попиарить новые возможности C++17).
Читать дальше →
Total votes 25: ↑23 and ↓2 +21
Views 13K
Comments 33

Аналитическое вычисление производных на шаблонах C++

Abnormal programming *C++ *
Тут на днях писали про аналитическое нахождение производных, что напомнило мне об одной моей маленькой библиотечке на C++, которая делает почти то же, но во время компиляции.


В чём профит? Ответ прост: мне нужно было запрогать нахождение минимума достаточно сложной функции, считать производные этой функции по её параметрам ручкой на бумажке было лень, проверять потом, что я не опечатался при написании кода, и поддерживать этот самый код — лень вдвойне, поэтому было решено написать штуковину, которая это сделает за меня. Ну, чтобы в коде можно было написать что-то такое:

using Formula_t = decltype (k * (_1 - r0) / (_1 + r0) * (g0 / (alpha0 - logr0 / Num<300>) - _1));    // сама формула
const auto residual = Formula_t::Eval (datapoint) - knownValue;    // регрессионный остаток

// производные по параметрам:
const auto dg0 = VarDerivative_t<Formula_t, decltype (g0)>::Eval (datapoint);
const auto dalpha0 = VarDerivative_t<Formula_t, decltype (alpha0)>::Eval (datapoint);
const auto dk = VarDerivative_t<Formula_t, decltype (k)>::Eval (datapoint);

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

Ещё неплохо быть достаточно уверенным, что компилятор это соптимизирует так, как если бы соответствующие производные и функции были написаны руками. А уверенным быть бы хотелось — находить минимум нужно было очень много раз (действительно много, где-то от сотни миллионов до миллиарда, в этом была суть некоего вычислительного эксперимента), поэтому вычисление производных было бы бутылочным горлышком, происходи оно во время выполнения через какую-нибудь рекурсию по древообразной структуре. Если же заставить компилятор вычислять производную, собственно, во время компиляции, то есть шанс, что он по получившемуся коду ещё пройдётся оптимизатором, и мы не потеряем по сравнению с ручным выписыванием всех производных. Шанс реализовался, кстати.

Под катом — небольшое описание, как оно там всё работает.
Читать дальше →
Total votes 80: ↑77 and ↓3 +74
Views 21K
Comments 28
1

Information

Rating
591-st
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity