0

What is the idiomatic way to name a Clojure protocol ? IProtocol or Protocol, or do they present different use cases, and why ?

So far I use IProtocol when dealing with interoperability (Java or js/google-closure in ClojureScript).

I am also wondering about the naming convention of the method names : -my-method vs my-method. I have seen both in the wild (in ClojureScript codebase), and could not come up with a rationale to explain when use one or the other.

So, what is the idiomatic way to name abstractions in Clojure and ClojureScript ?

nha
  • 17,623
  • 13
  • 87
  • 133
  • 1
    Difference between -my-method and my-method is that "-" is default prefix for gen-class. You can specify another prefix in gen-class construction. – JustAnotherCurious Aug 31 '15 at 07:48
  • @JustAnotherCurious thanks for the pointer I wasn't aware of that. Could you expand a bit ? This means it is useful in interop scenarios ? – nha Aug 31 '15 at 08:40
  • @JustAnotherCurious otherwise that would be an answer that I could accept. – nha Aug 31 '15 at 09:11

1 Answers1

0

Yes, this is a way of how you allow java to call clojure code.

If you create, for example, lein new app testapp (lein is command line interface for leiningen a widely used clojure projects automation tool) you may see in your core.clj a line

(ns testapp.core
  (:gen-class))

(defn -main 
  "Comment line"
  [&args]
  (println "Hello, World!"))

Here ns is a macro that makes easier to define namespaces and other things. Important thing here is (:gen-class). Let unwrap the macro:

> (macroexpand-1 '(ns testapp.core (:gen-class)))
(do 
  .... 
  (clojure.core/gen-class :name "testapp.core" :impl-ns testapp.core :main true)
  ....)

This code will tell the compiler to generate the byte code for the class named "testapp.core" and this class marked as ":main true". This mark will create a declaration of static public main function in the class, so jvm could start a program calling the main function. By java language convention the program entry point should be called main. You can add different methods to gen-class (see docs) declaring types or arguments and return value, but, as I can assume, it can be useful to separate java statically typed methods from your clojure functions to prevent name collapse. So gen-class allows you to define a :prefix that you use to name your java class implementation. Default one is "-". So you create a function -main and in java code it would look like testapp.core.main.

We can change it

(ns testapp.core
  (:gen-class :prefix my-prefix-))

When you compile your code to jar and run with java -jar you get

Exception in thread "main" java.lang.UnsupportedOperationException:
testapp.core/my-prefix-main not defined

Ok, we forgot to rename our implementation:

(defn my-prefix-main [&args] (println "Hello, World!"))

Compile and run:

"Hello, World!"

P. S. I can't tell you about naming conventions of protocols and interfaces that are used in clojure.

JustAnotherCurious
  • 2,208
  • 15
  • 32