Fork me on GitHub

mogge 😼


You look distinctly ‘grown up’ in that profile pic!


just old, not grown up



🙉 4
morning 4

<whispers>good morning @danieleneal</whispers>

🙂 4

Morning everyone 🙂


Anyone using RocksDB?




Morning All 🙂


@jonpither - I didn't realise that was still a thing... I looked at it a couple of years ago and heard nothing more about it and assumed it had died... I mean I am not using it, but I do know what it is...


...suffice it to say, I'd be interested in learning if you have some good results with it, as say an in-process cache... 😉


So, is anyone in here using Datomic at the moment..? I want to use it, mostly because the accretion-over-time approach is interesting and the Immutability / Point in Time stuff is useful to our domain as well, but I can't quite shake the feeling that people think it's neat, but aren't using it...


If I can't run it on my machine that's pretty much a dealbreaker imo


(also, morning)


We still use it. I'd question it for data at scale, as the sweet spot seems to be human generated data in a reasonable volume.




What size of data are we talking?


Would it scale as an opdb for a webapp for example?


I can tell you that Kafka uses RocksDB, to go back to an earlier question ;)


Not the way we’re using it, but if you do stuff with Kafka streams and I think KSQL it uses RocksDB to store the stream state or something


it uses rocksdb by default for the stream-table-equivalence stuff doesn't it @carr0t ?


Operational database


We use it for Web apps. If you've got large amounts of machine generated data then it might have trouble scaling.


How difficult have you found it to develop against?


Really easy. You can load it inside your JVM as part of your system.


@dominicm - Is that RocksDB or Datomic..?


(I've lost the thread of the thread)


I am hoping that you are talking about Datomic, as I am basically considering it for internal domain data as a way to have a datastore for business data, client info, some rarely-changed, domain data, that kind of thing. Large amounts of machine generated data would have other targets...


I'll check back later - meeting now...


Yeah. That sounds like a good split to me.


So i was thinking about helping a friend learn Clojure. I was wondering what you folks thought the top 10 most important functions were?


I’d say the most important things aren’t the functions but the core datastructures & the 7(+6) special forms and the R and E of REPL. If you understand that core, all else follows.


^ this guy knows what he’s on about


lol thanks Alex


no tbf you’ve trained, what now? 5-6 clojure devs? I’ve only successfully introduced one person (and weirdly they were a designer)


probably a dozen - but it doesn’t mean I’m doing it right… lol


the juxt folk will be orders of magnitude higher than me


👌 awesome


thanks for the tips!!


i'd put apply, first, rest, and seq on that list

👍 4

Based on my “every day is a school day” From last week, apply should deffo be on the list. I wish I had grokked that sooner...


the only thing I’d add is you often need to shock people out of their ways a bit


like, it’s too easy for people to go “oh I can do that in x language” without thinking through the implications of all the new stuff fully e.g. lambdas, immutability - some of it can be found elsewhere and looks familiar


I’ve had python devs pretty interested in fp just tune out because they decided to just take a couple of new things back to python, I guess


and that’s cool but that’s not what I was trying to do


people will take the path of least resistance if they can


@guy: TBF it depends what you want to teach them, and what they need to know… but I’d argue clojure has a pretty small core; which is kinda fundamental to its design. The interesting things about clojure are that it’s a lisp, so it builds itself up from a small core, it has a functional bias with immutable data and it runs on the JVM. I’d agree with @sundarj, eval & apply are kinda fundmental to lisp… seq is pretty fundamental to the clojure sequence library and the abstractions it contains… first/`rest` are probably less fundamental than in other lisps… or rather if we’re to include first/`rest` then you should also include assoc dissoc conj etc, as lists in clojure aren’t really any more special than hash-maps, vectors, sets etc… except that lists happen to also map onto function call syntax, but regardless Clojure is defined in terms of those core datastructures… other lisps are really just defined in terms of lists.


also thinking in terms of map and reduce is pretty fundamental


there’s a reason rich bangs on about reducers and transducers etc

💯 8

FWIW this blog post which recently resurfaced on HN is pretty good when it comes to understanding the abstractions in clojure collections: Though I’d not recommend starting here; you can probably just summarise it all by saying how clojure forms are all the literals (including symbols) plus maps, sets, lists, vectors.


Thanks all!!


when I show people clojure I show them filter map and reduce as those are three operation you might want to do with some data.


Yes map and reduce are good when you get to teaching functional programming in clojure; lazy sequences etc… They’re fundamental to writing idiomatic clojure, but not actually so fundamental to clojure itself… i.e. map is defined on line 2719 of clojure.core; whilst reduce is defined on line 6745! clojure.core is 7824 LOCs, so the bulk of clojure.core itself doesn’t use reduce.


and the data structures as well together with conj to show them what immutability means


Not that I’m literally implying you have to teach clojure in order of its definitions; but it does give a good indicator of what is really fundamental to clojure… i.e. the things that aren’t defined in clojure.core are really the core language; that includes data structures and reader/evaluation/compilation.


personal preference, but I’d show -> and ->> - I know they’re sugar, but they significantly improve readability of code for me

💯 4

this this this


couldn’t agree more


Yes, thread macros made Clojure so much more readable to me


But we are straying into "Just show them everything!" territory


(and then, yes, basic data structure operations, map, reduce, first, rest, conj, get-in and such)


Yeah… I’d introduce -> ->> only after sequences and FP, and after basic macros


see, I disagree since I think -> and ->> make it read more like imperative code, and thus make for an easier transition


(for anything beyond something like three-level nesting)


but as I said, personal preference 🙂


I tend to agree. Thread macros were one of the first things I learned. I didn't even know what macros were, but I was using thread macros and assoc/dissoc because a lot of what we were doing was manipulating hashmaps


I don't think a 'basic macro' exists 😉


Look at comment


which is how I teach macros


yeah but if you introduce -> ->> too early, and before you get to macros/special-forms you’ve confused the evaluation story… i.e. teach people those macros when after you’ve written things worse than: (into #{} (map str (filter odd? (range 10))))


I find that horrendous to read 😉 If I hadn't known thread macros existed early on I would have been writing

(let [result (range 10)
      result (filter odd? result)
      result (map str result)]
  (into #{} result))


Which is actually what our XQuery code is full of (although we do often name each intermediate var separate things even if they're just going to be thrown away, for clarity), because it doesn't do thread macros or similar


> I find that horrendous to read But that is how all forms are actually evaluated, so you need to be able to read it. ->> makes people think some functions are magic - because they don’t realise how they differ from macros.


I’m not saying don’t teach it… you definitely should… just leave it till after you’ve done the basics; which yes include understanding macros (even if you don’t actually show the writing of anything more complex than comment or when.)


Fair enough


I'm a bit late here, but if I was avoiding threading I would write it over a few lines like this:

(into #{}
      (map str
           (filter odd?
                   (range 10))))


i think the order in which aphyr teaches it is pretty good


thanks u folks too ❤️


Re collections (I'm not sure if anyone else has already mentioned this, but Eric shared an extensive article here


Alright got some good stuff 🙂


ultimately I guess it comes down to whether you want to teach it top down or bottom up… I’ve had excellent results with bottom up, people who’ve gone top down have struggled in my opinion. It’s purely anecdotal evidence granted… Having said that bottom up is also the way the classic lisp literature is taught

👌 8

Part of the problem is that I learned this stuff more than 2 weeks ago, so I can't actually guarantee I'm remembering how I learned it correctly 😉

👍 4

Having said all this, I’d be very curious to see what a learning clojure top down curriculum would look like. I think such an approach would be easier if clojure had a Rails; but it doesn’t; so there’s no good “top” to pick… I think you can only really settle for the middle; or if you’re a company your existing stack which you can take as the top… but clojure’s error messages etc, require knowledge of the bottom to debug etc, and understand why certain design choices are logical… and the basic syntax mistakes beginners make require knowledge of evaluation to understand the errors or just trial and error to debug.


@guy @rickmoynihan I think the data structures are fundamental, which is why I think map (and friends) and reduce are fundamental functions (and teach higher order FP). Then assoc I think as maps and seqs are the fundamental things in clojure


I think learning how to use map and reduce introduces people to first, assoc, rest et al.

👍 12

what about specter based data transformation? Did anyone try showing that to newbies?


I still object to (seq coll) being the Clojure idiomatic way instead of (not (empty? coll)) though 😉 A non-Clojure coder can immediately see what the latter does. The former requires knowledge of what seq does


tbh i used to be in the same camp, but writing just seq is faster so now i dont care


Once you look into empty it really feels like a waste to use it vs just seq.

(defn empty?
  "Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))"
  {:added "1.0"
   :static true}
  [coll] (not (seq coll)))

Like i used to argue the same thing, then my friend showed me the functions under it and i was convinced begrudgingly


not sure optimising for people unfamiliar with the language is the best approach 😉 seq means 'try to get a sequence out of this thing'; you naturally can't get a sequence of things from an empty collection, so it makes intuitive sense in my book


the only other requisite knowledge is that nil is falsey


@otfrom Completely agree. But I think when you teach those, you’re teaching FP on clojure, or rather you’re starting to teach people how to program clojure for real… rather than introduce them to the fundamental semantics. And this is all good; I’m just arguing don’t neglect teaching people the basic stuff at the bottom - it pays dividends later on. And also I think the fundamentals are what make clojure interesting and exciting to people. map/`reduce` - well javascript has them too 🙂


I have yet to do any specter based transformation myself


I didn't feel like I could use Clojure until I grokked reduce - once I had really got my head around it the rest came pretty quickly.


reduce-kv is also ❤️, as we're doing so much with maps


@carr0t - It's a doozy... @seancorfield opened mine eyes to it and I have to say I was greatly impressed by it.


@rickmoynihan I'm gonna think about that. I think it depends on whether you are teaching someone an experienced coder new to clojure or a new coder.


I’ve only really taught people with at least one other language under their belt; so can’t comment on teaching clojure as a first language.


though I’d probably still teach fundamentals 🙂


agree. Teaching to Java programmers is different. Teaching programming using clojure is different.


Were any of those people, people who already did/knew FP? Or was Clojure basically "Intro to FP", even for the experienced coders?


But SICP does a great job at it.. I am learning-teaching to my colleagues


so my audience are java programmers. It makes easy job..Show how to do typical operations


that's all I am doing


@carr0t probably 50/50 split between having some FP experience and no FP experience


but java / non-FP programmers are still used to writing things like String s = dosomethingElse(doSomething("foo"))


yeah, going from fluent interfaces to FP is a lot easier (it still mutates, but at least returns the mutated self each time, if that is what your example is showing)


just intended to show 1st order composition is not unfamiliar


Indeed. I can read it, I just think it's kinda horrible. I prefer patterns where you can do s.doSomething("foo").doSomethingElse(), for example. So each function returns self, effectively, and other functions can then chain off that


Most of the time if I have to nest functions like in your example I use intermedia vars to make it clear what is happening


Sure, I’m only saying imperative programmers are used to putting arguments into procedures and getting results out the LHS; and that it’s not uncommon to wrap a call over them without having an intermediate binding. Most developers I’ve met can read and write that kinda thing. return self and chaining is in my experience a less fundamental pattern… i.e. it comes from OOP not procedural programming… Perhaps I’m getting old, but programmers are still taught if and for and procedures before OOP and class hierarchies… aren’t they?!? 🙂


I am working on creating screen casts of clojure. I started reading core.clj


the order of things in that looks good to me


I started with seq operations


I am planning to show specter based data transformations and regular reduce/reduce-kv operations..


For our internal teams I shared an internal ClojurePrimer git repo that I created from the lessons I learned on


Coming back to @rickmoynihan's comment ( although possibly completely unrelated... I found understanding destructuring to be a massive help


TBH, working through most of the official guides is probably a great starting point

Rachel Westmacott15:06:26

destructuring is awesome, but you can get a long way without it

Rachel Westmacott15:06:35

you rarely need it


you definitely need it if you are going to read my code!

😂 8
Rachel Westmacott15:06:16

oh mine too! I wouldn’t want to give it up.

Rachel Westmacott15:06:19

my 2 pennies worth is that I found it very confusing to have multiple ways to do something when I was first starting, eg. why use ; to comment things out when there’s (comment ...) which a) does the job and b) is syntacticly consistent with the rest of the language?


you’d hate perl 😄

👍 4

I've never used (comment ,,,) as a comment as it returns nil, so can do strange things if the comment gets nested. I prefer the the brutalness of ;; for classic commenting. Or the elegance of #_ reader macro comment, for commenting expressions, even when nested inside other comments.


yeah destructuring is important to know & to use real world clojure & beginners seem to struggle with it initially; but it’s really built on top of let* which is one of the special forms I mentioned… so again I’d probably introduce it with macros… let is a very good example of what macros can do.


You deserve the thanks 🙂 After all, you were the author 👍