Is it possible to destructure a map in a bind? - clojure

Is it possible to do this in one function:
(binding [*configs* (merge default-configs configs)]
(let [{:keys [login url max-pages]} *configs*]
..
When I tried this:
(binding [{:keys [login url max-pages] :as *configs*} (merge default-configs configs)]
It gave me this error:
CompilerException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.Symbol
A little googling showed me that Common Lisp has a function called destructure-bind but I'm not sure if that's related.

No, nothing like this will work with core macros.
The reason is that both binding and let (and friends, e.g. with-bindings) do just one thing. In the case of binding, that thing is installing thread-local bindings for Vars; for let, it is introducing local bindings. These are entirely different operations.
In let, destructuring has a clear meaning: it introduces new locals, which is exactly what the basic, non-destructuring let bindings do. This is also clearly useful, as prying appart data structures and binding different parts to different locals is a common need. The names of the locals are also locally determined, so things like :keys in associative destructuring work well.
In binding, to be consistent with its main purpose, destructuring would need to bind several Vars simultaneously to several parts of a data structure. This is not nearly as useful. If instead destructuring in binding were to introduce locals, then all of a sudden binding would do two unrelated things, possibly both in the same binding pair (note how the failing binding form from the question text expects the bindings introduced by :keys to be locals, but the binding made by :as to be the usual thread-local binding of a Var). Thus binding simply opts not to support destructuring. (If you need to bind parts of a data structure to several Vars, you can use a let to perform the destructuring, then install the bindings with binding.)
As for destructuring-bind, it's basically the destructuring-enabled version of let in Common Lisp. CL's let does not support destructuring.

"Binding Forms (Destructuring)" section:
Clojure supports abstract structural binding, often called
destructuring, in let binding lists, fn parameter lists, and any macro
that expands into a let or fn. ...
AFAIK binding itself doesn't use destructuring mechanism (via fn of let).

Related

Is it possible to type hint a Clojure array filled with a deftype object?

I'm optimizing a small performance focused section of an application. I'm attempting to create a Java array of a type created via deftype
(deftype MyThing [foo bar baz])
However, I can't seem to find any documentation on how to type hint these arrays, and without a type hint, reflection occurs.
(def my-array (make-array MyThing 10))
(aget my-array 0)
Gives the warning:
Reflection warning, call to static method aget on clojure.lang.RT can't be resolved (argument types: core.MyThing, int).
Is there a way to correctly hint the type?
I'm surprised to not find any question on this topic on Stack Overflow, and still more surprised to see that the official documentation for adding type hints does not cover this - I was sure I'd be able to close this as a duplicate, or link to official documentation, but here I am typing it out by hand like a barbarian.
The "primitive" version of type hinting, for which other forms are mere shorthand1, is
^"Foo" xs
where Foo is the JVM's internal name for the class you want to hint. There are shorthands for primitive arrays (^ints xs), and for ordinary class types (^MyType x), but this doesn't cover arrays of non-primitive types. For that, you have to know the official class name for your type. You could look up the rules for this, but the simplest thing to do is to just ask the interpreter!
user=> (defrecord Foo [])
user.Foo
user=> (def foos (make-array Foo 10))
#'user/foos
user=> (class foos)
[Luser.Foo;
user=> (aget foos 0)
Reflection warning, null:1:1 - call to static method aget on clojure.lang.RT can't be resolved (argument types: unknown, int).
nil
user=> (aget ^"[Luser.Foo;" foos 0)
nil
1 Actually, even more primitive is ^{:tag "Foo"}, but this distinction doesn't matter for this question.

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.

What are 'if ,define, lambda' in scheme?

We have a course whose project is to implement a micro-scheme interpreter in C++. In my implementation, I treat 'if', 'define', 'lambda' as procedures, so it is valid in my implementation to eval 'if', 'define' or 'lambda', and it is also fine to write expressions like '(apply define (quote (a 1)))', which will bind 'a' to 1.
But I find in racket and in mit-scheme, 'if', 'define', 'lambda' are not evaluable. For example,
It seems that they are not procedures, but I cannot figure out what they are and how they are implemented.
Can someone explain these to me?
In the terminology of Lisp, expressions to be evaluated are forms. Compound forms (those which use list syntax) are divided into special forms (headed by special operators like let), macro forms, and function call forms.
The Scheme report desn't use this terminology. It calls functions "procedures". Scheme's special forms are called "syntax". Macros are "derived expression types", individually introduced as "library syntax". (The motivation for this may be some conscious decision to blend into the CS academic mainstream by scrubbing some unfamiliar Lisp terminology. Algol has procedures and a BNF-defined syntax, Scheme has procedures and a BNF-defined syntax. That ticks off some sort of familiarity checkbox.)
Special forms (or "syntax") are recognized by interpreters and compilers as a set of special cases. The interpreter or compiler may handle these forms via function-like bindings in some internal table keyed on symbols, but it's not the program-visible binding namespace.
Setting up these associations in the regular namespace isn't necessarily wrong, but it could be problematic. If you want both a compiler and interpreter, but let has only one top-level binding, that will be an issue: who gets to install their procedure into that binding: the interpreter or compiler? (One way to resolve that is simple: make the binding values cons pairs: the car can be the interpreter function, the cdr the compiler function. But then these bindings are not procedures any more that you can apply.)
Exposing these bindings to the application is problematic anyway, because the semantics is so different between interpretation and compilation. If your interpretation is interpreted, then calling the define binding as a function is possible; it has the effect of performing the definition. But in a compiled interpretation, code depending on this won't work; define will be a function that doesn't actually define anything, but rather compiles: it calculates and returns a compiled fragment written in some intermediate representation.
About your implementation, the fact that (apply define (quote (a 1))) works in your implementation raises a bit of a red flag. Either you've made the environment parameter of the function optional, or it doesn't take one. Functions implementing special operators (or "syntax") need an environment parameter, not just the piece of syntax. (At least if we are developing a lexically scoped Scheme or Lisp!)
The fact that (apply define (quote (a 1))) works also suggests that your define function is taking quote and (a 1) as arguments. While that is workable, the usual approach for these kinds of syntax procedures is to take the whole form as one argument (and a lexical environment as another argument). If such a function can be called, the invocation looks something like like (apply define (list '(define a 1) (null-environment 5))). The procedure itself will do any necessary destructuring on the syntax, and checking for validity: are there too many or too few parameters and so on.

What does "^:static" do in Clojure?

I've seen the ^:static metadata on quite a few function in the Clojure core.clj source code, e.g. in the definition of seq?:
(def
^{:arglists '([x])
:doc "Return true if x implements ISeq"
:added "1.0"
:static true}
seq? (fn ^:static seq? [x] (instance? clojure.lang.ISeq x)))
What precisely does this metadata do, and why it it used so frequently throughout core.clj?
In the development of Clojure 1.3 Rich wanted to add the ability for functions to return types other than Object. This would allow native math operators to be used without having to cram everything into one function.
The original implementation required functions that supported this to be marked :static. this meta data caused the compiler to produce two versions to the function, one that returned Object and one that returned that specific type. in cases where the compiler determined that the types would always match the more specific version would be used.
This was later made fully automatic so you don't need to add this anymore.
According to the Google Groups thread “Type hinting inconsistencies in 1.3.0”, it’s a no-op.
^:static has been a no-op for a while AFAIK, made unnecessary after changes to vars a while back.
— a May 2011 post by Chas Emerick
Seems it's a new metadata attribute in clojure 1.3. And you can compare the source between 1.3 and 1.2:
http://clojuredocs.org/clojure_core/clojure.core/seq_q
http://clojuredocs.org/clojure_core/1.2.0/clojure.core/seq_q
So I think it has something to do with ^:dynamic which indicates whether the var is allowed for dynamic binding. Just my guess. Not sure until I see document about this attribute.

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