Has anyone created a custom Clojure keyboard? Where integrated the main used “shortcuts”, keys? I use sometimes ducky-pad (not for all shortcuts, but few.. quicker to push one button cases).. just therefore I ask.
not strictly but my layout is quite clojure/emacs centric, quick access to various paired symbols, most of the important stuff on the home row + modifier etc etc
Does anyone else have this workflow, where in the exploratory phase of figuring out how to do a project (which can last a really long time) just having one huge namespace with everything in it, and continually scrapping that and starting again (obviously copying over big chunks)?
oh yeah
I rarely have separate namespaces unless it's important for the public API or some compilation reason
and then I'll do core.clj
, core2.clj
, core3.clj
....
as I write and rewrite it
Good to know I'm not alone. I'm approaching core100.clj for a thing
i think you are alone there
nope ) I’m on core35.cljc atm )
are these work products or more serial things like project euler or other challenge type things?
The big one is an ongoing personal side project
interesting. how do you navigate those files? if you needed to change the behavior of some function f
how do you know where it lives easily, and do you have an enormous require statement somewhere?
yeah the require statement is big. I generally navigate with just "ctrl-f" and emacs point/mark ring. I've wondered if I could optimize this a bit more, but I do think I personally find even that to be less mental overhead than remember which file something is in
And I guess a key thing is I'm making breaking changes frequently, which I also find easier to manage when all usages are in one file. (I know there are tools that also help with this I just never got used to them yet)
In many programming communities is common to start a project by creating a lot of files/dirs, with predefined names like models
views
etc..
I personally do not like this approach. I usually start in an empty dir with one file, and grow my namespaces "on demand"
I would like to search more about this problem/difference/pattern/practice, but I don't even know which terms should I search for to learn about it.
Like, it's very interesting to begin with nothing and discovers how to name your domains understanding some type of problem...
MVC project design/context is something that is attached at a time developers needed some sanity by isolating "Frontend I/O" from "Backend I/O" and nowadays it drives many carreers decisions...
naming is a very difficult issue, to not try to pre-bake them is a nice way of beginning stuff
One overlooked nuance is that a monolithic .clj ns will be slower to reload under at least two workflows (`require :reload` and tools.namespace refresh
; re-evaluating discrete forms is still fast oc)
e.g. you just change a single defn, want to reload the file, now every single defn has to be reloaded again. And the clojure compiler is quite slow
For me it's a big enough reason to favor small namespaces (which also tend to be conceptually simpler).
this effect can be pronounced even in small namespaces that mix unrelated concerns.
For example a util
ns that has json + spec + http stuff under 100 LOC can have many dependent namespaces on the json part, but just one in the http part.
you want to change the http part -> whoops, you're reloading your whole app (because of the json dependents), and takes 60s instead of 1s
Why would you reload the whole file on changing just a single defn
? Just eval that one form into the REPL and you’re good to go.
Your comment sounds more like an argument against reload-based workflows (which, hey, I agree with b/c I think those are the “wrong” approach).
It boils down to styles of thinking, I think all are fine My style of thinking is 'careless' (abstract?). I don't want to reason about what needs to be re-evaluated, and what needs to be done for that corpus to successfully propagate. I want to hit the same keyboard shortcut always and get the code reloaded
FWIW my side projects rarely grow beyond 1k lines, which means it's not super slow to reload the whole ns
e.g. https://github.com/lilactown/flex on the 10th, 12th iteration? and I finally got it to a state where I was like, OK i'll split it into separate namespaces
most of the complexity is in core.cljc
which is 400ish lines. small enough than I can eval the buffer and it's pretty much instant
one of the downsides of splitting up the namespaces is that I have some small bits of global state defined in the core
ns that don't get reset by evaling dependencies
but in general, my workflow is bang on a namespace, save and eval the buffer, run tests. In fact I have one hotkey that does that 🙂
I also try to avoid taking dependencies in my side projects. that also is probably a function of the types of projects I like to work on 😄
yeah more than one way to skin a cat! mostly I intended to share an insight that isn't commonly known almost all clojure workflows are fairly luxurious when compared with most compiled languages :)
It's not about "split or not split" files It's about "start with pré-defined names" vs "create names on-demand"
@souenzzo I think that Clojure as a Lisp with the facilities of a REPL that can evaluate forms, one at a time, liberates the programmer from much ahead of time thinking, so allowing more experimentation, and I think that is the reason why it's so difficult to push the framework mindset.
I think that MVC pattern has a widespread adoption because it's what full batteries-included web frameworks used to provide, so all applications developed using such frameworks ends up gravitating towards MVC, and it affects even applications that doesn't use a framework, and are building using libraries
Clojure being so plastic/flexible allows one to decide later and just move functions to proper namespaces when needed
I think that you both are focus in technical reasons that i don't have.
I work daily on a 100k line project, with some files larger then ~1k lines, many many namespaces, and I have no issues with reloading namespaces or their dependencies.
My change file -> run end-to-end (pedestal request-for, with everything running) test still run around ~0.1s.
I dislike model
view
gen projects for other reasons: the boilerplate/names etc...
the problem is to look into the idea of a model
or a view
these are names that are too generic
to think on effective programs is to go out from a view that we need generic boilerplates/names, isn't it?
Yes @d.ian.b and it's just a convention that happens to influence a lot how people design web apps
they usually mean nothing. They force you to translate names from here to there Any change in the project will be spread across many files etc
They just follow the convention, even if it doesn't apply
they don't mean nothing, I don't think at Clojure we use something like "Convention before Configuration".
Yes, and it hurts other communities until today. There are several discussions across the internet about "How Rails is not your application"
The "Convention over Configuration" thing was a reaction against the pile of XML needed to configure J2EE style frameworks circa 2000-2004
But Clojure is a totally different thing that doesn't work on the same level.
This is why I think that the attempts to make a Rails like framework on Clojure, that sometimes pops-up are diverging a lot of the "Clojure philosophy"
The best we can do is to provide a good template, and Luminus is a good one, but we have others that fulfill the same space.
Consultancies sometimes open source their templates, like Juxt, Cognitect, etc
Because can be hard to re-wire the same things (auth, not-found-pages, etc) over and over again
And it can be so simple as a base project that you clone e fill with customizations, but with the wire already done
what's your workflow? when you change a given defn, what do you do so that the next http request will see it?
@marciol At work, as we’ve built more and more web apps, we’ve refactored older code into “libraries” (`:local/root` subproject dependencies), so that it’s easier to stand up a new app and just reuse code we’ve built before. A lot of the web “boilerplate” for at least bootstrapping a new web app comes down to the initial middleware stack the components you have to startup to get the app running. At this point, we’ve mostly refined and refactored that into standard namespaces/code so there’s very little actual code to write to standup a new app.
Yes @seancorfield, that is what @d.ian.b is suggesting to me in a private conversation
I think each company builds up (and prefers) their own curated set of 3rd party libraries though so if you switch companies, you’ll have to learn “web app 101” all over again. Or maybe “web app 201" at that point.