• defining self-evaluating objects

    From James Cloos@21:1/5 to All on Wed Apr 12 12:41:03 2023
    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    searching didn’t return any help.

    i looked through the sbcl src to see how t is defined, but could not
    find it. nor did i find the code responsible for keywords...

    -JimC
    --
    James Cloos <[email protected]> OpenPGP: 0x997A9F17ED7DAEA6

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to James Cloos on Wed Apr 12 17:41:36 2023
    On Wed, 12 Apr 2023 12:41:03 -0400
    James Cloos <[email protected]> wrote:
    does cl support defining new self-evaluating objects
    (other than keywords)?

    Not that I know of but perhaps you can give some more information what
    kind of thing you have in mind or what you're trying to achieve. Perhaps
    reader macros would help.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Bawden@21:1/5 to All on Wed Apr 12 14:24:56 2023
    James Cloos <[email protected]> writes:

    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    Anything that isn't a symbol or a cons is self-evaluating. So you can
    just make new instances of any class or structure:

    * (defstruct frob)
    frob
    * #S(frob)
    #S(frob)

    - Alan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Russ@21:1/5 to James Cloos on Wed Apr 12 18:15:33 2023
    On Wednesday, April 12, 2023 at 9:41:10 AM UTC-7, James Cloos wrote:
    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    What sort of "defining" did you have in mind.
    One simple answer (for symbols) would be:
    (defconstant foo 'foo)

    There may be other things you could do via reader macros.
    One example of that is https://github.com/lispm/measures [*], which defined numbers with dimensions and optional reader macros so that something like
    35km or 18m/s2 would evaluate to equivalent objects, although not in an EQ sense.



    [* Software by Rainer Joswig that I extended while at ISI]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Russ@21:1/5 to Tom Russ on Wed Apr 12 18:18:26 2023
    On Wednesday, April 12, 2023 at 6:15:36 PM UTC-7, Tom Russ wrote:
    On Wednesday, April 12, 2023 at 9:41:10 AM UTC-7, James Cloos wrote:
    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?
    What sort of "defining" did you have in mind.
    One simple answer (for symbols) would be:
    (defconstant foo 'foo)

    There may be other things you could do via reader macros.
    One example of that is https://github.com/lispm/measures [*], which defined numbers with dimensions and optional reader macros so that something like 35km or 18m/s2 would evaluate to equivalent objects, although not in an EQ sense.

    A clarification, I meant that two instances of 35km and 35km would be equivalent
    objects. And likewise for 18m/s2 and 18m/s2. As expected, 35km and 18m/s2 are not equivalent.




    [* Software by Rainer Joswig that I extended while at ISI]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Cloos@21:1/5 to All on Thu Apr 13 16:37:49 2023
    "TR" == Tom Russ <[email protected]> writes:

    One simple answer (for symbols) would be:
    (defconstant foo 'foo)

    now i'm feeling stupid. ☺

    that accomplished exactly what i was thiking of.

    thanks.

    -JimC
    --
    James Cloos <[email protected]> OpenPGP: 0x997A9F17ED7DAEA6

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Bawden@21:1/5 to All on Thu Apr 13 17:44:27 2023
    James Cloos <[email protected]> writes:

    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    Here's another possibility:

    * (defvar x #1='#1#)
    x

    The value of X is now a self-evaluating object. Here's proof:

    * (eq x (eval x))
    t

    You might find the printed representation of the value of X to be a bit inconvenient...

    [I normally run with *PRINT-CIRCLE* set to NIL, because I find it
    annoying in some situations, and I can rely on *PRINT-LEVEL* and
    *PRINT-LENGTH* to keep printed representations under control. But in
    SBCL 2.2.0 at least, that's not good enough to keep the above example
    from blowing the stack when it tries to print the value of X, and only
    setting *PRINT-CIRCLE* to T prevents that.]

    - Alan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to Alan Bawden on Thu Apr 13 17:53:54 2023
    On 4/13/2023 3:44 PM, Alan Bawden wrote:
    James Cloos <[email protected]> writes:

    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    Here's another possibility:

    * (defvar x #1='#1#)
    x

    The value of X is now a self-evaluating object. Here's proof:

    * (eq x (eval x))
    t

    You might find the printed representation of the value of X to be a bit inconvenient...

    [I normally run with *PRINT-CIRCLE* set to NIL, because I find it
    annoying in some situations, and I can rely on *PRINT-LEVEL* and
    *PRINT-LENGTH* to keep printed representations under control. But in
    SBCL 2.2.0 at least, that's not good enough to keep the above example
    from blowing the stack when it tries to print the value of X, and only
    setting *PRINT-CIRCLE* to T prevents that.]
    I don't think your example above really works. If X is self evaluating
    then (EQ X (QUOTE X)) should be T. And this requirement directly entails
    that the reader must be involved to some degree.
    --
    Jeff Barnett

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Bawden@21:1/5 to Alan Bawden on Fri Apr 14 00:26:23 2023
    Jeff Barnett <[email protected]> writes:

    On 4/13/2023 3:44 PM, Alan Bawden wrote:
    >
    > Here's another possibility:
    >
    > * (defvar x #1='#1#)
    > x
    >
    > The value of X is now a self-evaluating object. Here's proof:
    >
    > * (eq x (eval x))
    > t
    >
    > You might find the printed representation of the value of X to be a bit
    > inconvenient...
    >
    > [I normally run with *PRINT-CIRCLE* set to NIL, because I find it
    > annoying in some situations, and I can rely on *PRINT-LEVEL* and
    > *PRINT-LENGTH* to keep printed representations under control. But in
    > SBCL 2.2.0 at least, that's not good enough to keep the above example
    > from blowing the stack when it tries to print the value of X, and only
    > setting *PRINT-CIRCLE* to T prevents that.]
    I don't think your example above really works. If X is self evaluating then
    (EQ X (QUOTE X)) should be T. And this requirement directly entails that
    the reader must be involved to some degree.

    This is exactly why I didn't claim that "X is now a self-evaluating
    object". I explicity wrote that "THE VALUE OF X is now a
    self-evaluating object". I knew that the OP was almost certainly
    looking for something that he could easily type in repeatably, but he
    only ASKED for something that was "self-evaluating", so I (perhaps mischievously) chose to answer his literal question. And I don't know
    what "self-evaluating" could possibly mean unless it is defined as:

    (defun self-evaluating-p (x)
    (eq x (eval x)))

    - Alan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to James Cloos on Fri Apr 14 05:17:59 2023
    On 2023-04-12, James Cloos <[email protected]> wrote:
    does cl support defining new self-evaluating objects
    (other than keywords)?

    All objects are self-evaluating other than compound
    forms (non-empty list syntax), and bindable symbols.

    if so, how?

    searching didn’t return any help.

    i looked through the sbcl src to see how t is defined, but could not
    find it. nor did i find the code responsible for keywords...

    Ah, if you mean new symbols which evaluate to themselves,
    and are not the keywords or T or NIL?

    The obvious way is to just bind them as lexical variables
    (or perhaps globals) or macros.

    E.g.

    (define-symbol-macro foo 'foo)

    Now when foo is evaluated, it goes to (quote foo) which goes to foo.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Cloos@21:1/5 to All on Sat Apr 15 15:15:09 2023
    "KK" == Kaz Kylheku <[email protected]> writes:

    Ah, if you mean new symbols which evaluate to themselves,
    and are not the keywords or T or NIL?

    The obvious way is to just bind them as lexical variables
    (or perhaps globals) or macros.

    E.g.

    (define-symbol-macro foo 'foo)

    Now when foo is evaluated, it goes to (quote foo) which goes to foo.

    cool intel. i hadn’t though of define-symbol-macro.

    -JimC
    --
    James Cloos <[email protected]> OpenPGP: 0x997A9F17ED7DAEA6

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to James Cloos on Sun Apr 16 00:07:52 2023
    On 2023-04-15, James Cloos <[email protected]> wrote:
    "KK" == Kaz Kylheku <[email protected]> writes:

    Ah, if you mean new symbols which evaluate to themselves,
    and are not the keywords or T or NIL?

    The obvious way is to just bind them as lexical variables
    (or perhaps globals) or macros.

    E.g.

    (define-symbol-macro foo 'foo)

    Now when foo is evaluated, it goes to (quote foo) which goes to foo.

    cool intel. i hadn’t though of define-symbol-macro.

    Fun fact: in the original LISP, the symbol T was implemented
    as a binding of the T variable to the value T. Only NIL was
    genuinely self-evaluating (iirc). This T was just a convention; as in,
    the system provided this T variable to be used as canonical
    representation of truth rather than just any non-NIL value.

    I see other answers in this thread have resorted to defconstant. It
    seems reasonable in this case. I don't like resorting to it because the
    spec says that it defines a constant variable, which is a ridiculous
    oxymoron to me: variable and constants are literally opposites,
    according to any major English language dictionary.

    What defconstant does is promise to the compiler that the variable will
    not change. Therefore the compiler can go to town with
    constant-propagating the value. This isn't a problem in this case.

    When you use defconstant, the timing of the evaluation of the form isn't precise. A compiler could evaluate it at compile time, for the purpose
    of the aforementioned constant propagation. Or it could be delayed to
    the time when the code is loaded (while still treated aggressively as a constant in other regards, like loaded into a register, and then assumed
    to be valid even across external function calls.) Not a problem in
    this case either: we have an obvious constant.

    defconstant is riddled with undefined consequences.

    - Another defcosntant for the same symbol must have a value which is eql
    to the original one.

    - Assigning to a defconstant is undefined.

    - The application binds a defconstant symbol as a lexical or
    dynamic variable.

    Even though implementations can diagnose situatons like that, the
    undefinedness is a turn-off.

    It's not clear whether makunbound is required to remove a defconstant,
    which can then be redefined as an ordinary dynamic or lexical variable,
    or a defconstant with a different value. Given all the admonishments in
    the specification of defconstant, it is hard to find assurance in the
    absence of any mention of defconstant under makunbound.

    defconstant was clearly introduced as an optimization mechanism, and its
    design is in keeping with that, similarly to (declare (optimize ..)) and
    all that, where you make some promises to the compiler with consequences
    if you break them.

    Thus, I instnictively reached for define-symbo-macro. I know when
    that will be expanded and what it will do:

    - define-symbol-macro's spec mentions udefined consequences only once.

    - the macro may be safely shadowed by a lexical.

    - If the symbol is already defined as a global variable, this is an
    error situation requiring a signal.

    - you can assign to a symbol macro if it expands to a form that is
    an assignable place (not applicable when it expands to a quoted
    symbol, obviously).

    - there is a lexical form for symbol macros: symbol-macrolet.
    defconstant has no local form.

    It's still unclear (or I would say even less clear) whether makunbound
    removes a global symbol macro.

    My analysis leads to be regard symbol macros bound to constant
    expressions as the true constant mechanism in Common Lisp, whereas
    defconstant is just a compiler jig for speed demons and daredevils
    looking to optimize their programs.

    The only advantage of defconstant is that it turns any expression into
    its value, after which the binding is regarded as cosntant. So if
    we wanted A to evaluate to itself, we could use not only
    (defcosntant a 'a) but also (defconstant a (cadr '(x a y)))

    This is quite necessary when constants are the result of complex math
    formuls, including function calls. It's a boon to numeric code.

    defconstant is the grand uncle of newly emerging mechanisms in blub
    languages, like constexpr in C++. However, those mechanisms are
    cleaner and have some things in common with symbol macros,
    like the ability to have lexical contexprs that cleanly shadow.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Mon Apr 17 07:07:02 2023
    * Alan Bawden <[email protected]> :
    Wrote on Fri, 14 Apr 2023 00:26:23 -0400:
    Jeff Barnett <[email protected]> writes:
    On 4/13/2023 3:44 PM, Alan Bawden wrote:
    > Here's another possibility:
    > * (defvar x #1='#1#)
    > x
    > The value of X is now a self-evaluating object. Here's proof:
    > * (eq x (eval x))
    > t
    >
    > You might find the printed representation of the value of X to be a bit
    > inconvenient...
    >
    > [I normally run with *PRINT-CIRCLE* set to NIL, because I find it
    > annoying in some situations, and I can rely on *PRINT-LEVEL* and
    > *PRINT-LENGTH* to keep printed representations under control. But in
    > SBCL 2.2.0 at least, that's not good enough to keep the above example
    > from blowing the stack when it tries to print the value of X, and only
    > setting *PRINT-CIRCLE* to T prevents that.]
    I don't think your example above really works. If X is self evaluating then
    (EQ X (QUOTE X)) should be T. And this requirement directly entails that
    the reader must be involved to some degree.

    This is exactly why I didn't claim that "X is now a self-evaluating
    object". I explicity wrote that "THE VALUE OF X is now a
    self-evaluating object". I knew that the OP was almost certainly
    looking for something that he could easily type in repeatably, but he
    only ASKED for something that was "self-evaluating", so I (perhaps mischievously) chose to answer his literal question. And I don't know
    what "self-evaluating" could possibly mean unless it is defined as:

    (defun self-evaluating-p (x)
    (eq x (eval x)))


    http://www.lispworks.com/documentation/HyperSpec/Body/03_abac.htm

    Certain specific symbols and conses might also happen to be
    ``self-evaluating'' but only as a special case of a more general
    set of rules for the evaluation of symbols and conses; such
    objects are not considered to be self-evaluating objects.

    So Common Lisp really takes the fun out of quines, by explicitly
    specifying that conses are not considered to be self-evaluating objects.

    So the defvar example above, #1=(print '#1#), ((lambda(lambda)`(,lambda',lambda))'(lambda(lambda)`(,lambda',lambda)))
    none of these count as self-evaluating objects according to the spec.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Bawden@21:1/5 to All on Mon Apr 17 01:27:29 2023
    Madhu <[email protected]> writes:

    http://www.lispworks.com/documentation/HyperSpec/Body/03_abac.htm

    Certain specific symbols and conses might also happen to be
    ``self-evaluating'' but only as a special case of a more general
    set of rules for the evaluation of symbols and conses; such
    objects are not considered to be self-evaluating objects.

    Yeah, I read that while I was writing my last message in this thread.
    Notice that this is just defining the term "self-evaluating object" --
    it is not trying to go so far as to say that keywords aren't
    "self-evaluating", only that keywords aren't "self-evaluating OBJECTS".
    The standard doesn't actually try to define the term "self-evaluating"
    at all. (I don't remember whether the glossary is part of the standard
    proper or whether it is just the product of Kent Pitman's hard work, but
    notice that there is no glossary entry for "self-evaluating", only "self-evaluating object".)

    But then the OP did in fact ask for a way to define new "self-evaluating objects". Was he trying to use that phrase as the standard explicitly
    defines it? I doubt it. But at this point I think there is no more
    room on this pin head for any more angels.

    - Alan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Alan Bawden on Mon Apr 17 07:38:49 2023
    On 2023-04-17, Alan Bawden <[email protected]> wrote:
    Madhu <[email protected]> writes:

    http://www.lispworks.com/documentation/HyperSpec/Body/03_abac.htm

    Certain specific symbols and conses might also happen to be
    ``self-evaluating'' but only as a special case of a more general
    set of rules for the evaluation of symbols and conses; such
    objects are not considered to be self-evaluating objects.

    In my opinion, this is mostly just bullshitting; text like this serves
    no purpose in a specification.

    All evaluation takes place under a set of rules. The fact that
    an array is self-evaluating is an evaluation rule which says that
    that type of object is given no special interpretation by the
    evaluator, and is just regurgitated.

    The rule which says that a keyword symbol evaluates to itself
    is a bird of the same kind of feather. The object obj is inspected
    and found to be a (keyword obj), and therefore regurigated
    as if it were quoted.

    Both vectorp and keyword are just properties of the object,
    which are referenced by the evaluation rules.

    Distinguishing special cases among general rules is just
    moving some invisible goalposts around.

    Yeah, I read that while I was writing my last message in this thread.
    Notice that this is just defining the term "self-evaluating object" --
    it is not trying to go so far as to say that keywords aren't "self-evaluating", only that keywords aren't "self-evaluating OBJECTS".

    Well, yes; it is saying that keywords aren't really self-evaluating,
    because it immediately follows text which says any form that is not a
    symbol or cons is self-evaluating. So that leaves in question symbols
    and conses. It doesn't confirm that any of those are; only that
    those which appear to be actually may not be.

    BTW, what are examples of apparently self-evaluating conses?

    This isn't one:

    ((LAMBDA (X) (LIST X (LIST 'QUOTE X))) '(LAMBDA (X) (LIST X (LIST 'QUOTE
    X))))

    it produces a new, similar object; the object's value is not EQL
    to the object.

    This one doesn't have that problem: it is self-evaluating:

    #1=(quote #1#)

    and it's *not* really due to any "special case" among the general rules, either.

    For that one I would tend to accept the goalposts: it's not
    self-evalatuing due to any rule (special OR general) which designates
    that object as self-evaluating, but due to quoting itself via circular embedding. (CL compilers are not required to support circular syntax.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Mon Apr 17 14:12:37 2023
    [more of the same, sry]

    * Kaz Kylheku <20230415162754.871 @kylheku.com> :
    Wrote on Sun, 16 Apr 2023 00:07:52 -0000 (UTC):
    I see other answers in this thread have resorted to defconstant. It
    seems reasonable in this case. I don't like resorting to it because the
    spec says that it defines a constant variable, which is a ridiculous
    oxymoron to me: variable and constants are literally opposites,
    according to any major English language dictionary.

    This must be some sort of etymological fallacy. A variable is a binding
    in the variable namespapce. Just because the word "variable" is used,
    it doesn't mean that the BINDING must CHANGE ("but you said variable")

    it is OK to have variables whose bindings do not change.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From HenHanna@21:1/5 to Tom Russ on Mon Oct 21 22:36:08 2024
    XPost: comp.lang.scheme

    On Thu, 13 Apr 2023 1:15:33 +0000, Tom Russ wrote:

    On Wednesday, April 12, 2023 at 9:41:10 AM UTC-7, James Cloos wrote:
    does cl support defining new self-evaluating objects
    (other than keywords)?

    if so, how?

    What sort of "defining" did you have in mind.
    One simple answer (for symbols) would be:
    (defconstant foo 'foo)

    There may be other things you could do via reader macros.
    One example of that is https://github.com/lispm/measures [*], which
    defined
    numbers with dimensions and optional reader macros so that something
    like
    35km or 18m/s2 would evaluate to equivalent objects, although not in an
    EQ sense.



    [* Software by Rainer Joswig that I extended while at ISI]


    Do we have Defconstant in Scheme ???

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