Fork me on GitHub
#clojure
<
2016-02-05
>
alexmiller00:02:16

Vars allow thread-local dynamic binding too

currentoor01:02:33

@jaen: Sorry I meant subtle and novel for me specifically given the languages I've used before Clojure.

currentoor01:02:15

So both vars and symbols can have metadata? Now I'm confused.

arrdem01:02:49

currentoor: that's correct

currentoor01:02:23

Why both? When would you need that?

currentoor01:02:53

A symbol can house where it was defined in source code. What could you put on the underlying var?

bfabry06:02:35

currentmoor: a symbol can't really do that, a symbol just "is", like a keyword. where it was defined depends on the load order of the code

bfabry06:02:16

scratch that. I was thinking of keywords. I guess you'd use metadata on a symbol when you're actually using it as data

meow07:02:07

data has metadata

meow07:02:28

and then its turtles all the way down, right?

agile_geek08:02:41

@meow: I never understood that phrase "turtles all the way down"?

crocket08:02:02

How do I extract a property from a JSON file and set it to leiningen project version?

crocket08:02:03

project.clj is a clojure file.

crocket08:02:19

It seems clojure doesn't have a built-in JSON parser.

crocket08:02:31

Without a built-in JSON parser, leiningen has to execute defproject first to load dependencies.

crocket08:02:23

After defproject is executed, I can't easily change project version.

crocket08:02:39

I perhaps want lein-npm.

bfabry09:02:41

crocket: you could make sure a json parser dependency is on your cp manually

crocket09:02:54

Is it possible to use (def) in project.clj?

solicode09:02:51

Yes, that’s possible

solicode09:02:47

Just note that when you use the var, you’ll likely need to prepend ~ to the name

crocket09:02:12

@solicode: Why do I need to prepend ~ to the name?

solicode09:02:38

Unquoting. defproject is a macro. But for version you won’t need to.

crocket09:02:51

I never needed to unquote anything when I used a macro.

solicode10:02:32

Well, it depends on the macro. If you macroexpand defproject, I think it’ll be clearer. But anyway, in your case with version it shouldn’t be an issue, so forget I said anything simple_smile

solicode10:02:47

If you’re curious though, I just looked up the source code. This is the reason why: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L177

solicode10:02:01

It’s a documented feature

crocket10:02:17

@solicode: It seems I need to prepend ~ to even clojure.core/str in defproject.

crocket10:02:39

It looks like a bug.

solicode11:02:43

That’s still arbitrary evaluation, which is why ~ is needed. Depending on what you’re doing, I’d extract everything out into a defn and then simply call the function with ~ preprended

crocket11:02:25

What do you mean by "extract everything out into a defn and then simply call the function with ~ preprended"?

solicode11:02:51

What are you trying to make dynamic inside defproject?

crocket11:02:46

How can I paste a long source file here permanently?

solicode11:02:13

Maybe creating a snippet? I’ve never actually used that feature, but clicking on the + icon shows it

solicode11:02:25

To the left of the message box

solicode11:02:05

Yeah, that str for the repo url will need ~ as well. That’s fine, but you can also define it outside defproject like you did with license and url. Like:

(def url "")
(def repo-url (str …))

solicode11:02:14

And then refer to repo-url

crocket11:02:26

Not so good.

crocket11:02:44

Will leiningen 3.0 still require ~ in project.clj?

solicode11:02:14

It seems like #= will replace ~

solicode11:02:25

But if you’re doing very complicated stuff, then maybe a plugin is better

solicode11:02:28

a lein plugin that is

dm311:02:30

if you need a lot of scripting - you'd be better of with Boot

solicode11:02:38

Or boot, yeah

crocket11:02:45

I just want to factor out frequently used constants as variables.

solicode11:02:29

But that’s exactly what def is, but you said “not so good” for that, so now I’m confused

crocket11:02:04

Does boot have templates as leiningen does?

dm311:02:27

it does now, with boot new

meow11:02:30

And there is great support for boot on the #C053K90BR channel.

meow11:02:19

You will probably be happier with boot in the long run.

crocket11:02:45

Leiningen starts becoming diffcult to wield if a build becomes more complex than a clojure library.

crocket11:02:24

By the way, does figwheel work on clojure REPL, too?

jaen11:02:06

Not really (though I've seen boot-figwheel somewhere, not sure how well that works) but there are boot-reload and boot-cljs-repl libs which achieve the same.

krchia11:02:11

if anyone knows where i can look at a example of a login system using enlive and compojure?

crocket12:02:16

I think you want Ring middlewares for handling login.

krchia12:02:48

@crocket i had some problems with wrap-session, but i got help in #C053AK3F9 simple_smile

jaen12:02:02

That's buddy with compojure

krchia12:02:34

@jaen i haven’t chanced upon that yet, thanks so much!

jaen12:02:24

No problem; looks like a solid blogpost (and I personally like buddy) and has a runnable repo linked at the bottom of the blogpost.

jaen15:02:15

@alexmiller: do you maybe know if there's any plans to support named groups in Clojure regexp functions? Right now (re-find #"t(?<test>es)t" "test") returns ["test", "es"] instead of something like ["test" {:test "es"}] or similar.

jaen15:02:49

Not really a feature request, just curiosity; named groups seem like terribly useful things to have when writing regexps (at least I use them all the time).

alexmiller16:02:10

Clojure really builds on Java's regex support

alexmiller16:02:22

it looks like java 7 added regex named group support

alexmiller16:02:11

presumably it would be possible to extend the existing fns to support that

alexmiller16:02:00

the difference in output would likely require either a new fn (or fns) or some sort of switch

jaen16:02:07

Yeah, it's something post-6, I remember first time when I tried that Java just complained about the syntax.

jaen16:02:21

Was just curious if there are already plans for that.

alexmiller16:02:26

this seems like a good idea for a feature to me but would require some investigation on the best way to add it in backwards-compatible way

alexmiller16:02:33

I've never seen anyone ask about it

alexmiller16:02:07

so, enhancement jira welcome (patches or further investigation also welcome)

jaen16:02:09

I think this would not require a switch - regexs with no named groups could behave as before and only regexes with named groups would return a map.

alexmiller16:02:25

seems possible

alexmiller16:02:09

if you wanted to do the work, I'd be happy to try to get it considered in 1.9

alexmiller16:02:55

b/c we still support jdk 6, there are some tricks likely needed to make this work in 1.7+ only, but there are other things like this already

jaen16:02:01

I can take a look at what this would entail when I have time, sure.

jaen16:02:07

Hopefully it's not too complex.

jaen16:02:54

Would certainly be a welcome enhancement; each time I had to do capturing groups I was all like "whyyy positional groups, we're in a dynamic language with maps". So, I'll get back to you when i'm through with my thesis and can investigate that.

lockdown16:02:07

alexmiller: what other things already do this? just curious

alexmiller16:02:54

what does "this" refer to?

lockdown16:02:56

yeah that, thanks

lockdown17:02:29

"A library for reduction and parallel folding. Alpha - is that still true for reducers? the alpha stage

ghadi17:02:19

yeah it is

ghadi17:02:58

personal opinion: transducers sort of obsolete reducers. Collections being reducible are officially legit with the introduction of the clojure.lang.IReduceInit interface.

ghadi17:02:14

fold may see some tweaks in the near term

ghadi17:02:10

transducers + eduction take care of 75% of c.c.reducers functionality

ghadi18:02:01

I'd like to do a tutorial on Eduction + reducible I/O sources. Have had a really good time with it

jstaffans18:02:44

what about cases when you want to do parallel processing? My understanding is that you need to combine transducers with a core.async pipeline or something, whereas c.c.reducers parallelise out-of-the-box

ghadi18:02:19

sorta -- it remains to be seen how to integrate transducers with parallel collections, a simple way is:

ghadi18:02:44

(fold 512 ((map f) my-reducing-function) combinef collection)

ghadi18:02:11

(details omitted, transducers have to be completed)

sveri19:02:48

Hi, what would you use to draw a graph from a background proces and continiously update it? Currently I dont have any gui running.

nkraft19:02:31

I've used Incanter for that kind of graphing with success. http://incanter.org/

nkraft19:02:24

And I just saw this from WalmartLabs if your needs are pure ascii: https://github.com/walmartlabs/active-status

sveri20:02:13

@nkraft: I also tried incanter for some stuff, but was not aware that you could update existing graphs? Everytime I used it, it created a new JFrame and window.

sveri20:02:10

active-statues looked interesting, but, as always, cool console stuff only runs on linux 😄

nkraft20:02:13

@sveri If you give incanter's view static data, it makes a static graph. If you hand it an active function it updates. For active-status, can't you use Git-Bash for that?

akiva20:02:34

Hey! @apa512 and/or @danielcompton, when you have a moment: does clj-rethinkdb not properly handle sets? Whenever I try to insert a data structure with a set as a value, it comes back with ExceptionInfo RethinkDB server: Expected a TermType as a NUMBER but found STRING.. I would think it would convert a set to an array for compatibility.

danielcompton20:02:52

Don't think it does because RethinkDB doesn't. I'd prefer if users manually converted it themselves so they know what's happening. Also, on the way back out we'd have no way of knowing if an array was meant to be a set

akiva20:02:16

That makes sense. I just wanted to be sure it wasn’t a bug. I'm handling the way back out because I know which keys have sets.

akiva20:02:14

Now that I’ve sat here thinking about it, it isn’t really necessary to have a set over a vector other than that sets automatically de-dupe. I’m going to just switch it all to vectors.

akiva20:02:25

Thanks for the info, @danielcompton.

danielcompton21:02:11

Also note RethinkDB has some functions for treating vectors as sets

chadhs21:02:00

hi everyone. i’m curious why a (log/info “event”) message at the top of a function will always output to the commandline one inside an anonymous function in the body of the function would not

chadhs21:02:33

(defn merge-product-events
  "run merge_events across all blocks for the given product event mappings."
  []
  (log/info "begin event merge:")
  (map (fn [product-event-map]
         (map (fn [working-dirs]
                (log/info "block:" working-dirs "event map:" (second product-event-map))
                 …

chadhs21:02:17

however as a test if i were to call (println merge-product-events) i see the output

drewr21:02:40

@chadhs if you were to wrap those maps in a doall you would see it

drewr21:02:04

since you aren't realizing the (lazy) seq until you invoke merge-product-events

drewr21:02:24

the first log/info isn't captured in a lazy-seq

chadhs21:02:43

@drewr: i think that makes sense, let me give that a shot

drewr21:02:33

and just to clarify, you don't need two doalls, just one around the outer (I made it sound like you needed it around each one)

chadhs21:02:13

blargh, that didn’t seem to do the trick

drewr21:02:00

can you paste more of the code?

drewr21:02:06

or at least the new version

chadhs21:02:00

@drewr:

(defn merge-product-events
  "run merge_events across all blocks for the given product event mappings."
  []
  (log/info "begin event merge:")
  (doall
   (map (fn [product-event-map]
          (map (fn [working-dirs]
                 (log/info "block:" working-dirs "event map:" (second product-event-map))
                 (shell/sh merge-tool working-dirs (second product-event-map)))
               (generate-block-files-list
                (generate-product-working-dirs basedir (first product-event-map) block-dirs))))
        (generate-product-event-map product-event-map-file))))

chadhs21:02:05

goal is to output that im starting event merging, and at each step

chadhs21:02:27

thanks stuart i’ll give that a read as well

drewr21:02:50

@chadhs actually there you would need a doall inside as well

drewr21:02:10

but as @stuartsierra is trying to lead you, this isn't a good use of map

chadhs21:02:44

yes i’m still pretty green/new to clojure. this was a one off work project to build a small utility. thought it would be a good learning exercise rather than just bashing it

drewr21:02:49

all that stuff you want to eventually shell/sh on, I would generate inside one seq and then doseq over that

chadhs21:02:56

(literal bash / bin/sh etc i mean)

drewr21:02:03

@chadhs perfectly fine! that's the way to learn

drewr21:02:25

and learning only comes through bad lines of code (which I still write every day)

chadhs21:02:38

that worked for now @drewr thank you. im going to read @stuartsierra ’s post and refactor

chadhs21:02:16

i think the last piece im going to read up on before i refactor that is to also pass standardout from the shell/sh commands to the commandline

datran22:02:44

is anybody up-to-date on compojure-api? I have a couple questions

datran22:02:05

mainly to clarify differences between what's documented in different places on github

datran22:02:38

is that up-to-date? ^ Because it's not matching what I get from (dir compojure.api.sweet)

alexisgallagher23:02:40

Let's say I want to send off a small piece of work to be done in the background. For this I would use an agent. But let's say I am only doing this for side-effects, so I don't care about the return value. Is an agent still the right way to do this?

ljosa23:02:36

Is there an existing convention for what it means if a symbol starts with -? I'm thinking about using it for symbols that are for internal use in my namespace, but that I don't want to make private (with def-) because it's too much of a pain to access them from my testing namespace (with #', etc.).

jonahbenton23:02:15

hey @alexisgallagher you may want to consider a go block from core.async instead. an agent includes internal state, so it may not be a precise semantic match for the work you need to perform, if it does not have any internal state implications.

alexisgallagher23:02:53

Huh. I thought go blocks were used only for communication along channels, not just for sending off work to background threads. I need to read up.

danielsz23:02:15

@crocket: system is a library optimized for code reloading in boot. https://github.com/danielsz/holygrail

jonahbenton23:02:18

there's no requirement to use channels with go blocks, and you can ignore the channel returned by calling go.

jonahbenton23:02:22

can also use a future

jonahbenton23:02:12

usually there is some use case for some sort of communication or notification or control over execution- side effect on an external system takes too long, or something

jonahbenton23:02:31

e.g. one doesn't care in the success case but if there is some ability to detect failure perhaps there is some need to take action

alexisgallagher23:02:53

Okay. Good to know. The reason I'm using an agent is because I want to use send-off, because I want send-off's guarantee that it won't execute if the dosync transaction does not commit. I only want my side-effect once, only if the transaction commits, and if a condition holds.

jonahbenton23:02:54

gotcha- sounds like a good reason simple_smile

alexisgallagher23:02:21

I did look at the source of future to try to figure out if it was also transaction-aware, w/r/t/ to dosync. It seems like it might be but I don't understand the underlying Java concurrency libs well enough to tell right away.

alexisgallagher23:02:23

They both reach down to a clojure.lang.Agent/SsoloExecutor. One is submiting, the other is dispatching....