> On Sep 17, 2018, at 12:21, Kevin Forchione <lyss...@gmail.com> wrote: > > That seems to be the nature of macros, and I’m not sure what the solution to > that paradox is, apart from perhaps building a symbol/function hash table as > part of a define. Presumably Racke does something like that for eva & > namespaces, but I’m surprised there isn’t a symbol->procedure function.
In general, I think Philip has hit the nail on the head. I, too, thought of other Lisp systems when you used the wording “associated procedure” for a symbol, and I agree that concept makes less sense in Racket. In a more traditional Lisp, symbols themselves are rich values with lots of information attached to them, but Racket follows the Scheme approach, which treats symbols as nothing more than interned strings. They are just names, not bindings. To elaborate a little more on this, it might make sense to think of the “associated procedure” for a symbol in Common Lisp, but in Racket, that information is stored in a separate place: namespaces. A Racket namespace represents an environment, and it maps names to values. At runtime, if you want to get the value bound to a particular symbol in a given namespace, you can use namespace-variable-value[1], but there are some caveats to that. As mentioned above, in Common Lisp, a package-qualified symbol is precise, but a Racket symbol is only meaningful in context. This means that the symbol 'foo might be mapped to one thing in one namespace but something completely different in another namespace. This is a philosophically different approach to binding, but the practical takeaway is that you need to be really careful to use the *right* namespace if you want to use namespaces in Racket. A namespace can be created that corresponds to the top-level of a module, using module->namespace, or it can be an entirely independent, “free-floating” top-level environment created with make-base-namespace. You can acquire a namespace that corresponds to the surrounding lexical environment using define-namespace-anchor[2] and namespace-anchor->namespace[3] or #%variable-reference[4] and variable-reference->namespace[5]. However, beware! As Philip alludes to, namespaces only include top-level or module-level bindings, *not* local bindings! Racket provides no reflective capabilities to inspect local bindings (at least not in general; you could theoretically write a #lang that implements this capability yourself). These are opaque, and indeed, the Racket compiler does not maintain information about the structure of local bindings. To summarize: Racket is a relatively static language relative to other Lisps, and even to other Schemes. The language is entirely {lexically, statically} bound. It provides limited reflective capabilities to manipulate top-level namespaces and inspect module-level bindings, but no more. There are definitely various advantages to this (e.g. local reasoning, encapsulation, optimization), but you may need to think differently about Racket’s binding model if coming from other Lisp systems. Alexis [1]: http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28quote._~23~25kernel%29._namespace-variable-value%29%29 [2]: http://docs.racket-lang.org/reference/Namespaces.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-namespace-anchor%29%29 [3]: http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._namespace-anchor-~3enamespace%29%29 [4]: http://docs.racket-lang.org/reference/Locations____variable-reference.html#%28form._%28%28quote._~23~25kernel%29._~23~25variable-reference%29%29 [5]: http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28quote._~23~25kernel%29._variable-reference-~3enamespace%29%29 -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.