is it idiomatic to create a record with no fields as the equivalent of what I'd use a python (implicitly static) class for - a quasi-namespace grouping related functionality?
@zimablue can you give an example of how you use it?
If you need a marker interface you can also use definterface
this question seems closely related: https://stackoverflow.com/questions/5024211/clojure-adding-functions-to-defrecord-without-defining-a-new-protocol
in interactive development, often around manipulating data like data munging, in python my workflow is like (mess with in repl) => (end up with lots of functions) => (throw those functions into static python classes grouped by area) => (refactor into some static classes, some normal classes, some loose functions)
so right now I'm messing with a git diff and I'd probably throw the functions I've some up with into a couple of static classes if I was in python, split by "upstream" and "downstream" processing
In clojure you usually use a namespace. why not use one?
being a clojure noob I don't get the idiomatic equivalent, from the linked stackoverflow it seems that what I'd normally do is funky since it would require creating protocols for no reason, and I need to use like a raw map
No need for extra wrapping, just defn them in the namespace
because the unit of grouping and formality is lower, each namespace should be in it's own file? I could do that but it's a bit more ceremony and slightly more complication than static classes would be
not a big deal, sorry I'm new-ish to clojure so overthinking stuff probably
If you want to subdivide functions within a namespace, some people use conventions like
(defn foo:bar1 [])
(defn foo:bar2 [])
interesting
thanks, that's an example of solving the same sort of problem I think
just rough organization
I could just split the files, it's not a big deal maybe, just feels like overkill
ok sounds like my three options: just use ordering/naming conventions, do something clever with maps/macros, just use namespaces
I'm not missing some perfect abstraction for my use-case hopefully
The feature in Clojure for grouping and naming functions is namespaces
I guess one question to ask about the practice you have developed in Python is: for what reason do you want to collect multiple Python functions in a Python 'static class'? Why did you do that, vs. put those Python functions at the top level in your source file? Clojure functions at the top level in a namespace seem to correspond closely with Python functions defined at the top level, certainly. There isn't a direct analog in Clojure of creating a static class that is there for nothing but containing methods, but it naturally leads to the question of "why bother creating such a class?"
@zimablue one thing that can be useful is to design functions such that they are meant to be used with a namespace alias
so like instead of
(ns your-project.stack)
(defn stack-create []
'())
(defn stack-pop [stack]
[(first stack) (rest stack)])
(defn stack-push [stack item]
(cons item q))
(ns other-ns
(:require [your-project.stack :refer [stack-create stack-pop stack-push]]))
(let [stack1 (-> (stack-create)
(stack-push 1)
(stack-push 2))
[head stack2] (stack-pop stack1)]
...)
you do
(ns your-project.stack)
(defn create []
'())
(defn pop [stack]
[(first stack) (rest stack)])
(defn push [stack item]
(cons item q))
(ns other-ns
(:require [your-project.stack :as stack]))
(let [stack1 (-> (stack/create)
(stack/push 1)
(stack/push 2))
[head stack2] (stack/pop stack1)]
...)
if you want object-ey things, this is a decent way - a protocol and a defrecord isn't strictly needed unless you want the dispatch bits of it