AxisPod: скорее наоборот, буду жалеть о потраченном времени на бессмысленные (для меня) развлечения, хотя мог бы развиваться, повышать свои профессиональные навыки и просто изучить столько всего интересного.
Я перфекционист, я постоянно стремлюсь к самосовершенствованию. К тому же программирование для меня - самое приятное занятие в жизни.
Вы упорно не желаете признавать, что люди могут быть разными, иметь разные ценности и приоритеты.
Don Kaban: между прочим, Гугл уже давно отказался от практики "20% времени на свои проекты", теперь там такого больше нет.
Скажите, на какой работе мне позволят писать компилятор своего языка, который при этом бесполезен фирме? Или изучать в своё удовольствие Rust, Haskell или даже Idris. Или разрабатывать свою игру, причём опять же без оглядки на рынок.
В этом и заключается прелесть личных проектов - я могу заниматься ими исключительно для своего удовольствия, делать только то, что мне нравится, не будучи скованным требованиями рынка.
AxisPod: лучший отдых - это смена вида деятельности. Согласен, смена Go на C++ и проекта сервера на проект компилятора - это не сильное изменение в деятельности, но всё же. Мозги отдыхают на ура. По крайней мере мои.
К тому же, у меня круг интересов ограничен лишь информационными вещами, тем, что приносит информацию. Любой иной вид отдыха будет мучить меня, так как будет дико скучен. Максимум, я могу вместо программирования паять или читать книгу.
Но я согласен, что спорт, например, необходим. Но для меня он как горькое лекарство - необходим, но неприятен. (Только мне - ничего не хочу сказать плохого про спорт в общем.)
В общем, все люди разные, имхо, не стоит всех под одну гребёнку.
Позвольте с вами не согласиться. Я вот не могу представить такую работу, с которой бы меня не посещало желание кодить что-то в выходные. Всегда есть какие-то свои проекты, идеи и прочее. Плюс, опять же самообучение - когда? На работе не всегда есть возможность и время на него, а нужно оно постоянно.
Вы уверены что хотели получить именно такой массив?
Да, я специально назвал вспомогательную функцию cons - по аналогии с Lisp. Фактически, она должна создавать не массивы из двух элементов, а так называемые точечные пары (терминология Lisp). Из них и строится список.
То есть это просто такой способ представления списков. Он удобен, в частности, для реализации самых типовых функций для работы со списками в функциональном программировании - head (взятие головы) и tail (взятие хвоста, т. е. всего, кроме головы) (в терминологии Lisp, соответственно, это CAR и CDR).
Хотя, если честно, конкретно у меня список строится немного не правильно. Во-первых, самая внутренняя пара должна иметь вид [число, NIL], где NIL - некий символ пустого списка. Во-вторых, канонический Lisp-список должен быть вида [1, [2, [3, [4, [5, NIL]]]]], а не то, что получилось. Так что да, над моей функцией ещё надо поработать.
По поводу той же суммы дам вам интересную идею на поиграться
Благодарю, но такой вариант я знаю, и он мне не подходит. Я именно поэтому и написал "Основные ограничения" в конце вопроса. Именно в их удовлетворении и была главная задача.
Ваше решение хранит состояние:
var sum = a;
И меняет его:
sum += b;
Т. о. это уже не чисто функциональный подход. А мне хотелось найти решение именно в терминах чистых лямбда функций арности 1.
Спасибо за наводку на BDD. Раньше уже слышал о ней, но как-то упустил, что это не просто ещё одно название, а хороший новый взгляд на тестирование. Почитал, очень понравилось.
Владимир: Уровень, который я хотел бы - миддл. И для него из неспецифичных знаний требуют как раз знание алгоритмов, структур данных и паттернов. И вопрос о том, каким образом их как раз изучать.
Или вы предлагаете выбрать конкретную область применения и вести личный проект именно в ней? Тут сложность в том, что я не хотел бы слишком привязываться к одной области. Вакансий на C++ и так не особо много. И все очень разношёрстные. Если выбрать только одну предметную область, то я сужу круг вакансий вообще до пары-тройки штук. Что сильно понизит шансы на устройство, да и просто маленький выбор - это плохо.
А по поводу гугла - на работе да, не запрещают. Но на собеседовании, если я не смогу написать без гугла базовые алгоритмы и структуры, меня никто не возьмёт миддлом.
А каким образом можно отобразить разнообразие оттенков, тонкости градиентов и т. п. текстом (в формате PPM)? Верно, просто записав байты (коды цветов пикселей) текстом.
Так что же мешает сделать точно так же для звуковых данных? Просто записать текстом последовательность байт в WAV. И все тембры, частоты и тональности полностью сохранятся.
Забыл уточнить. Я знаю про MusicXML, это не то. Мне нужны не ноты, а что-то вроде WAV в текстовом виде. Пусть с ограничениями на битность, на частоту дискретизации, на число каналов (только моно), но чтобы можно было записать любой звук.
Я умею пользоваться lex и yacc, хотя предпочитаю Boost.Spirit (не люблю дополнительные шаги сборки проекта, к тому же Boost.Spirit на C++).
Но при этом могу написать парсер с нуля, да. Считаю такой опыт необходимым тому, кто собирается профессионально заниматься компиляторами. Ведь генераторы парсеров часто не справляются с какой-нибудь сложной грамматикой. И многие компиляторы или интерпретаторы пишутся самостоятельно, без генераторов.
> (cons 1 2) => '(1 . 2)
Я знаю это. И что список определяется именно через точечные пары: список = NIL | "(", S-выражение, ".", список, ")".
Я же как раз хочу заменить точечные пары на список из двух элементов, и тогда (cons 1 2) => `(1 2), а список будет определяться как NIL | "(", S-выражение, {" ", S-выражение}, ")".
Вроде бы это ничего существенно не изменит с точки зрения использования языка. А парсинг существенно упростится.
> Обязательна возможность сравнения.
Верно, я включил функции сравнения в арифметические. И есть идея полностью отказаться от логического типа, а сделать как в C: 0 - это ложь, а 1 - истина. Ну и пустой список тоже ложь.
> Ну и наконец необходима возможность отличать список от атома.
А зачем? Я, честно говоря, не совсем понимаю области применения этой функции. Наверное в написании макросов она полезна, но у меня их не будет.
Не понял вашего совета. Clojure - мощный современный диалект LISP, расширяющий его в сравнении с классической версией. А мне нужно напротив, упростить язык.
Большое спасибо! Теперь понял свою ошибку - я почему-то считал, что после падения одного теста непременно нужно прекращать всё тестирование.
И потому не понимал, зачем в фреймворках есть разные типы ассертов - останавливающие тесты и не останавливающие. Теперь понятно - как раз для подобных случаев, когда нужно запомнить, что была ошибка, но проверять дальше.
И совет с разделением хороший - действительно, можно в крайнем случае разделить проект на разные библиотеки и тестировать их раздельно.
На части я тоже разделил бы, само собой. Тесты для Vector3D отдельно, тесты для Mesh отдельно. Выносить ли логику getBoundingBox() куда-то или нет, роли в данном случае не играет.
Потому что всё равно получается, что тесты для Mesh (или для того, куда я вынесу логику getBoundingBox()) должны запускаться после тестов для Vector3D, иначе при падении теста для Mesh будет не ясно - то ли проблема в методах Mesh, то ли в методах Vector3D, которые используются внутри.
И тест теряет свою информационную роль - указывать на место возникновения проблемы. Я допущу ошибку в методе Vector3D, а падать тест начнёт для Mesh, потому что вызывался раньше. И это совсем не хорошо.
По поводу АТД - вектор как раз не АТД, в нём нет абстракции и не должно быть по причинам производительности. Когда вершин в сцене миллион, даже лишний байт в структуре данных становится в итоге гигабайтом. А для таблицы виртуальных функций, хранимой по указателю, нужно минимум 4 байта.
Каким образом пишутся сами тесты я знаю. И с Google Testing Framework знаком. Проблема вовсе не в этом!
Проблема в том, что в вышеописанной ситуации при обычном описании тестов они будут зависеть от порядка из вызова, что считается плохой практикой (в том же gtest есть даже специальная опция для запуска тестов каждый раз в новом случайном порядке - чтобы гарантированно не привязываться к порядку тестов). А классический способ обхода этого - внедрение зависимости - тут не применимо. Вопрос был в том, как разрешить эту трудность.
AxisPod: скорее наоборот, буду жалеть о потраченном времени на бессмысленные (для меня) развлечения, хотя мог бы развиваться, повышать свои профессиональные навыки и просто изучить столько всего интересного.
Я перфекционист, я постоянно стремлюсь к самосовершенствованию. К тому же программирование для меня - самое приятное занятие в жизни.
Вы упорно не желаете признавать, что люди могут быть разными, иметь разные ценности и приоритеты.