Избранные сообщения alienclaster
Короче: где ещё есть macro characters?
Я пытался спросить это же в своей прошлой теме, но вышло слишком замудрёно. Поэтому спрашиваю прямо. В каких языках ещё есть
set-macro-character, как в CL, и где оно сделано хорошо (не хуже, а желательно лучше, чем в CL)?
Для тех, кто не успел поставить часы, технология описана в этой статье, искать «макросы чтения».
Муки выбора первого юзабельного языка (pascal за язык не считается). Есть два ООП ЯП: лиспы точеные и питоны золоченые...
Решил изучать первый (после псевоязыка: паскаля) ООП ЯП. Всё думаю, куда сесть то: на лиспы точеные или на питоны золоченые? Цели: нейронные сети, работа с БД, ФС, мелкие поделки школьного уровня (типа машинного обучения на SVM).
Какие преимущества и недостатки у того и другого ЯП?
Ещё говорят, что питон жутко тормозит, т.к. полностью интерпретируемый, а вот лисп компилируется и летает после этого. Ну и да: скобки мне импонируют куда больше этих уродливых отступов.
Python — простой и понятный язык, говорили они.
https://github.com/cosmologicon/pywat
Предлагаю померяться скором в прилагаемом quiz'е.
Подскажите что-нибудь по управлению окнами emacs
Интересует такой функционал как:
- Быстрое изменение рамок текущего окна с клавиатуры
- Изменение расположения текущего окна (поменять местами с другим?)
- Группировка окон (Например окна с prog-mode открываются только в левой половине фрейма)
Можете посоветовать пакеты и настройки?
Многопоточное программирование в Python
Всем доброго дня.
Хотел узнать, как правильно многопоточно программировать в Python. Мне необходимо параллельно запускать кучу тестов Selenium. Как я делаю сейчас - у меня есть отдельный скрипт, который принимает аргументы из sys.argv от программы вышестоящей(которая собирает Pool, делает map_async, и открывает через subprocess новый процесс интерпретатора Пайтона).
То есть схема примерно получается такая:
Основное приложение - Thread на вызов клиента - Pool - в одном потоке Пула вызывается subprocess - subprocess открывает новый интерпретатор Пайтона, который выполняет нужную мне программу.
Таким образом я могу запускать 100-200 тестов, перехватывать stdout и stderr программ-тестов, и вообще не особо париться. Но проблема только в том, что Pool как-то нестабильно работает. Допустим, у меня есть Pool на 100 потоков, есть инфа, 70к записей, по которой нужно сделать map, то есть передать параметры в реальный тест. Но иногда Pool зависает, не запускает больше потоков, либо держит включёнными только 2-3(может чуть больше), хотя в параметрах указано явно 100.
В общем хотел узнать, какой есть стабильный вариант многопоточного программирования в Python. И по тому что я сказал, мне нужна больше не функциональность многопоточного программирования, а уже видимо что-то типа nohup, но с контролем количества процессов.
Извиняюсь заранее за скомканное изложение, если что-то непонятно - пишите.
P.S. Прямой вызов функций из Pool я перестал юзать после того как неосилил исключения, которые вроде как и есть, но их не видно и вообще пофиг. С отдельным скриптом я многое сумел побороть, и это наиболее удобный для меня вариант получился.
ФВП и производительность
Провёл тест на скорость работы одной и той же функции, написанной нормально и через ФВП. Получил потерю производительности в полтора раза:
SBCL:
(declaim (optimize (speed 3) (safety 0)))
(asdf:oos 'asdf:load-op :alexandria)
(defun f (x)
(+ (+ (+ x 1) 2) 1))
(let ((f-comp
(alexandria:compose
(lambda (x) (+ x 1))
(lambda (x) (+ x 2))
(lambda (x) (+ x 1)))))
(defun f-comp (x)
(funcall f-comp x)))
(defconstant iter 10000000)
(time
(dotimes (i iter)
(f i)))
(time
(dotimes (i iter)
(f-comp i)))
Evaluation took:
0.181 seconds of real time
0.180000 seconds of total run time (0.180000 user, 0.000000 system)
99.45% CPU
325,363,554 processor cycles
0 bytes consed
Evaluation took:
0.296 seconds of real time
0.296000 seconds of total run time (0.296000 user, 0.000000 system)
100.00% CPU
530,610,480 processor cycles
0 bytes consed
Racket:
#lang racket
(define (f x)
(+ (+ (+ x 1) 2) 1))
(define f-comp
(compose
(lambda (x) (+ x 1))
(lambda (x) (+ x 2))
(lambda (x) (+ x 1))))
(define iter 1000000)
(time
(for ([i iter])
(f i)))
(time
(for ([i iter])
(f-comp i)))
cpu time: 728 real time: 726 gc time: 0
cpu time: 1244 real time: 1244 gc time: 0
Получается, функции высшего порядка лучше не использовать? А как с этим борются в Haskell, если там без них почти ничего написать нельзя (точнее не принято рекомендуемым стилем программирования)?
Вопрос по макросам
До меня не доходит до конца смысл макросов. Очевидно, что, все выражения, которые можно раскрыть в компилтайме, можно раскрыть и в рантайме. Если экспандер написан на лиспе, например, скорость макроэкспанда будет одинаковой. То есть, мы тут ничего не выигрываем в плане производительности. С другой стороны, необходимость раскрытия той или иной формы может быть продиктована в самом рантайме, таким образом, часть форм раскрывать, возможно, не придется, тогда мы экономим ресурсы. Ведь в компилтайме раскрываются все макросы, не так ли? Тогда какое преимущество мы получаем от раскрытия в компилтайме?
Форма begin
Здравствуйте!
Изучаю scheme и в связи с этим вопрос. Насколько я понимаю, выражение (begin foo bar baz) в точности соответствует ((lambda() foo bar baz)). Так ли это?
И более того, в любом выражении, насколько я понимаю, форму begin можно тупо заменить отсутствием какой-либо формы,[upd] если не требуется группировки, когда нам нужно получить в качестве аргумента результат вычисления выражения — как указал namelessOne[/upd].
((lambda() zoo (begin foo bar baz) moo))
vs
((lambda() zoo foo bar baz moo))
Динамические возможности CLOS
Я тут задумался, одной из фишек CLOS является динамичность: возможность в рантайме изменять методы обобщённых функций, слоты классов, перестраивать иерархию наследования, изменять классы ранее созданных объектов. Я вполне могу представить, как это всё используется в интерактивном режиме в процессе разработки, но что-то юз-кейсы, когда самой программе может это понадобиться, ограничиваются только какими-то несбыточными фантазиями про ИИ.
Является ли эта динамичность намеренно реализованной киллер-фичей собственно CLOS или это просто побочный эффект образо-ориентированного подхода к разработке на Common Lisp?
Пару мыслей о c++ и скобках
Сидя в раздумьях, пришел к интересным мыслям:
1. С++ — это на самом деле не столько язык, сколько инструмент для создания ваших собственных языков. Его элегантность заключается отнюдь не в простоте (слова С++ и простота режут слух своим явным противоречием), а в его потенциальных возможностях. За каждой уродливой проблемой прячется какая-нибудь умная идиома, изящный языковой финт, благодаря которому проблема тает прямо на глазах. Проблема решается так же элегантно, как это сделал бы настоящий язык типа Smalltalk или Lisp, но при этом ваш процессор не дымится от напряжения, а на Уолл-Стрит не растут акции производителей чипов памяти. С++ — вообще не язык. Это мировоззрение или наркотик, меняющий способ мышления.
2. Ревнители частоты языка часто нападают на С++. Они полагают, что высшее достижение современной цивилизации — язык, построенный исключительно из атомов и скобок. По мнению этих террористов от синтаксиса, если простую переменную с первого взгляда невозможно отличить от вызова функции или макроса — это вообще не язык, а шарлатанство для развлечения праздной толпы. К сожалению, теория расходится с практикой. В реальной жизни толпа платит лишь за то, чтобы видеть языки, в которых разные идеи выглядят по-разному. «Простые и последовательные» языки никогда не пользовались особым успехом за стенками академий, а языки с блочной структурой овладели массами. Стоит ли этому удивляться? Ведь компьютерные языки приходится изучать и запоминать, а для этого используется то же серое вещество, с помощью которого мы изучаем и запоминаем естественные языки. Попробуйте-ка назвать хотя бы один естественный язык без существительных, глаголов и скобок! Я бы не рискнул. Все наши познания в лингвистике говорят о том, что эти «плохие» особенности только ускоряют изучение компьютерного языка и делают его более понятным. i++ во всех отношениях действительно понятнее, чем i:=i+1, а x=17+29 читается лучше, нежели (setq x(+17, 29)). Речь идет не о строении компьютерного языка, а скорее о нашем собственном строении. Все уродства С++ — это в основном наши уродства. Когда вы научитесь понимать и любить его странности, когда перестанете беспокоиться о математической стройности, будет сделан ваш первый шаг к достижению элегантности в С++.
Рекламные ролики програмных продуктов от Symbolics из прошлого
Вот некоторые интересные ролики от Symbolics конца 80х — начала 90х годов:
- Броузер гипертекстовой документaции
- Презентация ОС Symbolics Genera
- Экспертная система Symbolics Joshua
- Издательская система Symbolics Concordia
- Редактор 3D анимации Symbolics S-Package 3D
- Графический и анимационный редактор Symbolics Graphics Division
- Реализация ЯП Ада Symbolics Lisp Ada
http://www.reddit.com/r/lisp/comments/1o20q2/old_marketing_videos_of_symbolic...
Я верно понимаю, что в scheme нельзя макрос выполнять изнутри макроса?
На лиспе есть вот такой код
(defmacro template (vars args &body body)
(let ((%do (gensym "DO"))
(%vars (gensym "VARS")))
(cond
((null vars)
`(macrolet ((,%do () ,@body))
(,%do)))
((consp vars)
`(template ,%vars ,args
(destructuring-bind ,vars ,%vars
,@body)))
(t `(macrolet ((,%do ()
`(progn
,@(mapcar (lambda (,vars) ,@body)
',args))))
(,%do))))))
Используется, например, так:
(template
((type word) (list :in) (string :across) (vector :across))
`(defmethod process ((l ,type))
(loop :for i ,word l :collect (process-element i)))
Суть макроса template в том, что создаётся анонимный макрос по переданному коду и тут же выполняется. Можно ли такое сделать в Scheme или Racket?
Работа с последовательностями в разных языках
Навеяно темой Ментальный вирус, пример взят и дополнен оттуда. Интересует реализация подобной операции на других языках. Лично я хотел бы увидеть на Lisp, Java, Smalltalk, Erlang.
array = ["John", "James", "Jakob", "Peter", "Janette", "Tom", "Vasya", "Jean", "Juilia", "Heather"]
puts array.select{|v|v[/^J[a-z]+/]}. # ВЫБРАТЬ ПО someregexp
each_slice(3). # КАЖДЫЙ КУСОК ПО 3 ЭЛЕМЕНТА
map{|v| "#{v[0]} and #{v[1]} follow #{v[2]}"}. # ПОДСТАВИТЬ ЗНАЧЕНИЯ В СТРОКУ
join("\n") # ОБЪЕДИНИТЬ
# John and James follow Jakob
# Janette and Jean follow Juilia
Пошагово для тех, кто не знаком с Ruby:
array.select{|v|v[/^J[a-z]+/]}
# ["John", "James", "Jakob", "Janette", "Jean", "Juilia"]
array.select{|v|v[/^J[a-z]+/]}.
each_slice(3).to_a # в массив
# [["John", "James", "Jakob"], ["Janette", "Jean", "Juilia"]]
array.select{|v|v[/^J[a-z]+/]}.each_slice(3).
map{|v| "#{v[0]} and #{v[1]} follow #{v[2]}"}
# ["John and James follow Jakob", "Janette and Jean follow Juilia"]
array.select{|v|v[/^J[a-z]+/]}.each_slice(3).map{|v| "#{v[0]} and #{v[1]} follow #{v[2]}"}.
join("\n")
# "John and James follow Jakob\nJanette and Jean follow Juilia"
Использовать только стандартную библиотеку.
Целесообразность операции не важна. Вопрос кратности количества найденных элементов трем не рассматриваем.
Как на макросах изобразить инстанциирование
Есть макрос, который должен создавать функцию.
(defmacro build (info) `(lambda ...))
Текст функции зависит от содержимого структуры info.
Где-то в коде он многократно вызывается с разными параметрами. Можно ли как-то сделать, чтобы он при первом запуске где-то создавал функцию, а при последующих только ссылался на неё? То есть нужен механизм, аналогичный инстанциированию шаблонов C++.
Есть какие-нибудь идеи, как сделать? Реализация лиспа (CL, Scheme, ...) не важна.
ооп и функциональщина кратко, внятно.
Дабы не слать напраслину на любителей создавать классы и объекты, пытаюсь разобраться в плюсах, которые отличаются от родителя, на первый взгляд, только названиями файлов, функций и приемами организации мышления погромиста. Так вот, эти ваши классы даже в учебнике называют почти структурами, а мизерное отличие сомнительного профита легко можно решить и в анси си(далее - ансися) при ближайшем обновлении. Ансися страдает перегрузкой названий функций для каждого из подлежащих обработке типов, отсутствием удобной иногда перегрузки функций, что, конечно минус, но не критично, ибо решаемо. Сиплюсик конечно удобен школьникам, тяжело принимающим всякие %s %d %x и так далее в качестве аргументов принтфов и сканфов, но зачем создавать для этого отдельный язык? Ведь << и >> становится лишним препятствием при освоении, если параллельно сдвиги битов читать. Итого, я вывел для себя, что в попытке облегчить участь программиста, разработчики языка усложнили его до степени родителя, не получив особенного профита. Чем же ооп так всем нравится, если оно не облегчает код?
Отодвиньте вашу тарелку с борщом в сторону, специалисты по макросам!
Итак, условия нашего микро-квеста заключаются в следующем: имеем n переменных, k из которых выражается через (n-k). Эти переменные служат для инициализации чего-то сферического в вакууме. Нам лень писать процедуры выведения и проверки в отдельном шаге, поэтому хотим сделать так, чтобы можно было, например, вызывать фабричный метод с аргументами - любыми k переменными, чтоб на выходе получить инициализированное n переменными нечто. Имеем набор правил (в любой из удобных вам форм), в котором описаны отношения между переменными. Например,
n = 3, k = 1, {x = y + z, y = x - z, z = x - y}smth = init(x = 100, y = 10)smth = init(y = 10, x = 100)Квест заключается в написании макроса, который генерирует все возможные варианты init(...), потому что нам, например, лень. В тред приглашаются лисперы, racket-пацаны, скальщики, с++-темплейт-шаманы, nemerle-писатели (есть такие вообще здесь?) и остальные, кого еще меньше. У D там вроде зачаточно что-то было? Напишу все эти языки в теги.
Я думаю, это можно было бы сгенерить и каким-то питонячим/руби-скриптом в отдельный файлик и его включать, но это не слишком спортивно.
Пример признаю абсолютно теоретическим.
Не понимаю, что такое замыкание (closure)
Если почитать SICP, то замыкания - это такое свойство функции, что, например, «мы говорим, что операция объединения данных обладает замыканием в том случае, если результаты объединения этой операции могут объединяться этой же операцией». Поэтому я думал, что суть примера с языком описания изображений в том, что это круто, когда наши процедуры обладают этим свойством - из несложных операций с изображениями мы можем получать сложные, потому что операция над изображением - это изображение.
Но если прочитать вики, то «Замыкание (англ. closure) в программировании — функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде).» Ну и что? Получается просто, что процедура использует глобальные переменные, ничего примечательного тут вроде и нет.
Так что такое замыкание? Помогите разобраться.
Откуда у Scheme такие макросы?
Существует ли книга, в которой написано, почему макросы в scheme такие странные.
Логика макросов CL понятна. Всё есть список, дальше программист сам разберётся.
Часть решений в Scheme тоже: гигиена по-умолчанию, паттерны.
Но зачем нужна отдельная от списка структура кода (syntax)? Почему этот syntax, будучи созданным внутри макроса не привязывается автоматически к строке, где был использован макрос (вместо #' #` приходится писать syntax/loc)?
| ← назад |