What does the leading arrow in a name mean in clojure - clojure

Learning Clojure I came across code like below:
=> (defrecord Person [name, age])
user.Person
=> (->Person "john" 40)
#user.Person{:name "john", :age 40}
=> (Person. "tom" 30)
#user.Person{:name "tom", :age 30}
the question is, what does the leading arrow(i.e., ->) in the ->Person mean ? It's a reader macro or what ? I see no description of it in the reader section of clojuredoc. Further, what is the difference between ->Person and Person. ?

It has no syntactic meaning. It is just part of the symbol name. In Lisps, the arrow -> (or even just '>') is often used to imply conversion of, or casting of, one type into another. In the macro expansion of the defrecord:
(macroexpand '(defrecord Person [name age]))
you can see that it defines ->Person as a function that calls the Person constructor. ->Person (the function) may be more convenient for you to use than Person. (the direct call to the Java constructor) as you can pass it as an argument to other functions, capture it in a variable and use it, etc:
(let [f ->Person]
(f "Bob" 65))
Compare that to:
(let [f Person.]
(f "Bob" 65))
Which is syntactically invalid.

Obviously not in your specific example, but in the general context this operator -> is called the threading operator and is considered one of the thrush operators. Along with its cousin the ->> operator, these operators are quite useful when you need to have code appear more clearly, especially when feeding the output of functions as parameters to another function. Both operators are macros. Here's another SO post concerning both operators.
I have not yet had cause to use the ->, but did need ->> to make sense of code that needed to compute intermediate values and put them all into one function call.
Here is another explanation.

Related

Canonical approach to return based on type of the argument in Clojure

If the argument is a symbol return it. If the argument is a list call another method.
New to Clojure and cannot find the canonical way to do it. In Python, one could do:
def return_on_arg_type(arg):
if type(arg) is str:
return arg
if type(arg) is list:
return another_method(arg)
May be I could use multi-methods but how to match on type of the argument and also is matching on type acceptable in Clojure?
There's essentially 3 dispatch methods in Clojure:
Use cond combined with predicates (that's methods that return true or false and often have a name ending in ?) as Alan has described.
Use Protocols which dispatch on the type of the first argument. The reference documentation for this would be at https://clojure.org/reference/protocols
Multimethods. You can think of Multimethods as a programmable dispatch method. They can do much more than just look at the type of their arguments, they could also look into arguments, count elements on a vector argument and much more. Canonical documentation at https://clojure.org/reference/multimethods
Take a look at Clojure multimethods vs. protocols for a short discussion on Multimethods vs Protocols.
Not sure of the goal, but this should work:
(defn something [arg]
(cond
(str? arg) arg
(list? arg) (other-fn arg)))
It is ok to check for types in Clojure. It is not an un-typed language.
The code proposed by Alan is idiomatic IMHO if you need a simple dispatch mechanism.
There are other possibilities here. One you mentioned already: multi-methods.
Your example could be written as
(defmulti something class [arg])
(defmethod something String [arg] arg)
(defmethod something java.util.List [arg] (some-other arg))
The dispatch fn is class in this case, but you can implement any kind of dispatch condition.
There's also clojure.match, a general purpose matching library (among others). See https://github.com/clojure/core.match
Next to using a multimethod or a method to explicitly check, it's also possible to dispatch on the type of first argument with a protocol:
(defprotocol OnArgTypeReturner
(return-on-arg-type [arg]))
(extend-protocol OnArgTypeReturner
String
(return-on-arg-type [arg] arg)
clojure.lang.IPersistentList
(return-on-arg-type [arg] "another-method-called"))
(return-on-arg-type "foo")
;; => "foo"
(return-on-arg-type '(1 2 3))
;; => "another-method-called"

Why do some lisps put the function name outside of the argument list in a function definition?

common lisp and clojure do
(defn function-name (arg1 arg2) (body))
racket/scheme does
(defn (function-name arg1 arg2) (body))
The latter makes more sense to me because the syntax for function definition and invocation is similar. What's the reasoning for the former?
TL;DR It's not quite as simple as you put it. The syntax is slightly more different and every time someone create a language they get to decide new syntax, usually to make it more concise that previous languages or the language has a design that requires it. Of course what is "better" is a matter of opinion.
In Scheme (and the descendant Racket) you have one namespace for both variables and functions. Thus you use define for everything.
(define variable 10)
(define function (lambda (arg1 arg2) body ...))
Now define has a short cut for that last one, which is:
(define (function arg1 arg2) body ...)
So the rule is if the first part is a pair? it is supposed to be expanded to the longer form with lambda. That it resembles an application is just a conicident I guess. This extra feature is just to save some keystrokes and is often omitted in books like The little Schemer since its confusing to have two ways and the learner and they might think defining a binding for a function is more special than defining 10, which is ridiculous. The rest argument usually confuses. eg. these are the same:
(define (test . x) x)
(define test (lambda x x))
In Common Lisp you have two namespaces and thus defun is only used for global scope and there are function equivalents of variable forms that makes functions. in defun you have a list first argument in Common Lisp too, but it does something completely different:
(defun (setf name) (new-value)
body ...)
This provides a way to get the same symmetry as other accessors in CL. eg. if (car x) gets the car value from a cons (setf (car x) 10) will alter it. In my example name can be used in the same manner as car. It's quite handy.
Clojure does it with def and fn and uses an array for parameters:
(def function (fn [arg1 agr2] body ...))
defn is just a shorthand version just like the define that starts with a pair. How it didn't end up more similar to Scheme is perhaps either the fact that the parameter data is an array or that they kept syntax as close to the original as possible. If I remember correctly you can have a function name as second argument with fn as well making fn and defn look almost identical.
The latter makes more sense to me because the syntax for function definition and invocation is similar.
In Common Lisp the function definition generally is not similar to the invocation, thus it makes no sense to pretend they do.
This is a valid function defintion:
(defun foo (arg1 arg2
&optional (ovar 10)
&rest args
&key (ak 11 a-p)
&allow-other-keys
&aux (aux1 12))
(list arg1 arg2 ovar args ak a-p aux1))
These are valid calls for above:
(foo 1 2)
(foo 1 2 3)
(foo 1 2 3 :ak 4)
(foo 1 2 3 :foo 10 :ak 4)
Thus the call arguments look different from the definition argument list.
In the case of DEFMETHOD a definition may look like:
(defmethod (setf foobar) :around ((value integer) (object foo))
(setf (slot-value object 'a) value))
and a call would be
(setf (foobar object) 10)
Summary
In Common Lisp function definitions won't look like calls anyway
Excursion
It's simple to define a Scheme-like syntax for simple CL functions:
(defmacro define ((name &rest args) &body body)
`(defun ,name ,args ,#body))
CL-USER 36 > (macroexpand-1 `(define (foo a b c) (baz) (bar)))
(DEFUN FOO (A B C) (BAZ) (BAR))
T
Some programs even use something similar...
Function definition is just an operation in the Lisp family. There is actually little meaning in making function definition similar to function application.

how to combine protocol function with function with same name and different arity?

I have a function foo that takes a single argument whose implementation depends on the type of the argument, hence a protocol:
(defprotocol Foo
(foo [x]))
On the same namespace, I also would like a function with the same name (foo) that takes variable arguments and that calls for each argument the single-arg foo. Something like:
(defn foo [x1 x2 & more]
(doseq [x (concat [x1 x2] more)])
(foo x))))
How to implement that?
Just adding to Tim Pote's answer, let me quote an answer from Stuart Halloway:
[...] protocols are the contract for implementers, not the contract for callers. If you change a contract for implementers, then the implementers must change.
[...] a function that has a reasonable default for any object. Often such a function does not need to be part of the contract for implementers (i.e. the protocol) at all.
It's liberating for the protocol implementers, because you can set default values or add support to multiple arities (like in your case) in the public api fn, without having to worry about all of that in the concrete implementations.
With the defprotocol you've declared the function foo. Later calling (defn foo ...) effectively overwrites your previous declaration.
One common idiom is to prepend a - to your protocol fn (i.e. -foo). This is basically Hungarian Notation for "This is an internal protocol function. There is a wrapper for it in this namespace. You should call that instead." This leaves the protocol open for extension, but allows you to wrap the invocation.
Another thing I would consider in your case is whether or not the name foo is appropriate for your wrapper. The fact that it operates on multiple Foos indicates that maybe something like do-foos is more appropriate.

multiple functions with same name in clojure

(defn hi[](+ 5 6))
(hi)
(defn hi[](+ 6 7))
(hi)
Hi,
i'm new to clojure . as above writen code i wrote two functions with same name.
can we have same name for multiple functions in clojure. if yes does it conflict within same namespaces?
You cannot have several functions with the same name in the same namespace. If you define function foo and then redefine it again, newer version will replace the older.
It's not quite clear what you're trying to achieve, but Clojure has quite a few ways to have several implementations under one name.
Arity Dispatch
You can dispatch functions on arity:
(defn foo
([x] :version-one)
([x y] :version-two)
([x y & more] :version-tree))
Different arities of the same function can call one another, and this is somewhat equivalent to having several functions with the same name.
Multimethods
You can dispatch using multimethods. They allow you to define a function that will be called on arguments and its result will be used for dispatching.
(defmulti foo odd?)
(defmethod foo true [x]
(format "look, ma, %d is odd!" x))
(defmethod foo false [x]
(format "look, ma, %d is even!" x))
Protocols
This technique is similar to polymorphism in other languages. You can dispatch on argument type. Here is example:
(defprotocol foo
(my-fnc [x] "description..."))
(extend-protocol foo
Number
(my-fnc [x] :number-version)
String
(my-fnc [x] :string-version))
Multimethods are most powerful tool, you can emulate protocols with them this way:
(defmulti foo class)
I wrote two functions with same name.
Yes and No:
You wrote two function definitions with the same name.
The second definition overwrote the first.
The functions never shared the name.
Can we have same name for multiple functions in clojure?
Not in the same namespace. A second def or defn for a symbol erases the first.
There is only one symbol with a given name in a namespace.
A symbol refers to only one var at a time.
The def form ties a symbol to the var it refers to.
The fn form creates a function.
The defn macro is a wrapper round the def and fn forms,
causing the named symbol to refer to a var holding the function.
Symbols with the same name in different namespaces do not conflict:
they are different symbols.
If yes does it conflict within the same namespace?
Yes.
But ...
One function can have several arities - argument counts. This applies to functions referred to by symbols through vars and in other contexts.
Function definition is a side-effect of evaluating a defn. The best explanation I know of how lisps evaluate function definitions is Chapter 2 of Paul Graham's On Lisp.

What's the convention for using an asterisk at the end of a function name in Clojure and other Lisp dialects?

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*.
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.
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!
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*.
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