unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* prefab structs in guile
@ 2012-07-05  8:00 ` Andy Wingo
  2012-07-05 20:57   ` bug#11198: " Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Wingo @ 2012-07-05  8:00 UTC (permalink / raw)
  To: guile-devel; +Cc: 11198

Hi,

We should think about supporting prefab structs in Guile.  For more
details, see:

  http://docs.racket-lang.org/guide/define-struct.html?q=prefab#%28part._prefab-struct%29
  http://docs.racket-lang.org/reference/structures.html?q=record&q=structs&q=records#(tech._prefab)

The reason is that sometimes you want to allow structures to be
serialized (to Scheme or into object code) and read back in.  See bug
11198 for an example.

I don't have time for this currently, but here's one plan on how you
would do it.

  You would create a new Scheme module, (ice-9 prefab) or
something.  It would contain a map from (name, number of fields) ->
record type descriptor.  (We don't have #:mutable, #:auto, or
supertypes; these would be separate projects.)

  Then you would modify the reader to call out to (ice-9 prefab) with
the list after #s, e.g. the (foo ...) in #s(foo ...).  (ice-9 prefab)
would return the record, creating the RTD if needed.

  You also modify the printer.

  You also modify SRFI-9's define-record-type to recognize #:prefab, or
some other name.

  You also add code to the glil->assembly compiler to recognize prefab
structs, and you add an opcode to look up a prefab struct RTD.

I think that would be it.

Anyone interested?

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
       [not found] ` <877gui7i3y.fsf__23815.4873405167$1341492684$gmane$org@pobox.com>
@ 2012-07-05 13:42   ` Thien-Thi Nguyen
  2012-07-05 15:21     ` Andy Wingo
  0 siblings, 1 reply; 9+ messages in thread
From: Thien-Thi Nguyen @ 2012-07-05 13:42 UTC (permalink / raw)
  To: guile-devel

() Andy Wingo <wingo@pobox.com>
() Thu, 05 Jul 2012 10:00:17 +0200

   For more details, see:

     [...]

See also (info "(elisp) Byte Packing")
which describes Emacs' bindat.el.

The context there is network protocols,
but the design requirements are the same.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 13:42   ` Thien-Thi Nguyen
@ 2012-07-05 15:21     ` Andy Wingo
  0 siblings, 0 replies; 9+ messages in thread
From: Andy Wingo @ 2012-07-05 15:21 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: guile-devel

On Thu 05 Jul 2012 15:42, Thien-Thi Nguyen <ttn@gnuvola.org> writes:

> See also (info "(elisp) Byte Packing")
> which describes Emacs' bindat.el.
>
> The context there is network protocols,
> but the design requirements are the same.

Interesting.  The use cases are a bit different though; much of bindat
seems to be covered by bytevectors, whereas prefab "structs" (really,
records) can contain arbitrary Scheme data -- symbols, strings, arrays,
etc.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05  8:00 ` prefab structs in guile Andy Wingo
@ 2012-07-05 20:57   ` Ludovic Courtès
  2012-07-05 21:06     ` Andy Wingo
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2012-07-05 20:57 UTC (permalink / raw)
  To: Andy Wingo; +Cc: 11198, guile-devel

Hello,

Andy Wingo <wingo@pobox.com> skribis:

>   Then you would modify the reader to call out to (ice-9 prefab) with
> the list after #s, e.g. the (foo ...) in #s(foo ...).  (ice-9 prefab)
> would return the record, creating the RTD if needed.

The problem with this is that one could precisely forge instances of a
given record type, thereby breaking the type safety we currently have
(each instance of a record type is genuine, in the sense of Rees’ “A
Security kernel Based on the Lambda-Calculus”.)

Does Racket address this somehow?

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 20:57   ` bug#11198: " Ludovic Courtès
@ 2012-07-05 21:06     ` Andy Wingo
  2012-07-05 21:55       ` Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Wingo @ 2012-07-05 21:06 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 11198, guile-devel

On Thu 05 Jul 2012 22:57, ludo@gnu.org (Ludovic Courtès) writes:

> Andy Wingo <wingo@pobox.com> skribis:
>
>>   Then you would modify the reader to call out to (ice-9 prefab) with
>> the list after #s, e.g. the (foo ...) in #s(foo ...).  (ice-9 prefab)
>> would return the record, creating the RTD if needed.
>
> The problem with this is that one could precisely forge instances of a
> given record type, thereby breaking the type safety we currently have
> (each instance of a record type is genuine, in the sense of Rees’ “A
> Security kernel Based on the Lambda-Calculus”.)
>
> Does Racket address this somehow?

See:

  http://docs.racket-lang.org/guide/define-struct.html?q=record&q=structs&q=records#(part._prefab-struct)

Specifically:

  Every prefab structure type is transparent—but even less abstract than
  a transparent type, because instances can be created without any
  access to a particular structure-type declaration or existing
  examples. Overall, the different options for structure types offer a
  spectrum of possibilities from more abstract to more convenient:

    Opaque (the default) : Instances cannot be inspected or forged without
    access to the structure-type declaration. As discussed in the next
    section, constructor guards and properties can be attached to the
    structure type to further protect or to specialize the behavior of its
    instances.

    Transparent : Anyone can inspect or create an instance without access
    to the structure-type declaration, which means that the value printer
    can show the content of an instance. All instance creation passes
    through a constructor guard, however, so that the content of an
    instance can be controlled, and the behavior of instances can be
    specialized through properties. Since the structure type is generated
    by its definition, instances cannot be manufactured simply through the
    name of the structure type, and therefore cannot be generated
    automatically by the expression reader.

    Prefab : Anyone can inspect or create an instance at any time, without
    prior access to a structure-type declaration or an example
    instance. Consequently, the expression reader can manufacture
    instances directly. The instance cannot have a constructor guard or
    properties.

  Since the expression reader can generate prefab instances, they are
  useful when convenient serialization is more important than
  abstraction. Opaque and transparent structures also can be serialized,
  however, if they are defined with define-serializable-struct as
  described in Datatypes and Serialization.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 21:06     ` Andy Wingo
@ 2012-07-05 21:55       ` Ludovic Courtès
  2012-07-05 22:03         ` Andy Wingo
  2012-07-05 22:06         ` Andy Wingo
  0 siblings, 2 replies; 9+ messages in thread
From: Ludovic Courtès @ 2012-07-05 21:55 UTC (permalink / raw)
  To: Andy Wingo; +Cc: 11198, guile-devel

Hi,

Andy Wingo <wingo@pobox.com> skribis:

>   Since the expression reader can generate prefab instances, they are
>   useful when convenient serialization is more important than
>   abstraction. Opaque and transparent structures also can be serialized,
>   however, if they are defined with define-serializable-struct as
>   described in Datatypes and Serialization.

So I’d be in the ‘define-serializable-struct’ camp, so to speak.

Prefabs raise an number of interesting issues.  For instance, what’s the
meaning of #s(sprout bean #f 17) in a module where ‘sprout’ is unbound?
In a module where it’s bound to a given RTD vs. in a module where it’s
bound to a different RTD?  Does ‘read’ have to be current-module-aware?
Etc.

This example is a bit scary to me:

    > (define lunch '#s(sprout bean))
                                     
    > (struct sprout (kind) #:prefab)
                                     
    > (sprout? lunch)                
    #t                               

since it implies that types are compared by name.

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 21:55       ` Ludovic Courtès
@ 2012-07-05 22:03         ` Andy Wingo
  2012-07-05 22:14           ` Ludovic Courtès
  2012-07-05 22:06         ` Andy Wingo
  1 sibling, 1 reply; 9+ messages in thread
From: Andy Wingo @ 2012-07-05 22:03 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 11198, guile-devel

On Thu 05 Jul 2012 23:55, ludo@gnu.org (Ludovic Courtès) writes:

> So I’d be in the ‘define-serializable-struct’ camp, so to speak.

That's a valid position to have in general.  I can also imagine cases in
which you would choose other things.  It's a spectrum.

> Prefabs raise an number of interesting issues.  For instance, what’s the
> meaning of #s(sprout bean #f 17) in a module where ‘sprout’ is unbound?

Prefab structs are not modular.  It is the same as in a module where
`sprout' is bound.  Reading #s(sprout bean #f 17) may create an RTD if
needed, but it does not create any bindings.

> types are compared by name.

As the documentation clearly indicates :), prefab structs are indeed
compared by name, though in a combination with other characteristics
(number of fields, and more characteristics for racket).

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 21:55       ` Ludovic Courtès
  2012-07-05 22:03         ` Andy Wingo
@ 2012-07-05 22:06         ` Andy Wingo
  1 sibling, 0 replies; 9+ messages in thread
From: Andy Wingo @ 2012-07-05 22:06 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 11198, guile-devel

On Thu 05 Jul 2012 23:55, ludo@gnu.org (Ludovic Courtès) writes:

> Andy Wingo <wingo@pobox.com> skribis:
>
>>   Since the expression reader can generate prefab instances, they are
>>   useful when convenient serialization is more important than
>>   abstraction. Opaque and transparent structures also can be serialized,
>>   however, if they are defined with define-serializable-struct as
>>   described in Datatypes and Serialization.
>
> So I’d be in the ‘define-serializable-struct’ camp, so to speak.

To be clear: in Racket, serializable structs are not readable.  That's
the whole point of prefab structs: a struct that is readable.

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bug#11198: prefab structs in guile
  2012-07-05 22:03         ` Andy Wingo
@ 2012-07-05 22:14           ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2012-07-05 22:14 UTC (permalink / raw)
  To: Andy Wingo; +Cc: 11198, guile-devel

Hi,

Andy Wingo <wingo@pobox.com> skribis:

> On Thu 05 Jul 2012 23:55, ludo@gnu.org (Ludovic Courtès) writes:
>
>> So I’d be in the ‘define-serializable-struct’ camp, so to speak.
>
> That's a valid position to have in general.  I can also imagine cases in
> which you would choose other things.  It's a spectrum.

Yes, sure.  It can be convenient to have something that makes it easy to
serialize structs.  But given that prefabs have to be “built in”, and
that they look can-of-wormey to my demanding eye ;-), I’d be in favor of
anything built atop structs.

And actually, there’s (oop goops save), which is extensible and
everything.  :-)

Side note: while writing readers/writers by hand may look tedious, the
advantage is that it makes it easy to leave room for future extensions,
like allowing the reader to suitably map an old version of a serialized
struct to the new data structure.

>> Prefabs raise an number of interesting issues.  For instance, what’s the
>> meaning of #s(sprout bean #f 17) in a module where ‘sprout’ is unbound?
>
> Prefab structs are not modular.  It is the same as in a module where
> `sprout' is bound.  Reading #s(sprout bean #f 17) may create an RTD if
> needed, but it does not create any bindings.

OK.  So there can only be one ‘sprout’ prefab RTD in the whole process,
I guess.

>> types are compared by name.
>
> As the documentation clearly indicates :), prefab structs are indeed
> compared by name, though in a combination with other characteristics
> (number of fields, and more characteristics for racket).

Right.  Argh.

Thanks,
Ludo’.



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-07-05 22:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <Pine.LNX.4.61.1204072212190.6107@commlink.zdv.uni-tuebingen.de>
2012-07-05  8:00 ` prefab structs in guile Andy Wingo
2012-07-05 20:57   ` bug#11198: " Ludovic Courtès
2012-07-05 21:06     ` Andy Wingo
2012-07-05 21:55       ` Ludovic Courtès
2012-07-05 22:03         ` Andy Wingo
2012-07-05 22:14           ` Ludovic Courtès
2012-07-05 22:06         ` Andy Wingo
     [not found] ` <877gui7i3y.fsf__23815.4873405167$1341492684$gmane$org@pobox.com>
2012-07-05 13:42   ` Thien-Thi Nguyen
2012-07-05 15:21     ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).