Hi,
The following form breaks when evaluated:
(json:encode-json-to-string '((:a . ((:b . ((:c . 42)))))))
Help! 11 nested errors. SB-KERNEL:*MAXIMUM-ERROR-DEPTH* exceeded. 0: (SB-DEBUG::MAP-BACKTRACE #<CLOSURE (LAMBDA (SB-DEBUG::FRAME)) {10032BDAF9}> :START 0 :COUNT 1152921504606846975) 1: (BACKTRACE 1152921504606846975 #<SYNONYM-STREAM :SYMBOL SB-SYS:*TTY* {100021E341}>) 2: ((LAMBDA NIL)) 3: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<CLOSURE (LAMBDA NIL) {10032BDAB9}>) 4: (SB-IMPL::ERROR-ERROR "Help! " 11 " nested errors. " "SB-KERNEL:*MAXIMUM-ERROR-DEPTH* exceeded.") 5: (SB-IMPL::INFINITE-ERROR-PROTECTOR) 6: (ERROR JSON:UNENCODABLE-VALUE-ERROR :DATUM (:C . 42) :CONTEXT JSON:ENCODE-JSON) 7: (JSON:UNENCODABLE-VALUE-ERROR (:C . 42) JSON:ENCODE-JSON) 8: (SIGNAL #<TYPE-ERROR expected-type: LIST datum: 42>) 9: (ERROR TYPE-ERROR :DATUM 42 :EXPECTED-TYPE LIST) 10: (SB-KERNEL::OBJECT-NOT-LIST-ERROR-HANDLER #<unavailable argument> #.(SB-SYS:INT-SAP #X7FFFF6D8CC20) #<SB-ALIEN-INTERNALS:ALIEN-VALUE :SAP #X7FFFF6D8C600 :TYPE (* (STRUCT SB-VM::OS-CONTEXT-T-STRUCT))> (405)) 11: (SB-KERNEL:INTERNAL-ERROR #.(SB-SYS:INT-SAP #X7FFFF6D8C600) #<unavailable argument>) 12: ("foreign function: #x417860")
debugger invoked on a SIMPLE-ERROR in thread #<THREAD "initial thread" RUNNING {1002990EE1}>: Maximum error nesting depth exceeded
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level.
Regards,
-- Nicolas Martyanoff http://codemore.org khaelin@gmail.com
On 6/5/11 Jun 5 -2:47 PM, Nicolas Martyanoff wrote:
(json:encode-json-to-string '((:a . ((:b . ((:c . 42)))))))
On Allegro, this encounters no error. Clozure CL likewise.
It certainly does explode in an exciting way on SBCL, and in a way that seems to bork SLIME (SBCL 1.0.47, SLIME who-knows-what from cvs).
The following is enough to cause SBCL to choke:
(json:encode-json-to-string '(:c . 42))
and somehow this seems to be invoked by the above, although
(json:encode-json-to-string '((:c . 42)))
makes cl-json happy.
This really looks like an SBCL internal hiccup; may I suggest submitting the bug report also to sbcl-devel?
best, r
On 5 Jun 2011, at 23:47, Nicolas Martyanoff wrote:
The following form breaks when evaluated:
(json:encode-json-to-string '((:a . ((:b . ((:c . 42)))))))
Help! 11 nested errors. SB-KERNEL:*MAXIMUM-ERROR-DEPTH* exceeded.
Hello. That's expected behaviour (sort of).
Essentially, when ENCODE-JSON is passed a cons cell, it has no way of telling whether the cell is the head of A) an alist (which should be encoded as a JSON Object), or B) of a proper list which is not an alist (which should be encoded as a JSON Array), or C) of an improper list (which is unencodable and so should produce an error). So it tries the option B first, and, if that fails, the option A. In your case, this situation is reproduced on every level of nesting. The problem is that SB-KERNEL:*MAXIMUM-ERROR-DEPTH* is quite shallow by default (10), and the try-proper-list-fall-back-to-alist approach results in a layering of nested conditions which is deeper than that number. Writing, e. g.,
(let ((sb-kernel:*maximum-error-depth* 20)) (json:encode-json-to-string '((:a . ((:b . ((:c . 42))))))))
produces the correct result, "{"a":{"b":{"c":42}}}" .
I know this is not a sustainable approach, but at this moment I have no good idea how to modify CL-JSON to get around this issue. Your best options at this moment would be to use either CLOS objects instead of alists, or the explicit encoder from the repository version:
(json:with-explicit-encoder (json:encode-json-to-string '(:object :a (:object :b (:object :c 42)))))
or
(json:with-explicit-encoder (json:encode-json-to-string '(:object (:a . (:object (:b . (:object (:c . 42))))))))
Sincerely, - B. Smilga.