Fork me on GitHub

Can I ask a question about clojure.spec? I am now using multi-spec, considering different ways to categorise pills, the spec growing exponentially. Is there something like interface in clojure.spec? So that I can define a spec which implements several interfaces.


1) I think most people are asleep. 2) Can you give a concrete example? three backticks = pastes code


Europe is awake already :)


and Africa* 🙂


2/8631 🙂


I do have a question -- perhaps you guys can help me


what I love about emacs is C-h f , writing elisp code, then C-x C-e. I now want to switch to a full cljs solution and I'm looking at nightlight, nightcode, lighttable, and atom -- and I'm curious which one gives me the most "ability to be configured/programmed/extended in cljs" ?


that's basically the single, unique metric which I"m picking my next editor on


^^ going to sleep now; for anyone answering the above "what editor/ide is most extensible in cljs", please feel free to direct-message me, I want to make sure I read your response and might miss it in the log


poking around at the sources, it seems like nightlight = clj + cljs, lighttable = cljs, atom = coffeescript?


qqq: I don't think it's very actively developed for some time


@U071E81KK: that is my impression indeed, I think I'll go atom -- which is too bad, I'd really like cljs all the way down instead of coffeescript


It might sound like heresy but you can also take a look at Visual Studio Code. If I wasn't using Vim thats where I would look.


For what it is worth, light table is still being developed but atom would be a better choice for your needs at the moment


@U071E81KK: I currently have ~ 1K LOC emacs config; nothing but "replace elisp with cljs" would get me to switch


@U08CH3K54: any idea what the roadmap is? I took a look at it, and it seems to be "we're in a shitty state; we need better docs, or else no one else would contrib" -- this amkes me sad, as I'd really prefer to do pure cljs instead of atom/coffeescript


That's about it, light table needs docs and some dependencies updated otherwise it won't be attractive for new people to contribute to


Docs are ongoing, as well as updating dependencies, but it all takes time to do


I think the thing that concerns me most


is that the Eve blog post is basically "the future of programming is something that clojure can't do" so we're off to build a new IDE / language at this point, I can't see how there'd be time for clojure at all


Oh, the project was open sourced and Chris granger has little to no involvement at this point... It is now community managed


right, saw the code, which is what got me excited at first since it was cljs all the way down


but given atom has more ppl and lighttable lost it's lead dev, it's hard to see it compete, just on man power


Completely valid point


Hi, does someone know about a helper library that has if-empty? that works like if-let but checks for empty instead of nil?


@sveri: what about (if-let [a (seq the-thing-that-should-not-be-empty)] ...) ?


@stijn Cool, I did not know that. Although I would prefer an if-empty? as it is more clear in its intent. Converting into a seq first seems a bit "hacky".


@sveri: I'm not a fan of code that pulls in an entire jar for a single function. 🙂


Hehe, I am not a fan of rewriting stuff again and again 🙂


I was going to make an argument about how pulling in a new library in CLJS slows down the load time, and multipled by millions of users / day = # of human lives wasted --- but then I realized, closure agressively elimiinates dead code


Hehe, I hear you talking about flash here 😄 If you are concerned about load times and stuff I would argue to not start with cljs / javascript at all and add it only if there is a real need for it.


I started caring about # of jars since # jars greatly afected my "gae deploy" time, and as it turns out, for my server side I've even ripped out ring -- right now, for my gae apps, on server side, only dependency = clojure itself 🙂


Hm, I wonder how GAE works in that regards. What exactly is deploy time for you? Upload + restart of the application?


@qqq is there no way to specify files that GAE instances always have access to?


@svrei @bfabry: a gae deploy is: 1) create a giant WAR 2) google uploads it 3) if you app has no request for past 10 mins, it dies; and on new request, GAE has to fire up a new JVM + load all your ajrs


and for whatever reason, cutting down to depending only on clojure (ripping out ring, compojure, and whatever else) has reduced my "create this war and upload it" time from tens of seconds down to seconds


btw, atom is beautiful; I think I'm switching


Hm, I see. One more reason not to use GAE. Although from an economic point of view it surely makes more sense to shutdown instances that are not used.


yeah what I meant was can you put your dependencies in a gcs bucket and manipulate the classpath or something. anyway sounds like you have a solution


Btw. how did you rip out ring and compojure? Just remove the jars and code everything yourself?


so Im reading this book on GAE dev with java


that book doesn't use ring or compojure; it just extends javax.servlet.HttpServelet or something


and I just converted the code line by line into clojure


so now I know about things like doGet and doPost


I see. I liked to do this kind of stuf too, years ago. Today I am more concerned about developer productivity. Which is raised by well designed and tested libraries and readability. There are like several million edge cases I will not think of myself. But by using libraries that are used by many other devs, chances are a lot more edge cases have been covered already. Btw. I am not talking about the npm ecosystem that might have taken this to the extreme 😄


@sveri: for anything besides AWS Lambda and GAE, I would agree with you; for these two, I think as small a footprint the better


IIRC, your hosting on some 16-core 1TB RAM monster machine; so having a few extra jar lying around doesn't matter; whereas for me, these jars for some stupid reason, slow down both (1) deploy to gae and (2) firing up JVMs


@qqq take a look at proto-repl ( an atom plugin )... lots of fun


🙂 We agree, basically. Maybe you want to look into clojurescript on npm: @yogthos started working on that


Not sure if that works on GAE.


Also nice: > Hi #42. It doesn't seem that this will be ever fixed, as this post is from 2012 and affects ALSO the python instances. If they can't make python to boot fast, it won't ever work for java as well.


@sveri: nice to know they still havne't fixed it in 2017, 5 %&#* years later


someone needs to find who thought it was a good idea to have a jvm run in 512 MB RAM, and fire that person 🙂


my guess if you were to ask that person the answer would be "it wasn't designed with loads low enough that warmup time mattered in mind"


"if your app can go for 10 minutes without anyone making a request, you don't need google scale"


I don't know how big the JVM is, but if it takes up 256 out of the 512 MB, it's as if the machines are operating at half effiiency (compared to say, one beefy machine)


I would assume its not the the RAMs fault. RAM access should be fast enough and you can fit a lot of stuff into 256 MB, also in the Java world. From the ticket it reads like they transfer data over the wire and this is what makes the class loading take so long. But I am just guessing here. Also, after reading half of it, I just cannot see why I would use GAE for small scale java projects that are "large" enough to take more than 60s to load on GAE, which means, it does not start at all. So I am picking a cheap instance just to have it not work, which forces me to take multiple small instances and hope enough are up or pick fewer large instances and pay more. I mean, any VPS for a few bucks will just hold your service in memory and you have no startup time at all, except on redeploys of course.


Although, even transferring a few 100 classes over the wire should be done in a few seconds and not minutes


@genec are you sure the class name syntax you're using is supposed to work? my guess is that core.match thinks Zero is just a local name you want to use; e.g., if you replace "Zero" with ["I'm in this part of the code and the Zero is" Zero], what do you get?


@gfredericks ["I'm in this part of the code and the Zero is" brave_and_true.utils.Zero] hmmm, I see what you mean. Are you using something else for pattern matching?


no, I just don't need it much; destructuring covers most of the use cases


I've implemented everyting with cond, but thought pattern matching would be nicer (coming from F#/OCaml)


if you only test for one thing cond(p) is probably a better choice anyway


(condp (type x) = ...)


@gfredericks @mpenet i agree, but i'm matching on a whole set of contract records with different fields. thanks for your help, really appreciate it. i'll stick with cond for now though, since it works fine


then it would make sense yes


@mpenet i didn't know about condp though, thank you for that!


I guess that would be it. It's actually very similar to the ocaml syntax


yes, i think i was leaving out the :or keyword


hi everyone, im having trouble while generating an uber for my compojure application


everything works normally with lein ring server


but when i try to lein do clean, ring uberjar


it complains docjure cant be found

Compiling excel-service.error
Compiling excel-service.handler Could not locate dk/ative/docjure/spreadsheet__init.class or dk/ative/docjure/spreadsheet.clj on classpath., compiling:(xlsx.clj:1:1)
Exception in thread "main" Could not locate dk/ative/docjure/spreadsheet__init.class or dk/ative/docjure/spreadsheet.clj on classpath., compiling:(xlsx.clj:1:1)


Is it possible to define a function in a def which is called, eveytime the def is referenced?



(def id (rand-int 1000))


well, that’s called a function and you define those with defn 😉


@arttuka I assumed so. Thank you


@plins: could be a profile issue - check for differences between profiles


@rickmoynihan , thanks, they were declared inside the dev dependencies


cool glad it worked


hey guys I have a map data structure with maps within it and I need to replace any nil values with empty-strings. Any suggestions


are the nested maps infinitely nested, or just one level?


Can be multiple levels of netsting


@john.carnell can brute force it with Specter with: (setval (walker nil?) "" my-map)


Cool thank you


(defn nil->string
  (f/fmap #(if (map? %)
             (nil->string %)
             (if (nil? %)


can do it more precisely and more efficiently by defining your own recursive navigator


where f/fmap is clojure.algo.generic.functor/fmap


just require [clojure.algo.generic.functor :as f :only [fmap]] @john.carnell


Will give it a try


(nil->string {:a nil :b {:x 42 :y nil}})
=> {:a "", :b {:x 42, :y ""}}


and fmap is defined simply as: (defn fmap [f m] (into (empty m) (for [[k v] m] [k (f v)])))) in , a very useful function

Sam H16:02:44

you could use clojure.walk/stringify-keys and modify to your problem:

(defn nil->empty [m] (let [f (fn [[k v]] (if (nil? v) [k ""] [k v]))] (clojure.walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
^^ seems to work, only did a quick test


shan your nil->empty example is the reason specter exists 🙂

Sam H17:02:54

schmee: I see, I've only heard specter mentioned but never read/looked into it. I should have a look at it


yeah, it makes functions like that much easier to deal with


Does anybody use docker to containerize their development environment with clojure?


IMO there's little reason to do that normally, because Jars are already containers and the JVM runs everywhere


Well I am hoping to create an environment that has all the tools I need to be productive and allows me to sit down on any machine and have access to them


I was thinking that with docker I could package up emacs in one container, and then jvm + boot in another


then run the boot repl with some port exposed on the container, and connect to it in the emacs container


Then I could regulate the versions of everything, and make sure that things are not different on dev then they are in qa or prod


you can already do that


But for whatever reason, when I tried to do it getting the repl open in one container and connecting it to another isn’t working out to well


you can specify the boot version in


the only variable left would be the JVM version used


and the JVM is a mighty ship of compatibility


what do you think about the micro service architecture? where you can mix many different languages, and want to have a uniform strategy for deploying code into the wild regardless of what stack that developer decided to use.


I feel like there is something to gain by dockerizing your workflow, as tools like kubernetes, or docker swarm let you handle the dev ops part of your system in a way running raw on the machine seems really difficult. But i’m curious if you’ve had a different experience?


Mixing "many different languages" is a recipe for failure, imo.


Microservices in general however seem to be a good idea depending on the situation.


Well if every service just agrees to a standard data format like edn or json why does the implementation matter?


At that point they are just swappable components as long as they maintain faithful to the previous api


I think the way I would put it is, people have a hard enough time getting stuff to work correctly using a single language


arguing against using multiple languages seems like arguing against clojure to me


noone is going to switch their entire stack to clojure if they’re using something else, the only way to make headway is to do it in steps


plenty have


I feel like it is a lot easier to convince the team to just write one component in a new language rather then rewrite the entire app in clojure


then if things go well you can slowly bring it in more places


convincing the devops guys to learn new build tools is a hard sell


but "hey aren't we all so cool, lets just write everything in whatever language" is very different from "lets look at language X"


well sure you can evaluate many different languages


but unless you are greenfielding a new project, you have legacy code


just did that, implemented a new microservice using clojure instead of java, and I'm never going back 😛


And I can sit here and tell you horror stories of people that use: Ruby, Python, Elm, Scala, Go, Rust, Java, Clojure all in one project.


A few languages is fine, more than 2-3 and I think it's time to have a intervention.


Even more so if the languages overlap. So IMO, a codebase in Java, Clojure, and Python isn't nearly as bad as Elm, Dart, and ClojureScript 😉


These days it's easy to get 2 automatically - JavaScript on front-end and whatever you're using on backend.


That said I think my place is currently in a situation where a previous monolith used Erlang but having finished a first-pass splitting into services we'd be better served with Clojure.


you almost always have a frontend team, which is js+otherlang and a backend team which may user otherlang but may use otherlang'


perhaps we could invent a Universal Machine, say, let's call it a "Turing Machine" -- then we (1) make sure Turing Machines run on every existing language (2) all existing languages can . emade to run on this "Turing Machines" problem solved //sarcasm


since there isn't infinite tape, i say we all just go to the beach


Now there's an idea, @dpsutton!


This slack needs a place to put out-of-context quotes, and I nominate that one as the first one.


I’ve been maintaining a couple fortune files of quotes, could be pursuaded to throw up a git repo 😛


@qqq: except that Turing Machines are useless, since they cannot do IO. Actual useful programming languages would just befuddle them.


TM computability is special case


I suspect no existing (useful) programming language could be run on a TM.


@tbaldridge : ok, tell us some horror stories! simple_smile Seriously, it strikes me as a mgmt problem not a technial one. if you can manage 10 different teams programming microservices in 10 different languages, you win.


i would not want to try it, but microservices do open up possibilities for staffing. i might hate php, but if it's a lot easier to find php programmers than clojure programmers, why not give them a microservice to implement?


Sure, if the teams were completely isolated, but that's not the case most of the time. A single team may be responsible for a dozen microservices, and have a different language for each would be an nightmare


isn't that precisely how amazon is run?


"you only get to expose an API", everything else is hidden


Not only do devs have to context switch more often, but it further narrows your talent pool by requiring that you hire devs that share the intersection of all the teams you have in place.


@qqq never assume what works for a mega-corp will work well for a startup.


ah, reality rears its ugly head!


And once again, they probably have a few dozen engineers for each service


lol, I heard the GOOG solution to "the cpu doesn't do this is" (1) call up intel (2) tell them if they don't add this instruciton, we're ordering from AMD


Hi all, I feel like I must be missing something obvious in the standard library. I find myself doing this a lot:

(into {}
      (for [{:keys [:product-manufacturer/slug] :as m} manufacturers]
        [slug m])) I've got a seq of maps, and I'm pulling out a single field of each map to construct a map from that one identifying field to the whole map that was in the seq. Is there a more elegant / concise way to express this?


tried that, they won't take my phone calls.


well, for phone calks, you probably want a waterproof case


@timgilbert: so you want a map where key = (:foo m) and value = m ?


(into {} (map (fn [x] [(:foo x) x]) manufactuerers))


eh, not sure is that's better


for my persona use, I have a function m-map, where (m-map f lst) = (into {} (map f lst))


@timgilbert assuming I have specter I would (s/transform sp/MAP-VALS first (group-by :product-manufacturer/slug manufacturers))


you could also (into {} (map (juxt :product-manufacturer/slug identity) manufacturers))


bfabry++ , the use of juxt is brilliant


I've always been angry I can't write #([f1 %, f2 %]) -- and (juxt f1 f2) is precisely the solution ot that problem


(map #({(:foo %) %}) m)? untested. never mind, that'll teach me.


that won't work, trying to use a map as a function with zero arguments


yeah qqq juxt is a nice one to remember. there's a few higher order functions like that that are easy to forget. juxt, constantly, complement, fnil, every-pred, some-fn. all super generally useful


I feel like I always forget precisely what juxt does about 3 minutes after I read its documentation


personally I forget fnil, I always confuse (fnil f foo) with #(or (f %) foo)


Hmm, thanks for the advice. I'll think about the juxt one, not sure I like it better though


I really like the idea of specter, but the all-caps conventions make me think it's always SHOUTING AT ME


hummmmm I wanna say there’s a (map-by :product-managers/slug manufactureres) that’s equivalent, but it may be in one util library or another not core