[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ANN] guile-msgpack: MessagePack for GNU Guile (+ help needed)

From: HiPhish
Subject: Re: [ANN] guile-msgpack: MessagePack for GNU Guile (+ help needed)
Date: Wed, 19 Sep 2018 16:06:48 +0200

Thompson, David wrote:
> So does this allow for sending over arbitrarily nested s-expressions
> (i.e. anything supported by Guile's 'read' and 'write' procedures)?
> For example:
>     (pack '((foo . 1) (bar . (2 3 4)) (baz . "hello")))
Not quite, you are limited to the types MessagePack defines, because the 
recipient might have no idea what types Guile has. Think of it like binary 
JSON. However, the standard leaves room for your own extension via the `ext` 
type. There is an example in the documentation:

    (define (rational->ext x)
      (make-ext 13
                (pack (vector (numerator   x)
                              (denominator x)))))

Let's say you want to pack an exact rational number while preserving its 
exactness. There is nothing in the spec that supports such a type, so we will 
chose to represent rational number as an extension with the number 13 (no 
particular reason). An extension is a pair of a number and the data as a 
bytevector. The simplest way to encode the numerator and denominator is to 
pack a vector of the two numbers.

You can now pack this ext object and send it off through a port where on the 
other end the recipient hopefully knows what to do with an extension object of 
type 13:

    (pack! (rational->ext 2/3) (current-output-port))

If you receive such an object it's easy to make a rational number from it 

    (define (ext13->rational e)
      ;; The data gets unpacked as a vector of two numbers
      (define numbers (unpack (ext-data e)))
      ;; The result is the quotient of those two numbers
      (/ (vector-ref numbers 0)
         (vector-ref numbers 1)))

If you don't want to go through this conversion ritual every time you can also 
register rational numbers with the `packing-table` parameter. The manual goes 
into more detail. But yes, with extension you could in principle pack an 
expression like ` '((foo . 1) (bar . (2 3 4)) (baz . "hello"))`, you would 
just have to first define *how* to pack pairs. Symbols are currently packed as 
strings, but that can be overridden as well.

> Guile doesn't provide any static type system. I haven't looked at your
> source, but when you say "a pair", do you mean a literal cons cell?
> If so, I recommend switching to record types via the (srfi srfi-9)
> module.  You can write a custom constructor that does the type checks
> if you'd like.
I already use SRFI 9 (define-record-type) to generate everything, an `ext` is 
a record with two slots. I'll look into it again then, seems like I missed 
that part.

> You could resolve this by changing 'pack' to only accept a single
> value. If the user wants to pack multiple items, then they would pass
> a list or vector.
MessagePack already defines arrays (vectors), so packing a vector of three 
objects and packing three objects is not the same.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]