[Openmcl-devel] square bracket list

Taoufik Dachraoui dachraoui.taoufik at gmail.com
Sun Jul 24 13:28:02 UTC 2011


Thank you it is exactly what i needed.

I had to modify the code as follows:

? (cons 1 nil)
(1)
? (my-special-print (cons 1 nil) *standard-output*)
(1 NIL)
(1)

(:method ((object cons) stream)
   (flet ((print-list (start list end stream)
            (princ start stream)
            (when list
              (loop
                 :for cell = list :then (cdr cell)
                 :do (if (not (eq cell list)) (princ " " stream))
                     (my-special-print (car cell) stream)
                     (cond
                       ((null (cdr cell))
                        (loop-finish))
                       ((atom (cdr cell))
                        (princ " . " stream)
                        (my-special-print (cdr cell) stream)
                        (loop-finish)))))
            (princ end stream)))
     (cond
       ((eql (car object) #\[)  (print-list #\[ (cdr object) #\] stream))
       ((eql (car object) #\{)  (print-list #\{ (cdr object) #\} stream))
       (t                       (print-list #\( object       #\) stream))))
   object)

? (my-special-print (cons 1 nil) *standard-output*)
(1)
(1)
?

Kind regards
Taoufik

On Sun, Jul 24, 2011 at 1:46 PM, Pascal J. Bourguignon
<pjb at informatimago.com> wrote:
> Taoufik Dachraoui <dachraoui.taoufik at gmail.com> writes:
>> On Sun, Jul 24, 2011 at 11:56 AM, Taoufik Dachraoui
>> <dachraoui.taoufik at gmail.com> wrote:
>>> Hi
>>>
>>> is it possible to print special lists using square brackets
>>>
>>> example:
>>>
>>> (a b [1 2 3] e)
>>>
>>> the list [1 2 3] is special and is printed using a square bracket.
>>>
>>> I can cons a special character to differentiate special lists like the
>>> following:
>>>
>>> (a b (#\$ 1 2 3) e)
>>>
>>> but it is better if i can find a way to print special lists using
>>> square brackets.
>>
>> to be more precise, is there a way to print lists depending on the car
>> of the list
>>  (cond
>>    ((eq (car lst) #\[) (print list using [...]))
>>    ((eq (car lst) #\{) (print list using {...}))
>>    (t (print list using (...))))
>
> AFAIK, it is not possible, with the standard printer and print-object
> generic function.
>
> The problem is that you're not allowed by 11.1.2.1.2 point 19. to define
> a method of print-object on the standard class CONS.
> Furthermore, PRINT may just NOT call PRINT-OBJECT on standard types.
>
> Therefore the only conforming solution you have is to define your own
> printing function and/or your own printing generic function and methods.
>
> Beware that you are not allowed to call directly PRINT-OBJECT yourself!
>
>
>
> (defgeneric my-special-print (object stream)
>  ;; BUG: Doesn't handle circular structures!
>  ;; See "4.3.7 Integrating Types and Classes" for the classes you can use.
>  (:method ((object bit-vector) stream)
>    ;; bit-vectors are vectors, but they cannot contain special lists.
>    (prin1 object stream))
>  (:method ((object string) stream)
>    ;; strings are vectors, but they cannot contain special lists.
>    (prin1 object stream))
>  (:method ((object vector) stream)
>    (princ "#(" stream)
>    (when (plusp (length object))
>      (my-special-print (aref object 0) stream))
>    (loop :for i :from 1 :below (length object)
>       :do (princ " " stream)
>       (my-special-print (aref object i) stream))
>    (princ ")" stream)
>    object)
>  (:method ((object array) stream)
>    ;; have fun, implementing multi-dimensional array printing.
>    object)
>  (:method ((object hash-table) stream)
>    ;; some implementations can print the hash-table contents
>    ;; perhaps you'll want to do so you too.
>    object)
>  (:method ((object cons) stream)
>    (flet ((print-list (start list end stream)
>             (princ start stream)
>             (when list
>               (my-special-print (car list) stream)
>               (loop
>                  :for cell = (cdr list) :then (cdr cell)
>                  :do (princ " " stream)
>                      (my-special-print (car cell) stream)
>                      (cond
>                        ((null (cdr cell))
>                         (loop-finish))
>                        ((atom (cdr cell))
>                         (princ " . " stream)
>                         (my-special-print (cdr cell) stream)
>                         (loop-finish)))))
>             (princ end stream)))
>      (cond
>        ((eql (car object) #\[)  (print-list #\[ (cdr object) #\] stream))
>        ((eql (car object) #\{)  (print-list #\{ (cdr object) #\} stream))
>        (t                       (print-list #\( object       #\) stream))))
>    object)
>  (:method ((object t) stream)
>    (prin1 object stream)))
>
> CL-USER> (my-special-print #((a b (#\{ c d) (#\[ e f)) 42 "Hello" (g h i) (#\{ k l (#\{ c d) (#\[ e f) m n)) *standard-output*)
> #((A B {C D} [E F]) 42 "Hello" (G H I) {K L {C D} [E F] M N})
> #((A B (#\{ C D) (#\[ E F)) 42 "Hello" (G H I) (#\{ K L (#\{ C D) (#\[ E F) M N))
>
>
> Of course if you need a REPL to use my-special-print instead of print,
> you can write your own REPL.
> See for example: http://paste.lisp.org/display/18280
>
>
>
> http://www.lispworks.com/documentation/HyperSpec/Body/11_abab.htm
> http://www.lispworks.com/documentation/HyperSpec/Body/f_pr_obj.htm#print-object
>
> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
> A bad day in () is better than a good day in {}.
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>



More information about the Openmcl-devel mailing list