• What does (gensym) generate?

    From none) (albert@21:1/5 to All on Thu Aug 31 11:11:14 2023
    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    (let* (aaa (gensym)) .. aaa .. )

    In the context `` .. aaa .. '' `aaa is obviously a symbol.
    The interesting question is what value is aaa coupled to due to
    the environment (aaa (gensym))?
    Apparently aaa must be evaluated before it is any use.
    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.
    I have the following lisp type of objects:
    symbols lists numbers strings arrays hashes normal-function
    special-functions booleans
    and more MAL oddballs:
    nil key atom

    Nothing seems an appropriate type for `aaa.

    Example studied:

    (defmacro! or
    (fn* (& xs)
    (if (empty? xs)
    nil
    (if (= 1 (count xs))
    (first xs)
    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Tom Russ on Thu Aug 31 18:57:40 2023
    On Thu, 31 Aug 2023 11:18:56 -0700 (PDT)
    Tom Russ <taruss@google.com> wrote:
    On Thursday, August 31, 2023 at 2:11:21 AM UTC-7, none albert wrote:
    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    The theoretical background is essentially this:
    * For regular symbols, when the reader encounters a symbol, it creates a
    symbol object and "interns" it. Interning means creating a mapping from
    the symbol name to the symbol object.

    No , interning means creating an association between a symbol and a package. Different packages can have symbols with the same name. Other relevant facts {for Common Lisp} :

    A name is a string and each symbol has a name and it can even be the empty string.

    Each package can have at most 1 symbol with a given name.

    You can have an unlimited number of uninterned symbols with a given name.

    * GENSYM will generate an "uninterned" symbol. It creates and returns a
    symbol object, but does *not* create a mapping from the (generated)
    name to the symbol object. That means that even if you type in the same
    as gets internally chosen for this uninterned symbol, it will not be the
    same object.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to albert@cherry on Thu Aug 31 18:21:24 2023
    On 2023-08-31, albert@cherry.(none) (albert) <albert@cherry> wrote:
    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    (let* (aaa (gensym)) .. aaa .. )

    In the context `` .. aaa .. '' `aaa is obviously a symbol.
    The interesting question is what value is aaa coupled to due to
    the environment (aaa (gensym))?

    gensym is an ordinary function which returns an object.
    That object is a symbol.

    If we replace it with (aaa (list 1 2 3)), then aaa is bound
    to list of three elements.

    The object returned by gensym is always a newly created symbol,
    different from any other symbol in the system that has hitherto existed.

    In Common Lisp, gensym returns an uninterned symbol: a symbol which
    is not registered in a package. (There are some subtle details to it,
    but let that suffice.) Common Lisp prints such symbols with a #:
    (hash colon) prefix. E.g. (gensym "ABC-") -> #:ABC-0013 .
    The Common Lisp gensym maintains an incrementing counter which it uses
    to generate new names, but those names are just for human readability,
    not the basis for the uniquenes..

    Each time the reader encounters the #: syntax, it creates a new,
    uninterned symbol so that (eq '#:abc '#:abc) will be false.
    Those are two different symbols, which have the same name.

    For interned symbols, that is impossible: only one symbol can
    exist in a package under a given name: there can at most be one cl:list
    or abc:foo or whatever.

    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.

    It's a variable binding construct, so it only allows variable names,
    which are symbols.

    I have the following lisp type of objects:
    symbols lists numbers strings arrays hashes normal-function
    special-functions booleans
    and more MAL oddballs:
    nil key atom

    Nothing seems an appropriate type for `aaa.

    The obect aaa itself is a symbol. The token aaa appears in your code.
    The Lisp reader scans that token, recognizes it as having the
    shape of a symbol, and so it interns it: it produces either the
    existing symbol that exists under that name, or else produces a new
    one and registers it under that name. (If it didn't register it,
    the symbol would be uninterned, like the ones from gensym.)

    I'm guessing that since you've gone this far in MAL, you must
    have that working.

    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    So here condvar is a generated, unique symbol.

    It is interpolated into the backquote template.

    ~convar says, insert the value of condvar here. The value is
    a symbol, which is what we want there.

    The macro is generating code in which there is a local variable boudd
    using let*, and that variable's name is machine generated.

    This the same as what you see in any compiler: machine generated
    temporaries, jump labels and so on.

    --
    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 Tom Russ@21:1/5 to none albert on Thu Aug 31 11:18:56 2023
    On Thursday, August 31, 2023 at 2:11:21 AM UTC-7, none albert wrote:
    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    The theoretical background is essentially this:
    * For regular symbols, when the reader encounters a symbol, it creates a
    symbol object and "interns" it. Interning means creating a mapping from
    the symbol name to the symbol object.
    * GENSYM will generate an "uninterned" symbol. It creates and returns a
    symbol object, but does *not* create a mapping from the (generated)
    name to the symbol object. That means that even if you type in the same
    as gets internally chosen for this uninterned symbol, it will not be the
    same object.

    This is useful if you want a symbol for some purpose, in modern lisp usually only for creating bindings inside macros, but don't want that symbol to have any possibility of interfering with any other symbols, you can use one of these generated symbols.

    For some discussion of this, see https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node114.html#SECTION001530000000000000000


    (let* (aaa (gensym)) .. aaa .. )

    In the context `` .. aaa .. '' `aaa is obviously a symbol.
    The interesting question is what value is aaa coupled to due to
    the environment (aaa (gensym))?
    Apparently aaa must be evaluated before it is any use.
    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.
    I have the following lisp type of objects:
    symbols lists numbers strings arrays hashes normal-function special-functions booleans
    and more MAL oddballs:
    nil key atom

    Nothing seems an appropriate type for `aaa.

    Example studied:

    (defmacro! or
    (fn* (& xs)
    (if (empty? xs)
    nil
    (if (= 1 (count xs))
    (first xs)
    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    One of the general uses of GENSYM is in macros. By introducing a new, uninterned symbol one
    does not have to worry that the new symbol can inadvertently capture (rebind) an external symbol
    when the macro is expanded.

    These are a bit silly, since there isn't
    (defmacro bad-example (value &body body)
    `(let ((x ,value))
    (print x)
    ,@body))
    (defmacro good-example (value &body body)
    (let ((v (gensym)))
    `(let ((,v ,value))
    (print ,v)
    ,@body))))

    Now consider these two cases:
    (let ((x 5))
    (bad-example 20 (print x)))
    (let ((x 5))
    (good-example 20 (print x)))
    The bad example will print 20 20 and the good one will properly print 20 5.

    That is because if you expand the macros you would end up with:
    (let ((x 5))
    (let ((x 20))
    (print x)
    (print x)))
    vs
    (let ((x 5))
    (let ((#1=#:GENSYM100 20)) ; The actual printed value may differ and isn't important.
    (print #1#)
    (print x)))
    This version uses the printer's alias ability to make sure that the same symbol is used
    in the LET and the PRINT, since there is no mapping from name to symbol object when
    the symbol is not interned.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Spiros Bousbouras on Thu Aug 31 19:07:06 2023
    On 2023-08-31, Spiros Bousbouras <spibou@gmail.com> wrote:
    No , interning means creating an association between a symbol and a package. Different packages can have symbols with the same name. Other relevant facts {for Common Lisp} :

    Plus, in a simple Lisp with no package system, interning just means
    recording the symbol in some pervasive dictionary of symbols (that is essentially the one and only package).

    The CL-like package systems refines the concept by dividing the
    previously global dictionary into named namespaces.

    --
    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 none) (albert@21:1/5 to 864-117-4973@kylheku.com on Fri Sep 1 14:23:21 2023
    In article <20230831104914.534@kylheku.com>,
    Kaz Kylheku <864-117-4973@kylheku.com> wrote:
    On 2023-08-31, albert@cherry.(none) (albert) <albert@cherry> wrote:
    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    (let* (aaa (gensym)) .. aaa .. )

    In the context `` .. aaa .. '' `aaa is obviously a symbol.
    The interesting question is what value is aaa coupled to due to
    the environment (aaa (gensym))?

    gensym is an ordinary function which returns an object.
    That object is a symbol.

    If we replace it with (aaa (list 1 2 3)), then aaa is bound
    to list of three elements.

    The object returned by gensym is always a newly created symbol,
    different from any other symbol in the system that has hitherto existed.

    In Common Lisp, gensym returns an uninterned symbol: a symbol which
    is not registered in a package. (There are some subtle details to it,
    but let that suffice.) Common Lisp prints such symbols with a #:
    (hash colon) prefix. E.g. (gensym "ABC-") -> #:ABC-0013 .
    The Common Lisp gensym maintains an incrementing counter which it uses
    to generate new names, but those names are just for human readability,
    not the basis for the uniquenes..

    Each time the reader encounters the #: syntax, it creates a new,
    uninterned symbol so that (eq '#:abc '#:abc) will be false.
    Those are two different symbols, which have the same name.

    For interned symbols, that is impossible: only one symbol can
    exist in a package under a given name: there can at most be one cl:list
    or abc:foo or whatever.

    That is all trivial to implement.


    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.

    It's a variable binding construct, so it only allows variable names,
    which are symbols.
    Huh?


    I have the following lisp type of objects:
    symbols lists numbers strings arrays hashes normal-function
    special-functions booleans
    and more MAL oddballs:
    nil key atom

    Nothing seems an appropriate type for `aaa.

    The obect aaa itself is a symbol. The token aaa appears in your code.
    The Lisp reader scans that token, recognizes it as having the
    shape of a symbol, and so it interns it: it produces either the
    existing symbol that exists under that name, or else produces a new
    one and registers it under that name. (If it didn't register it,
    the symbol would be uninterned, like the ones from gensym.)

    I'm guessing that since you've gone this far in MAL, you must
    have that working.

    Right you are


    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    So here condvar is a generated, unique symbol.

    It is interpolated into the backquote template.

    ~convar says, insert the value of condvar here. The value is
    a symbol, which is what we want there.

    Can we conclude that the only time to worry is inside
    quasiquote? That helps a lot. There is a moment in time
    where we expand, and the


    The macro is generating code in which there is a local variable boudd
    using let*, and that variable's name is machine generated.

    This the same as what you see in any compiler: machine generated
    temporaries, jump labels and so on.

    The big question how to parse
    (let (aaa <object> ) ...
    In the abstract structure tree `let and `aaa are symbols
    that are manipulated during evaluation.
    The spec's of let is that aaa is a symbol that is bound to object.
    This cannot be the whole story. For instance there is no notice
    to evaluate aaa , the previous binding is lost.
    That are the spec's of `let , or so I thought.
    Comes gensym . If I previously encountered `` (aaa (gensym)) ''
    everything changes. But how can I even know that the previous
    binding was this weird contraption?

    I have 256 Gbyte RAM and MAL is a toy implementation, so bear with me:
    each object has 7 64 bit fields.
    All objects are uniform and have a tag giving its type:
    pointer to code, pointer to data, a flag field (containing tags),
    a link field, a name field, a source field (not used) and
    one spare.

    It is related to the following implementation choice I made.
    All objects have a place to set a name.
    All object have some data and possibly no name (e.g. numbers, lists
    functions, strings)
    Symbols have a name and all other fields are free.
    Binding a symbol : fill the name of the symbol in the object
    and possibly link it into an environment (linkfield is the hook for that). Sometime we have to clone the whole object, if it previously had a name
    and were linked to some environment.
    For example an anonymous lambda looks like this:
    code pointer : forth interpreter
    data pointer : forth code to be interpreted
    flag : contains either #func or #special or-ed with possibly Forty flags.
    link , name : empty.

    The contradiction caused by (gensym) is that you have symbols with
    two names, where the only property of a symbol is that it has
    a name that identifies itself. Or so I thought.


    --
    TXR Programming Language: http://nongnu.org/txr

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to albert@cherry. on Fri Sep 1 14:27:19 2023
    On Fri, 01 Sep 2023 14:23:21 +0200
    albert@cherry.(none) (albert) wrote:
    In article <20230831104914.534@kylheku.com>,
    Kaz Kylheku <864-117-4973@kylheku.com> wrote:
    On 2023-08-31, albert@cherry.(none) (albert) <albert@cherry> wrote:

    [...]

    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.

    It's a variable binding construct, so it only allows variable names,
    which are symbols.
    Huh?

    let binds variables ; so in something like

    (let ((<something> value) ...))

    the <something> has to be a variable name which means a Lisp object of
    type symbol.

    [...]

    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    So here condvar is a generated, unique symbol.

    It is interpolated into the backquote template.

    ~convar says, insert the value of condvar here. The value is
    a symbol, which is what we want there.

    Can we conclude that the only time to worry is inside
    quasiquote? That helps a lot. There is a moment in time
    where we expand, and the

    There is no special worry involved but more on this below.

    The macro is generating code in which there is a local variable boudd
    using let*, and that variable's name is machine generated.

    This the same as what you see in any compiler: machine generated >temporaries, jump labels and so on.

    The big question how to parse
    (let (aaa <object> ) ...
    In the abstract structure tree `let and `aaa are symbols
    that are manipulated during evaluation.
    The spec's of let is that aaa is a symbol that is bound to object.
    This cannot be the whole story. For instance there is no notice
    to evaluate aaa , the previous binding is lost.
    That are the spec's of `let , or so I thought.
    Comes gensym . If I previously encountered `` (aaa (gensym)) ''
    everything changes. But how can I even know that the previous
    binding was this weird contraption?

    (let ((aaa (foo)))) binds aaa to whatever (foo) returns. As
    far as this goes there is nothing special with something like
    (let ((aaa (gensym)))) . aaa gets bound to whatever (gensym)
    returned much like (let ((aaa (+ 1 1)))) binds aaa to whatever
    (+ 1 1) returns which is 2.

    (gensym) returns a symbol with the special property that it is
    uninterned. So the only reference to the symbol returned is through
    aaa .There is nothing you can type on the REPL to get the same
    symbol {although you can get a symbol with the same name} and every
    other call to gensym will also return a different symbol.

    I have 256 Gbyte RAM and MAL is a toy implementation, so bear with me:
    each object has 7 64 bit fields.
    All objects are uniform and have a tag giving its type:
    pointer to code, pointer to data, a flag field (containing tags),
    a link field, a name field, a source field (not used) and
    one spare.

    I don't think such low level details are helpful but anyway.

    It is related to the following implementation choice I made.
    All objects have a place to set a name.

    The first problem here is that you are using what is standard Lisp
    terminology , or at least Common Lisp terminology , for something
    which seems to be different. In Common Lisp a symbol has a name
    which is a string. So the name of the symbol aaa is the string
    "aaa" .But a symbol is a different thing than its name ; it's a
    different datatype and a different object.

    All object have some data and possibly no name (e.g. numbers, lists functions, strings)
    Symbols have a name and all other fields are free.
    Binding a symbol : fill the name of the symbol in the object
    and possibly link it into an environment (linkfield is the hook for that). Sometime we have to clone the whole object, if it previously had a name
    and were linked to some environment.
    For example an anonymous lambda looks like this:
    code pointer : forth interpreter
    data pointer : forth code to be interpreted
    flag : contains either #func or #special or-ed with possibly Forty flags. link , name : empty.

    So if you have something like (let ((aaa 19))) what value are the
    various things you mention going to have ?

    The contradiction caused by (gensym) is that you have symbols with
    two names, where the only property of a symbol is that it has
    a name that identifies itself. Or so I thought.

    What identifies a symbol is its location in memory. You don't have
    direct access to that location {i.e. you can't get the address} but
    in that location there will be stored {in an appropriate layout known
    to the Lisp implementation} the various properties of the symbol
    which include the following :

    A symbol has a name {meaning a string , as I explained above} and
    whether it is bound to a value and whether it is interned or not. For simplicity lets assume that "interned" is a binary property although
    in Common Lisp it isn't , if a symbol is interned then it is interned
    in some package. With something like

    (let ((aaa (gensym))))

    the symbol aaa has the following properties :

    - it has the name "aaa" which is a string.

    - it is interned because you typed it into the REPL or read it from source
    code in some file.

    - it is bound to the value returned by (gensym) .By the definition of
    gensym this value will have the following properties :

    - it will be a symbol therefore it will also have a name which will also
    be a string. In Common Lisp you can even control what that string will be
    and you can even make it to be "aaa" .But even if you make the name
    to be "aaa" , the symbol returned by (gensym) will be distinct
    from aaa which you typed on the REPL ; "distinct" meaning it will be
    stored at a different place in memory and its various properties
    can be different than the properties of aaa and that includes whether
    it is bound to a value and which value.

    - it will be uninterned.

    These facts are unrelated to quasiquoting although often are used in combination
    with quasiquoting. But note that your code

    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    could be written as

    (defun or-function (list-of-clauses)
    (if list-of-clauses
    (let* ((condvar (gensym)))
    (list 'let* (list (list condvar (first list-of-clauses)))
    (list 'if condvar condvar
    (or-function (rest list-of-clauses)))))
    nil))

    .Obviously this is a lot less readable but I hope it illustrates the
    point that gensym is not based on quasiquoting nor the other way
    around.

    --
    vlaho.ninja/prog

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to spibou@gmail.com on Mon Sep 4 13:08:07 2023
    In article <8GRTwaqPt+TSAYagO@bongo-ra.co>,
    Spiros Bousbouras <spibou@gmail.com> wrote:
    On Fri, 01 Sep 2023 14:23:21 +0200
    albert@cherry.(none) (albert) wrote:
    In article <20230831104914.534@kylheku.com>,
    Kaz Kylheku <864-117-4973@kylheku.com> wrote:
    On 2023-08-31, albert@cherry.(none) (albert) <albert@cherry> wrote:

    [...]


    (let ((aaa (foo)))) binds aaa to whatever (foo) returns. As
    far as this goes there is nothing special with something like
    (let ((aaa (gensym)))) . aaa gets bound to whatever (gensym)
    returned much like (let ((aaa (+ 1 1)))) binds aaa to whatever
    (+ 1 1) returns which is 2.

    (gensym) returns a symbol with the special property that it is
    uninterned. So the only reference to the symbol returned is through
    aaa .There is nothing you can type on the REPL to get the same
    symbol {although you can get a symbol with the same name} and every
    other call to gensym will also return a different symbol.

    Remember that my big question was,what is the type of the value
    `aaa is bound to. So apparently that is a symbol that has
    uninterned.
    Can you please elaborate what uninterned means?


    I have 256 Gbyte RAM and MAL is a toy implementation, so bear with me:
    each object has 7 64 bit fields.
    All objects are uniform and have a tag giving its type:
    pointer to code, pointer to data, a flag field (containing tags),
    a link field, a name field, a source field (not used) and
    one spare.

    I don't think such low level details are helpful but anyway.

    It is related to the following implementation choice I made.
    All objects have a place to set a name.

    The first problem here is that you are using what is standard Lisp >terminology , or at least Common Lisp terminology , for something
    which seems to be different. In Common Lisp a symbol has a name
    which is a string. So the name of the symbol aaa is the string
    "aaa" .But a symbol is a different thing than its name ; it's a
    different datatype and a different object.

    I should have said, a field that associated it with a symbol.

    It is clear that you can have a symbol that is floating around
    and has not been placed in abstract structure tree or a
    hash table. Is that uninterned?


    All object have some data and possibly no name (e.g. numbers, lists
    functions, strings)
    Symbols have a name and all other fields are free.
    Binding a symbol : fill the name of the symbol in the object
    and possibly link it into an environment (linkfield is the hook for that). >> Sometime we have to clone the whole object, if it previously had a name
    and were linked to some environment.
    For example an anonymous lambda looks like this:
    code pointer : forth interpreter
    data pointer : forth code to be interpreted
    flag : contains either #func or #special or-ed with possibly Forty flags.
    link , name : empty.

    So if you have something like (let ((aaa 19))) what value are the
    various things you mention going to have ?
    let : symbol
    aaa : symbol
    19 : number
    (let...) list (( aaa 19)) a list with one object that is again a list.

    Let us discuss what I understand `let does.
    In MAL the function coupled to let is a special function and it looks
    like (let* (aaa 19) ...
    In my book, the arguments are not evaluated (that what special means, not?)
    and `let is allowed to evaluate it, on its own terms.
    In my interpretation:
    `let inspects the first argument, requires this to be a list,
    an requires that all odd elements be symbols, lest it is allowed
    to call "fire!".


    The contradiction caused by (gensym) is that you have symbols with
    two names, where the only property of a symbol is that it has
    a name that identifies itself. Or so I thought.

    What identifies a symbol is its location in memory. You don't have
    direct access to that location {i.e. you can't get the address} but
    in that location there will be stored {in an appropriate layout known
    to the Lisp implementation} the various properties of the symbol
    which include the following :
    Okay that is what I do.
    (let (aaa 19)
    The symbol aaa is a location in memory. I borrow its name and
    fetch 19 and put it in a hash list.

    A symbol has a name {meaning a string , as I explained above} and
    whether it is bound to a value and whether it is interned or not. For >simplicity lets assume that "interned" is a binary property although
    in Common Lisp it isn't , if a symbol is interned then it is interned
    in some package. With something like

    (let ((aaa (gensym))))

    the symbol aaa has the following properties :

    - it has the name "aaa" which is a string.

    - it is interned because you typed it into the REPL or read it from source
    code in some file.

    - it is bound to the value returned by (gensym) .By the definition of
    gensym this value will have the following properties :

    - it will be a symbol therefore it will also have a name which will also
    be a string. In Common Lisp you can even control what that string will be
    and you can even make it to be "aaa" .But even if you make the name
    to be "aaa" , the symbol returned by (gensym) will be distinct
    from aaa which you typed on the REPL ; "distinct" meaning it will be
    stored at a different place in memory and its various properties
    x can be different than the properties of aaa and that includes whether
    it is bound to a value and which value.
    x
    - it will be uninterned.

    Be it is it may, `aaa has only one meaning. It is the thingy that has
    been found in the current environment.
    Suppose I use a name for a symbol that is already present in the environment.
    I hope that that the new and old symbol are distinct despite having the
    same name. Otherwise I seriously misunderstand lisp.

    An implementation comes up.
    I can introduced a flag "uninterned".
    Prior to using a symbol I look whether it is bound in the current
    context. If it is bound to a non-symbol, I do nothing.
    If it is bound to an uninterned symbol, (only example generated
    by (gensym) ), I replace it by the uninterned symbol.
    These action should be taken, irrespective if the symbol is in
    a context where it should be evaluated or not.
    It can be done at the lexing/parsing stage, where the abstract structure
    tree is build (is that a general term, or is that MAL jargon?),
    and it not terrible involved.
    --
    ninja

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to albert@cherry on Mon Sep 4 15:56:05 2023
    On 2023-09-04, albert@cherry.(none) (albert) <albert@cherry> wrote:
    In article <8GRTwaqPt+TSAYagO@bongo-ra.co>,
    Spiros Bousbouras <spibou@gmail.com> wrote:
    On Fri, 01 Sep 2023 14:23:21 +0200
    albert@cherry.(none) (albert) wrote:
    In article <20230831104914.534@kylheku.com>,
    Kaz Kylheku <864-117-4973@kylheku.com> wrote:
    On 2023-08-31, albert@cherry.(none) (albert) <albert@cherry> wrote:

    [...]


    (let ((aaa (foo)))) binds aaa to whatever (foo) returns. As
    far as this goes there is nothing special with something like
    (let ((aaa (gensym)))) . aaa gets bound to whatever (gensym)
    returned much like (let ((aaa (+ 1 1)))) binds aaa to whatever
    (+ 1 1) returns which is 2.

    (gensym) returns a symbol with the special property that it is
    uninterned. So the only reference to the symbol returned is through
    aaa .There is nothing you can type on the REPL to get the same
    symbol {although you can get a symbol with the same name} and every
    other call to gensym will also return a different symbol.

    Remember that my big question was,what is the type of the value
    `aaa is bound to. So apparently that is a symbol that has
    uninterned.
    Can you please elaborate what uninterned means?

    Uninterned means "not remembered by name for the purposes of
    turning the same syntactic tokeen into the same symbol object".

    Interning refers to turning multiple occurrences of an identifier
    in the printed notation into references to the same symbol,
    rather than distinct symbols. When (x x x) is read, there
    are three references to the same symbol x, because of interning.

    An uninterned symol is created without entering it into the dictionary
    of interned symbols. Because it's newly created, it's a distinct object
    from any other object, and because it's not interned, it cannot be found
    by name. You cannot possibly read any object from text that would
    contain that uninterned symbol.

    It is clear that you can have a symbol that is floating around
    and has not been placed in abstract structure tree or a
    hash table. Is that uninterned?

    Yes, if by that hash table you refer to the structure that is used
    to identify (x x x) has having the same symbol three times,
    rather than three symbols.

    (In ANSI Common Lisp, which has a package system, that table is the
    package. Packages themselves are named: there is more than one package.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Russ@21:1/5 to none albert on Tue Sep 5 10:27:17 2023
    On Monday, September 4, 2023 at 4:08:19 AM UTC-7, none albert wrote:

    Suppose I use a name for a symbol that is already present in the environment.
    I hope that that the new and old symbol are distinct despite having the
    same name. Otherwise I seriously misunderstand lisp.

    What happens depends on whether the symbol in question is interned or not.

    Interned symbols:
    If the reader encounters a symbol with a (package-qualified) name that is the same
    as an already encountered symbol name, then the same symbol is returned. That is
    why the CommonLisp expression (eq 'x 'x) returns T. Remember that EQ is object equality.
    So with normal interned symbols, seeing the same name means you have the same symbol.
    Now the same symbol can be bound to different values in different environments, but
    the symbol object is always the same. So in the following (ignore the ".")
    (let ((x 1))
    ..(print x)
    ..(let ((x 2))
    ....(print x))
    ..(print x))
    The printed values will be 1, 2, 1 because of the lexical bindings of the LET form, even
    though the symbol X is the same symbol object in all the forms.

    Uninterned symbols:
    If the reader encounters a symbol with the special syntax indicating that it is an uninterned
    symbol, then a new symbol is created. So that is why the CommonLisp expression (eq '#:x '#:x) returns NIL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From steve@21:1/5 to albert@cherry. on Tue Sep 5 23:27:46 2023
    albert@cherry.(none) (albert) writes:

    The explanations about the usage of gensym are clear,
    how your are supposed to used them.
    The theoretical background however is far from it.

    gensym is used in macros. like mkstemp in C.




    (let* (aaa (gensym)) .. aaa .. )

    In the context `` .. aaa .. '' `aaa is obviously a symbol.
    The interesting question is what value is aaa coupled to due to
    the environment (aaa (gensym))?
    Apparently aaa must be evaluated before it is any use.
    However subsequently you see
    (let* (aaa (rest whatever)) ... )
    What is disturbing to me is that let* only allows symbols into the
    position of aaa and normally the coupling of aaa hides previous usage.
    I have the following lisp type of objects:
    symbols lists numbers strings arrays hashes normal-function
    special-functions booleans
    and more MAL oddballs:
    nil key atom

    Nothing seems an appropriate type for `aaa.

    Example studied:

    (defmacro! or
    (fn* (& xs)
    (if (empty? xs)
    nil
    (if (= 1 (count xs))
    (first xs)
    (let* (condvar (gensym))
    `(let* (~condvar ~(first xs))
    ;; try (let* (,~condvar ~(first xs))
    (if ~condvar ~condvar (or ~@(rest xs)))))))))

    instead of using macro names with thisvar_ as you would use in C use
    gensym. here is a small example.

    (defmacro dostring ((var str &optional (return-value nil)) &body forms)
    (declare (string str))
    `(loop for ,var of-type character across (the string ,str)
    do (locally ,@forms) finally (return ,return-value)))

    (defmacro do-string-codes ((var string &optional return-value) &body forms)
    (let ((ch-var (gensym "CHARACTER")))
    `(dostring (,ch-var ,string ,return-value)
    (let ((,var (char-code ,ch-var)))
    ,@forms))))

    (dostring (chr "hello world")
    (print chr))

    #\h
    #\e
    #\l
    #\l
    #\o
    #\
    #\w
    #\o
    #\r
    #\l
    #\d
    NIL

    macroexpand

    (LOOP FOR CHR OF-TYPE CHARACTER ACROSS (THE STRING "hello world")
    DO (LOCALLY (PRINT CHR))
    FINALLY (RETURN NIL))

    sorry for the convoluted code - this is what I have..

    usually make-symbol is used; gensym is never eq.

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