Fork me on GitHub

Morning all


how did your day go yesterday @yogidevbear ?


Was alright. Felt a bit long 😄


Could have been the pint in the middle though that made me feel that way


Fairly productive though


How was your day?


yeah not bad, im on gardening leave for another month so a great chance to spend time with my kids/wife. haha a pint at lunch ahh i miss that.


Morning All 🙂


Quick question… Does anyone have any specific recommendations for using Elasticsearch from Clojure..? I am about to get started on a little project and while I could Google and pick the most popular, I would be interested by the opinions of my peers 🙂


@guy Morning's the garden 😉


i'm currently using a hacked version of an earlier mpenet ES client project ( ), and then he went and released spandex just after we ported esearch to manifold ... elastisch used to be my goto client, but it doesn't support async so i moved


@agile_geek haha im on my flat balcony atm, which is pretty sweet. My little 2 year old is going mad, running around like a maniac which is nice. How’s things ur end?


@guy chillin' at home. In my case the kids are out at work and the dog's running around like a maniac.


I miss having a dog really


It's a bit like having a small child...they destroy the furniture, poop in unexpected places, make lots of noise when people visit...same thing really


agile_geek: 😂😂😂


Friday's hammock time question: how much Clojure do you need to know to be a 'proficient' Clojure developer? Is just knowing the syntax of the language enough (I assume not). How much of the clojure.core library functions should you know (650+ functions last time I checked)


I am assuming a basic understanding of functional programming concepts is a given


i’d saying the “philosophy” of clojure is more important than knowing core fns


@jr0cket I'd agree with @glenjamin ... I look up core fn's all the time. It's understanding how best to express your problem in a functional way (and the idea of using sequences, maps, etc. for data) that is most important IMO


@glenjamin @agile_geek ah, but can you learn the 'philosophy' of Clojure without having learnt a part of the clojure.core library


I think you have to 'use' the`clojure.core` library but you don't need to remember it. It's enough to know there's probably a function to partition or shuffle a seq... you cna look up the syntax.


I agree with your point that understanding the principles of Clojure is an important foundation of applying the language correctly


So I would say your 'proficiency' is dependant on putting some 'time in' using the language to solve some relevant much time is dependent on how you learn.


So I would not measure proficiency' by the number of core fn's you fact you can be extremely effective with just a handful.


I have been thinking there may be groups or families of functions in clojure.core that are valuable to be aware of. I am not suggesting measuring proficiency by specific numbers of functions. That would be as ludicrous as measuring lines of code 🙂


@guy yes, something like that, but simpler and focused more around the Clojure principles


@jr0cket I agree there are groups of fn's that you should be aware of. I don't think the grouping in the cheatsheet highlights the most important. You can probably take 2-3 from a few of the major sections and highlight them to form the principles you alude to. Some sections are more important than others, for example, look at the seq in, seq out and Using a seq sections and think about how many fn's there are ones you use all the time?


So it seems worthwhile creating a cheat sheet that highlights the core principles of Clojure and function families that help you apply those principles... at least for my own sense of knowing the language. I think it could also be a useful teaching reference for those new to Clojure (without feeling overwhelmed).


FWIW, I found my adoption of -> ->> and FINALLY groking reduce were big factors in my feeling comfortable / remotely competent. I was suddenly able to DO a lot more.


@maleghast interesting...I didn't find the thread macro's that revealing (just convenient in places). For me it was understanding sequence and map processing using map and reduce that started my understanding


I do get a sense that developers build up their own selection of functions they rely on. I am starting to do more TDD kata's and purposely trying to solve them using different approaches (and therefore work with different functions).


@agile_geek - Yeah, I got__ map and filter from the beginning, but more “interesting” applications of reduce were things I really struggled with. I found that -> and ->> helped me do more in less code, and that the code was more readable / understandable to non-Clojure devs, but I agree that seqs, laziness and immutable data structures are all pretty important 🙂


I found the threading macros early on and thought they were amazing (and still do), so want to use them everywhere.


@jr0cket - I do actually credit you for “putting me onto them”, so to speak 🙂


it is a pleasure to have shared...


I don't find I have a problem with reading code 'from the inside, out' although it gets harder in very large fn's. I tend to apply the same standards to Clojure that I do with Java, etc. I.e. make fn's (methods) small and responsible for one thing, make names meaningful (although I adopt accepted short name paradigms in Clojure like xs, m, [k v]).


a puppy messes someones carpet every time developers use bad names for their functions 🙂


Although I use threading macro's I often see them over used to thread through many fn's and transformations that, arguably, should be broken up into separate fn's. We've talked about this before in this forum, but I'm with @glenjamin on his rule of thumb that you should avoid threading that transforms the 'type' of data i.e. threading through fn's that take a vector and halfway through change it to a map. Split this out into different fn's (IMO)


i don’t remember saying that


@glenjamin maybe it wasn't you then, sorry


I know @jarohen thinks that


It wasnt @jarohen I don't think but I agree with him.


i personally don't mind as long as the "type transformation" happens as the last step of the threading


I see that analagous to a set of mapping operations + a final reduction


sounds like a good topic for ClojureX - 17.5 days left for CfP


My rule of thumb is that I like to give names to things that do something (or represent something) that is more than trivial. Hence I would have fairly small fn's, although I accept some peoples push back that this makes some fn's so trivial as to be almost worthless, but I'd favour readability first and you can always inline the fn again if required.


@bronsa - I’d agree with you in that as long as the data is in the same shape all the way to the last step there is not really any reason to not use the convenience of the approach to get the response you want without invoking another function.


(-> data transform transform transform compile)


@bronsa I'm OK with that too. It's the halfway thru I'm not so comfortable with.


this is how I read it


Having said that, @agile_geek I do like the “many small, simple functions” approach too. I just tend to write lots of small functions that do one thing well and then write an “action” function that threads them all together 😉


my general approach is to try and get my function extractions and names to match up to the domain language and requirements


When I change the 'shape' of data I tend to assign the result in something like a let (creating an intermediary) and then explicitly use that, rather than in the middle of a large threading form.


I'm absolutely fine with transform at the end as that fit's my mental model of the reduction fn at the end of a reduce, reduction or transduction


What is the problem with threading macro changing the shape of the data?


@glenjamin I think you raise a really important point here. It is also my reason for wanting some guidance in the form of intermediate level tutorials, blogs and books about how to structure Clojure code beyond the individual fn level, i.e. advice on namespaces, etc. BTW this is also a problem in other lang's as they often default to naming for the technical structure rather than the domain (e.g. how many Ruby or Java systems have packages/modules named for MVC with little to reflect the business domain?)


@reborg I find I create a mental model of the data flowing thru the threaded fn's and I find a fundamental change of data shape mid flow is hard for me to keep in my head...but I don't have many brain cells left to spare so YMMV


Well, I'm with you then, in the sense that is mostly a contextual choice and there isn't probably an universal rule.


I'm not sure there's a universal rule for anything in any language! However, style and conventions matter as they aid speed of understanding (and we spend more time reading code than writing it)


it totally should be


is there a linter that can do that?


shadowing via def is an error


shadowing via let is not


but eastwood should have a linter for that


but i would prefer to forbid shadowing by let too... i can live without naming my local vars count or type


that would be problematic because clojure.core is always imported


imagine having a local named foo


then clojure gets a var called foo


upgrade clojure & your program breaks


having the linter complain about that seems fine to me


yeah, i think i would be ok with that, though i can equally understand why it's not so


I don't think eastwood checks for clojure.core shadowing. I have written a linter which does though. Seems to work OK.


resolving those new warnings would be part of the clojure upgrade


i have been caught out by using map more than once


yeah, i just got caught out by type when i refactored the name to something more sensible and obvs didn't get any compile errors


what linter did you write for @dominicm ? eastwood ?


@mccraigmccraig I extended lein-bikeshed. Which already had this feature. I just rewrote it to be less strange. So I suppose my real answer is, lein-bikeshed has this.


how extensible is eastwood?


or is bikeshed the one people use these days?


bikeshed is pretty naff. It mostly checks line width (80 columns) and dead whitespace. I just happened to like the shadowing part.


I think Eastwood may not work with Clojure 1.9 still, but I'm uncertain. I didn't watch the issue.


I think eastwood needs some love from what I gather. Whoever picks it up will have my favour, the API could use reworking to be more like kibits.


eastwood definitely needs some love and we'd love some contributors 😬


ha, well bikeshed borks my :pedantic? :abort and i can't figure out how to fix it... :exclusions don't seem to work on :plugins


(tbh what eastwood probably needs is a rewrite)


@bronsa Seems like an interesting task. I'd be interested in your perspective on how to approach the design? Learned lessons, etc.


I'd start with abstracting a matching framework over sexps & ASTs, probably using something like datascript rather than manual matching over AST nodes


I was just thinking about how to do the pattern matching. datascript probably makes way more sense than using core.match like I was thinking.


what's the relationship between datascript and pattern matching?


eslint has done a good job of making a pluggable linter toolkit


(for javascript)


but architecture-wise, it’s probably a decent project to take inspiration from


@reborg I guess you can easily express the patterns to match by jumping around the whole AST.


datalog is more expressive than simple pattern matching


Kind of querying the AST like a DB


tools.analyzer already provides a way to go from AST to datomic style EAV tuples


so querying ASTs via datascript/datalog is already possible


here's a simple example


but I see that more as a building block for a more abstract matching framework


cool stuff


The fixes part looks quite curious in eslint.


i know less about that bit, it’s new


so, eslint does the walk for you. Datascript would make it pretty trivial to do the walk yourself (No need to register a set of ast nodes you'd like to be triggered by).


the main reason it does that is for perf i think


the idea being you can do single pass


historically, at least


node.js is slower than java too 🙂 Hurts more there no doubt.


Not sure if there are any digital ocean users here, but I had someone suggest another SSD cloud hosting provider which seems to have better specs for the price tag: