From: Fernando Mato Mira
Subject: One of the best reasons to learn SERIES
Date: 
Message-ID: <2ce16d$50f@disuns2.epfl.ch>
Here's a great example of why SERIES is so cool:

(defun dump-htable-of-htables (tb)
  (iterate (((key val) (scan-hash tb)))
    (format t "~%Key: ~S Value: ~%" key)
    (iterate (((sub-key sub-val) (scan-hash val)))
      (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))))

Write the same using WITH-HASH-TABLE-ITERATOR instead,
and you'll see..

-- 
Fernando D. Mato Mira                           
Computer Graphics Lab                           
Swiss Federal Institute of Technology (EPFL)    Phone    : +41 (21) 693 - 5248
CH-1015 Lausanne                                FAX      : +41 (21) 693 - 5328
Switzerland                                     E-mail   : ········@di.epfl.ch

"The only good C++ is a corrupt C++."

From: Robert P. Goldman
Subject: is SERIES way cool?
Date: 
Message-ID: <1993Nov18.191959.19182@src.honeywell.com>
Has it been reimplemented in a CLtL2-compatible way?
From: Zdzislaw Meglicki
Subject: Re: is SERIES way cool?
Date: 
Message-ID: <2dmb0j$7uh@manuel.anu.edu.au>
In article <······················@src.honeywell.com>, ·······@src.honeywell.com (Robert P. Goldman) writes:
|> 
|> Has it been reimplemented in a CLtL2-compatible way?

We had problems running "series" under Lucid 4.0.2. It worked OK, but the
compiled code was disappointingly slow. Compiled and optimised (?) 
Lucid CL 4.0.2 + series was 5 times slower than New Jersey SML with unoptimised
streams implemented the way discussed in Paulson's book. To make things worse
ephemeral garbage collection could not be used - it looks like there might have
been a clash between "series" and whatever Lucid compiler attempts to do.

However, from pure programming point of view "series" provides a very neat 
replacement for iteration and maps very elegantly on various problems - we
tried it with ODEs. It was fun to program and real dog to optimise and run.

For more detailed information contact ·····@arp.anu.edu.au".

-- 
   Zdzislaw Meglicki, ·················@cisr.anu.edu.au,
   Automated Reasoning Program - CISR, and Plasma Theory Group - RSPhysSE,
   The Australian National University, Canberra, A.C.T., 0200,
   Australia, fax: +61-6-249-0747, tel: +61-6-249-0158
From: Espen J. Vestre
Subject: Re: One of the best reasons to learn SERIES
Date: 
Message-ID: <2cibs8INN9og@coli-gate.coli.uni-sb.de>
In article <··········@disuns2.epfl.ch> Fernando Mato Mira,
········@disun45.epfl.ch writes:
> Here's a great example of why SERIES is so cool:
> 
> (defun dump-htable-of-htables (tb)
>   (iterate (((key val) (scan-hash tb)))
>     (format t "~%Key: ~S Value: ~%" key)
>     (iterate (((sub-key sub-val) (scan-hash val)))
>       (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))))
> 
> Write the same using WITH-HASH-TABLE-ITERATOR instead,
> and you'll see..

I see, but:
What makes your example better than

(defun dump-htable-of-htables (tb)
  (maphash 
   #'(lambda(key val)
       (format t "~%Key: ~S Value: ~%" key)
       (maphash 
        #'(lambda(sub-key sub-val)
            (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))
        val))
   tb))

?

(btw: Of course your SERIES example macroexpands into code using MAPHASH!)

  Espen
________________________________________________________________________
 Espen J. Vestre,                                  ·····@coli.uni-sb.de
 Universit�t des Saarlandes,
 Computerlinguistik, Geb�ude 17.2
 Postfach 1150,                                 tel. +49 (681) 302 4501
 D-66041 SAARBR�CKEN, Germany                   fax. +49 (681) 302 4351
From: Mark A. Tapia
Subject: Re: One of the best reasons to learn SERIES
Date: 
Message-ID: <1993Nov19.095732.21000@jarvis.csri.toronto.edu>
In article <············@coli-gate.coli.uni-sb.de> Espen J. Vestre <·····@coli.uni-sb.de> writes:
in response to Fernando Mato Mira (········@disun45.epfl.ch) espousal
of the series package proposing: to replace
>>
>> (defun dump-htable-of-htables (tb)
>>   (iterate (((key val) (scan-hash tb)))
>>     (format t "~%Key: ~S Value: ~%" key)
>>     (iterate (((sub-key sub-val) (scan-hash val)))
>>       (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))))
>> 
With
>
>(defun dump-htable-of-htables (tb)
>  (maphash 
>   #'(lambda(key val)
>       (format t "~%Key: ~S Value: ~%" key)
>       (maphash 
>        #'(lambda(sub-key sub-val)
>            (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))
>        val))
>   tb))
>
Neither example handles n-level hash tables (where the values are themselves
hash tables, which in turn are hash tables). The following code uses
loop to print the keys of nested hash tables:

(defun non-empty-hash-table (table)
  (when (hash-table-p table)
    (unless (zerop (hash-table-count table))
      table)))

(defun dump-hash-keys (table &optional keys)
  (when (non-empty-hash-table table)
    (loop for key being the hash-key in table using (hash-value value)
          if (hash-table-p value)
          do (dump-hash-keys value (cons key keys))
          else do (format t "~&   Keys ~{~s ~}~%" (reverse (cons key keys))))))


Mark Tapia
From: Harley Davis
Subject: Re: One of the best reasons to learn SERIES
Date: 
Message-ID: <DAVIS.93Nov22153451@passy.ilog.fr>
In article <······················@jarvis.csri.toronto.edu> ·····@dgp.toronto.edu (Mark A. Tapia) writes:

   Neither example handles n-level hash tables (where the values are
   themselves hash tables, which in turn are hash tables). The
   following code uses loop to print the keys of nested hash tables:

What's usually needed in these cases is multi-keyed hash tables.  For
example, in Ilog Talk:

(let ((ht (make-hash-table 2)))
  (setf (htref ht 'k11 'k12) 'v1)
  (setf (htref ht 'k21 'k22) 'v2)
  (for (((key1 key2 value) in-hash-table: ht)
        (index from: 0))
    (printf "%d: Key1 is %s, key2 is %s, and value is %s.\n" 
            index key1 key2 value)))

1: Key1 is k11, key2 is k12, and value is v1.
2: Key1 is k21, key2 is k22, and value is v2.

-- Harley Davis
--

------------------------------------------------------------------------------
nom: Harley Davis			ILOG S.A.
net: ·····@ilog.fr			2 Avenue Gallie'ni, BP 85
tel: (33 1) 46 63 66 66			94253 Gentilly Cedex, France
From: Fernando Mato Mira
Subject: Re: One of the best reasons to learn SERIES
Date: 
Message-ID: <2cjf93$30n@disuns2.epfl.ch>
In article <············@coli-gate.coli.uni-sb.de>, Espen J. Vestre <·····@coli.uni-sb.de> writes:

|> What makes your example better than ...

OK. Given maphash, the solutions could be considered equivalent.

Now, for the relative advantages of each approach, for those who like to
knit fine:

1. MAPHASH

   a. Easier to port when moving to another lisp-like language where SERIES is not available.
   b. One construct to learn (maphash) against two in the other case (iterate + scan-hash).

2. SERIES

   a. Easier to read for non-lispers
   b. The tables argument to maphash are more difficult to find in the code than the
      tables on which iterate is operating (they are on the same line, and well marked by scan-hash.
   c. Usual formatting styles result in at least one less line of code per iteration in the SERIES version
      (better for screen display).
   d. Non-lispers will say lambdas confuse them
   e. Schemers will be happy not having to write #' :-)

-- 
Fernando D. Mato Mira                           
Computer Graphics Lab                           
Swiss Federal Institute of Technology (EPFL)    Phone    : +41 (21) 693 - 5248
CH-1015 Lausanne                                FAX      : +41 (21) 693 - 5328
Switzerland                                     E-mail   : ········@epfl.ch

"My e-mail address got shorter again!"
From: Jason Trenouth
Subject: Re: One of the best reasons to learn SERIES
Date: 
Message-ID: <JASON.93Nov19133434@monty.harlqn.co.uk>
>>>>> On 17 Nov 1993 20:22:37 GMT, ········@disun45.epfl.ch (Fernando Mato Mira) said:

Fernando> Here's a great example of why SERIES is so cool:
Fernando> 
Fernando> (defun dump-htable-of-htables (tb)
Fernando>   (iterate (((key val) (scan-hash tb)))
Fernando>     (format t "~%Key: ~S Value: ~%" key)
Fernando>     (iterate (((sub-key sub-val) (scan-hash val)))
Fernando>       (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))))
Fernando> 
Fernando> Write the same using WITH-HASH-TABLE-ITERATOR instead,
Fernando> and you'll see..

Alternatively (in Common Lisp):

[1]

(defun dump-htable-of-htables (tb)
  (loop for key being each hash-key of db using (hash-value val) do
    (format t "~%Key: ~S Value: ~%" key)
    (loop for sub-key being each hash-key of val using (hash-value sub-val) do
      (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))))

[2]

(defun dump-htable-of-htables (tb)
  (maphash #'(lambda (key val)
               (format t "~%Key: ~S Value: ~%" key)
               (maphash #'(lambda (sub-key sub-val)
                            (format t "~%   Key: ~S Value: ~S ~%" sub-key sub-val))
                        val))
           db))
--
_____________________________________________________________________________
| Jason Trenouth,                        | EMAIL: ·····@uk.co.harlequin     |
| Harlequin Ltd, Barrington Hall,        | TEL:   (0223) 872522             |
| Barrington, Cambridge CB2 5RG, UK      | FAX:   (0223) 872519             |