Is struct or create-struct deprecated?.
I´ve read here that I should use defrecord instead:
https://clojuredocs.org/clojure.core/struct
Thanks
R.
According to "Why have both deftype and defrecord?", ...
Overall, records will be better than structmaps for all
information-bearing purposes, and you should move such structmaps to
defrecord. It is unlikely much code was trying to use structmaps for
programming constructs, but if so, you will find deftype much more
suitable.
According to the Clojure v1.8 API documenatation the struct and create-struct are not deprecated.
Related
I have just recently started to learn some clojure and in order to make something like types (more like contracts) for validations etc, the go-to solution is a library named schema.
Recently I learned that clojure 1.9 however will have something similar named clojure.spec
Can anyone please tell me the differences between them?
When should I use one or the other, pros and cons, etc?
Eric Normand did this comparison, but as already pointed out you should definitely check the rationale, and there is also the guide and a podcast where Rich Hickey talks abouts clojure.spec.
The spec rationale is quite in-depth, I would suggest reading it: https://clojure.org/about/spec after that feel free to compare it with any other library you may be considering.
I'm reading some Clojure code at the moment that has a bunch of uninitialised values as nil for a numeric value in a record that gets passed around.
Now lots of the Clojure libraries treat this as idiomatic. Which means that it is an accepted convention.
But it also leads to NullPointerException, because not all the Clojure core functions can handle a nil as input. (Nor should they).
Other languages have the concept of Maybe or Option to proxy the value in the event that it is null, as a way of mitigating the NullPointerException risk. This is possible in Clojure - but not very common.
You can do some tricks with fnil but it doesn't solve every problem.
Another alternative is simply to set the uninitialised value to a symbol like :empty-value to force the user to handle this scenario explicitly in all the handling code. But this isn't really a big step-up from nil - because you don't really discover all the scenarios (in other people's code) until run-time.
My question is: Is there an idiomatic alternative to nil-punning in Clojure?
Not sure if you've read this lispcast post on nil-punning, but I do think it makes a pretty good case for why it's idiomatic and covers various important considerations that I didn't see mentioned in those other SO questions.
Basically, nil is a first-class thing in clojure. Despite its inherent conventional meaning, it is a proper value, and can be treated as such in many contexts, and in a context-dependent way. This makes it more flexible and powerful than null in the host language.
For example, something like this won't even compile in java:
if(null) {
....
}
Where as in clojure, (if nil ...) will work just fine. So there are many situations where you can use nil safely. I'm yet to see a java codebase that isn't littered with code like if(foo != null) { ... everywhere. Perhaps java 8's Optional will change this.
I think where you can run into issues quite easily is in java interop scenarios where you are dealing with actual nulls. A good clojure wrapper library can also help shield you from this in many cases, and its one good reason to prefer one over direct java interop where possible.
In light of this, you may want to re-consider fighting this current. But since you are asking about alternatives, here's one I think is great: prismatic's schema. Schema has a Maybe schema (and many other useful ones as well), and it works quite nicely in many scenarios. The library is quite popular and I have used it with success. FWIW, it is recommended in the recent clojure applied book.
Is there an idiomatic alternative to nil-punning in Clojure?
No. As leeor explains, nil-punning is idiomatic. But it's not as prevalent as in Common Lisp, where (I'm told) an empty list equates to nil.
Clojure used to work this way, but the CL functions that deal with lists correspond to Clojure functions that deal with sequences in general. And these sequences may be lazy, so there is a premium on unifying lazy sequences with others, so that any laziness can be preserved. I think this evolution happened about Clojure 1.2. Rich described it in detail here.
If you want option/maybe types, take a look at the core.typed library. In contrast to Prismatic Schema, this operates at compile time.
Clojure has this handy way to view a function's definition in REPL.
Is there one in Elixir REPL ?
No, there isn't a convenient way yet.
Well, I'm going to post this as an answer, even though it's not the same as "source". In IEX, you can type h function_name to see the documentation for function_name. It's basically Clojure REPL's doc feature. So far, in Elixir, this is good enough for most cases where I want source.
I'm at loss of how to create a Java enum in Clojure. I want to create a Java enum that uses a Java interface and then pass it into a Java method, all within Clojure. I want to do this to work with the neo4j graph library (I don't want to use someone's prebuilt interface, I want to write my own interop code).
I searched around the internet, and it looks like I can use the proxy method, but I can't for the life of me get it to work. Here's the equivalent Java code I need to write in Clojure:
private static enum RelTypes implements RelationshipType
{
KNOWS
}
And here's my stab at it (It's not right :( ):
(proxy [org.neo4j.graphdb.RelationshipType] [] (KNOWS))
I'm also wondering if there's a good website that documents things like this that I'm missing. I know about the Clojure docs on the Clojure site, which is really useful, but for example of usage I can't always find what I need. Perhaps I need a good reference book?
Why not just create the enum in Java? Sometimes falling back to Java is the simplest answer.
Here is a very old thread about using proxy to define enums from Rich Hickey and Stuart Sierra along with some alternatives using gen-class. I think the proxy path should work with something like this for you:
(proxy [Enum org.neo4j.graphdb.RelationshipType] [ "KNOWS" 1 ])
But that won't generate anything you'd want an external Java user to use, in which case gen-class is likely the better solution.
Yesterday, Rich pulled the 'new' branch of Clojure into master. We are now embracing the beauty that is deftype and defprotocol. Of course, I, coming from Haskell, am very tempted to define types like I would in Haskell, which would be for virtually everything short of a throwaway tuple, but I don't think it works like that in Clojure world ;). In the Common Mistakes thread for Clojure, one guy mentioned that overusing structs was a mistake he made when he first started, coming from OOP. Since deftypes seem to be similar to structs, I was wondering if the same thing applies there.
So, my question is: when is it a good time to use deftype?
One area deftype shines is performance. Methods of protocols are very fast on a deftype. Also deftype may have primitive fields, so no boxing anymore when crunching numbers...
Another area might be Java interoperation, since deftype can implement interfaces (and if AOT compiled) have a named class.
In general is the basic idea to define abstractions with protocols and to implement them with deftype.
Rich details his motivation here: http://www.assembla.com/wiki/show/clojure/Datatypes