Note that I'm not talking about ear muffs in symbol names, an issue that is discussed at Conventions, Style, and Usage for Clojure Constants? and How is the `*var-name*` naming-convention used in clojure?. I'm talking strictly about instances where there is some function named foo that then calls a function foo*.
问题:
回答1:
In Clojure it basically means "foo* is like foo, but somehow different, and you probably want foo". In other words, it means that the author of that code couldn't come up with a better name for the second function, so they just slapped a star on it.
回答2:
Mathematicians and Haskellers can use their apostrophes to indicate similar objects (values or functions). Similar but not quite the same. Objects that relate to each other. For instance, function foo
could be a calculation in one manner, and foo'
would do the same result but with a different approach. Perhaps it is unimaginative naming but it has roots in mathematics.
Lisps generally (without any terminal reason) have discarded apostrophes in symbol names, and *
kind of resembles an apostrophe. Clojure 1.3 will finally fix that by allowing apostrophes in names!
回答3:
If I understand your question correctly, I've seen instances where foo*
was used to show that the function is equivalent to another in theory, but uses different semantics. Take for instance the lamina library, which defines things like map*
, filter*
, take*
for its core type, channels. Channels are similar enough to seqs that the names of these functions make sense, but they are not compatible enough that they should be "equal" per se.
Another use case I've seen for foo*
style is for functions which call out to a helper function with an extra parameter. The fact
function, for instance, might delegate to fact*
which accepts another parameter, the accumulator, if written recursively. You don't necessarily want to expose in fact
that there's an extra argument, because calling (fact 5 100)
isn't going to compute for you the factorial of 5--exposing that extra parameter is an error.
I've also seen the same style for macros. The macro foo
expands into a function call to foo*
.
回答4:
a normal let binding (let ((...)))
create separate variables in parallel
a let star binding (let* ((...)))
creates variables sequentially so that can be computed from eachother like so
(let* ((x 10) (y (+ x 5)))
I could be slightly off base but see LET versus LET* in Common Lisp for more detail
EDIT: I'm not sure about how this reflects in Clojure, I've only started reading Programming Clojure so I don't know yet