将通用序列系统与 jonathan 的列表一起使用 lisp
using Generic sequences system in common lisp with an alist from jonathan
我正在使用 messenger api from facebook, using ningle. there is a moment in my program that I need to work with this alist coming from jonathan:
CL-USER> (defparameter *params*
'(("entry"
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968)
("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
("object" . "page")))
*PARAMS*
CL-USER> (length *params*)
2
然后我必须处理入口部分:
CL-USER> (defparameter entries (cdr (assoc "entry" *params* :test #'string=)))
ENTRIES
CL-USER> entries
((("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
CL-USER> (length entries)
1
然后我定义了两个函数来处理这个:
(defun extract-entry (entry)
(let ((id (cdr (assoc "id" entry :test #'string=)))
(time (cdr (assoc "time" entry :test #'string=)))
(messaging (cdr (assoc "messaging" entry :test #'string=))))
messaging))
(defun extract-messaging (event)
(let ((message (cdr (assoc "message" event :test #'string=))))
message))
那我操作:
CL-USER> (defparameter messaging (extract-entry (first entries)))
MESSAGING
CL-USER> messaging
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
CL-USER> (length messaging)
1
CL-USER> (defparameter message (extract-messaging (first messaging)))
MESSAGE
CL-USER> message
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
CL-USER> (length message)
3
而且效果很好,那么我想将 generic-sequences 应用到这部分:
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging messaging))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))
(((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
它可以工作,但是当我连接函数时我遇到了这个问题:
CL-USER> (trace extract-entry extract-messaging)
(EXTRACT-ENTRY EXTRACT-MESSAGING)
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
; Evaluation aborted on #<TYPE-ERROR expected-type:
"(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER)"
datum: ("message" ("text" . "hola") ("seq" . 3227) ..)>.
在调试器中使用此输出:
The value
("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
is not of type
(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL
CHARACTER)
when binding SB-IMPL::STRING2
[Condition of type TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003180003}>)
Backtrace:
0: (STRING= "message" ("message" ("text" . "hola") ("seq" . 3227) ("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))) [more]
1: (SB-KERNEL:%ASSOC-TEST "message" #<unavailable argument> #<FUNCTION STRING=>)
2: (EXTRACT-MESSAGING ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
3: (SB-DEBUG::TRACE-CALL #<SB-DEBUG::TRACE-INFO EXTRACT-MESSAGING> #<FUNCTION EXTRACT-MESSAGING> ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
4: ((LABELS GENERIC-SEQ::TRAVERSE :IN GENERIC-SEQ::SEQ-MAP-1) (((# # # #)) . #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004CF1F5B}>))
5: (GENERIC-SEQ:SEQ->LIST #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004C9A46B}>))
6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))) #<NULL-LEXENV>)
7: (EVAL (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))))
8: (SWANK::%EVAL-REGION "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
9: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
10: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1CB}>)
11: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1AB}>)
12: (SWANK::%LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
13: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
14: (EVAL (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
15: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
16: (SWANK::PROCESS-REQUESTS NIL)
17: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
18: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
19: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100317FFEB}>)
20: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
21: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100309EAE3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003167973}>) (*TRACE-OUTPUT* . #2#) (*ERR..
22: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
23: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
24: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
25: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
26: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A4DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
27: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003180003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100317FF6B}> (#<SB-THREAD:THREAD "re..
28: ("foreign function: call_into_lisp")
29: ("foreign function: new_thread_trampoline")
30: ("foreign function: _pthread_body")
31: ("foreign function: _pthread_body")
32: ("foreign function: thread_start")
此时的问题是 extract-entry returns 一个列表所以我真的应该这样工作:
CL-USER> (apply #'mapcar #'extract-messaging (mapcar #'extract-entry entries))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但随后无法使用库:
CL-USER> (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))
attempt to use VALUES-LIST on a dotted list:
#S(GENERIC-SEQ::BASIC-SEQ
:DELAYED-ENUM #<CLOSURE (LAMBDA ()
:IN
GENERIC-SEQ::SEQ-MAP-1) {100499978B}>)
[Condition of type SIMPLE-TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003160003}>)
Backtrace:
0: (APPLY #<FUNCTION GENERIC-SEQ:SEQ-MAP> #<CLOSURE SB-IMPL::ENCAPSULATION {1002E5970B}> #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {100499978B}>))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)) #<NULL-LEXENV>)
2: (EVAL (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)))
3: (SWANK::%EVAL-REGION "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
4: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
5: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {100499951B}>)
6: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {10049994FB}>)
7: (SWANK::%LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
9: (EVAL (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
10: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
11: (SWANK::PROCESS-REQUESTS NIL)
12: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
13: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
14: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100315FFEB}>)
15: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
16: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100307F5A3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003147DD3}>) (*TRACE-OUTPUT* . #2#) (*ERR..
17: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
18: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
19: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
21: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A57CFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
22: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003160003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100315FF6B}> (#<SB-THREAD:THREAD "re..
23: ("foreign function: call_into_lisp")
24: ("foreign function: new_thread_trampoline")
25: ("foreign function: _pthread_body")
26: ("foreign function: _pthread_body")
27: ("foreign function: thread_start")
问题是一样的,但我可以解决它:
CL-USER> (gen-seq:seq->list (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但是当我这样做时,我失去了对术语 so 的惰性求值,我怎样才能在不失去泛型序列中的惰性求值的情况下实现它。
如果您的函数处理关联列表,您可能会使用如下函数检查它们是否确实获得了有效的关联列表:
(defun assert-valid-alist (alist)
(assert (and (not (null alist)) ; not the empty list
(listp alist) ; it is a list
(every #'consp alist) ; every item is a cons
(every (lambda (item)
(symbolp (car item))) ; every key should be a symbol
alist))
(alist)
"Not a valid assoc list: ~a" alist))
(defun get-age (person)
(assert-valid-alist person)
(cdr (assoc 'age person)))
示例:
CL-USER 106 > (get-age '((name . ute) (age . 34)))
34
CL-USER 107 > (get-age '(((name . ute) (age . 34))))
Error: Not a valid assoc list: (((NAME . UTE) (AGE . 34)))
1 (continue) Retry assertion with new value for ALIST.
2 (abort) Return to level 0.
3 Return to top loop level 0.
这可能会降低性能,您可以在代码运行后删除它。
我正在使用 messenger api from facebook, using ningle. there is a moment in my program that I need to work with this alist coming from jonathan:
CL-USER> (defparameter *params*
'(("entry"
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968)
("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
("object" . "page")))
*PARAMS*
CL-USER> (length *params*)
2
然后我必须处理入口部分:
CL-USER> (defparameter entries (cdr (assoc "entry" *params* :test #'string=)))
ENTRIES
CL-USER> entries
((("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
CL-USER> (length entries)
1
然后我定义了两个函数来处理这个:
(defun extract-entry (entry)
(let ((id (cdr (assoc "id" entry :test #'string=)))
(time (cdr (assoc "time" entry :test #'string=)))
(messaging (cdr (assoc "messaging" entry :test #'string=))))
messaging))
(defun extract-messaging (event)
(let ((message (cdr (assoc "message" event :test #'string=))))
message))
那我操作:
CL-USER> (defparameter messaging (extract-entry (first entries)))
MESSAGING
CL-USER> messaging
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
CL-USER> (length messaging)
1
CL-USER> (defparameter message (extract-messaging (first messaging)))
MESSAGE
CL-USER> message
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
CL-USER> (length message)
3
而且效果很好,那么我想将 generic-sequences 应用到这部分:
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging messaging))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))
(((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
它可以工作,但是当我连接函数时我遇到了这个问题:
CL-USER> (trace extract-entry extract-messaging)
(EXTRACT-ENTRY EXTRACT-MESSAGING)
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
; Evaluation aborted on #<TYPE-ERROR expected-type:
"(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER)"
datum: ("message" ("text" . "hola") ("seq" . 3227) ..)>.
在调试器中使用此输出:
The value
("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
is not of type
(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL
CHARACTER)
when binding SB-IMPL::STRING2
[Condition of type TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003180003}>)
Backtrace:
0: (STRING= "message" ("message" ("text" . "hola") ("seq" . 3227) ("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))) [more]
1: (SB-KERNEL:%ASSOC-TEST "message" #<unavailable argument> #<FUNCTION STRING=>)
2: (EXTRACT-MESSAGING ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
3: (SB-DEBUG::TRACE-CALL #<SB-DEBUG::TRACE-INFO EXTRACT-MESSAGING> #<FUNCTION EXTRACT-MESSAGING> ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
4: ((LABELS GENERIC-SEQ::TRAVERSE :IN GENERIC-SEQ::SEQ-MAP-1) (((# # # #)) . #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004CF1F5B}>))
5: (GENERIC-SEQ:SEQ->LIST #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004C9A46B}>))
6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))) #<NULL-LEXENV>)
7: (EVAL (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))))
8: (SWANK::%EVAL-REGION "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
9: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
10: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1CB}>)
11: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1AB}>)
12: (SWANK::%LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
13: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
14: (EVAL (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
15: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
16: (SWANK::PROCESS-REQUESTS NIL)
17: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
18: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
19: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100317FFEB}>)
20: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
21: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100309EAE3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003167973}>) (*TRACE-OUTPUT* . #2#) (*ERR..
22: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
23: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
24: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
25: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
26: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A4DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
27: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003180003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100317FF6B}> (#<SB-THREAD:THREAD "re..
28: ("foreign function: call_into_lisp")
29: ("foreign function: new_thread_trampoline")
30: ("foreign function: _pthread_body")
31: ("foreign function: _pthread_body")
32: ("foreign function: thread_start")
此时的问题是 extract-entry returns 一个列表所以我真的应该这样工作:
CL-USER> (apply #'mapcar #'extract-messaging (mapcar #'extract-entry entries))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但随后无法使用库:
CL-USER> (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))
attempt to use VALUES-LIST on a dotted list:
#S(GENERIC-SEQ::BASIC-SEQ
:DELAYED-ENUM #<CLOSURE (LAMBDA ()
:IN
GENERIC-SEQ::SEQ-MAP-1) {100499978B}>)
[Condition of type SIMPLE-TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003160003}>)
Backtrace:
0: (APPLY #<FUNCTION GENERIC-SEQ:SEQ-MAP> #<CLOSURE SB-IMPL::ENCAPSULATION {1002E5970B}> #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {100499978B}>))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)) #<NULL-LEXENV>)
2: (EVAL (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)))
3: (SWANK::%EVAL-REGION "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
4: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
5: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {100499951B}>)
6: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {10049994FB}>)
7: (SWANK::%LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
9: (EVAL (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
10: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
11: (SWANK::PROCESS-REQUESTS NIL)
12: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
13: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
14: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100315FFEB}>)
15: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
16: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100307F5A3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003147DD3}>) (*TRACE-OUTPUT* . #2#) (*ERR..
17: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
18: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
19: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
21: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A57CFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
22: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003160003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100315FF6B}> (#<SB-THREAD:THREAD "re..
23: ("foreign function: call_into_lisp")
24: ("foreign function: new_thread_trampoline")
25: ("foreign function: _pthread_body")
26: ("foreign function: _pthread_body")
27: ("foreign function: thread_start")
问题是一样的,但我可以解决它:
CL-USER> (gen-seq:seq->list (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但是当我这样做时,我失去了对术语 so 的惰性求值,我怎样才能在不失去泛型序列中的惰性求值的情况下实现它。
如果您的函数处理关联列表,您可能会使用如下函数检查它们是否确实获得了有效的关联列表:
(defun assert-valid-alist (alist)
(assert (and (not (null alist)) ; not the empty list
(listp alist) ; it is a list
(every #'consp alist) ; every item is a cons
(every (lambda (item)
(symbolp (car item))) ; every key should be a symbol
alist))
(alist)
"Not a valid assoc list: ~a" alist))
(defun get-age (person)
(assert-valid-alist person)
(cdr (assoc 'age person)))
示例:
CL-USER 106 > (get-age '((name . ute) (age . 34)))
34
CL-USER 107 > (get-age '(((name . ute) (age . 34))))
Error: Not a valid assoc list: (((NAME . UTE) (AGE . 34)))
1 (continue) Retry assertion with new value for ALIST.
2 (abort) Return to level 0.
3 Return to top loop level 0.
这可能会降低性能,您可以在代码运行后删除它。