Ещё замечание: except Exception: таки считается более культурным вариантом, чем просто except:, потому что системные исключения наследуются не от Exception, и программу как раз-таки можно завершить без kill -9.
А какие бы возникли вопросы? Вот в Julia значения по умолчанию вычисляются в момент вызова функции, и там это ни у кого проблем не вызывает. Бонусом это даёт возможность ссылаться в значении по умолчанию на предыдущие аргументы. Наоборот, предостережения видел только в руководствах по Python и по Common Lisp. Причём в Lisp это относится только к литералам типа '(1 2), т.к. они по стандарту могут быть вычислены однократно при определении функции, вместо этого рекомендуется значения по умолчанию просто задавать как (list 1 2), тогда они гарантированно вычисляются в момент вызова.
А оно с bar=1 одинаковое, вот с bar=[] будет разное. Вообще согласен, непонятно, зачем в Python 3 не сделали интерпретацию аргументов по умолчанию как выражений и не сделали нормальные области видимости, коль уж всё равно с Python 2 обратную совместимость сломали.
Насколько я помню, магнитное поле проистекает из электрического только если постулировать отсутствие магнитных зарядов. Тогда уравнения Максвелла становятся асимметричны, и действительно, магнитное поле может порождаться только электрическими зарядами. А если найдётся магнитный заряд, то уравнения Максвелла будут полностью симметричны относительно электрического и магнитного полей, и даже можно электрическое поле считать релятивистской поправкой к магнитному в отсутствие электрических зарядов.
Ещё вроде как есть поддержка работы с зависимостями в рамках блокнота, но в статье вопрос не раскрыли.
Вот меня тоже удивило, что не раскрыто, это же второе главное преимущество перед юпитером, на мой взгляд. Я бы ещё сказал, преимущество не только в воспроизводимости, а ещё в отвязывании окружения блокнота от окружения установки marimo.
Сорри за некропост. Вообще, что там как выделяется - в джулии не специфицируется. Если есть константная структура - на неё тоже может не аллоцироваться память. constant folding и всё такое. Так-то даже банальное x.attribute - это в джулии синтаксический сахар для getproperty(x, "attribute"). Но никакая строка там, конечно, не передаётся в явном виде, компилятор видит, что это константа времени компиляции, и преобразует её в статический байтовый сдвиг относительно адреса структуры в памяти. Гарантируется только то, что неизменяемые структуры в массивах и в полях других структур хранятся "in-line", т.е. массив N структур размером c sizeof(T) = s будет занимать N * s байт. Изменяемые же в массив или в поле другой структуры кладутся всегда по ссылке, потому что семантика требует отдельного времени жизни для внешнего и внутреннего объекта. При этом изменяемая структура тоже может выделяться на стеке, если компилятор сможет доказать, что у неё время жизни ограничено конкретной областью видимости.
Вроде как, обычно "Космос" - это то, что оставалось на околоземной орбите. Смею предположить, что если аппарат ушёл с околоземной орбиты, то уже бессмысленно было скрывать истинную цель запуска, т.к. иностранные астрономы уже могли отследить и рассчитать траекторию.
Не только для удобства чтения. Функция, в частности, локализует контекст. Отдельные функции проще при необходимости отрефакторить с гарантией, что остальная часть общей функции не затронется. Насчёт дополнительных накладных расходов - бывает по-всякому. И компилятор заинлайнить может, и кэш инструкций может освободиться, если обработку какого-то редкого условия в функцию вынести.
Нет сам интерпретатор не может решить проблему, т.к. это на уровне правил языка - если где-то указывается тип, то он должен быть либо параметром, либо определён выше.
за счет вращения Земли получаются даровые 0,3 км/с, а чтобы вывести на полярную, сначала вы должны их наоборот погасить, а потом доложить столько же своих в другую сторону
Вот эти даровые 0,3 км/с и нужно закрыть. Ракета же не будет запускаться сперва строго на запад с погашением вращения Земли, потом разворачиваться на полярную орбиту. Нужна величина векторной суммы 7,8 км/с на наклонении 97° и 0,3 км/с на запад в сравнении с векторной суммой 7,8 км/с на восток и 0,3 км/с на запад.
Так и не пойму, можно ли трюк Норвига с заменой `(symbol-function fn-name)` провернуть где-то кроме CL и основанных на нём вариантов. При наличии исходного текста функции макрос выглядит как более переносимое решение всё-таки, да. Хотя по сути это точно функция - отображение входного аргумента в возвращаемое значение.
У Норвига в PAIP сделано функциями. Там как-то проще, чем через макросы, в том смысле, что о просачивании символов в другую область видимости не надо заботиться.
(defun memo (fn name key test)
"Return a memo-function of fn"
(let ((table (make-hash-table :test test)))
(setf (get name 'memo) table)
#'(lambda (&rest args)
(let ((k (funcall key args)))
(multiple-value-bind (val found-p)
(gethash k table)
(if found-p
val
(setf (gethash k table) (apply fn args))))))))
(defun memoize (fn-name &key (key #'first) (test #'eql))
"Replace fn-name's global definition with a memoized version"
(setf (symbol-function fn-name)
(memo (symbol-function fn-name) fn-name key test)))
У макроса есть какое-то существенное преимущество?
Как я понимаю, getd - это функция из HomeLisp'а, которая возвращает исходный код функции? В Common Lisp такого нет, вроде бы.
В 1945 году, в одном из лучших совхозов Омской области «Лесном», с площади посевов озимой пшеницы в 91 га, посеянной по всем правилам, рекомендованным акад. Лысенко, собрали всего 6 ц, зерна, то есть в среднем по 7 кг с гектара... Наконец, в прошлом 1946 году, в том же Сибирском научно-исследовательском институте, которым руководит акад. Лысенко, из 150 [га] стерневых посевов было запахано 112 га, так как на них родился один бурьян.
Функция x*ln(x) около нуля ведёт себя вроде бы нормально, в бесконечности не уходит.
Не уходит, но у неё, как и у квадратного корня, в нуле экстремум с бесконечной производной, поэтому нужно как-то делать, чтобы оптимизация в область притяжения этого экстремума не заходила.
если f(x) дважды дифференцируема, то липшицева непрерывность гарантируется.
Если всюду дважды дифференцируема — возможно, да. А так есть, например, квадратный корень, который в окрестности нуля не липшиц-непрерывен. У меня вот лично в решаемой задаче появляется функция, которая около нуля ведёт себя как x ln(x) — если туда минимизатор залез, то уже не вылезает.
Недавно ещё узнал, что есть немонотонный поиск по направлению, где условия Вульфа выполняются только "в среднем за n итераций", что может для CG или L-BFGS ускорить сходимость (спрямляет путь через кривые овраги).
Автор вот пишет, что посмотрел Scratch — и решил, что Basic лучше.
Я тоже не понимаю, почему — там и набор спрайтов из коробки, и игры кто-то на нём вполне пишет.
Подозреваю, это собственный синдром утёнка у автора, а ребёнка, очевидно, никто не спрашивал.
«Список кошек» — это частный случай «списка животных», в список животных можно занести кошку, а в список кошек занести любое животное (например, собаку) нельзя.
Тут вы сами себе противоречите. Правильно было бы "элемент, доставаемый из списка кошек, будет животным, а вот гарантировать, что из списка животных мы всегда будем получать именно кошек, нельзя".
В этом противоречии собака-то и зарыта. IEnumerable<T> — это функция int -> T (получить элемент по индексу), с одной стороны, и функция (int, T) -> IEnumerable<T> (записать элемент типа T по индексу), с другой. Т.е. это функция и принимающая, и возвращающая T.
Решить весь SICP и систематизировать свой опыт — огромный труд, поклон вам!
Как по-вашему, нужна ли первокурсникам реально часть относительно интерпретации?
Когда начинается написание интерпретатора — понятно, зачем брать один из Лиспов — выражения распарсить легко. То, что идёт до этого — как мне показалось, достаточно неплохо переносится практически на любой язык с динамической типизацией (кроме потоков языка для изображений, но они, как я понимаю, не входят даже в стандарт Scheme) и уже даёт неплохой фундамент для типичных студенческих задач. Написать интерпретатор на основе изученного — это красиво, конечно (eval-apply как электричество и магнетизм в уравнениях Максвелла), но не такое уж CS 101.
По итогу решения всех задач, использование списков в тех местах, где можно было бы сделать структуры с именованными полями, вам видится как полезный дидактический ход или введение затруднений на пустом месте? С одной стороны, понятно, что авторы хотят донести идею, что любые данные в конечном счёте можно построить на одной примитивной структуре (пусть в реальности это байт, а не список). С другой стороны, всякие cadadr для доступа к частям структуры не столь самоочевидны, как они подаются.
Ещё замечание:
except Exception:таки считается более культурным вариантом, чем простоexcept:, потому что системные исключения наследуются не отException, и программу как раз-таки можно завершить безkill -9.А какие бы возникли вопросы?
Вот в Julia значения по умолчанию вычисляются в момент вызова функции, и там это ни у кого проблем не вызывает. Бонусом это даёт возможность ссылаться в значении по умолчанию на предыдущие аргументы. Наоборот, предостережения видел только в руководствах по Python и по Common Lisp. Причём в Lisp это относится только к литералам типа
'(1 2), т.к. они по стандарту могут быть вычислены однократно при определении функции, вместо этого рекомендуется значения по умолчанию просто задавать как(list 1 2), тогда они гарантированно вычисляются в момент вызова.А оно с
bar=1одинаковое, вот сbar=[]будет разное.Вообще согласен, непонятно, зачем в Python 3 не сделали интерпретацию аргументов по умолчанию как выражений и не сделали нормальные области видимости, коль уж всё равно с Python 2 обратную совместимость сломали.
Насколько я помню, магнитное поле проистекает из электрического только если постулировать отсутствие магнитных зарядов. Тогда уравнения Максвелла становятся асимметричны, и действительно, магнитное поле может порождаться только электрическими зарядами.
А если найдётся магнитный заряд, то уравнения Максвелла будут полностью симметричны относительно электрического и магнитного полей, и даже можно электрическое поле считать релятивистской поправкой к магнитному в отсутствие электрических зарядов.
Вот меня тоже удивило, что не раскрыто, это же второе главное преимущество перед юпитером, на мой взгляд.
Я бы ещё сказал, преимущество не только в воспроизводимости, а ещё в отвязывании окружения блокнота от окружения установки marimo.
Сорри за некропост.
Вообще, что там как выделяется - в джулии не специфицируется.
Если есть константная структура - на неё тоже может не аллоцироваться память. constant folding и всё такое. Так-то даже банальное
x.attribute- это в джулии синтаксический сахар дляgetproperty(x, "attribute"). Но никакая строка там, конечно, не передаётся в явном виде, компилятор видит, что это константа времени компиляции, и преобразует её в статический байтовый сдвиг относительно адреса структуры в памяти.Гарантируется только то, что неизменяемые структуры в массивах и в полях других структур хранятся "in-line", т.е. массив
Nструктур размером csizeof(T) = sбудет заниматьN * sбайт. Изменяемые же в массив или в поле другой структуры кладутся всегда по ссылке, потому что семантика требует отдельного времени жизни для внешнего и внутреннего объекта.При этом изменяемая структура тоже может выделяться на стеке, если компилятор сможет доказать, что у неё время жизни ограничено конкретной областью видимости.
Вроде как, обычно "Космос" - это то, что оставалось на околоземной орбите.
Смею предположить, что если аппарат ушёл с околоземной орбиты, то уже бессмысленно было скрывать истинную цель запуска, т.к. иностранные астрономы уже могли отследить и рассчитать траекторию.
Не только для удобства чтения. Функция, в частности, локализует контекст. Отдельные функции проще при необходимости отрефакторить с гарантией, что остальная часть общей функции не затронется.
Насчёт дополнительных накладных расходов - бывает по-всякому. И компилятор заинлайнить может, и кэш инструкций может освободиться, если обработку какого-то редкого условия в функцию вынести.
Нет сам интерпретатор не может решить проблему, т.к. это на уровне правил языка - если где-то указывается тип, то он должен быть либо параметром, либо определён выше.
Вот эти даровые 0,3 км/с и нужно закрыть. Ракета же не будет запускаться сперва строго на запад с погашением вращения Земли, потом разворачиваться на полярную орбиту. Нужна величина векторной суммы 7,8 км/с на наклонении 97° и 0,3 км/с на запад в сравнении с векторной суммой 7,8 км/с на восток и 0,3 км/с на запад.
Спасибо, что добавили разъяснение в статью.
Так и не пойму, можно ли трюк Норвига с заменой `(symbol-function fn-name)` провернуть где-то кроме CL и основанных на нём вариантов. При наличии исходного текста функции макрос выглядит как более переносимое решение всё-таки, да. Хотя по сути это точно функция - отображение входного аргумента в возвращаемое значение.
У Норвига в PAIP сделано функциями. Там как-то проще, чем через макросы, в том смысле, что о просачивании символов в другую область видимости не надо заботиться.
У макроса есть какое-то существенное преимущество?
Как я понимаю,
getd- это функция из HomeLisp'а, которая возвращает исходный код функции? В Common Lisp такого нет, вроде бы.(https://ru.wikipedia.org/wiki/Лысенко,_Трофим_Денисович)
Скорее, очень хорошо умел читать запросы высокого руководства и подгонять результат под нужный ответ.
Не уходит, но у неё, как и у квадратного корня, в нуле экстремум с бесконечной производной, поэтому нужно как-то делать, чтобы оптимизация в область притяжения этого экстремума не заходила.
Да, похоже, что те же. У них и в статье про МСГ метод поиска вдоль направления предлагается, который и отдельно от МСГ тоже используют.
Если всюду дважды дифференцируема — возможно, да. А так есть, например, квадратный корень, который в окрестности нуля не липшиц-непрерывен. У меня вот лично в решаемой задаче появляется функция, которая около нуля ведёт себя как x ln(x) — если туда минимизатор залез, то уже не вылезает.
Недавно ещё узнал, что есть немонотонный поиск по направлению, где условия Вульфа выполняются только "в среднем за n итераций", что может для CG или L-BFGS ускорить сходимость (спрямляет путь через кривые овраги).
Автор вот пишет, что посмотрел Scratch — и решил, что Basic лучше.
Я тоже не понимаю, почему — там и набор спрайтов из коробки, и игры кто-то на нём вполне пишет.
Подозреваю, это собственный синдром утёнка у автора, а ребёнка, очевидно, никто не спрашивал.
Тут вы сами себе противоречите. Правильно было бы "элемент, доставаемый из списка кошек, будет животным, а вот гарантировать, что из списка животных мы всегда будем получать именно кошек, нельзя".
В этом противоречии собака-то и зарыта.
IEnumerable<T>— это функцияint -> T(получить элемент по индексу), с одной стороны, и функция(int, T) -> IEnumerable<T>(записать элемент типаTпо индексу), с другой. Т.е. это функция и принимающая, и возвращающаяT.Решить весь SICP и систематизировать свой опыт — огромный труд, поклон вам!
Как по-вашему, нужна ли первокурсникам реально часть относительно интерпретации?
Когда начинается написание интерпретатора — понятно, зачем брать один из Лиспов — выражения распарсить легко. То, что идёт до этого — как мне показалось, достаточно неплохо переносится практически на любой язык с динамической типизацией (кроме потоков языка для изображений, но они, как я понимаю, не входят даже в стандарт Scheme) и уже даёт неплохой фундамент для типичных студенческих задач. Написать интерпретатор на основе изученного — это красиво, конечно (eval-apply как электричество и магнетизм в уравнениях Максвелла), но не такое уж CS 101.
По итогу решения всех задач, использование списков в тех местах, где можно было бы сделать структуры с именованными полями, вам видится как полезный дидактический ход или введение затруднений на пустом месте? С одной стороны, понятно, что авторы хотят донести идею, что любые данные в конечном счёте можно построить на одной примитивной структуре (пусть в реальности это байт, а не список). С другой стороны, всякие
cadadrдля доступа к частям структуры не столь самоочевидны, как они подаются.Так что нещитается