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))
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.
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.
I think -> is a fun prefix, and it's already used by the factory functions generated by defrecord.
Related
Is is good practice to use Clojure nested let in the following way, or is it confusing ?
(defn a-fun [config]
(let [config (-> config (parse) (supply-defaults))]
;; do something with config
))
I noticed I have this pattern of parsing/checking/validating things quite often in my input functions that talk to the external world (in this case a Clojurescript library that exposes public functions, but I also had Compojure routes with this same feeling).
Is it confusing, because one has to understand the rules for bindings visibility (not sure what the exact wording is) ?
What would be the idiomatic way to do it ? Change the config name to parsed-config, put it in another function, something else completely ?
I would reach for this idiom when
the rebinding is the same kind of thing and
you want to make clear that the local binding supersedes the
global one.
For example
(defn fact [n]
(loop [n n, answer 1]
(if (pos? n)
(recur (dec n) (* answer n))
answer)))
This also stops you using the global binding by accident, as I was prone to do.
#Thumbnail's answer is good, but I personally would almost never shadow an outer binding with an inner one in this way. Even if you understand binding rules, and want to shadow an outer variable for a good reason, it's confusing for someone reading the code--which could very well be you, later, after you've forgotten how the code works.
Suppose I have a complex function, and I see the variable foo used somewhere in the middle of it. I look up and see a binding for it--perhaps as a function parameter, which would be obvious and easy to notice. If I don't notice that somewhere below that, the name was rebound, then I will misunderstand what's in the variable.
So I usually make up new, related names that correspond to the role of the different variables in the code. Sometimes the name differences are somewhat arbitrary.
I think these are good reasons not to shadow variables, and I think #Thumbnail gives go reasons to go ahead and shadow them. There are tradeoffs, and you have to decide what's best for your situation.
Short functions are probably better contexts for shadowing. Personally, I'd add a very noticeable comment if I did this sort of thing, or if I was doing it over and over again, maybe a very noticeable comment near the top of the file.
EDIT: As nha's comment made me realize, it can be more reasonable to shadow variables when the new binding occurs immediately after the previous binding; that makes it hard to miss the fact that the name is being redefined.
Another option would be to slightly rename the argument, keeping the general name for the "final" version of the data:
(defn a-fun [config-in]
(let [config (-> config-in (parse) (supply-defaults))]
;; do something with config
))
I also sometimes use the suffixes -arg, -orig, etc to differentiate various stages of processing.
I spent a couple of years doing Scheme "back in the day" and am now learning Clojure. One of the "best practices" in Scheme was to define helper functions within the parent function thus limiting their visibility from "outside." Of course back then TDD wasn't done (or known!) so testing such functions wasn't an issue.
I'm still tempted to structure Clojure functions this way; i.e., using letfn to bind helper functions within the main function. Of course testing such "local" functions is problematic. I realize I can define "private" functions, but this scopes the visibility to the namespace which helps, but is not as fine grained. If you come upon a letfn within another function it's pretty clear that the function is not available for general use.
So, my question is, can one test such local functions and if so, how? If not, then is there some convention to aid in code reading so that it's clear that a function has only one caller?
TIA,
Bill
The usual approach is to just put the functions in the namespace.
One option is using metadata:
user=> (defn ^{::square #(* % %)} cube [x]
#_=> (* x ((::square (meta #'cube)) x)))
#'user/cube
user=> (meta #'cube)
{…, :user/square #<user$fn__780 user$fn__780#2e62c3f9>}
user=> (cube 3)
27
It is of course possible to write a macro to make this prettier.
I am using binding as a means to make it easier to pass around state within a call. I currently have something like the following
(binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"]
(binding [*session* (session "localhost")]
...
The reason that I need to do this is that the session function requires private-key-path to be defined. Since binding doesn't allow related values, is there any simpler way to do the above without the needed nesting?
EDIT:
Currently prototyping using clj-ssh.ssh. The plan is to make most of my current usage of binding to be a static config (most are static values already, so read once on boot). Was using binding as a way to make prototyping easier so I didn't have to keep passing things around while seeing how the API worked.
I was just curios how I can get the bindings to be dependent on each other. When I use let, the second binding has access to the first one, but it seems that when I do this that the second binding doesn't have access to the first. I would assume there would be another function that acts like binding but would allow the second binding to have access to the first. I can also see this not existing in the default since its more of state than anything else.
Edited: some experiment in the REPL
(def ^:dynamic *a* "a not bound")
(def ^:dynamic *b* "b not bound")
(defn show-a! []
*a*)
(binding [*a* 1 *b* (show-a!)] *b*) ;; => "a not bound"
(binding [*a* 1]
(binding [*b* (show-a!)]
*b*)) ;; => 1
I was surprised to know the given code is NOT the same as:
(binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"
*session* (session "localhost")]
...)
so Clojure tends to have less parentheses than other Lisps in let forms cases but not binding.
Please think about your overall code (and/or API design?) again and again. Dynamic bindings are bad. You will suffer soon. Tip: make more and more code unit-testable.
I'm not sure what you are trying to do, so I recommend this:
A feature called "Graph" for structural computation. Never worry about dependencies between functions again!
https://github.com/Prismatic/plumbing
I'm learning Clojure. I wrote this code to recursively walk a directory.
(tree-seq #(.isDirectory %1) #(.listFiles %1) (File. "/my-directory"))
Why can't I use .isDirectory as a first-class function in Clojure? Is there a better way to rewrite this code?
Joost is spot on about Java methods not being first class functions.
As an approach to dealing with this, I usually like to wrap Java functions in a Clojure function (or find a library that does this already), then it is easy to use them in an idiomatic first-class way:
(defn directory? [^java.io.File file]
(.isDirectory file))
(defn list-files [^java.io.File file]
(.listFiles %1))
(tree-seq directory? list-files (File. "/my-directory"))
This is a few more lines of code, but has the following advantages:
You can add type hints in your functions to avoid reflection (as above)
The final code is cleaner and more idiomatic
You have abstracted away from the underlying Java interop
Java methods aren't clojure functions because you can't call a method on its own; you have to call a method on an object, and it has to be an object of the type that the method expects. In other words, in java, a method cannot be fully separated from its defining class (at least not efficiently).
An alternative to #(.foo %) would be (memfn foo), which hardly anyone uses anymore after #(...) was introduced.
You could have a look at the sourcecode of file-seq (which uses a tree-seq) to see how it works.
By the way: your code works perfectly well for me. I just have to use java.io.File instead of File in the REPL so it knows the Java class.
You've already been given the correct answers, but just to add a bit more Clojure idiomatic code, I'd also use
#(.foo %)
as Joost Diepenmaat did (yet I believed it might've been overlooked).
I would also suggest reading Listing files in a directory in Clojure.
I'm using a 3rd-party library (clj-msgpack), and wish to extend a protocol for a type which the library also provides a handler for.
On its own, this is simple enough -- but is there any way to do this which wouldn't impact other users of this library running inside the same JVM? Something similar to a dynamic var binding (only taking effect under a given point on the stack) would be ideal.
At present, I'm doing an unconditional override but using a dynamic var to enable my modified behavior; however, this feels far too much like monkey-patching for my comfort.
For the curious, the (admitted abomination) I'm putting into place follows:
(in-ns 'clj-msgpack.core)
(def ^:dynamic *keywordize-strings*
"Assume that any string starting with a colon should be unpacked to a keyword"
false)
(extend-protocol Unwrapable
RawValue
(unwrap [o]
(let [v (.getString o)]
(if (and *keywordize-strings* (.startsWith v ":"))
(keyword (.substring v 1))
v))))
After some thought I see two basic approches (one of which I get from you):
Dynamic binding (as you are doing it now):
Some complain that dynamic binding holds to the principal of most supprise; "what? is behaves this way only when called from there?". While I don't personally hold to this being a bad-thing(tm) some people do. In this case it exacly matches your desire and so long as you have one point where you decide if you want keywordized-strings this should work. If you add a second point that changes them back and a code path that crosses the two well... your on your own. But hey, working code has it's merits.
Inheritance:
good'ol java style or using clojure's add-hoc heirarchies you could extend the type of object you are passing around to be keywordized-string-widgewhatzit that extends widgewhatzit and add a new handler for your specific subclass. This only works in some cases and forces a different object style on the rest of the design. Some smart people will also argue that it still follows the principal of most surprise because the type of the objects will be different when called via another code path.
Personally I would go with your existing solution unless you can change your whole program to use keywords instead of strings (which would of course be my first (potentially controversial) choice)