Fork me on GitHub
#clojure
<
2016-10-20
>
gfredericks00:10:00

@jey what would you be missing if you made several independent leiningen projects?

darwin00:10:00

I tend to have one project.clj with multiple :profiles, if needed I use ^:replace trick to clear possible settings declared at the root level

darwin00:10:47

also I tend to write a bunch of aliases, which wrap my “with-profile” combos, to make it palatable when using from cmdline

lockdown00:10:49

gfredericks a single repo

gfredericks00:10:05

@lockdown you can put multiple leiningen projects in one repo

lockdown00:10:33

yeah, I guess he can nest them

darwin00:10:10

one problem with multiple projects are dependencies, I personally don’t want to dance around updating multiple files when libraries get updated, but maybe there are some tools to automate that

timrichardt00:10:03

cehckouts are the canonical way to work on several projects at the same time

timrichardt00:10:10

with interdependencies

darwin00:10:45

with checkout deps you start hitting issues like this one: https://github.com/emezeske/lein-cljsbuild/issues/413

darwin00:10:11

there are workarounds, but not all tools are aware of checkouts

darwin00:10:55

for me checkouts are good ad-hoc solution when I need to fork 3rd party library and want to develop a patch in the context of my project

darwin00:10:16

I don’t know, maybe other people have great experience with checkouts

darwin00:10:36

to me it is like git submodules, great sounding idea, but reality lacks tools

darwin00:10:18

the boot’s approach is much better, they watch the other repo with file watcher, and auto-install the dependency into maven on change, and update your project somehow

darwin00:10:39

so it goes through maven repo the usual way

darwin00:10:24

for example my most-monstrous project.clj using that profiles+aliases approach: https://github.com/binaryage/dirac/blob/master/project.clj note that is uses a some ugly tricks, e.g. Cursive/IntelliJ does not understand profiles, so I have to use the root level as instructions for Cursive and then negate it in profiles, sometimes I want to overload standard lein commands like”test” or “install”, so I have to :nuke-aliases, sometimes I have to do weird things to work around cljsbuild issues, etc.

darwin00:10:56

would like to do it in a better way, but I didn’t find better solutions...

cfleming00:10:25

@darwin BTW Cursive should understand profiles, it didn’t previously but it has for a long time now. If it doesn’t it’s a bug I’d like to know about.

darwin01:10:25

@cfleming well, what bothered me is Cursive’s auto-setup of source/resource/test folders after reading project.clj, even if I set it up manually via IntelliJ project settings, next time Cursive opens project.clj it overwrites my setup with stuff found in :source-paths and similar from root level

cfleming01:10:06

Right, if you want a different setup there you should configure it in your project.clj

cfleming01:10:15

But assuming you do that, Cursive should pick it all up.

darwin01:10:46

yes, that is what I do, but it sometimes does not fit needs in my :profiles

darwin01:10:11

what I have to do is to do union of my needs on root level and then reset it in profiles to subsets

darwin01:10:29

assuming multiple sub-projects share one project.clj

cfleming01:10:48

Hmm, I don’t understand that. I actually have to go now, but I’m interested to know more about what you need and why it doesn’t work.

darwin01:10:11

yeah, we should move into #cursive anyways

darwin01:10:23

will ping you, maybe

cfleming01:10:32

It’s bedtime for me, but yeah, let me know.

darwin01:10:35

as I said, I found workarounds

cfleming01:10:43

Or if you have an example I can look at I’ll check that out too.

darwin01:10:48

and my setups are pretty complex

cfleming01:10:11

Yeah, no doubt. Still, if Cursive can’t handle complex setups, that’s still a bug 🙂

cfleming01:10:20

Ok, GTG, seeya

hueyp01:10:50

is there a way to test for LazySeq vs other things that impl ISeq? I am using transit and encoding a persistent list (list? x) ;;=> true and want to turn those back into list on the other side.

hueyp01:10:01

right now I’m just instance testing but unsure if this is smart or foolish 🙂

madstap02:10:52

why does run! only take one collection argument, unlike map?

mikeb03:10:14

Hi all I'm having some problems with lein uberjar inside of docker. Lein jar works, as does lein run. It's just hanging up on creation of the uberjar right after creation of the standar jar. The same project can be uberjar'd outside of docker no problems. Has anyone else encountered this? (Also tried disabling AOT and no difference)

mikeb04:10:33

A quick update for those that use docker for mac and may run into this issue... it's a docker bug that causes high cpu usage on disk access. The actual uberjar was successful it just took over 8 minutes to generate.

Yehonathan Sharvit05:10:09

A question about reader conditionals: I’m looking for a way to receive a .cljc file and returns the .cljs branch - but without actually reading the file, but leaving the content of the branch as is

Yehonathan Sharvit05:10:19

But my problem is that the forms are read by the clojure reader - so for instance ::abx becomes :my.tag/abx

Yehonathan Sharvit05:10:33

What I want is to leave the branched forms as they are

Yehonathan Sharvit05:10:38

Any idea how to do that?

Yehonathan Sharvit05:10:14

My use case is for dev time when you use reader conditionals and you want to see the branches :clj or :cljs

danielcompton06:10:02

@viebel: maybe cljsee might have some hints?

danielcompton06:10:15

It's a cljc preprocessor

Yehonathan Sharvit10:10:23

thx @danielcompton this is exactly what I was looking for

Alex Miller (Clojure team)11:10:38

You can also use the :preserve mode of :read-cond to preserve both branches in the reader

alqvist11:10:55

Trying to use namespaced maps. myns.spec is required

alqvist11:10:31

can I do something like #::s/state{:id 1}?

alqvist12:10:03

state is a namespaced keyword in myns.spec

brabster12:10:21

@alqvist pretty sure I've done that in the past, checking

brabster12:10:48

@alqvist no not what I've done - I've done more like #::s{:state 1}

brabster12:10:19

what is :id if ::s/state is a namespaced keyword?

alqvist12:10:12

(s/def ::state (s/keys :req [::id]))

brabster12:10:57

@alqvist ok so ::state and ::id are both in the same namespace

brabster12:10:15

so you'd want #::s{:id 1} I think

brabster12:10:47

s is your ns alias that contains both

alqvist12:10:00

@brabster I think you are quite right. Feeling dumb now 😕

brabster12:10:03

#::s{:id 1} should be valid for the ::s/state spec

alqvist12:10:09

@brabster thanks for your help

brabster12:10:26

you're welcome 😄

gfredericks15:10:34

I finished the proof-of-concept for a how-to-ns lein-plugin-linter-thing: https://github.com/gfredericks/how-to-ns

idiomancy15:10:28

So, of the following two core.async bits of code, which one is better:

idiomancy15:10:45

(defn my-func! [in-chan] (+ 1 (<!! in-chan))) ; <- function returns result
(let [sample-chan (chan)]
  (>!! sample-chan 1)

  (alts!! [(timeout 1000)
           (go (my-func! sample-chan))])) ; things that use it put it in a channel

idiomancy15:10:01

(defn my-func! [in-chan] (go (+ 1 (<! in-chan)))) ; <- function returns a channel
(let [sample-chan (chan)]
  (>!! sample-chan 1)

  (alts!! [(timeout 1000)
           (my-func! sample-chan)]))  ; <- things that use it treat it like a channel

idiomancy15:10:18

hopefully you understand what I'm getting at. I come across this choice all the time and have no real reason for favoring one over the other

idiomancy15:10:38

the latter one seems obviously better if I definitely want to use it in an alts!! block, but the former one seems more general for cases where I just want the result

darwin15:10:26

the second one will be easier to port to ClojureScript if that could be a task in future

idiomancy15:10:44

oh? thats interesting, why is that?

darwin15:10:15

there are no threads in javascript, so only go blocks are supported

darwin15:10:29

no >!! or alts!!, just >! alts! etc.

idiomancy15:10:08

huh, I didnt realize that required threads to implement

darwin15:10:02

if you used just go and single excamation version of things, all your code would run on single thread “cooperatively”, I believe

darwin15:10:21

for example when you use <!! you are blocking the thread

idiomancy15:10:49

versus just blocking the go-block

idiomancy15:10:10

which is different, because a blocked go-block thread can be re-purposed to other go-blocks

idiomancy15:10:23

but a blocked thread can not.

darwin15:10:06

not sure about that, (go … <!! …) from the first example, that still looks like a blocking go block, so it won’t “park” to release the thread to other go blocks

darwin15:10:27

but I’m no expert on java version of core.async, I grew up with cljs version

darwin15:10:00

but you have a thread pool powering all go blocks, so blocking one of them is not that big deal

darwin15:10:05

that is my understanding

idiomancy15:10:09

huh, interesting. But youve given me some key vocab. you say "parking" means "release the thread to other go blocks"?

darwin15:10:22

but you should not be doing blocking stuff systematically, you could run out of worker threads

darwin15:10:21

right, parking happens on commands like <!, core.async will “save” state of the go “thread” and release the worker thread to do other work for other go blocks

darwin15:10:00

and when it getd signal that it can continue, it restores state of the go “thread” and runs with it until next parking

idiomancy15:10:19

huh, how about that.

liamd16:10:29

I have a situation where i’m trying to construct a collection that looks like [1 2 3] but i have a vec that looks like [1 [2 3]] essentially. is there a way to “dump” a list into its containing form? flatten won’t work because it flattens multiple levels

liamd16:10:58

you know what here’s the whole example, it’s for forming hiccup:

[:ul {:class "collection"}
                        (mapv (fn [c] [:li {:class "collection-item"} c]) config-vec)]

exupero16:10:05

(mapcat #(if (sequential? %) % [%]) [1 [2 3 [4]]])

jr17:10:47

(into [:ul {:class “collection”}]
         (mapv ....))

hiredman17:10:50

if I recall you don't need to do any flattening with hiccup

hiredman17:10:06

by which I mean, I think it will generate the same html fore [:ul foo] and [:ul [foo]]

liamd17:10:27

it gave me an error along the lines of [:li … ] is not a valid tag

hiredman17:10:06

Oh of course, sorry

hiredman17:10:13

nesting of sequences

hiredman17:10:36

vectors are treated as a tag and body

hiredman17:10:05

so the issue is you are using mapv, not map, and hiccup treats vectors and seqs differently

hiredman17:10:49

[:ul (map ...)] or better [:ul (for ...)] will do the correct thing

bensu18:10:54

I have an expression (get-special x) that should only be called if at some point in the call chain it was wrapped with (prepare-special x (get-special x).

bensu18:10:28

So (prepare-special (several-levels (get-special x))) should work but (get-special x) should not

bensu18:10:05

Is there any way I could check that at compile time?

jr18:10:09

does it have to be compile time?

bensu19:10:13

I already have a version that does it at runitme

bensu19:10:38

(get-special x) asserts that dynamic var was set by prepare-special

bensu19:10:14

but I’m trying to see if I can be more strict

hiredman19:10:46

it depends on if you want to check in the static or dynamic extant, it is in theory possible in the static extant, but it is going to suck to write that macro

hiredman19:10:32

dynamic extant meaning something like

(defn foo [] (get-special x))
(prepare-special (foo))

hiredman19:10:46

and static being like the examples you posted

bensu19:10:40

yeah it is the dynamic version I’m struggling with

bensu19:10:57

(by extant you mean extent right?)

hiredman19:10:44

you aren't going to be able to do the dynamic extent version without doing whole program analysis

bensu19:10:09

what I suspected 🙂

bensu19:10:44

thank you @hiredman and @jr if I come up with some specific hack I’ll post it back here

romain22:10:00

I just saw a #’ in a code and it reminds me something about being deprecated recently, can someone confirms it or tells me if there is something new about it ?

amacdougall22:10:03

So I just had a need for this little helper:

(defn n-times [f input n]
  (if (= n 0)
    input
    (recur f (f input) (dec n))))

amacdougall22:10:23

And although it's simple, it seems like something that would already be possible with the core library. Suggestions?

amacdougall22:10:16

Specifically, I'm trying to do just a few steps of an iteration as part of a unit test.

jr22:10:25

(nth (iterate f input) n)

amacdougall22:10:57

Ah, iterate is what I was missing. It must give a lazy sequence?

jr22:10:07

yep and returns the result of applying input to f

amacdougall22:10:53

Also, clojure.spec is nice, but I just gave ::grid/grid grid as one key/value in a map and it reminded me of Thing thing = new Thing(). Some things never change.

amacdougall22:10:01

Thanks for the help, @jr!