• deftype and side-effects

    From Stefan Monnier@21:1/5 to All on Mon May 5 19:06:45 2025
    I can't see anything in the hyperspec about the semantics of "derived
    type specifiers" (DTS) when the FORM that defines them has side-effects.
    E.g.

    (deftype my-funny-vector (elem)
    "A funny vector type."
    `(vector ,elem ,(random 100)))

    IOW, when are DTS expanded? Is it firmly in the
    "implementation-defined" nebula, or does the hyperspec make it more
    precise somewhere?


    Stefan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Stefan Monnier on Mon May 5 23:22:45 2025
    On 2025-05-05, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
    I can't see anything in the hyperspec about the semantics of "derived
    type specifiers" (DTS) when the FORM that defines them has side-effects.
    E.g.

    (deftype my-funny-vector (elem)
    "A funny vector type."
    `(vector ,elem ,(random 100)))

    IOW, when are DTS expanded? Is it firmly in the
    "implementation-defined" nebula, or does the hyperspec make it more
    precise somewhere?

    It mentions:

    "The programmer must ensure that the body of a deftype form can be
    evaluated at compile time if the name is referenced in subsequent type
    declarations."

    From which we can infer that one situation that might cause the material
    to be evaluated is when the type name is mentioned in a declaration, and
    it happens at that time, such as in a compiler. But more importantly,
    it seems to be saying that the compiler must not expand deftypes
    if they are not mentioned in a declaration. (However, that doesn't
    necessarily mean anything, since Common Lisp allows arbitrary compile
    time computations. I think it can be interpreted as meaning that the compilation process won't inherently expand deftypes, so the only way
    it will happen is if the program goes out of the way to arrange it
    itself.)

    Could it expand separately each time the name is mentioned, or is there
    a cache? The spec is mum about that.

    The side effect /cannot/ reasonably be counted upon to be executed
    as many times as the name is mentioned somewhere in some type cruft.

    In code that is not being compiled, it seems that it is permissible
    for the deftype to expand immediately and associate the name with
    the expanded type.

    I'm guessing it could be propagated to run-time if the program uses
    not only eval and compible, but, say, subtypep without constant-time
    reducible arguments.

    Say we calculate lists L1 and L2 which are the syntax of types,
    and call (subtypep L1 L2). They reference the name in our deftype.
    The expansion and side effect will happen then, surely.

    But if the type is not subsequently redefined, maybe the expansion
    stays cached somewhere.

    The spec doesn't talk about these things because it is not envisioned
    that someone be be stuffing side effects into deftype; but the
    need for any referenced helper functions to be defined at compile
    time must be mentioned.

    (I'm actually surprised that the body of deftype isn't a single form,
    but progn-like, for imperative programming.)

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Tue May 6 09:04:25 2025
    i refer you both to my discussions with tim bradshaw and ron garret
    from october 2009 on comp.lang.lisp under the subject
    "Re: DEFSTRUCT and lexical environment"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Tue May 6 11:23:52 2025
    Could it expand separately each time the name is mentioned, or is
    there a cache? The spec is mum about that.

    IOW, I didn't miss anything? Not sure if I should be happy about it.

    The side effect /cannot/ reasonably be counted upon to be executed
    as many times as the name is mentioned somewhere in some type cruft.

    That's the main question for me.

    I'm guessing it could be propagated to run-time if the program uses
    The spec doesn't talk about these things because it is not envisioned
    that someone be be stuffing side effects into deftype;

    I'd have hoped to see some mention that the body's side-effect can't be
    relied upon or something like that.

    but the need for any referenced helper functions to be defined at
    compile time must be mentioned.

    That one makes sense:

    (defun my-fun ...)
    (deftype my-type ()
    (my-fun ..))

    Clearly needs `my-fun` to be defined when `my-type` appears in code
    being compiled.

    (I'm actually surprised that the body of deftype isn't a single form,
    but progn-like, for imperative programming.)

    🙂


    Stefan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)