Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lisp как универсальная обертка


Published on

Published in: Technology, Education
  • Be the first to comment

Lisp как универсальная обертка

  1. 1. Lisp как универсальнаяоберткаVsevolod Dyomkin@vseloved2013-05-31
  2. 2. Темы* Кратко о языке* Примеры Lisp-путирешения задач* Нужен ли Lisp и кому?
  3. 3. “Perl делает простыевещи простыми,a сложные —возможными”
  4. 4. Lisp делает сложныевещи доступными,а простыескладываются самисобой
  5. 5. Принципы Lisp* Всё — выражение* Всё — первоклассное* Программа — это живой образ* Ядро языка — 25 базовых форм,всё остальное — надстройка над ними,которую можно менять
  6. 6. Lisp — этовычислительно-ориентированныйязык
  7. 7. (defstruct node(key 0 :read-only t)(value 0 :read-only t)(left nil :type (or null node) :read-only t)(right nil :type (or null node) :read-only t))(defun copy-node (node &key (key (node-key node))(value (node-value node))(left (node-left node))(right (node-right node)))(make-node :key key:value value:left left:right right))(defun left-rotate (node)(let ((left (node-left node)))(copy-node left:right (copy-node node:left (node-right left)))))Вместо “Hello World”
  8. 8. (clsql:def-view-class synset ()((synsetid :initarg :synsetid :reader synset-id:type integer :db-kind :key)(pos :initarg :pos :reader synset-pos:type char)(lexdomainid :initarg :lexdomainid:type integer :db-constraints (:not-null))(definition :initarg :definition :reader synset-def:type string)(word :initarg :word :reader synset-word :db-kind :virtual)(sensenum :initarg :sensenum :db-kind :virtual))(:base-table "synsets"))CL-USER> (make synset :word "foo" :synset-id 42 :pos #V:definition "A test synset")#<SYNSET foo/V 42 {100329C7F3}>Оборачиваем SQL или A poor mans ORM
  9. 9. Оборачиваем SQL или A poor mans ORM(defmethod slot-unbound (class (synset synset) (slot (eql word)))(setf (slot-value synset slot)(query1 (select (lemma :from words)`(:where wordid:= ,(select (wordid :from senses)`(:where synsetid:= ,(synset-id synset):limit 1)):limit 1)))))
  10. 10. (defun select (from &optional args)(values (fmt "(SELECT ~A ~{~A~^ ~})"(etypecase from(symbol(fmt "* FROM ~A"(clsql:view-table (find-class from))))(list(ds-bind (fields tables) (split :from from)(fmt "~{~A~^,~} FROM ~{~A~^,~}"(mapcar #`(if (listp %)(fmt "~A(~A)"(first %) (second %))%)fields)table))))(mapcar #`(case %(:group-by "GROUP BY")(:order-by "ORDER BY")(t %))args))(when (symbolp from) from)))Оборачиваем SQL или A poor mans ORM
  11. 11. Альтернативный вариант SQL(clsql:select [item_id] [as [count [*]] num]:from [table]:where [is [null [sale_date]]]:group-by [item_id]:order-by ((num :desc)):limit 1)
  12. 12. Оборачиваем черные ящики – клиент redis(def-cmd HMGET (key field &rest fields) :multi"Get the values associated with the specified FIELDSin the hash stored at KEY.")
  13. 13. Оборачиваем черные ящики – клиент redis(defmacro def-cmd (cmd (&rest args) reply-type docstring)`(defun ,cmd ,args,docstring(return-from ,cmd(with-reconnect-restart(tell ,cmd ,@args)(prog1 (expect ,reply-type)(unless *pipelined*(clear-input (conn-stream *connection*))))))))
  14. 14. Оборачиваем черные ящики – клиент redis(let ((redis:*echo-p* t))(redis:with-persistent-connection (:port 10000)(loop (process-job)))(defun process-job ()(red:blpop "queue")(let* ((id (red:incr "id"))(results (calculate-results)))(result-key (fmt "result~A" id)))(redis:with-pipelining(dolist (result results)(red:lpush result-key result))(red:lpush "results" result-key))))
  15. 15. Оборачиваем сложные алгоритмы - CKY(macrolet((CKY (&body body)`(with-slots (rules nts->idx) grammar(let* ((pi0 #{}) (bps #{}) ;; also need to init them(min most-negative-single-float))(do ((pos 1 (1+ pos)))((>= pos *sentence-length*))(do ((i 1 (1+ i)))((> i (- *sentence-length* pos)))(let ((j (+ i pos)))(dotable (_ k nts->idx)(let (max arg)(do ((s i (1+ s)))((>= s j))(dotable (rule q rules)(when (and (tryadic rule)(= k (first rule))),@body)))(when (if (listp max) max (> max min))(setf (@ pi0 (1- i) (1- j) k) max(@ bps (1- i) (1- j) k) arg)))))))(values pi0 bps)))))
  16. 16. Оборачиваем сложные алгоритмы - CKY(defmethod parse ((grammar pcfg) (sentence list))"Return the parse tree of SENTENCE for PCFG.Parsing is performed in 2 steps:- the main method returns as values the matrices PI0 (pi matrix)and BPS (backpointers matrix)- the :around method restores the parse tree from these matricesThis brings additional flexibility for the return values of themethod: for instance, we can try to return several trees or haveseveral roots."(CKY (let* ((cur (cons rule (1- s)))(l (@ pi0 (1- i) (1- s) (second rule)))(r (@ pi0 s (1- j) (third rule)))(score (if (and l r)(+ (log q) l r)min)))(when (> score (or max min))(setf max scorearg cur)))))
  17. 17. Оборачиваем сложные алгоритмы - CKY(defmethod parse :around ((grammar pcfg) (sentence list))(with-raw-results(values (idx->nts (decode-parse-tree sentence bps 0 last iroot))(exp (or (@ pi0 0 last iroot) min))pi0bps)))
  18. 18. Оборачиваем сложные алгоритмы - CKY(declaim (inline @))(defun @ (m i j k)(get# (+ (* i *sentence-length* *nt-count*)(* j *nt-count*)k)m))(defsetf @ (m i j k) (v)`(set# (+ (* ,i *sentence-length* *nt-count*)(* ,j *nt-count*),k),m ,v))
  19. 19. Бонус: оборачиваем оптимизацию perform-pass-1 ((poly-ctx poly-ctx)(hash-table node-idx))"Scans SRC-OSM xml stream extracting <node> tags, checks each nodefor polygon belonging via POLY-CONTEXT, and sets index NODE-IDXin case of success"(:with (the (unsigned-byte 56) way-offset) := 0)(xml-on-tag "node"(attrs ("id" uint64 node-id)("lon" float lon)("lat" float lat))(on-match (when (poly-check poly-ctx lon lat)(setf (gethash node-id node-idx) 1))))(xml-on-tag "way" (on-match (when (zerop way-offset)(setf way-offset tag-offset))))(tracing-tag-offset tag-offset)(:finally (return (1- way-offset))))
  20. 20. Бонус: оборачиваем оптимизацию defun/iter-xml (name (&rest typed-args) doc-string&rest clauses)`(defun/fast ,name ,(cons (sb-sys:fd-stream src-osm) typed-args),doc-string(iter-xml-stream (upon-stream src-osm),@clauses)))
  21. 21. Бонус: оборачиваем оптимизацию defun/iter-xml (name (&rest typed-args) doc-string&rest clauses)`(defun/fast ,name ,(cons (sb-sys:fd-stream src-osm) typed-args),doc-string(iter-xml-stream (upon-stream src-osm),@clauses)))(defmacro defun/fast (name typed-args doc-string &body body)`(defun ,name ,(mapcar #second typed-args),doc-string(declare (optimize (speed 3) (safety 0) (debug 0)(compilation-speed 0) (space 0)),@(mapcar (curry #apply(lambda (type arg)`(type ,type ,arg)))typed-args)),@body))
  22. 22. (defun graylog (message &key level backtrace file line-no)(let (sock)(unwind-protect(let ((msg (salza2:compress-data(babel:string-to-octets(json:encode-json-to-string#{:version "1.0" :facility "lisp":host (get-hostname):|short_message| message:|full_message| backtrace:timestamp (local-time:timestamp-to-unix(local-time:now)):level level :file file :line line-no}):encoding :utf-8)salza2:zlib-compressor)))(setf sock (usocket:socket-connect *graylog-host**graylog-port*:protocol :datagram:element-type ub8))(usocket:socket-send sock msg (length msg))))(usocket:socket-close sock)))Тупой индустриальный код
  23. 23. Lisp ресурсы1. Hyperspec - Cookbook - Cliki – http://cliki.net4. lispdoc - Google Styleguide - - Lisp books -
  24. 24. Инструменты1. Реализации – 8+2:SBCL, CCL, ECL, ABCL2. SLIME, SLIMV3. quicklisp
  25. 25. LispПочему?Зачем?Для кого?И другие вопросы...