Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: Should I prepend new- or make- to constructor functions?

Tags:

clojure

When creating a new Java object via a wrapper function, what is the "constructor" naming standard? Should I prepend make- or new- to the function name? Or just call it the type of thing it returns? At one point I got accustomed to using make- because it's the way it was done in the Scheme book SICP.

For example, I'm passing some stuff to a function which eventually returns an instance of a Java class. Here are a few examples:

(def myimage1 (make-image "img.svg" 100 200))  ; These all return
(def myimage2 (new-image "img.svg" 100 200))   ; an instance of
(def myimage3 (image "img.svg" 100 200))       ; javafx.scene.image.Image

Is it the same for creating Clojure-only structs, such as maps, etc?:

(def mystruct1 (make-custom-struct args))
(def mystruct2 (new-custom-struct args))
(def mystruct3 (custom-struct args))

I prefer the last version without make- or new-, but often times the binding (for example inside a let) would have the same name, which would suggest prepending the constructor name, or using a different binding name, such as:

(let [image (make-image "img.svg" 100 200)] ...)
(let [imuj (image "img.svg" 100 200)] ...)

However other times I'd just like to use the function in-line without the cluttering of the new- or `make-':

(do-something-with-an-image (image "img.svg" 100 200))
like image 486
Sonicsmooth Avatar asked Sep 10 '25 16:09

Sonicsmooth


2 Answers

Stuart Sierra suggests not using a prefix. His idea is that a pure function can be replaced with its implementation, and so a simple noun makes a better name in that sense than a verb.

like image 139
gfredericks Avatar answered Sep 13 '25 07:09

gfredericks


I agree that (image ...) is the version that looks the best. However, you are right that you can easily end up shadowing the function with local variables. What can you do?

  • Namespaces are here to counter the issue introduced by the Lisp-1 nature of Clojure:

    (let [image (png/image "file.png")] ...)
    
  • Alternatively, when you are in the same namespace, you should give better variable names: image is a little bit generic; try something more precise, like avatar or thumbnail. Note also that sometimes image is the best name to give to the variable.

  • You can also prefix or suffix variable names, like user-image, old-image or new-image.

  • Regarding functions, the make- prefix is not bad: it is readable, unambiguous and it fixes the problem of shadowing existing bindings. So don't discard it too quickly. This prefix tends to be found more often than new-, which is a little unclear: sometimes you have old and new data, where new is an adjective.

like image 31
coredump Avatar answered Sep 13 '25 07:09

coredump