(:keyword m)
calls in turn (get m :keyword)
That's just a basic feature of the language. No macros involved.It seems to me that a function must be defined somewhere before one could call it.)
As I understand it, the roles which things like lists and functions play in a traditional lisp are replaced in Clojure by abstract datatypes corresponding to Java interfaces. Which on one hand is kinda neat because the core lisp datatypes aren't tied to specific concrete implementations and other datatypes (including user-defined ones) can participate in the same abstractions.
On the other hand it means the semantics become quite tied up in underlying JVM-related details and don't seem as clean/elegant as (say) Scheme.
On the other hand it means the semantics
become quite tied up in underlying JVM-related
details and don't seem as clean/elegant as (say)
Scheme.
That's not very true. Instead, Clojure is defined in terms of specific abstractions. Whether those take the form of interfaces or protocols is irrelevant because it's the abstractions that count. If it were tied strictly to JVM-related details then ClojureScript would have been much harder to implement than it was.The elegance of Scheme is subjective.
I recall some debate about changing this so you can implement them using the native abstraction facilities in clojure (protocols), at which point I'd probably withdraw my point.
But yeah elegance is subjective. I use Clojure and broadly like it, JVM interop is really useful, but the lack of a crisp separation between clojure semantics and JVM semantics does still irk the purist in me a bit.
I guess I'd see Clojure and ClojureScript not as one language on two host platforms, but as one JVM language and another similar but not really source-compatible language on another platform which is influenced by it. Part of the philosophy seems to be to make pragmatic decisions which blur the boundary with the host platform, rather than try to abstract over the differences in APIs and runtime semantics.
>> I recall some debate about changing this so you can implement them using the native abstraction facilities in clojure (protocols)
You mean records (defrecord): http://clojure.org/datatypes
Dunno how feasible this is, but if a language is going to define its own abstraction features (here, protocols) on top of the underlying platform, it would seem cleaner to eat ones own dogfood in using these abstraction facilities for the core abstractions which the language and its core library are based on.
The keyword is a function i.e. (in Java terms) it implements the IFn interface.
The effect of that function is the same as calling the get function on a map using the keyword as the argument.
If it is a function, where it is defined and when?
That's why I'm arguing that this form is confusing, and that transformation is more correct notion, at least if people are insisting to call it Lisp.)
It is also a function though, and can be used in the function position of a function application just like any other function.
Keywords and all their functionality are defined as a primitive in Clojure, i.e. in the Java source code for the language.
It's typically one of the first things people learn when they pick up Clojure, and is used as an idiomatic way to access maps whose keys are keywords. I would argue that is is not confusing and that it is totally consistent - all you were missing is one fact: keywords are functions.
The logic is that this object could be called as a function and at the same time always evaluated to itself?
That means whenever you call it you always getting it back - this is behavior of a constant. But if you could call it with an argument, you will get back some value, different from whatever it is?
As long as maps are immutable, it will behave as a function - return the same value for the same argument.
OK, but, please, don't tell me that this isn't confusing.)
No! You're confusing functions-as-callable-things and functions-as-values. The phrase "a constant" does not generally imply anything about a thing's behavior when called. It just means something whose value will never change. A self-evaluating constant is a constant that circularly evaluates to itself — nothing else can have that value without referring to the constant. But neither of these things have to do with calling anything; they're just about taking values.
A constant can certainly refer to a function that returns something other than that constant. For example, in Ruby: `Example = lambda { 1 }`. If you just evaluate "Example", you will get a Proc value, but if you call Example, you will get the Fixnum 1.
In most languages that have them, you cannot call a self-evaluating constant. It won't return itself — it's just not a callable thing. In Clojure, keywords are self-evaluating constants that have the behavior of looking themselves up as a key in the argument when called. They serve the purpose of self-evaluating constants exactly the same as in other languages, but they also have the handy property of doing map lookups.
Call it "callable" if you prefer. Much the same way as in C++ objects that define operator() are callable; only cleaner.