Hi all,

with version 22.5.26 PicoLisp has two new powerful functions: 'input' and
'output' (haha, no kidding!).

They offer some quite interesting possibilities.

See the references at https://software-lab.de/doc/refI.html#input and
https://software-lab.de/doc/refO.html#output

They operate on the character level. Both take an 'exe', which should return the
next char on input, or receive a char (and optionally the next look-ahead char)
to be output (or handled in some other way).

'output', for example, could convert everything to upper case

   : (output (prin (uppc @@))
      (prinl "abc") )
   ABC

Or insert a carriage return before every linefeed unless it is not already
present:

   (output
      (cond
         ((= "\n" @@)
            (prin "\r\n") )
         ((nand (= "\n" @@@) (= "\r" @@))
            (prin @@) ) )
      ... printing code ... )



We often had the question how to "print" into a string. Until now this was not
really possible, except with the hardcoded conversion functions 'any', 'sym'
and 'str'.

Now, with 'output', we can do that:

   : (pack
      (make
         (output (link @@)
            (print '(+ 2 (* 3 4))) ) ) )
   -> "(+ 2 (* 3 4))"

The same goes for 'input':

   : (let S (chop "(+ 2 (* 3 4))")
      (input (++ S)
         (read) ) )
   -> (+ 2 (* 3 4))


Of course these functions can be nested in 'in' and 'out' calls and thus work as
filters, or even nest themselves:

   : (let S (chop "ABC")
      (input (++ S)
         (input (and (char) (char (inc (char @))))
            (while (char)
               (println @) ) ) ) )
   "B"
   "C"
   "D"
   -> "D"

   : (output (prin (uppc @@))
      (output (println @@ @@@)
         (prin "abc") ) )
   "A" "B"
   "B" "C"
   "C" NIL
   -> "abc"

These are a bit nonrealistic examples, but a real use case is e.g. in
'serverSend', which needs to put the String "data: " before each line of HTML
output (see @lib/xhtml.l):

   (de serverSend (Sock . Prg)
      (when Sock
         (out @
            (ht:Out (bool *Chunked)
               (prin "data: ")
               (output
                  (cond
                     ((<> "\n" @@) (prin @@))
                     (@@@ (prin "\ndata: ")) )
                  (htPrin Prg 2) )
               (prinl "\n") ) ) ) )

   : (serverSend 1
      (<table> NIL NIL NIL
         (<row> NIL 123 "abc") ) )
   data: <table>
   data: <tr>
   data: <td>123</td>
   data: <td>abc</td>
   data: </tr>
   data: </table>

Let's explore the chances and limits of these concepts!

☺/ A!ex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to