Fork me on GitHub
#clojure
<
2017-01-17
>
jgh00:01:10

is there a way of getting the string value of datomic enums?

zane00:01:11

You mean the ident?

seancorfield03:01:41

user> `(require '[clojure.string :as ~‘s])
(clojure.core/require (quote [clojure.string :as s]))

seancorfield03:01:01

(which is basically the same — the answer is “no”)

seancorfield03:01:19

(at least, as I understand your question)

seancorfield03:01:55

Perhaps if you provide a bit more context around what you’re doing, folks might be able to offer a suggestion @neupsh ?

seylerius04:01:58

What's the best way to turn dates and team (seqs) into something like this?

[[[:shift team-member day] [:shift team-member day]]
 [[:shift team-member day] [:shift team-member day]]]

thedavidmeister04:01:00

@seylerius you've got 2 seqs, how do they line up with that structure?

thedavidmeister04:01:50

(partition 2 (map (fn [t d] [:shift t d]) team dates)) does this do it?

seylerius04:01:51

More precisely: for team-member-i within team and day-j within dates, I need this:

[[[:shift team-member-1 day-1] [:shift team-member-1 day-2]]
 [[:shift team-member-2 day-1] [:shift team-member-2 day-2]]]

thedavidmeister04:01:55

probably with for then

seylerius04:01:39

Do I need a pair of fors? Like this?

(for [team-member team]
  (for [day dates]
    [:shift team-member day]))

thedavidmeister04:01:41

(partition (count dates) (for [t team d dates] [:shift t d]))

thedavidmeister04:01:55

something like that?

thedavidmeister04:01:23

you can already pass a few bindings to for and it goes through all the combinations

thedavidmeister04:01:35

after that you're just grooming the structure of the output data

seylerius04:01:59

Dig it, thanks!

nikki07:01:34

what's the best channel to brainstorm a new oo / msg passing model (like smalltalk mixed with erlang) to build in clojure? i asked in #off-topic if ppl are interested to check it out

dottedmag07:01:41

Clojure looks to be a very good match for this kind of computers: https://lwn.net/Articles/655437/ (The Machine by HP).

minikomi08:01:51

Hiya. I’m trying to set up a new vagrant dev env with a new luminus project.. running lein repl gives me the following error: Caused by: java.lang.UnsupportedClassVersionError: from/riddley/Util : Unsupported major.minor version 52.0, compiling:(from/riddley/compiler.clj:1:1) .. not sure what steps i should take to pin it down..

nblumoe09:01:56

@tbaldridge good progress with fn-fx! Here is an issue I encountered though: Is it already possible to construct controls that have mandatory constructor arguments? for example controls/scatter-plot which needs to get two axes in the ctor. I suspect that something like render-core/construct-control could be used to build it, but I do not yet understand how everything fits together. Maybe you could help with that?

karol.adamiec09:01:51

@brabster would you mind sharing a bit of that meta endpoint ? i am wrestling similiar issue… And AOT uberjar and env vars seeem a bit tricky to navigate...

brabster09:01:46

@karol.adamiec hey, I found the leiningen configleaf plugin. It lets you generate and store a copy of your project.clj as it appears under a profile in your jar, so that you can access it as a clojure data structure

brabster10:01:00

That's probably enough for me, I can set my project version using System/getenv and run lein set-profile foo to generate the code... is that any help?

karol.adamiec10:01:30

hmm, i was thinking more along the lines of generating a edn file with echo and reading that on startup… but will take a look at that plugin 🙂.

nblumoe10:01:18

@tbaldridge was able to render it via diff/component. I think it is brittle though because only prop-names-kw gets checked for matches and this is empty for all ctors of the ScatterPlot even though there are arity 2 and 3 ctors. However, that’s a bit too much detail for the chat I guess… will proceed the way it works for now.

danielgrosse10:01:56

I want to push a library to clojars. I set the projectname to my org, but still get a 401 after several broken pipe errors. What do I have to consider? Return code is: 401, ReasonPhrase: Unauthorized.`

gfredericks12:01:44

@danielgrosse what does "I set the projectname to my org" mean exactly?

sophiago12:01:19

hi all. i'm a bit stuck on how to recursively nest keys in a map to store the output of a recursive function. i have a simple function that does list comprehension on vectors and i'm mapping it to core.async channels recursively so if "fans out" exponentially, but i can't figure out how to store the output in a map at each step without overwriting previous values, if that makes sense.

sophiago12:01:53

here's an example with the current output and how i'd like it to look: https://gist.github.com/Sophia-Gold/c686cd3efac3e5389878b2011351be57. the base is one less than the count of the nested vectors i'm processing, so in this case two. right now the map obviously just ends up with the last values of each index to finish as they overwrite the previous ones. in order to store them all i'd need the map to be nested so it has 2^n values for the nth recursive call, but i'm struggling to imagine how to do this with assoc-in.

joshjones12:01:38

@sophiago 1 - I would not recommend the nested defn it may work but it’s not idiomatic and “looks funny” for lack of a better description .. prefer letfn (as you need recursion) 2 - why are you using core.async?

sophiago12:01:04

ah, that's my scheme roots showing 😛

sophiago12:01:09

i'm using core.async because the number of processes on each recursive call quickly grows quite large and i don't need the output to be ordered

sophiago12:01:01

(this is calculating derivatives, so just the third derivative of a three dimensional function will have 27 partials)

gfredericks13:01:56

You're using core.async as a way of parallelizing?

sophiago13:01:57

essentially

sophiago13:01:41

i considered pmap or reducers, but this seemed the most flexible way to go

joshjones13:01:17

Not trying to cop out here @sophiago , but I think the mutable variable and core.async channels makes it hard to reason about (at least for me, it does), for this particular problem. Others may have another opinion, but I would not use async tools here, as you do not have an async problem to solve. You said "i can't figure out how to store the output in a map at each step without overwriting previous values”, and I don’t think your choice of tools is making it easy

sophiago13:01:47

np, i appreciate the input. i don't think core.async is the issue, though. perhaps refactoring it to not use doseq would make it easier to reason about. otherwise, well, i am currently living somewhere with a hammock 🙂

gfredericks13:01:11

you might have similar flexibility by just using futures

gfredericks13:01:25

but with less trickiness

sophiago13:01:42

futures? i'm not sure what you're getting at

joshjones13:01:16

I would opt for solving the problem first — without parallelism at all — then parallelize if desired

sophiago13:01:20

well, the addition of go blocks here really isn't making it more difficult at all

sophiago13:01:11

the only thing is they come out unordered so i have to store them with keys

sophiago13:01:45

so it's true if it was sequential, it'd be a cinch just because i could have one long vector and not worry about labeling anything right away

joshjones13:01:45

isn’t the “unordered” part directly contributing to your difficulty in constructing the data the way you want it?

sophiago13:01:36

yes of course. but an ordered implementation wouldn't translate to the concurrent version

sophiago13:01:50

so i don't see how doing that would help

sophiago13:01:57

i do think i may be onto something though

joshjones13:01:00

why does it need to be concurrent?

joshjones13:01:21

there is a danger in solving problems which do not exist

sophiago13:01:40

to scale beyond this tiny example i'm using simply because i can mentally check whether it's correct

sophiago13:01:41

i was playing around with a third index earlier rather than nesting so deeply and i think i may be able to figure it out that way

pyr14:01:41

Hi #clojure

pyr14:01:54

In search of common/conventional wisdom

pyr14:01:03

I have a library which exports a protocol with several signatures

pyr14:01:17

some of these signatures are optional

pyr14:01:33

would you break the protocol into several smaller protocols

pyr14:01:51

or add a signature to yield the set of implemented capabilities?

Alex Miller (Clojure team)14:01:22

More protocols, fewer signatures per protocol

pyr14:01:26

om gave me this impression

pyr14:01:55

I was a bit reluctant, but it's more elegant than having to advertise what you're doing I guess

pyr14:01:10

Will do that, thanks

luxbock15:01:05

never really thinking too much about how clojure.test works I just noticed that I can create a function and place multiple is statements in its body, and then returning something completely different, and calling that function in a deftest still seems to check the results of those is forms

luxbock15:01:59

I have some tests that need to perform side-effectful preparation and teardown work, is it a fine practice to just set up the context like this within a function body, call a few is forms in the middle and then perform teardown afterwards

luxbock15:01:19

and then wrap a call to this no-argument function inside a deftest, or am I overlooking something?

tbaldridge15:01:15

nope, that's fine

Lambda/Sierra15:01:32

Yes, is is side-effecting. It depends on a thread-local binding for output reporting. I was young and foolish.

tbaldridge15:01:27

Well it's a very nice and clean way of doing asserts and getting reporting. I prefer it over having to make sure all my tests return a collection of test results.

Lambda/Sierra15:01:48

Yeah, there are trade-offs either way.

mavbozo15:01:03

@stuartsierra so, will there be clojure.test2?

Lambda/Sierra15:01:52

@mavbozo There was. It was called Lazytest. It never really worked out as a testing framework, but the core of it became tools.namespace.

schmee15:01:07

mavbozo there are a bunch of other alternatives

schmee15:01:18

expectations, speclj and midje are the ones that come to mind

tbaldridge15:01:27

None of them solve the problem stuart mentioned though, and they come with their own set of problems.

schmee15:01:19

yeah, pick your poison I guess

tbaldridge15:01:44

In the end, the simplicity of clojure.test always wins, IMO. If you took out the fixture stuff from clojure.test the core could be about 100 lines of code.

luxbock15:01:33

btw @tbaldridge do you know if it's somehow possible to pay for your videos on your YT channel without having access to a Google Wallet? I used to subscribe to them while you still hosted them on Pivotshare but have been unable to watch any of your new content because of this

tbaldridge15:01:24

@luxbock there's a link in the description of the YT site that talks about that. Basically no, but I also offer the vids via Paypal+Dropbox (or Google Drive)

luxbock15:01:55

do you have a link for how to do it via the latter option?

luxbock15:01:46

you will use the email address attached to the Paypal account to share the videos?

tbaldridge15:01:48

and we should probably move this off-topic now. But I'm happy to answer any more questions

luxbock15:01:22

yep, sorry that should be all, I am happy with this

tvalerio16:01:44

Guys, anyone that has worked with quartzite and can give some help? I'm trying do implement a basic schedule but it never executes

tvalerio16:01:40

And I'm calling the main function from the project's main function

tvalerio16:01:16

Any ideas of why the schedule never executes? :thinking_face:

sveri16:01:36

@tvalerio without taking a closer look, are you sure you keep your process running after you started the scheduler? Often the main process shuts down and with it the scheduler will be killed too.

tvalerio16:01:49

@sveri I'm pretty sure the process keep running, I'm using ring as server and I'm calling the scheduler main function when the server initializes

tvalerio16:01:48

well, I'll do some more tests here and try to solve this

tcrawley16:01:16

@tvalerio your job does nothing, so how would you know if it executes?

tvalerio16:01:44

actually, I've changed do print some text but nothing happens as well

sveri16:01:03

@tvalerio Your main function exits after scheduling the job. Like I said, you need to keep the process running.

tcrawley16:01:36

Gotcha. If you don't need all the bells & whistles that quartz/quartzite provides, you may want to look at org.immutant/scheduling. It uses quartz as well, but your example above would collapse to:

(require '[immutant.scheduling :as s])

(defn my-job [] (println "howdy!"))

(s/schedule my-job (-> (s/every 300) (s/limit 11)))

sveri16:01:57

@tvalerio You could add a sleep to your main function after scheduling and you should see the outputs.

tcrawley16:01:59

though that's unrelated to why your job isn't firing :)

sveri16:01:27

(Thread/sleep 10000)

tvalerio16:01:19

Gee, after adding sleep to the main function the schedule did execute

tvalerio16:01:27

Well, thanks guys

tvalerio16:01:27

I'll try to see now why the main function is terminating, it shouldn't 😂

sveri17:01:12

@tvalerio It should, as your code shows 😉

tvalerio17:01:14

@sveri I have a main function that starts a ring server. In this function I start the schedule, thats why I think it should not exit... But it must be a simple thing

sveri17:01:30

@tvalerio At least the code you pasted does not have a ring server inside. It only required quartzite libs.

tvalerio17:01:37

yes, sorry for that Its just that I thought it would be to much code to send 🙃

joshjones17:01:07

Not sure about vanilla ring, but using http-kit server, the function returns and does not block. So, the main function is usually expected to return after starting the server.

sophiago18:01:09

@joshjones so i had to step away for a bit, but as mentioned earlier i did get that core.async code working by just replacing the lowest level of nesting with unique indices. the thing that's really confusing me now, though, is that each time i run it i'm getting a slightly different set of values. i understand the order will differ based on when each channel finishes, but since they're all on separate channels it should be returning the same values each time it recurses and certainly not duplicating others in place of the slower ones. do you have any guesses why this could be occurring? here's the code again with new output: https://gist.github.com/Sophia-Gold/c686cd3efac3e5389878b2011351be57

joshjones18:01:18

you are reset!ting the atom between runs?

sophiago18:01:03

oh... no. i've just been redefining it

sophiago18:01:46

that does seem to clear it out

joshjones18:01:54

that’s fine, same result if you def it again

sophiago18:01:34

the only thing i can think of is if it could have to do with the let bindings?

sophiago18:01:44

wow, i'm really confused by what's going on here

hiredman18:01:31

you shouldn't defn inside a defn

hiredman18:01:06

clojure is not scheme, def (and forms based on it like defn) binds names to values in the top level scope

sophiago18:01:39

@hiredman @joshjones told me the same thing (and it is my scheme background). but that's not the source of this error

hiredman18:01:25

how are you sure?

sophiago18:01:18

anyway, i think i may be doing some things they say not to in that wiki doc

hiredman18:01:21

you are binding different functions to the global name diff-loop, each different function has closed over different values of s m and n

sophiago18:01:15

but are you saying using letfn would fix that because i get the same behavior regardless?

hiredman18:01:49

I dunno, its a complicated chunk of code

sophiago18:01:50

i would have liked to use a go-loop but you can see i'm not recurring from tail position

sophiago18:01:02

ok, lemme read up then

hiredman18:01:20

partial-diff is returning a lazy seq, and then you put it in to a channel unrealized

hiredman18:01:16

writing to a chanel in one go block, and then immediately reading from it is weird

hiredman18:01:26

(in another go block on the next line)

hiredman18:01:49

why are you using a channel at all there?

joshjones18:01:10

(sound familiar @sophiago ? ) 😉

hiredman18:01:53

why are you pre-allocating all those channels? the usage (which I don't why they are being used) doesn't escape that one area, so if you do need them, create them locally there and use them there

sophiago18:01:01

@joshjones i thought you said to not use concurrency entirely? he seems to be pointing out exactly what it says at the beginning of that doc

sophiago18:01:12

use take! instead of a go block

hiredman18:01:23

don't use take!

hiredman18:01:30

forget that take! exists

sophiago18:01:35

that's what the github wiki says

hiredman18:01:46

why are you using a channel at all?

tbaldridge18:01:00

you should never do (go (<! c)), that should be a take! but I agree, you don't need so many channels

hiredman18:01:28

your channels are doing nothing

sophiago19:01:06

well presently i'm mapping one function to each channel

sophiago19:01:13

so they are all being used

joshjones19:01:39

yes @sophiago , and I still say that after a lot of headache with this, you should work to get it correct using sequential methods, then understand the mechanisms for making it parallel, if you find some benefit to doing so, and then implement it using those mechanisms, if necessary. and unless you have a good reason for using async tools for their intended purpose (not this problem, IMO), don’t use them

sophiago19:01:49

how is their intended purpose not to run many calculations concurrently? this seems like a perfect use case

tbaldridge19:01:54

But what @hiredman says is right, your channels being created in the go blocks aren't doing much at all. But one of the core issues here, is that you're firing off go blocks and then not doing anything with the results, so it's possible to get a result in the repl before the go blocks have finished executing

sophiago19:01:33

@tbaldridge that's consistent with what i'm seeing

sophiago19:01:15

by "in the repl" do you mean i just need to wait longer for them to finish? or should i be doing something differently?

sophiago19:01:53

although if that was the case i'd expect to see values missing from the map, not ones repeated

tbaldridge19:01:01

go blocks return channels, those channels will contain results or return nil when the go block executes. So you need to be taking from every block you create

tbaldridge19:01:16

Or use futures and deref

joshjones19:01:46

^^ @sophiago … asynchrony != concurrency

sophiago19:01:58

well i currently only have one go-block

sophiago19:01:20

and nothing is returning nil, i'm just seeing values repeated in place of others

sophiago19:01:40

i get the same behavior even with no go blocks at all...

tbaldridge19:01:38

can you post that code?

sophiago19:01:04

sure. one sec, let me modify the gist with what i've eliminated

7h3kk1d20:01:01

Btw, slack has clojure highlighting if you change it from plain text

sophiago20:01:12

so i tried putting a one second thread sleep between the puts and takes and even with that the behavior is the same... i should try reducing channels (although i don't think eight running concurrently is so excessive), but i'm having trouble both mapping my function to the channels and indexing the return values to store in the hash-map since apparently nesting doseqs causes an infinite loop 😕

seancorfield20:01:04

Perhaps this (long) discussion belongs in #core-async ?

seancorfield20:01:52

Definitely seems like it’s gone beyond general #clojure discussions at this point (with my Admin hat on).

sophiago20:01:22

good idea. i didn't intend it to be so long 😛

sophiago20:01:41

and that emoji never comes out how i imagine it

seancorfield20:01:57

😄 I think sometimes, when a discussion gets to be essentially one-on-one and goes deep in the weeds, taking it to DM is worth considering (and perhaps reporting back just a summary of the solution so folks know how an issue got resolved).

sveri20:01:26

@seancorfield While I would agree in a corporate kind of setting where human "resource" is scarce and expensive this makes sense I think at a place like this I would do this only very seldom. In the end everybody can learn and go through the thought process. For instance right now I am following this discussion interested although I never used core.async in a useful way and I am curious to find out what the problem / better solution here is.

sveri20:01:03

Btw, I refer to the "going DM" part, not switching to #core-async, which does make sense as it is more on topic there.

seancorfield20:01:58

A DM conversation can be multi-party so if you’re interested in a discussion where the folks involved decide to take it out of the channel, you can always ask to be added in. We just need to bear in mind that in some of these channels, our audience is ~8,000 people. follow-up on discussion etiquette can go to #community-development as it’s not relevant to this channel — I’m happy to continue it there.

sophiago20:01:07

from personal experience often when there's a long discussion between few people going on there are other people who have questions or want to say something unrelated and are waiting out of politeness

7h3kk1d20:01:18

if done properly

baptiste-from-paris21:01:24

hello guys, I try to use source on one of my defn but Source is not found

7h3kk1d21:01:00

Are you in the same namespace?

baptiste-from-paris21:01:11

I looked and .getResourceAsStream returns null

baptiste-from-paris21:01:17

yes, same namespace

baptiste-from-paris21:01:48

* .getResourceAsStream is used internally by source-fn

7h3kk1d21:01:58

Did you define the function from the repl or in a source file? And can you call the function?

7h3kk1d21:01:02

Not sure then 😕

baptiste-from-paris21:01:43

ok, thx anyway 🙂

sova-soars-the-sora22:01:34

(fwiw i learn a lot by lurking here)

jondejung22:01:15

how insane would it be to reimplement Ethereum Core in Clojure?