Fork me on GitHub
#clojure-uk
<
2021-01-14
>
jiriknesl06:01:52

Good morning

6
dharrigan06:01:43

Hey Everyone! 🙂

alexlynham08:01:57

i seem to have implemented clojure's case and cond forms, complete with square bracket list syntax in my current TS project lol

alexlynham08:01:53

the typescript switch bulls--t was so verbose for what we needed (predicate matching for querystrings) so started writing a data oriented thing and then eventually realised it was just a mini lisp DSL

alexlynham08:01:12

except lazy like haskell, thunks everywhere carrying around little happy monads

alexlynham08:01:33

like Bob Ross' little happy trees

dharrigan08:01:02

No mistakes, just happy little accidents.

dharrigan08:01:12

He's great Bob

alexlynham13:01:33

@arohner whenever i see your handle, my brain somehow reads it as the title of this perfect circle song (renholdër) https://youtu.be/KayJYjg1vbI

😂 3
dharrigan15:01:23

Coffee time!

👍 6
dharrigan16:01:59

Here's a question. You know in architecture, you would traditionally have a 3-tier layer, i.e., Presentation/API, Service/Application, Repository/Data, would there be a similar setup in Clojure, i.e., an API layer, then an intermediate layer that may do some data translations before hitting the data layer? What do people do in Clojureland?

alexlynham16:01:30

i quite like vertical slices where each vertical slice has a transformations namespace and a db namespace so similar to what you're describing

👍 3
dharrigan16:01:20

would you call that foo.bar.transformations?

alexlynham16:01:17

probably yers

alexlynham16:01:57

db.clj transformations.clj utils.clj format.clj are very common namespaces in my subfolders lol

alexlynham16:01:31

in current typescript project very similar too (typed functional typescript) db.ts transformations.ts schemas.ts types.ts

alexlynham16:01:16

and then the api layer is all in a totally separate folder - oriented into REST entity subfolders with stuff grouped into files there

dharrigan17:01:42

ha, like me!

dharrigan17:01:53

except for the transformations thingie 🙂

alexlynham17:01:26

i tend to try and get any data -> data functions for a given entity away from the side effecting ones if possible cos you very quickly see then what the general case is & then can lift them up and out to more general helper namespaces or whatever

alexlynham17:01:39

in our current project that's led us to a monadic approach

alexlynham17:01:35

cos generalising the transformation functions leads you to pipelines of composed monads which you can then safely chain in your side effecting functions (i.e. the outer handlers -> equivalent to the main fn essentially)

mccraigmccraig17:01:29

i wouldn't worry @dharrigan - i think R is far below 1 for this particular pathogen

alexlynham17:01:31

it's really noticeable how the railway style we are using Eithers how composable they become

alexlynham17:01:47

the general case for a problem becomes ludicrously general

alexlynham17:01:23

hence why i was essentially reimplementing clojure's case and cond yesterday so we could chain thunks of compatible monads

alexlynham17:01:39

just partial application innit :D

alexlynham17:01:00

or, at least, just syntactic sugar for what we could accomplish with partial application :)

mccraigmccraig17:01:17

yeah, i've been working on my monad lib a bit recently and it's really interesting how some very generic concepts are emerging, which can be uniformly applied across very different types of contexts

alexlynham17:01:43

i'm definitely beginning to see how combinators become increasingly useful

alexlynham17:01:48

cos the general case of a cond where the dispatch of each pair is a thunk is that the predicate should be a thunk too, which is a combinator i think... it's thoughts like these that reveal some of this stuff is above my brainpower level lol

mccraigmccraig17:01:38

yeah, general cond sounds like a list of [pred-thunk match-thunk] pairs

alexlynham09:01:34

xactly, but then you go "is this too general to be useful"

alexlynham09:01:59

i mean the answer is no, but it's like an alien language to anybody that's not done much fp i guess

alexlynham09:01:21

becoming increasingly aware of the fact this code base is going to need handing over in 3 mths or so

mccraigmccraig09:01:44

it's the abstraction dilemma - do you build new abstractions to make more robust software re-using fewer, more fundamental, better tested, components, or do you use familiar generic components more verbosely and repetitively because new developers will find it easier to grok ?

alexlynham10:01:09

see also: monads

alexlynham10:01:15

see also: fp in general

alexlynham10:01:19

but yeah exactly

alexlynham10:01:08

i suppose it's a different tradeoff calculation when you're a contractor who knows you've gotta hand over software on paper - but in reality all developers come and go on a project so maybe it's more about pragmatism in the face of that

alexlynham10:01:46

what would you do if onboarding wasn't an issue / what is the most robust general case solution sui generis

mccraigmccraig11:01:52

i'll probably always favour a better abstraction 😬, although i've not gotten around to rewriting everything in haskell yet, so maybe not

dharrigan20:01:13

If I'm playing around at the repl, can I "inject" a var in #'user to another namespace, i.e., #'user/foo injected into my.namespace/foo so that if I was to then do my.namespace/foo it would be the same as the value of #'user/foo?

dharrigan20:01:47

inject is probably a bad word, but I hope I convey what I mean

seancorfield20:01:08

(intern (find-ns 'my.namespace) 'foo foo) will stick foo in my.namespace with the current value of foo from the current ns.

seancorfield20:01:59

dev=> (ns foo.bar)
nil
foo.bar=> (in-ns 'dev)
#object[clojure.lang.Namespace 0x7bdf8c92 "dev"]
dev=> (defn foo [x] (* x x ))
#'dev/foo
dev=> (intern (find-ns 'foo.bar) 'quux foo)
#'foo.bar/quux
dev=> (in-ns 'foo.bar)
#object[clojure.lang.Namespace 0x2bfa5678 "foo.bar"]
foo.bar=> (quux 12)
144
foo.bar=> 
@dharrigan

seancorfield20:01:10

I don't know if that's the best way but...

dharrigan20:01:42

it's only for playing around 🙂

dharrigan21:01:34

works a treat