6 ms·
Could you explain the significance of this blunder? Or like where this distinction would be important? I see lots of confusion between "packages" and ASDF syste
by beepbooptheory 3y ago
Could you explain the significance of this blunder? Or like where this distinction would be important? I see lots of confusion between "packages" and ASDF systems, but none between packages and environments. It seems to me, I write a function in a package and whether I am in the package or using it, I refer to that function by the symbol it is given in the defun, even if really in the latter case its some sugar around a string implied by the original defun. Where will it matter to think about it the right way? When I need to shadow things maybe?
Definitely take your authority on this in general, just genuinely curious.
- lisper 3y agoThat's a great question, and actually not so easy to answer. To understand it you have to put yourself in the mindset of a beginner, and here there are two possibilities: either you are a beginner, in which case putting yourself in a beginner mindset is trivial because you're already there, or you are not, in which case putting yourself in a beginner mindset is very, very hard because you have to actively forget (or ignore) things that you know, and that is not easy to do. I don't know which you are, but either way, I'm going to ask you to put yourself into a beginner mindset. So with your beginner mindset on, imagine reading this sentence for the first time: "The existence of packages (multiple name spaces for symbols) in Common Lisp is very important for allowing several people to cooperate in producing a large system." Now, as a beginner, you don't know what "package" or "name space" or "symbol" means, though you might have some preconceived notions about these words. But embedded in this sentence is the "fact" that packages are name spaces for symbols (whatever that might actually mean), and so you tuck this little factoid away in your mind so you can try to make sense of it later because the author has taken pains to point out that whatever it means, it's "very important". And then you read the rest of the book, where you find that the term "name space" is never mentioned again. At this point you might find yourself scratching your head a bit. So on the one hand the author takes pains to call out packages as "very important", and tells you what they are, but then never bothers to explain what the words that define them actually mean. So you, being intellectually curious, go to try to find out so you go out onto the Internet to try to find out what a "name space" is. A reasonable place to start might be the definition in the Common Lisp Hyperspec: > namespace n. 1. bindings whose denotations are restricted to a particular kind. ``The bindings of names to tags is the tag namespace.'' 2. any mapping whose domain is a set of names. ``A package defines a namespace.'' This seems promising, though it seems a bit odd that here a package defines a namespace, rather than a package is a namespace. Maybe "defines" and "is" are actually synonyms? But the bigger problem is that this definition is chock-full of new words which you as a beginner don't know the meaning of, most notably "binding". So you go to find out what that means, and your first step is to go back to the book, which turns out to be no help because despite the fact that it uses the word "binding" it never actually defines it, and also when the word is first introduced it is used as a verb, not a noun. So back to the Hyperspec: > binding n. an association between a name and that which the name denotes. ``A lexical binding is a lexical association between a name and its value.'' When the term binding is qualified by the name of a namespace, such as ``variable'' or ``function,'' it restricts the binding to the indicated namespace, as in: ``let establishes variable bindings.'' or ``let establishes bindings of variables.'' Whoa! That's a lot of new words, starting with "name", which is hyperlinked so it has a definition of its own: > name n., v.t. 1. n. an identifier by which an object, a binding, or an exit point is referred to by association using a binding. 2. v.t. to give a name to. 3. n. (of an object having a name component) the object which is that component. ``The string which is a symbol's name is returned by symbol-name.'' 4. n. (of a pathname) a. the name component, returned by pathname-name. b. the entire namestring, returned by namestring. 5. n. (of a character) a string that names the character and that has length greater than one. (All non-graphic characters are required to have names unless they have some implementation-defined attribute which is not null. Whether or not other characters have names is implementation-dependent.) Double whoa! What is an "identifier"? > identifier n. 1. a symbol used to identify or to distinguish names. 2. a string used the same way. OK, at least now this is a short definition, with only two new words, SYMBOL and STRING. So what is a symbol? > symbol n. an object of type symbol. Well, that's not very helpful. And at this point you might be forgiven if you decide that this whole Lisp thing is not really worth the bother and you really ought to go learn Rust instead because that seems to be what the cool kids are using anyway. The Right Way to explain this to a beginner IMHO is to start with strings because everyone has an intuition about what those are which is close enough: a STRING is a sequence of characters (which are a complicated topic in heir own right, but a naive view of what characters are is good enough to start with). A SYMBOL is a thing with a NAME, which is a string, and which cannot be changed. A symbol is created with a name, and it retains that same name forever. A PACKAGE is just a map, a function, from strings onto symbols such that the name of the symbol mapped from string S has the name S. This is significant because it insures that there is one and only one symbol with the name S in a given package at a given time. Packages are COLLECTIONS OF SYMBOLS WITH UNIQUE NAMES stored in a way that allows you to efficiently find the unique symbol with any given name in that collection. That's it (or at least close enough for a beginner). The reason this matters is that it allows different people to write code without stomping on each other. Alice can put her symbols in one package, and Bob can put his symbols in a different package, and so when Alice types "foo" into her code she can count on that referring to the One Symbol Named "foo" in Alice's package, and likewise when Bob types "foo" into his code he can count on that referring to the One Symbol Named "foo" in Bob's package. But these are nonetheless two different symbols (with the same name) and so Alice's code doesn't stomp on Bob's code. That's it. ~250 words with no unfamiliar terminology for a beginner to have to scratch their head over (assuming they already know what a "map" or a "function" is).
- beepbooptheory 3y agoThis makes sense, but I guess I don't see, still, how this might get the beginner into too much trouble. Pedagogical methods and statements will always not quite stay true to the letter of the spec. When we teach, we say one thing "is like" another, or you "might understand this by comparing it to foo," knowing well that the concept isn't actually foo. This is never meant to confuse the student, but to help them get in the right position to actually understand something. But still, I get your point. Certain diligent students might read that statement and, rationally, read a lot into the terms "namespace" and "binding," and then get confused when they look up those terms in the hyperspec. It does come across careless in this way. But I just don't think, in itself, this would lead to a confusion about what packages are good for, or why they are used. Whether a beginner wrongly considers a package a namespace, or something like a namespace, wouldn't affect the way they would decide to actually use a package in their work. (Not to disregard how an experienced, real-lisp-understander might use their precise knowledge of the way packages work to make even better/cleaner/organized code.) But either way, thank you for the thoughts, and please take my thoughts with a grain of salt.
- lisper 3y agoThe problem is not so much with the use of the word "namespace" per se, but with saying that packages are name spaces for symbols. That's just wrong, and is in direct conflict with the definition of things that are actually talked about as name spaces for symbols, most notably, variable and function bindings. The difference is that the domains of these "name spaces" are disjoint. The domain of packages is the set of strings, but the domain of (say) lexical variable bindings is the set of symbols. So, for example, lexical environments and dynamic environments are name spaces for symbols because their domains are symbols. If you insist on thinking about packages as name spaces (which no one actually does, which is another reason the sentence is misleading) then they are name spaces for strings, not for symbols.
- kagevf 3y agoI get the impression that the original quote from the book is using "name space" as it's used in other languages outside of CL, except that the book is from 1992 so not sure if that usage was widespread yet - maybe in C++? But it's almost like they wanted to say "a package is analogous to a name space as it's used in [algol-derivative]." Definite potential for confusion there, since "namespace" has a very specific meaning in CL and in general helps explain the difference between Lisp-1 and Lisp-2 (Lisp-n) varieties.