Difference between definterface and defprotocol in Clojure - clojure

Other than lack of documentation, what is the difference between definterface and defprotocol in Clojure?

According to the Joy of Clojure:
The advantages of using definterface over defprotocol are restricted
entirely to the fact that the former allows primitive types for
arguments and returns. At some point in the future, the same advantage
will likely be extended to the interfaces generated [by protocols], so use
definterface sparingly and prefer protocols unless absolutely
necessary.

My possibly incomplete understanding was definterface produces an interface .class that java code can implement in order to create classes suitable to pass to your Clojure functions.
Protocols are, in short, a faster and more focused way of doing dispatch than multimethods. you actually have running code in a protocol that is used by other clojure code.

Related

Is there an idiomatic alternative to nil-punning in Clojure?

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.

deftype vs. defrecord

While defrecord is the preferred form -for the general case- in Clojure for defining an "entity", in ClojureScript one can find far more references to deftype, as reflected in various documentation.
What is the difference between both forms? Which should one prefer?
deftype creates a bare-bones object which implements a protocol.
defrecord creates an immutable persistent map which implements a protocol.
Which to use depends on what you want. Do you want a full ClojureScript data structure? Then use a record. Do you just want a bare-bones thing that does nothing but satisfy a protocol? Then use a type.
The two bits of documentation you reference use types because they're trying to illustrate protocols at the most basic level, and types have less "going on" than records, so to speak.
However, most real-world uses of object-like things in Clojure/ClojureScript need to store fields of data along with the object, and for that you should emphatically use a record, for the same reason you should use any of Clojure's immutable collections.
According to DEFTYPE VS DEFRECORD,
you should distinguish programming constructs and domain constructs.
deftype is for programming constructs and defrecord is for domain constructs that need a custom type.
Hope this helps.

Clojure Protocols vs Types

Disclaimer
Despite the title, this is a genuine question, not an attempt at Emacs/Vi flamewars.
Context
I've used Haskell for a few months, and written a small ~10K LOC interpreter. In the past year, I've switched to Clojure. For quite a while, I struggled with Clojure's lack of types. Then I switched into using defrecords in Clojure, and now, switched to Clojure's defprotocols.
I really really like defprotocols. In fact, more than types.
I'm now at the point where for my Clojure functions, for it's documentation string, I just specify:
* the protocols of the inputs
* the protocols of the outputs
Using this, it appears I now have an ad-hoc type system (not compiler checked; but human checked).
Question
I suspect there's something about types that I'm missing. What does types provide over protocols?
Questioning the question...
Your question "What [do] types provide over protocols?" seems awkward to me. Types and protocols are perpendicular; They describe different things. Types/records define structure of data, while Protocols define the structure of some behavior or functionality. And part of why this question seems weird to me is that these things are not mutually exlusive! You can have types implement a protocol, thereby giving them whatever behaviour/functionality that protocol describes. In fact, since your context makes it clear that you have been using protocols, I have to wonder how you've been using them. My guess is that you've been using them with records (or possibly reifying them), but you could just as easily use protocols and (def)types together.
So to me, it seems you've compared apples with oranges here. To help clarify, let me compare apples to apples and oranges to oranges with a couple of different questions:
What problems do protocols solve, and what are the alternatives and their respective advantages/disadvantages?
Protocols let you define functions that operate in different ways on different types. The only other ways to do this are multimethods and simple function logic:
multimethods: have value in being extremely flexible. You can dispatch behavior on type by passing type as the dispatch function, but you can also use any other arbitrary function for dispatching.
internal function logic: You can also (of course) manually check for types in conditionals in your function definitions to decide how to process differently given different types. This is more primitive than multimethod dispatch, and also less extensible. Except in simple cases, multimethods are preferred.
Protocols have the advantage of being much more performant, being based on JVM class/method dispatch, which has been highly optimized. Additionally, protocols were designed to address the expression problem (great read), which makes them really powerful tools for crafting nice, modular, extensible APIs.
What are the advantages/disadvantages of (def)records or reify over (def)types?
On the side of how we specify the structure of data, we have a number of options available:
(def)records: produce a type good for "representing application domain information" (from http://clojure.org/datatypes; worth a read)
(def)types: produce a lighter weight type for creating "artifacts of the implementation/programming domain", such as the standard collection types
reify: construct a one-off object with an anonymous type implementing one or more protocols; good for... one-off things which need to implement a protocol(s)
Practically, records behave like clojure hash-maps, but have the added benefit of being able to implement protocols and have faster attribute lookup. Conveniently, the remain extensible via assoc, though attributes added in this fashion do not share the compiled lookup performance. This is what makes these constructs convenient for implementing applciation logic. Using deftype is advantageous for aspects of implementation/programming domain because they don't implement excess bagage, making the the use cleaner for these cases.
Protocols create interfaces and interfaces are a well, the interface to a type. they describe some aspects of a type though with much less rigor than you would come to expect in a language like Haskell.
machine checking
type inference (you don't get some of your protocols generated from docs of others)
parametric polymorphism (parameterised protocols / protocols with generics don't exist)
higher order protocols (what is the protocol for a function that returns a protocol?)
automatic generation of code / boilerplate
inter-operation with automated tools

defmulti vs defprotocol?

It seems like both can be used to define functions that you can implement later, with different data types. AFAIK the major difference is that defmulti works on maps and defprotocol works on records.
What other differences there? What are the benefits of using one over the other?
Short version: defmulti is much more flexible and general, while defprotocol performs better.
Slightly longer version:
defprotocol supports dispatch on type, which is like polymorphism in most mainstream programming languages.
defmulti is a more general mechanism where you can dispatch on other things than just a single type. This flexibility comes with a performance penalty.
More on protocols
More on multimethods
Just an addition to cover the motivation, corvuscorax's answer covers the origional question nicely.
Originally Clojure only had multimethods and very early on a lot of thought went into building a dispatch abstraction that could handle all cases very well and would not force people to structure their abstractions around a limitation of the abstractions offered by the language.
As Clojure matured the desire to create "clojure in clojure" required abstractions that where at least in theory capable of producing any bytecode that could be produced by java and thus the need for protocols, a dispatch abstraction that more closely matched native Java.
Clojure has a strong "embrace your platform" ideal and protocols suit this mindset very well.

Methods for side-effects in purely functional programming languages

At the moment I'm aware of the following methods to integrate side-effects into purely functional programming languages:
effect systems
continuations
unique types
monads
Monads are often cited to be the most effective and most general way to do this.
Which other methods exist? How do they compare?
Arrows, which are more general than monads.
The very simplest method is to simply pass around the environment between the functions. This is often used to teach scheme.
To me a more general way is via a monad/comonad pair. This generalizes the common "monad" approach which should correctly be called the "strong monad" approach, since it only works with strong monads.
Moving to a monad/comonad pair allows effects to be modeled that result in some variables no longer being available. An example where this is useful is the effect of migrating a thread to another host in a distributed setting.
An additional method of historical interest is to make the whole program a function mapping a stream/list of input events to a stream/list of output events. See: "How to Declare an Imperative" by Phil Wadler: http://www.cs.bell-labs.com/~wadler/topics/monads.html#monadsdeclare