Fork me on GitHub
#clojure
<
2017-03-06
>
mike_ananev04:03:08

@tbaldridge Hi! pedestal is interesting framework. how to avoid repl hang out when running a server? in your latest tutorial about pedestal there was the same error in demo.

mpenet08:03:29

@tbaldridge any numbers to back this up or is it just a conclusion from its design?

h.elmougy11:03:45

I have the following channel (def ch (chan 10 (partition-all 3)))

h.elmougy11:03:25

when e.g. 10 msgs sent to the channel only the first 9 grouped together and the remaining 1 not

h.elmougy11:03:45

how to make this behave like with seq

h.elmougy11:03:58

why core.async is different from seq?

mpenet11:03:56

the remaining is on hold until more messages come in, the channel is not a fixed size thing that closes after 10 puts

mpenet11:03:30

it will emit a value every 3 puts (as long as there is space in the chan)

h.elmougy11:03:58

do you mean if I closed the channel the remaining message will be delivered?

mpenet11:03:09

yes, very likely

qqq11:03:33

I have a list (:a 1 :b 2 :c 3 :d 24323 :e 205829 :f 824) What is the shortest code for transforming into a {:a 1 😛 2 :c 3 ... } map ?

sudodoki11:03:52

(hash-map :a 1 :b 2 :c 3 :d 24323 :e 205829 :f 824) but if you need to preserve ordering, might need sorted hash map or similar

qqq11:03:53

so basically #(apply hashmap %); interesting

sveri13:03:34

Hi, someone linked a talk here about data driven development, I think it was about clojure, In the talk the presenter used junit or spring as an example, does someone know which one this was?

tbaldridge13:03:44

@mpenet Pedestal "bends" the rules in several areas to improve performance quite a bit. For example, compojure's routing time is O(n), and has to be due to how complex the routes are. Pedestal can be constant time if you're willing to give up some things like parameters in the route, or wildcards

mpenet13:03:57

interesting

tbaldridge13:03:23

@mpenet that's a theme you'll see other places in Pedestal as well, you can get better performance by switching into a mode were requests maps are "map-like" and not exactly PersistentHashMaps

tbaldridge13:03:53

If you say "map-like" you can do things like zero copy of HTTP requests, where getting a key from a request map taps directly into the HTTP buffer

mpenet13:03:01

(I am sort of evaluating pedestal for a small service we have to build soon)

mpenet13:03:05

Yes I saw that, very nice

mpenet13:03:27

The async bits scare me a bit tho, seems like there's blocking IO in go blocks in a few places

mpenet13:03:53

like async requests and websocket handlers

mpenet13:03:34

About routing, it's rarely the bottleneck of a service I guess, but faster is always better

mpenet13:03:13

I made the same mistakes in a framework I authored on top of jetty9 for the blocking IO in go blocks, and that becomes a real problem when number of users hitting the service is decent (fixed it in branches in emergency mode). Jetty9 provides ways to avoid these issues as well, no reason not to do it

plins14:03:29

hello everyone, I'm having problems with pattern matching

plins14:03:49

(match a
  () "1"
  {:email email :ativo nil} "2"
  {:email email :ativo 0} "3"
  {:email email :ativo 1} "4"
  :else :no-match)
the first case is an empty list, how can i get this to work?

dpsutton14:03:26

i had luck the other day by putting it into a let binding

dpsutton14:03:52

(let [empty '()] (match a empty "1" ...)

qqq14:03:20

in my experiece, putting the expr inside .a [], i.e. (match [a] ... makes things much easier

synthomat14:03:17

Hm, I somehow cannot find anything about Lock primitives in clojure or I don’t understand how the same result can be achieved with included concepts… Say, I temporarily want to interrupt a thread (pause a future). Is there a introduction for such things somewhere?

synthomat14:03:14

Maybe Agent + Await?

joshkh15:03:58

can someone help me understand a problem i'm having in my repl? i'm trying to get the version number of my lein project. when i fire up the repl it loads the redgenes.server namespace, but when i run the following:

(some-> ( "project.clj") slurp clojure.edn/read-string)
i get the project.clj for.... clj-time!
redgenes.server=> (some-> ( "project.clj") slurp clojure.edn/read-string)
(defproject clj-time/clj-time "0.11.0" :description "A date and time library for Clojure...
why isn't it picking up my project.clj?

rauh15:03:11

@joshkh Don't use io/resource just use io/file

bostonaholic15:03:52

io/resource uses the classpath

rauh15:03:28

Better would be to do a def in your project.clj and use that (defproject fooo ~version...) and pass it in as an env variable too

bostonaholic15:03:33

io/file, like @rauh mentioned is probably what you want to grab a file by its path

bostonaholic15:03:10

(-> "project.clj" slurp clojure.edn/read-string (nth 2)) 😛

joshkh15:03:28

ah okay, thanks guys. i'm trying to build the version number of my project into my clojurescript application using lein. your suggestions worked! are functions in project.clj evaluated? i have the following in my project.clj in a build configuration:

:closure-defines {goog.DEBUG false
                                      redgenes.core/VN (-> "project.clj" slurp read-string (nth 2))}
but cljsbuild returns
value for  must be string, int, float, or bool

joshkh15:03:54

in the repl it definitely returning a string

joshkh15:03:11

actually, i think i can figure this one out myself 🙂

rauh15:03:33

@joshkh It's probably nil. But why not define it and pass it to places you need it. An example:

joshkh15:03:15

yup, i'm going with your suggestion of def'ing it. one last question. when i attempt to evaluate this:

(def version "3.3")
(defproject redgenes ~version ....
i get Caused by: java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote (thanks for the help on the newbie questions by the way)

joshjones15:03:06

@joshkh I think you just want (defproject redgenes version …

joshkh15:03:12

i've steered clear of macro syntax until now

dpsutton15:03:31

the unquote is useful when defining a macro, not invoking one

joshkh15:03:56

oh, of course. thanks.

dpsutton15:03:59

but always in the context of a ` (backquote)

joshkh15:03:53

you know, maybe i'm chasing my tail. perhaps it's a problem with figwheel or cljsbuild.

The key redgenes.core/VN at (:cljsbuild :builds :min :compiler :closure-defines) has a non-conforming value: 
  (str "thisisatest")
It should satisfy one of: Number | NonBlankString | boolean?

  {:cljsbuild
   {:builds
    {:min
     {:compiler
      {:closure-defines
       {goog.DEBUG false
        redgenes.core/VN (str "thisisatest")
        ^---- The value at key redgenes.core/VN doesn't conform
        }}}}}}
i don't think i can get any more NonBlankString than that 😉

joshkh16:03:26

(just to sum up my misunderstandings, Lein implicitly quotes everything and that's why it's breaking)

dergutemoritz16:03:42

I just came across http://dev.clojure.org/display/community/Library+Coding+Standards and am confused about "Don't unroll optional named arguments" as the example goes on to suggest that unrolled arguments are actually "good". So either the example is wrong or my understanding of what unrolling means in this context is flawed 🙂 Can somebody clarify this?

dergutemoritz16:03:15

Also, the "don't unroll" rule is contradicted by both the clojure.spec and the core.async API so it seems a bit odd.

bronsa16:03:08

can't comment on what's written there, but that page might be quite old and it's been the consensus for a while now that The Clojure Way is to provide maps rather than keyword args

bronsa16:03:56

keyword args have the only benefit of requiring 2 less characters to type and tons of downsides

dergutemoritz16:03:57

@bronsa I generally agree with you here but as mentioned in my own reply to my message above (let's maybe continue the discussion in that thread), fairly recent core libraries (`clojure.spec` and core.async) actually exclusively use unrolled keyword args.

bronsa16:03:40

that's usually more true for marcos than it is for functions

bronsa16:03:17

where the keyword args are less "optional named arguments" and more "syntax knobs"

dergutemoritz16:03:31

Yeah, that would at least explain it for clojure.spec

donaldball16:03:44

A rule I generally follow is: when giving a fn multiple arities, keep the same types in the same positions. Thus, if there is an optional options map, it’s almost certainly going to be at the end.

dergutemoritz16:03:44

OK, so that wiki page is maybe obsolete then

bronsa16:03:08

same for core.async where kw args are usually on macros like alt! that already introduce syntax

donaldball16:03:36

The advice to generally order fn args from least to most variance is good though

dergutemoritz16:03:12

@bronsa Right, I was thinking of alts! and alts!!, but maybe here they were also unrolled for symmetry with the syntax versions.

bronsa16:03:05

¯\(ツ)

dergutemoritz16:03:50

In any case, the wiki page is inconsistent here. If anyone with editing rights reads this, maybe they could fix it 🙂 Even if it hasn't been touched for 3 years, I wouldn't consider its contents obsolete. On the contrary!

madstap18:03:24

I'm getting a fairly inscrutable error when I try to cider-jack-in-clojurescript. I also get the same error if I do lein repl, but not with lein figwheel dev. It's on a commit that worked yesterday and stopped working. I get this error:

Compiling soul.server
2017-03-06 12:10:47.853:INFO::main: Logging initialized @1493ms
java.lang.NoClassDefFoundError: javax/servlet/http/HttpUpgradeHandler, compiling:(ring/adapter/jetty.clj:27:11)
Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/http/HttpUpgradeHandler, compiling:(ring/adapter/jetty.clj:27:11)
The only info I can find by googling suggests that ring 1.2.1 is the cause, but I'm on 1.5.1. The project is based on the re-frame template. Can anyone give me any pointers as to where to start looking for the cause of this?

tanzoniteblack18:03:22

@madstap you're assertion that you're on ring 1.2.1 is based off your project.clj or the output of lein deps :tree?

tanzoniteblack18:03:05

(just the first thing I would check to debug, that you're actually running the versions of code that you think you are, which makes the googling of errors easier)

madstap18:03:50

I'm running 1.5.1

tanzoniteblack18:03:01

@madstap what does your actual project.clj look like?

madstap18:03:04

I've tried using [ring "1.5.1" :exclusions [javax.servlet/javax.servlet-api]] like suggested by lein deps :tree, just as a random thing that might make sense if it worked, but it didn't

tanzoniteblack19:03:00

adding [ring/ring-jetty-adapter "1.5.1"] explicitly might fix it...but I don't know why it wouldn't be pulling that through correct as it is?

madstap19:03:21

let me try

madstap19:03:10

Nope, same error

tanzoniteblack19:03:33

sorry, I don't know how to help then.

madstap19:03:08

Thanks for trying

rauh19:03:37

@madstap Try pulling in [ring/ring-core "1.5.1"] manually

madstap19:03:46

@rauh Didn't work 😞

weavejester19:03:17

It sounds like you want to add an exclusion in java-kit

weavejester19:03:34

Dependencies that are “closer” take priority over dependencies that are more removed.

weavejester19:03:46

So the newer servlet 3.1.0 dependency is being overridden.

weavejester19:03:08

You either need to add the servlet dependency explicitly, or put an exclusion on java-kit

rauh19:03:26

Well then it's got to be [javax.servlet/javax.servlet-api "3.1.0"]

rauh19:03:19

Yup, exactly what weavejester suggested! 🙂

madstap19:03:11

Yes! It worked. Thanks! You guys are awesome

madstap19:03:03

I swear it worked before though, I used the java-kit stuff in the repl with everything working...

rauh19:03:54

@madstap Order matters, so if you moved your ring from top to bottom, then that'd explain why it failed now

Alex Miller (Clojure team)19:03:29

@dergutemoritz I removed that item from the wiki page.

dominicm20:03:12

Is there any way to know whether the thread backing a cancelled future has actually ended yet?

dominicm20:03:21

Hacks appropriate, it's a REPL session

hiredman20:03:17

futures aren't backed by a thread, they are backed by a threadpool, the thread a future runs on can end up running multiple futures one after another

dominicm20:03:11

@hiredman so, can I know if any more execution will happen on a future?

hiredman20:03:32

the java Future interface defines a get that takes a timeout, and an isDone and isCanceled method. clojure has a future-canceled? predicate

dominicm20:03:20

@hiredman does cancelled mean that the future will see no more execution? I would think that incompatible with the JVM execution model?

hiredman20:03:40

I would recommending checking out the documentation

ronald.petty20:03:03

Hello. I am new to Clojure and trying to recreate a program in code via the lein repl. I am stuck on the dependencies first thing. Can someone educate me on the following (link appreciated).

user=> (require '[org.elasticsearch/elasticsearch "2.3.2"])
ClassCastException java.lang.Character cannot be cast to clojure.lang.Named  clojure.core/name (core.clj:1546)

hiredman20:03:27

that is a maven dependency, not a clojure namespace

ronald.petty20:03:48

does that mean there are two different ways to do dependencies in the REPL?

hiredman20:03:08

clojure only knows about clojure namespaces

ronald.petty20:03:16

Like this? (require '[clojure.set :as set])

hiredman20:03:57

[org.elasticsearch/elasticsearch "2.3.2"] is a maven artifact coordinate which you build tool (lein) needs to make available

ronald.petty20:03:17

Does this mean there is no way to do this without a configuration file? I noticed the usage of it, didn't know if it was required.

hiredman20:03:32

it depends on the build tool you use

hiredman20:03:58

and what plugins and what not you use with the build tool

ronald.petty20:03:23

OK, thanks, I need to read more 🙂 before I get off the beaten path.

slipset20:03:36

We’re discussing (or at least I am) deployment of our app at work.

slipset20:03:01

currently It’s Complicated(TM) and takes too much time

slipset20:03:21

and the simpler way would be something like CodeDeploy (yes we’re on aws)

slipset20:03:55

but, as the app is (mostly) stateless, and written in clojure, one could imagine something like figwheel, but for servers.

hiredman20:03:43

what is complicated about what you are doing, and why does it take too much time?

slipset20:03:23

@hiredman: if we stick to scp’ing an uberjar to an aws instance (or two)

slipset20:03:32

it would involve restarting the app, right?

slipset20:03:43

and deregistering it from the load-balancer.

hiredman20:03:49

depends what you mean by that

hiredman20:03:29

if you have a load balancer in front, you have it hitting your app on port X, you dpeloy a new version on port X+1, have your lb direct new traffic to X+1, and take X out of the lb, once there is no more traffic

nooga20:03:49

@slipset you can try building WARs and putting them on elastic beanstalk, or perhaps, write a Dockerfile and leverage docker

hiredman20:03:51

its a standard pattern and some aws services will eeven do it for you

slipset20:03:09

I’m sort of aware of this. My point being

slipset20:03:19

imagine you have a repl open to your production app.

slipset20:03:43

to deploy new code, you enter the code in the repl, and redefine the functions as needed.

nooga20:03:54

use nrepl then 😄

hiredman20:03:54

absolutely not

nooga20:03:10

the point is, this is DANGEROUS

hiredman20:03:26

having a repl is nice for debugging, handling production issues, but it absolutely is not your deployment mechanism

slipset20:03:33

I know it is dangerous, that’s why I’m not doing this.

slipset20:03:19

But, instead of killing the idea off, I thought it would be interesting to think of how it could be done safer/safely.

hiredman20:03:37

the safe way to do it is a restart

nooga20:03:42

I once read that NASA had a lisp system running on a freaking spaceship and they did software updates on it using its repl

nooga20:03:12

and when I read that I though “boy, I’d like that for my apps in production"

seancorfield20:03:19

@nooga Their options were limited: pushing new code and “restarting” the system wasn’t really an option.

nooga20:03:22

and even entertained the idea for a while

dpsutton20:03:35

the machine was deadlocked 40 million miles away

dpsutton20:03:48

i wouldn't base my AWS strategy on that though

nooga20:03:48

but it turns out that scping jars does the job better

nooga20:03:59

when it comes to production

seancorfield20:03:22

If you have to push code in multiple namespaces, doing so “safely” via the REPL gets to be complex real quick and often impossible (since you have some functions redefined but not others).

hiredman20:03:23

the point is, you want to build and deploy immutable artifacts

hiredman20:03:33

you can do that via jars or some other mechanism

slipset20:03:05

@hiredman: I’d like to disagree. I want to be able to reproduce what’s in production.

seancorfield20:03:26

Even if you could push some small set of changes live via the REPL, you still need to push the updated source (via an updated JAR, for example), in case of a restart etc. So now you have to keep multiple things in sync.

dpsutton20:03:33

i think he's saying you create something and put it into production

dpsutton20:03:47

there's no question about "what" is in production

slipset20:03:52

@seancorfield that’s a good argument against. Thank you

hiredman20:03:04

you don't want to reproduce what is in production, you want what is in production to be a reproduction of something you know is good

dpsutton20:03:07

whereas if you're evaling different forms there's no telling what "version" is actually running at any one time

seancorfield20:03:45

@slipset And, just to be clear, at World Singles we do run REPLs in (some) production apps and we have very occasionally pushed critical fixes live via the REPL. And we have run into the “keep stuff in sync” issue where a patch was pushed via the REPL, then another patch was pushed via the REPL and via a source code update, and then we had to restart the process [and one patch had not made it to the source code on that machine].

seancorfield20:03:07

So it is very dangerous to go down that path. I can tell you from experience 🙂

seancorfield20:03:41

We no longer run REPLs in our production processes (with one special exception).

hiredman20:03:56

the runtime itself is a big ball of mutable state, you want to touch it as little as possible, you have to touch it some because it has to load code, once you start loading code more than once, and mutating the state, all bets are off

nooga20:03:05

@slipset embed https://github.com/clojure/tools.nrepl and run some experiments, it shouldn’t take long to test out the idea

slipset20:03:28

Again, I’m not going down that path any time soon. But I like thinking about the idea, and what kind of support infrastructure you’d need.

slipset20:03:53

like, as several people have pointed out, you woudn’t want to do this willy-nilly

seancorfield20:03:06

We used to stop/start REPLs in all our production processes back in the day… and we used to do mostly source-based deploys too (so we could “in theory” use the REPL to force a reload from source “easily” — but practice doesn’t match theory here in general).

slipset20:03:47

We do this all the time with databases, though not saying they’re equal.

seancorfield20:03:33

Do you replace stored procedures in DBs on the fly “all the time”? Or just update data?

slipset20:03:23

I don’t use stored procedures, but I change tables, change indexes etc.

slipset20:03:35

And yes, I understand there is a difference.

seancorfield20:03:08

The lure of “live updates” was why we originally went down this path. And it proved useful (and safe) maybe half a dozen times max over about five years. But it also trashed the app state several times, even tho’ we were really careful.

slipset20:03:25

@seancorfield I can imagine. And that sort of reflects what’s said about, and my experiences with, figwheel and stateless programming on the front-end.

slipset20:03:56

But I hadn’t at all thought about the source/restart thing you explained.

hiredman20:03:25

if you are annoyed at scping a large uberjar, there are a bunch of neat binary diffing tools

dpsutton20:03:45

also, how do you do "breaking" changes. If function A changes its return type and function B is the consumer of that new type, how do you update them in tandem so that the application remains in a valid state the entire time?

seancorfield20:03:10

We still have machinery embedded in most of our processes so that we can fire up a version with a REPL active (based on an env var) — but that is now a specific, deliberate choice, purely for debugging if necessary.

seancorfield20:03:42

We keep a socket server REPL active in just one production process these days and we almost never use it, preferring to start a command line REPL server (and “start” a specific component-based debugging application from scratch) when we need to do anything complex.

slipset20:03:16

@seancorfield sounds like a talk I’d like to attend.

slipset20:03:39

“Running World Singles"

seancorfield20:03:33

Maybe one day...

nooga21:03:46

what is World Singles?

seancorfield21:03:52

I gave a talk at Clojure/West years ago about our gradual introduction of Clojure (2012 maybe?) but we’ve come a long way since then and pretty much every part of our system is different. And it’s all still changing so any talk I gave would be just a snapshot and shouldn’t be taken as best practice.

seancorfield21:03:16

World Singles is about 100 Internet dating sites, powered by about 50,000 lines of Clojure (and a bunch of legacy code).

nooga21:03:14

Ouch, that’s a lot of code.

slipset21:03:29

@seancorfield most talks are reflections of current state of the art.

slipset21:03:39

and the art progresses.

seancorfield21:03:49

I actually submitted a talk about our use of clojure.spec last year but had to pull it because a) I was slammed in my personal life and couldn’t find time to write the talk and b) our use of spec kept changing so what I’d submitted wouldn’t match what we were actually doing a few months later 🙂

seancorfield21:03:28

We’re one of those places that has consistently run alpha builds of Clojure in production… starting with 1.3.0 Alpha 7 (or 8) back in 2011.

slipset21:03:40

I remember being awestruck by @matlux talk at euroclojure in 201(3|4) about jvm-breakglass https://github.com/matlux/jvm-breakglass

seancorfield21:03:43

We’ve been on 1.9.0 Alpha 14 in production for many months.

tolitius21:03:49

@ronald.petty take a look at , it can load dependencies on the fly (while you are inside the REPL):

boot.user=> (set-env! :dependencies '[[org.elasticsearch/elasticsearch "2.3.2"]])
;; Retrieving elasticsearch-2.3.2.pom from 
;; ...
boot.user=>

slipset21:03:03

and the introspection it offered into a production environment.

tolitius21:03:08

@slipset I tend to always run nrepl baked into the app when I actively work on it. As the app gets to be more mature, stable and better thought out, I tend to keep it off, but still configurable: i.e. I can bounce the app with the nrepl on/off. There are no absolutes. There are risks and benefits with everything. Do what makes sense in your use case

tech_hutch21:03:12

I have a quick question. If I define a function in a namespace, can I use that function in a function further up in the same namespace, like e.g. JavaScript? (Obviously not "namespaces" there, but you hopefully know what I mean.)

seancorfield21:03:39

@tech_hutch You can declare it ahead of use.

nooga21:03:44

@seancorfield I wanted to introduce spec while re-writing one of our core services but I’m not entirely sure about using language 1.9-alpha...

tech_hutch21:03:47

Well, actually, I suppose in JS it wouldn't even have to be inside another function.

slipset21:03:48

I find it strange that the capability to inspect and alter a running instance is not used/discussed more.

jstew21:03:01

That says a lot about clojure's stability, running huge sites on alpha releases.

tech_hutch21:03:25

Okay, I see.

seancorfield21:03:42

@slipset For dev, I do everything in a REPL. Either via an nREPL server running in an uberjar’d app, or by starting the components directly in a REPL in my editor.

tech_hutch21:03:51

What do you do? Usually just define functions above where they're used?

tanzoniteblack21:03:05

@tech_hutch generally, I just rearrange the NS so I don't need declare (i.e. make sure the function definitions always come before the call)

seancorfield21:03:06

@jstew Yeah, mostly Clojure has been incredibly stable in alpha and beta builds.

tanzoniteblack21:03:27

only time I use declare is when I have a circular reference between function definitions

nooga21:03:20

another thing is that I can’t imagine using namespaced keywords in my current codebase because I will get :foo.apples/oranges most of the time and it will make me gouge my eyes out

nooga21:03:15

but it’s just my bad design that I don’t like to be reminded of ;D

seancorfield21:03:29

@nooga We tend to have a namespace alias in place so ::m/username is what is used in “real” code.

schmee21:03:20

> I find it strange that the capability to inspect and alter a running instance is not used/discussed more. @slipset this becomes less fun when you have the same app deployed on >50 servers

nooga21:03:36

what I would do, most likely, is to make namespaces just for keywords, because sometimes there’s no code associated directly with them

seancorfield21:03:07

(specifically we have ::api-spec/username for a username provided via the REST API and ::m/username for a username within our domain model, so typically we only have two main aliases)

slipset21:03:11

@schmee I can see that, but that’s not one of my problems right now.

tolitius21:03:27

> I find it strange that the capability to inspect and alter a running instance is not used/discussed more. @slipset I think there are two reasons for that: 1. Not many people who have "sensitive" clojure production apps are here active on slack discussing their setups. 2. "`alter`" is a keyword for the answer to your question. Clojure community is "bound to immutability", any time you say alter, there are many, good, CS and experience backed arguments why you "should not" or "should do it differently". Hence most people just don't bring it up. This is my feeling of course. Not a fact.

nooga21:03:59

Or, sometimes there is, but sometimes not. And trying to slap stray keywords into existing namespaces will end up as :foo.apples/oranges

nooga21:03:56

given that most of the keywords is born on the interfaces to/from wires

seancorfield21:03:57

@grav Leiningen typically starts two JVMs and does a bunch of stuff with dependency checking etc

slipset21:03:24

@tolitius you may have a point. but the whole Repl driven development is about mutating the environment. And yes, I get that development is different from production.

schmee21:03:37

@slipset as you mentioned CodeDeploy earlier, what we do is we have Travis build a JAR which gets deployed by CD whenever someone pushes the master branch

schmee21:03:45

works great

tolitius21:03:18

@slipset I don't disagree with you. I do talk about it 🙂

seancorfield21:03:34

@grav here’s what I see

(! 679)-> time lein run -m clojure.main -e nil

real	0m2.107s
user	0m1.772s
sys	0m0.266s

seancorfield21:03:47

That’s outside any project.

hiredman21:03:56

lein start time is going to depend on a lot of stuff

hiredman21:03:18

but basically, the answer is, lein is doing way more than clojure.main, and that is why it takes longer to start

seancorfield21:03:36

(! 681)-> lein new app grav
Generating a project called grav based on the 'app' template.

Mon Mar 06 13:17:00
(sean)-(jobs:0)-(~/clojure)
(! 682)-> cd grav

Mon Mar 06 13:17:03
(sean)-(jobs:0)-(~/clojure/grav)
(! 683)-> time lein run -m clojure.main -e nil

real	0m2.704s
user	0m2.600s
sys	0m0.283s
With a small, new app — pretty much no dependencies.

hiredman21:03:42

what exactly it is doing will depend on your setup, you plugins, your project, the command you are running etc

grav21:03:44

Ah, okay, so I just tried without a project, and that took ~3 secs. So I guess I’ll have to take a look at the deps

jr21:03:03

lein deps :tree

hiredman21:03:56

my guess would be some plugin you are using

slipset21:03:04

Not defending, nor explaining lein startup times, I generally have my repls running for days. In that respect, the startup time doesn’t matter too much to me.

tolitius21:03:33

@slipset unless you change protocols. then all bets are off: bouncing repl works though.

slipset21:03:09

We’re not using that many protocols.

tolitius21:03:18

@slipset one is enough 🙂

tolitius21:03:24

if you change it

slipset21:03:41

let me rephrase. we’re not changing protocols.

hiredman21:03:23

forget changing it

hiredman21:03:34

just redefining the same protocol can break stuff

hiredman21:03:48

there is a nice isomorphism between deployments and clojure's epochal time model. a load balancer is like some kind of mutable reference, an identity, versions of your software are like immutable values. clojure generally provides two ways to mutate mutable references, something like reset! which just sets the value of the reference, which corresponds to deploying a new artifact, and something like swap! which takes a function from old value to new value, which would correspond to something like applying a binary patch to get a new artifact (which most people don't do)

lvh21:03:01

When using core.match regex matching ,can I also immediately assign the result of the match for extraction? Or does that mean using :<<?

plins21:03:35

is there an way to make cider point out unused imports?

plins21:03:20

thanks!!!

Ilya22:03:03

Is there anything in Clojure like assoc but that won't overwrite existing keys?

joshjones22:03:25

or do you mean, if you call it, and the key exists, it simply does nothing?

Ilya22:03:00

I mean the latter - no key - do nothing

dpsutton22:03:05

and just keep the map that should prevail on the left

Ilya22:03:28

Sorry - if the keys exists - do nothing

dpsutton22:03:21

so merge should work then, yes?

Ilya22:03:58

that would add keys in the second map, but not the first, right?

Ilya22:03:02

so no, I don't think so

dpsutton23:03:08

user> (let [my-map {:a 1 :b 2}]
        (merge {:a 2 :c 3} my-map))
{:a 1, :c 3, :b 2}
user> 

dpsutton23:03:12

does this not do what you need?

dpsutton23:03:27

if the key exists (here, :a 1) then do nothing?

dpsutton23:03:42

if the key does not exist (:c 3) then add it?

dpsutton23:03:17

> Sorry - if the keys exists - do nothing

dpsutton23:03:23

i'm going off of that

Ilya23:03:54

oh you're right. So I can use merge. Thanks!