Clojure Protocols Against Types

Renouncement

Despite the title, this is a real question, not an attempt to attack Emacs / Vi flipewars.

Context

I used Haskell for several months and wrote a small LOC ~ 10K LOC interpreter. Last year I switched to Clojure. For some time I struggled with the lack of Clojure types. Then I switched to using defrecords in Clojure and now switched to Clojure defprotocols.

I really like defprotocols. In fact, more than types.

Now I am at the point where, for my Clojure functions, for this line of documentation, I simply indicate:

* the protocols of the inputs * the protocols of the outputs 

Using this, it seems that now I have an ad-hoc type system (not verified by the compiler, but verified by humans).

Question

I suspect that there are some types that I am missing. What types provide protocols?

+4
source share
3 answers

Protocols create interfaces and interfaces - that's good, an interface to a type. they describe some aspects of the type, but with much less rigor than you would expect in a language such as Haskell.

0
source

Poll question ...

Your question, "What types of [do] do protocols provide?" It seems uncomfortable to me. Types and protocols are perpendicular; They describe different things. Types / records determine the structure of the data, and protocols define the structure of some behavior or functionality. And part of why this question seems strange to me is that these things are not mutually exclusive! You may have types that implement the protocol, thereby providing them with any behavior / functionality described in the protocol. In fact, since your context makes it clear that you are using protocols, I need to wonder how you use them. I suppose you used them with records (or perhaps re-creating them), but you could easily use protocols and (def) types together.

So, I think you compared apples to oranges here. To help clarify, let me compare apples with apples and oranges with oranges with a few different questions:

What problems are solved by protocols, and what are the alternatives and their respective advantages / disadvantages?

Protocols allow you to define functions that work differently on different types. The only other ways to do this are through dots and simple function logic:

  • multimethods: value is extremely flexible. You can send behavior by type by passing type as a send function, but you can also use any other arbitrary function to send.
  • internal logic of functions. You can also (of course) manually check types in conditional expressions in function definitions to decide how to handle different data types. This is more primitive than multipoint sending, and also less extensible. In addition to simple cases, multimethods are preferred.

The advantage of protocols is that they are much more efficient based on the JVM class / method dispatch, which has been optimized. In addition, the protocols were designed to solve the problem of expression (well readable), which makes them really powerful tools for creating good, modular extensible APIs.

What are the advantages / disadvantages (def) of records or type overriding (def)?

Aside from how we specify the data structure, we have several options available:

  • (def): create a good type for "presenting application domain information" (from http://clojure.org/datatypes ; worth reading)
  • (def): create a lighter weight type to create "implementation / programming domain artifacts" such as standard collection types
  • reify: create a one-time object with an anonymous type that implements one or more protocols; good for ... one-time things that should implement protocol (s)

In practice, entries behave like clojure hash maps, but have the added benefit of being able to implement protocols and have faster attribute searches. It is convenient to remain extensible through assoc , although attributes added in this way do not share compiled search performance. This is what makes these constructs convenient for implementing application logic. Using deftype is beneficial for aspects of the implementation / programming domain, since they do not implement redundant packages, which makes using clean for these cases.

+1
source
  • machine check
  • type inference (you do not get some of your protocols created from other documents)
  • parametric polymorphism (parameterized protocols / protocols with generics do not exist)
  • higher order protocols (what is a protocol for a function that returns a protocol?)
  • automatic code / template generation
  • interaction with automated tools
0
source

Source: https://habr.com/ru/post/1413861/


All Articles