Инструментом надо уметь пользоваться. И уметь пользоваться хорошо, в противном случае преимуществ сам язык не даст никаких. Даст преимущества лежащая под ним платформа, написанные на нём библиотеки, whatever (что, конечно, тоже крайне важно), но не язык.
я спросил что _прирнципиально_ там отличного
Я же написал: ленивость, чистота, мощная система типов. Т.е., собственно, отличается всем, потому что это основы языка. Строгие нечистые языки с [почти] одинаковой системой типов как раз ничем и не отличаются принципиально: Java, C#.
С continuation в scheme можно за день разобраться, а где их использовать? Это всё равно новые знания, которые ещё надо научиться применять.
В неделю обучения C++ входят шаблонные шаблонные параметры, надеюсь? Человек после C и недели обучения факториал напишет на системе типов?
Ну это как показатель хорошего понимания. Иначе — это Си с классами, ну и дай бог шаблонными контейнерами.
Haskell чистый и ленивый язык программирования. Там вполне в порядке вещей бесконечные структуры данных, к которым вряд ли человек привык в других языках. Надо задачу решать по-другому, чтобы воспользоваться этим. Сайд-эффекты надо отделять, потому что, к примеру, функция sort принципиально не может выводить на консоль, ну и так далее. Чтобы хорошо его понимать, желательно знать хотя бы о функторах (не из Си++, а из теории категорий), монадах, стрелках.
Т.е. писать на нём как на Си, везде впихивая IO (обозначающий, что может быть осуществлён ввод-вывод, это не ключевое слово, это одна из монад) и не пользуясь преимуществами лени, — возможно и получится, но это не умение писать на Haskell.
Agda2 ещё хлеще, так как это вообще «доказатель теорем», но там система типов ещё мощнее, чем на Хаскеле, — dependent types.
То, что zipper для F(X) есть X × F'(X) берётся без доказательства, т.е. это не вывод на основе списка, ибо производную я взял уже позже. Это просто бездоказательное утверждение в данном контексте.
h(x) я ввёл, чтобы вынести f(x) за пределы определения, а то, что h(x) оказалось списком — это счастливая случайность :)
Насчёт f(x) всё именно так
f(x) = 1 + x + x*x + x*x*x + x*x*x*x +…
Но ведь так и есть, список — это или пустой, или один элемент, или два, или… и так до бесконечности. f(1) не является конечным числом, но это и понятно, так как возможных списков явно не конечное число даже для типа с одним элементом. А вот f(0) = 1, т.е. для типа без элементов список может быть только пустым.
Жаль, уходить надо, исправлять придётся вечером.
1. Ну на практике я его и сам не использовал, разве что Вы просто о примере в виде кода, как пройтись туда-обратно и поменять пару значений. Следует добавить, согласен.
2. Спасибо, не обратил внимания даже при нескольких перечитываниях, исправлю.
3. Даже дифференциальное кольцо. Возможно, стоит упомянуть, но я не ставил целью математическую точность, так как сам не обладаю достаточными знаниями, а, упоминая о кольцах, рискую нарваться на сложные вопросы :)
Порядок вычисления аргументов в функциях неопределён, поэтому в принципе возможна ситуация, когда оба new выполнятся до конструкции соответствующих им auto_ptr и при бросании исключения вторым из них, память после первого уже не освободится.
Случай описан у Саттера, но не помню в какой именно книге.
RAII этому не мешает.
В статье эта техника и описана, но только с частным случаем — умными указателями. Точно так же можно работать с любыми ресурсами, которые надо гарантированно освободить.
>Вы не проверяете quizFile на null перед его использованием, вы уверены, что память выделится в 100% случаев?
Опять же, если реализации соответствуют стандарту, то память либо выделится, либо вылетит std::bad_alloc
Поэтому я поменял как раз на такой, чтобы зайти.
И посыпаю голову пеплом
Я же написал: ленивость, чистота, мощная система типов. Т.е., собственно, отличается всем, потому что это основы языка. Строгие нечистые языки с [почти] одинаковой системой типов как раз ничем и не отличаются принципиально: Java, C#.
С continuation в scheme можно за день разобраться, а где их использовать? Это всё равно новые знания, которые ещё надо научиться применять.
Ну это как показатель хорошего понимания. Иначе — это Си с классами, ну и дай бог шаблонными контейнерами.
Haskell чистый и ленивый язык программирования. Там вполне в порядке вещей бесконечные структуры данных, к которым вряд ли человек привык в других языках. Надо задачу решать по-другому, чтобы воспользоваться этим. Сайд-эффекты надо отделять, потому что, к примеру, функция sort принципиально не может выводить на консоль, ну и так далее. Чтобы хорошо его понимать, желательно знать хотя бы о функторах (не из Си++, а из теории категорий), монадах, стрелках.
Т.е. писать на нём как на Си, везде впихивая IO (обозначающий, что может быть осуществлён ввод-вывод, это не ключевое слово, это одна из монад) и не пользуясь преимуществами лени, — возможно и получится, но это не умение писать на Haskell.
Agda2 ещё хлеще, так как это вообще «доказатель теорем», но там система типов ещё мощнее, чем на Хаскеле, — dependent types.
А так назову Haskell, Agda2.
Про теорию категорий что-либо слышали?
Это же к слову о «любой язык учится за неделю». На основе каких языков вывод сделан?
Насчёт f(x) всё именно так
f(x) = 1 + x + x*x + x*x*x + x*x*x*x +…
Но ведь так и есть, список — это или пустой, или один элемент, или два, или… и так до бесконечности. f(1) не является конечным числом, но это и понятно, так как возможных списков явно не конечное число даже для типа с одним элементом. А вот f(0) = 1, т.е. для типа без элементов список может быть только пустым.
1. Ну на практике я его и сам не использовал, разве что Вы просто о примере в виде кода, как пройтись туда-обратно и поменять пару значений. Следует добавить, согласен.
2. Спасибо, не обратил внимания даже при нескольких перечитываниях, исправлю.
3. Даже дифференциальное кольцо. Возможно, стоит упомянуть, но я не ставил целью математическую точность, так как сам не обладаю достаточными знаниями, а, упоминая о кольцах, рискую нарваться на сложные вопросы :)
Случай описан у Саттера, но не помню в какой именно книге.
—?
— Ну прибор-то имеется
foo(auto_ptr<T>(new T), auto_ptr<T>(new T));В статье эта техника и описана, но только с частным случаем — умными указателями. Точно так же можно работать с любыми ресурсами, которые надо гарантированно освободить.
Опять же, если реализации соответствуют стандарту, то память либо выделится, либо вылетит std::bad_alloc