Fork me on GitHub
#off-topic
<
2022-04-07
>
Oliver George01:04:16

So lets say you've got 163k lines of re-frame app (spa + mobile app) developed over the last 6 years and you want to start normalising and refactoring to make it more easier to reason about and maintain.

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
ClojureScript                 1405           9034            667         137420
ClojureC                         7            115             16          25472
Clojure                          3             20              4            225
-------------------------------------------------------------------------------
SUM:                          1415           9169            687         163117
-------------------------------------------------------------------------------
I use IntelliJ/Cursive and the refactoring tools aren't great for this sort of thing. e.g. Moving things between namespaces, splitting out re-frame registrations etc. Not finding them helpful. I bet emacs is better but my fear is the learning curve doesn't make it an easy tool to pick up. I see rewrite-clj but my gut says cutting code to refactor code is probably a temptation I should avoid. What would you do? I probably need to hear: roll your sleeves up and do it systematically. It won't be fun.

Oliver George01:04:28

While I'm looking at stats • 1113x reg-event • 331 reg-sub

Cora (she/her)01:04:40

emacs does indeed have some impressive refactoring https://github.com/clojure-emacs/clj-refactor.el/wiki

cfleming01:04:26

I have some good news and some bad news. The good news is that Cursive’s moving things around refactorings will get better soon, due to some work I’m doing now on ns rewriting. The bad news is that: > roll your sleeves up and do it systematically. It won’t be fun. is still going to be the correct answer.

❤️ 1
Cora (she/her)01:04:27

you could use something like doom emacs or spacemacs if you want an emacs distro that helps you get things all set up for this kind of thing

cfleming01:04:27

I’m interested to know what you mean by splitting out registrations, what is involved there?

cfleming01:04:54

AFAIK Emacs’ refactorings don’t yet work on CLJS either, since they’re REPL based.

cfleming01:04:09

I might be wrong/out of touch there, though.

Oliver George01:04:26

@U0567Q30W that one is pretty mechanical... I have lots of (reg-event-fx ::name (fn []...)))

Oliver George01:04:35

I want defns for handlers

Oliver George01:04:47

I might move the reg-event-fx to another file

cfleming01:04:09

So move an fn to a defn and replace the original with a reference to the new var?

👍 1
Oliver George01:04:11

I can almost do it neatly with many cursors but there's no way to make a nice defn name based on a fully qualified keyword

Oliver George01:04:22

That's the idea

Oliver George01:04:41

If I could kebabify the qualified keyword en-mass I'd be basically happy

cfleming01:04:53

Yeah, the name suggestion is a big part of that.

Oliver George01:04:43

@U0567Q30W sepearate but a way to replace all "::" use across the codebase would make moving stuff between namespaces safer but perhaps your new developments will cover that.

Oliver George01:04:41

All surmountable really

cfleming01:04:49

Yes, copying and pasting between namespaces will get better shortly, I’ll be fully-qualifying all code before copying it, and then shortening the qualified version on paste, which is what IntelliJ does for e.g. Java.

Oliver George01:04:03

sounds perfect

Cora (she/her)01:04:40

I didn't think about the fact it was cljs @U0567Q30W, good call

hiredman01:04:21

I question "easier to reason about and maintain"

Cora (she/her)01:04:38

clojure-lsp has some refactorings that may be helpful

hiredman01:04:02

For any sufficiently complex system there are many cross cutting concerns for everything, so any single organization is going to obscure things

hiredman01:04:33

So there is no promised land, and if there is no promised land, is there really a benefit to doing a code base reorg?

☝️ 1
hiredman01:04:37

And what are the costs? How many man hours, rewriting, testing, for no additional features

☝️ 1
Oliver George02:04:31

Let's not embrace chaos just yet!

Oliver George02:04:15

It was a bit of a throwaway statement. There are various justifications for specific refactoring in this case.

Oliver George02:04:52

Let's save the subject for another thread.

Oliver George02:04:37

(At me into it if you feel like exploring)

jumar03:04:08

Before doing big refactoring you might want to use something like CodeScene: http://codescene.com

Oliver George03:04:29

Have you used that with Clojurescript before?

jumar05:04:21

Not really but we use it for Clojure backends (I'm obviously biased since I work for them :) )

Drew Verlee20:04:18

@U055DUUFS what specifically isn't easy to reason about or maintain?

1
hkjels12:04:03

I see kebabify namespace keys as one thing, that’s just a regexp away. @U055DUUFS what exactly would you like to do?

Oliver George23:04:37

There's been a enough random pokes on the specific challenges i'd like to improve on in this specific codebase. I'll work up a gist and share them. Regarding kebabify. There are over 1000 event handlers registered across the codebase, say 50 files. We often used the (reg-event-fx ::x (fn [a b]...)) pattern. I want defns for each handler for testing purposes. I also plan to move registrations out of the namespace so tests can load files without having registration side effects. The event id was either ::foo or :bar/baz and sometimes either/with.dotted-name. Using IntelliJ I can use the multi-cursor approach to find reg-event, copy the keyword, find the fn, make it a defn above the registration. The niggle is picking a sensible handler name. It often works to take the event-id (keyword) and use the name with a "-handler" suffix. Not always though. A dot in the name part leads to an invalid symbol. Two events with the same name part causes a clash. Handling the three forms of keyword makes the process fiddly.

respatialized14:04:33

http://conal.net/papers/drafts/spacetime-computation.pdf Making data layout and computational resources explicit, rather than implicit, in a functional paradigm. > In addition to eliminating scheduling and layout (or simply “spacetime layout”) errors, there is a very simple criterion for functional correctness: “spacetime erasure” yields a desired purely functional computation. The design methodology thus formally relates simple precise specifications (as spacetime-independent functional programs) to efficient, spacetime-located implementations. I know we're all big on dynamic types here, but if static typing can spare me the trouble of figuring out array sizes and other data layout questions for high-performance work I will happily embrace it in that context.

😅 1
sova-soars-the-sora14:04:27

place-oriented-programming 😅

Martynas Maciulevičius14:04:04

And time. Place-time 😄

😄 1
😂 1
respatialized14:04:32

I studied geography and I can tell you right now that space and place are quite different and are used very differently in the literature broadly speaking, place is concrete and specific (e.g. a location - Los Angeles, Jakarta, etc), whereas space is abstract and non-specific (e.g. things like distance, scale, etc). I think the distinction is actually quite relevant here; the transformation described in this paper is not at all tied to implementation or hardware-specific details (place) but instead is a very general transformation from "pure" to "spatiotemporal" programs that works across systems and architectures (space).

respatialized14:04:41

in fact, in The Value of Values, where https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ValueOfValues.md was coined, Rich Hickey makes a very similar distinction between place and space: > What's really interesting about the definition of space is that it has always, if you go back to the oldest definitions in the oldest languages, the definition of space has always incorporated both place and time. It's never been something that applied only to one or the other of those two things. It's always connected to two and there's a certain physics aspect to that. One thing I like about that Conal Elliott paper is that it gets away a bit from the assumption of "infinite space" that's in Rich Hickey's argument, while still keeping the notion of space appropriately abstract. I think the assumption of unbounded and forever increasing computational resources (a common assumption across our profession, definitely not limited to this talk - and he does talk a bit about needing to manage garbage and reclaim some of those storage resources) is one that is ultimately quite unsustainable from an ecological point of view.

sova-soars-the-sora00:04:17

Neat, I appreciate your chiming in on the distinction between space & place

respatialized14:04:32

I studied geography and I can tell you right now that space and place are quite different and are used very differently in the literature broadly speaking, place is concrete and specific (e.g. a location - Los Angeles, Jakarta, etc), whereas space is abstract and non-specific (e.g. things like distance, scale, etc). I think the distinction is actually quite relevant here; the transformation described in this paper is not at all tied to implementation or hardware-specific details (place) but instead is a very general transformation from "pure" to "spatiotemporal" programs that works across systems and architectures (space).