views:

428

answers:

7

Scheme uses a single namespace for all variables, regardless of whether they are bound to functions or other types of values. Common Lisp separates the two, such that the identifier "hello" may refer to a function in one context, and a string in another.

(Note 1: This question needs an example of the above; feel free to edit it and add one, or e-mail the original author with it and I will do so.)

However, in some contexts, such as passing functions as parameters to other functions, the programmer must explicitly distinguish that he's specifying a function variable, rather than a non-function variable, by using #', as in:

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)

I have always considered this to be a bit of a wart, but I've recently run across an argument that this is actually a feature:

...the important distinction actually lies in the syntax of forms, not in the type of objects. Without knowing anything about the runtime values involved, it is quite clear that the first element of a function form must be a function. CL takes this fact and makes it a part of the language, along with macro and special forms which also can (and must) be determined statically. So my question is: why would you want the names of functions and the names of variables to be in the same namespace, when the primary use of function names is to appear where a variable name would rarely want to appear?
Consider the case of class names: why should a class named FOO prevent the use of variables named FOO? The only time I would be referring the class by the name FOO is in contexts which expect a class name. If, on the rare occasion I need to get the class object which is bound to the class name FOO, there is FIND-CLASS.

This argument does make some sense to me from experience; there is a similar case in Haskell with field names, which are also functions used to access the fields. This is a bit awkward:

data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)

This is solved by a bit of extra syntax, made especially nice by the NamedFieldPuns extension:

isOrigin2 Point{x,y} = (x == 0) && (y == 0)

So, to the question, beyond consistency, what are the advantages and disadvantages, both for Common Lisp vs. Scheme and in general, of a single namespace for all values versus separate ones for functions and non-function values?

+1  A: 

I've met a similar distinction in Python (unified namespace) vs Ruby (distinct namespaces for methods vs non-methods). In that context, I prefer Python's approach -- for example, with that approach, if I want to make a list of things, some of which are functions while others aren't, I don't have to do anything different with their names, depending on their "function-ness", for example. Similar considerations apply to all cases in which function objects are to be bandied around rather than called (arguments to, and return values from, higher-order functions, etc, etc).

Non-functions can be called, too (if their classes define __call__, in the case of Python -- a special case of "operator overloading") so the "contextual distinction" isn't necessarily clear, either.

However, my "lisp-oid" experience is/was mostly with Scheme rather than Common Lisp, so I may be subconsciously biased by the familiarity with the uniform namespace that in the end comes from that experience.

Alex Martelli
You can do more or less the same thing with methods in Ruby: `f = obj.method(:foo)` will give you a `Method` object, which is a perfectly normal object. You can use `f.call(...)` to invoke the method in the context of the object. That's not to say that functions are truly first-class in Ruby, however, though I don't want to get into all of the grungy details.
Curt Sampson
+10  A: 

The two different approaches have names: Lisp-1 and Lisp-2. A Lisp-1 has a single namespace for both variables and functions (as in Scheme) while a Lisp-2 has separate namespaces for variables and functions (as in Common Lisp). I mention this because you may not be aware of the terminology since you didn't refer to it in your question.

Wikipedia refers to this debate:

Whether a separate namespace for functions is an advantage is a source of contention in the Lisp community. It is usually referred to as the Lisp-1 vs. Lisp-2 debate. Lisp-1 refers to Scheme's model and Lisp-2 refers to Common Lisp's model. These names were coined in a 1988 paper by Richard P. Gabriel and Kent Pitman, which extensively compares the two approaches.

Gabriel and Pitman's paper titled Technical Issues of Separation in Function Cells and Value Cells addresses this very issue.

Greg Hewgill
A: 

The name of a function in Scheme is just a variable with the function as its value. Whether I do (define x (y) (z y)) or (let ((x (lambda (y) (z y)))), I'm defining a function that I can call. So the idea that "a variable name would rarely want to appear there" is kind of specious as far as Scheme is concerned.

Scheme is a characteristically functional language, so treating functions as data is one of its tenets. Having functions be a type of their own that's stored like all other data is a way of carrying on the idea.

Chuck
+6  A: 

Actually, as outlined in the paper by Richard Gabriel and Kent Pitman, the debate is about Lisp-5 against Lisp-6, since there are several other namespaces already there, in the paper are mentioned type names, tag names, block names, and declaration names. edit: this seems to be incorrect, as Rainer points out in the comment: Scheme actually seems to be a Lisp-1. The following is largely unaffected by this error, though.

Whether a symbol denotes something to be executed or something to be referred to is always clear from the context. Throwing functions and variables into the same namespace is primarily a restriction: the programmer cannot use the same name for a thing and an action. What a Lisp-5 gets out of this is just that some syntactic overhead for referencing something from a different namespace than what the current context implies is avoided. edit: this is not the whole picture, just the surface.

I know that Lisp-5 proponents like the fact that functions are data, and that this is expressed in the language core. I like the fact that I can call a list "list" and a car "car" without confusing my compiler, and functions are a fundamentally special kind of data anyway. edit: this is my main point: separate namespaces are not a wart at all.

I also liked what Pascal Constanza had to say about this.

Svante
The general debate is about Lisp-1 against Lisp-n. The idea in Scheme is that a few things are first-class objects and there is a single naming mechanism. Take for example tags, block names, etc. for non-local control transfer in Common Lisp - they are denoted by identifiers in something like their own namespace. Scheme uses continuations which are first class objects and don't have their own namespace.I also prefer a Lisp-n, but recognize the design principle behind Lisp-1: make everything 'first class' values and provide a single naming mechanism.
Rainer Joswig
Heh, I always thought that Scheme was much closer to Lisp, I didn't know that it doesn't have tags and blocks. Anyway, I didn't mean to put off Scheme in any way, either, just state my preference, and that in my view, having separate namespaces is _not_ a wart at all.
Svante
I'm not clear on your "always clear from context" remark. Are you saying that when I evaluate `(map f l)`, it will use the function namespace binding for `f`, and not the variable namespace binding? Or do I have to evaluate `(map #'f l)`, in which case it wasn't clear from context because the programmer had to explicitly disambiguate?
Curt Sampson
The first element of an s-expression is the thing to be executed, this is taken from the function associated with that symbol by default. All the following elements are things to be passed to the executed thing, these are taken from the values associated with the respective symbols by default. If you evaluate `(map f l)`, it is completely unambiguous that the function associated with `map` will be applied to the values associated with with `f` and `l`. "Context" means "lexical context", here. "#'" doesn't disambiguate, it just overrides the default.
Svante
minor correction: the first element names the function, correct. But it is not taken from the function associated with the symbol. It is taken from function lexically associated with the name in the function namespace. If there is no lexically bound function in the function namespace, then the symbol's function value is used. #'foo or (FUNCCTION foo) is then a way to access the function namespace and retrieve the function object as a value. If there is no lexical bound function under that name, then the symbol's function value is returned. For the lexically bound names no SYMBOLs are involved.
Rainer Joswig
Thanks for setting this straight.
Svante
A: 

There's good things to both approaches. However, I find that when it matters, I prefer having both a function LIST and a a variable LIST than having to spell one of them incorrectly.

Vatine
+2  A: 

The biggest downside I see, at least for Common Lisp, is understandability. We can all agree that it uses different namespaces for variables and functions, but how many does it have? In PAIP, Norvig showed that it has "at least seven" namespaces.

When one of the language's classic books, written by a highly respected programmer, can't even say for certain in a published book, I think there's a problem. I don't have a problem with multiple namespaces, but I wish the language was, at the least, simple enough that somebody could understand this aspect of it entirely.

I'm comfortable using the same symbol for a variable and for a function, but in the more obscure areas I resort to using different names out of fear (colliding namespaces can be really hard to debug!), and that really should never be the case.

Ken
A: 

There's an interesting rant on the topic by Erik Naggum: http://groups.google.com/group/comp.lang.lisp/msg/07b915645de0cec7