Fork me on GitHub
#beginners
<
2016-02-18
>
bendy04:02:39

hey all, quick question: I’ve found myself doing this a couple times

(reduce #(assoc %1 (%2 :some-key) (%2 :another-key)) {} vector-of-maps)

bendy04:02:53

is there a better way to do that? I feel like clojure probably has some awesome convenient folding method that does that for me

seancorfield06:02:41

@bendy: Well, reduce is the "folding" function but I suspect there are several ways to solve your problem and some may seem more idiomatic than others.

seancorfield06:02:47

My initial reaction, since you're applying two fixed keys to all the hash maps in the sequence, would be to use juxt and map or mapcat to get that sequence and then convert it to a hash map in one go...

seancorfield06:02:00

I haven't tested it but I feel something like (apply hash-map (mapcat (juxt :some-key :another-key) vector-of-maps)) is easier to understand, in terms of what is going on.

seancorfield06:02:24

Mentally I had to rewrite your code as (reduce (fn [r m] (assoc r (:some-key m) (:another-key m))) {} vector-of-maps) to figure out what it was doing...

seancorfield06:02:17

Or maybe (into {} (map (juxt :some-key :another-key) vector-of-maps))

seancorfield06:02:29

(again, untested, just thinking aloud)

seancorfield06:02:29

OK, just tested all of those and I think they work... Hope that helps!

seancorfield06:02:17

So, yeah, I'd go with into {} and the map/`juxt` approach.

slipset09:02:30

with the added benefit that you get to use juxt

alexrrr12:02:48

Hello! I wanted to try macroexpand but the example in clojuredocs does not seem to work for me.

alexrrr12:02:54

expected:

user=> (macroexpand '(-> c (+ 3) (* 2)))    
(* (clojure.core/-> c (+ 3)) 2)

alexrrr12:02:06

I get:

user=> (macroexpand '(-> c (+ 3) (* 2)))   
(* (+ c 3) 2)

alexrrr12:02:22

any clues why?

ordnungswidrig12:02:25

You want macroexpand-once

alexrrr12:02:46

thanks, but no dice

user=> (macroexpand-once '(-> c (+ 3) (* 2)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: macroexpand-once in this context, compiling:(/private/var/folders/5f/c61l8ll56vs8g146ydfxt8800000gp/T/form-init1108690395689265662.clj:1:1) 

solicode12:02:21

@alexrrr: Something must have changed there. With Clojure 1.5 and below that happens. 1.6+ I get the same result as you.

alexrrr12:02:01

I am using 1.8, that would explain things! thanks @solicode and @ordnungswidrig for taking the time.

solicode12:02:05

The (* (+ c 3) 2) result makes more sense to me as that’s what I would have expected.

solicode12:02:58

If you’re curious why (as was I), this seems to be the change: http://dev.clojure.org/jira/browse/CLJ-1121

alexrrr12:02:04

2013? that is a long time ago

solicode12:02:28

Yeah, 1.5 is fairly old now

solicode12:02:42

I’m also on 1.8 right now

solicode13:02:20

Would be nice to have clojuredocs updated on that

slipset13:02:17

@alexrrr: @ordnungswidrig might have meant macroexpand-1

ordnungswidrig13:02:58

@alexrrr whoops, yes exactly, I'm sorry.

bendy15:02:43

@seancorfield: that's exactly what I was looking for, thanks! I really need to figure out this juxt function, everytime I think I understand it, I find out it can do so much more

seancorfield16:02:54

@bendy: it's one of those functions that once you know about it, you find all sorts of places where it's super useful!

jcomplex17:02:11

hi guys I am trying to insert a timestamp of now into mongo but I am getting a codec error. has anyone tried this?

roberto17:02:37

what error are you getting and can you paste a code snippet?

jcomplex18:02:54

(mongo/update-by-id db coll (ObjectId. id) {$set{:CreatedAt t/now}}))

jcomplex18:02:29

:require [clj-time.core :as t]

jcomplex18:02:06

actual: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.joda.time.DateTime.

solicode18:02:30

@jcomplex: I don’t know what library you’re using, but if it’s Monger, take a look at this: http://clojuremongodb.info/articles/getting_started.html#cljtime_joda_time

jcomplex18:02:16

yes it is monger

echristopherson18:02:43

mongers gonna mong

roberto19:02:37

did that help?

jcomplex20:02:58

yup works thanks

yogidevbear21:02:19

Is anyone here familiar with lighttable? I'm trying to follow along with the lessons at http://iloveponies.github.io/120-hour-epic-sax-marathon/basic-tools.html#editor and I can't find Instarepl in the command bar.

nkraft21:02:35

Have you tried command-enter (mac) and control-enter (others)? That should give you the inline "instarepl".

enyert21:02:46

Go to View -> Plugin manager and verify if you have ClojureInstarepl installed

enyert21:02:16

You can install ClojureInstarepl with Plugin manager too

mikeb22:02:38

@yogidevbear: FYI instarepl was removed in the latest version of lighttable. I believe there has been some mis-understanding on the instarepl as well. You can still do inline evaluation with cmd+enter using the regular clojure repl which is included and it works great. It's just the instarepl was a stand alone repl window that continuously evaluated the entire file while typing and didn't require a project(I might be mistaken). Please see this link for more information https://groups.google.com/forum/#!topic/light-table-discussion/tm-CypjgMMU

josh.freckleton23:02:11

So, I've built a simple SPA using : CLJ, CLJS, reagent/reframe, secretary, schema, cljs-ajax, transit-cljs, and garden, plus a couple dependencies from a CDN in index.html (D3, bootstrap) I've developed with figwheel, and everything's looking good, and i'm ready to deploy to Heroku. But I have nooo idea how on earth to do it (despite reading through ~4-5 articles). I've deployed other apps, but the CLJ/CLJS ecosystem confuses me still. Any help on launching this?

shaun-mahood23:02:21

Cool, that's awesome that you got everything up and running on the dev side

shaun-mahood23:02:27

What did you use on the CLJ side?

josh.freckleton23:02:14

"What did you use on the CLJ side?" - I don't think I used anything but figwheel, I'm not sure I have too much of a backend now, but I will want one eventually simple_smile

shaun-mahood23:02:02

Ok, that's kind of what I meant - you can set things up using different leiningen templates and depending on which you started with there may be a different path to deployment

josh.freckleton23:02:09

(So, I didn't write any .clj code, and that makes me unsure how it's all working, but it does look great at localhost:3449!)

shaun-mahood23:02:20

Ok that's even easier - you've (I think) just created a clojurescript app. Essentially, if you compile it using :optimizations :advanced, it will produce a javascript file that should contain your entire application.

shaun-mahood23:02:16

Then all you need to do is throw your index.html onto a server along with your compiled .js file and whatever stylesheets you are using and your page should be good to go

codefinger23:02:43

@josh.freckleton: for heroku (assuming you'll eventually want a clj backend), you want to put that in an uberjar like the Chestnut template does (see: http://jkutner.github.io/2015/10/14/clojurescript-on-heroku.html)

josh.freckleton23:02:36

does an uberjar contain compiled down .js files, images, css, everything? Or how does that work (if easy to explain, otherwise I'll read the article)

codefinger23:02:38

@josh.freckleton: not sure how hard this would be, but it might be worth the effort to create a new chestnut or luminus template, and then port the cljs you've written into it

codefinger23:02:24

@josh.freckleton: the uberjar will contain the clj server and the :optimizations :advanced compiled cljs (if you do it the way chestnut does)

josh.freckleton23:02:53

@codefinger: I'd thought about that with chestnut/luminus, but they seem to have just a crazy amount of dependencies, stuff I may not use, and it looks like chestnut is built for om, when I had settled on reagent/reframe for this project. (not to mention, wouldn't this make heroku have a prohibitively high boot up time?) Anyways, those are my questions, but would you still recommend I do that? It probably wouldn't be an insane amount of work to port it over into the template, and if you think it best, it seems like a reasonable decision to me too...

codefinger23:02:37

it's probably easier to start with the template and then prune out the stuff you won't use. unless you think you just won't ever need a backend. unsure on that part

codefinger23:02:02

the boot time shouldn't be a problem. most clj/cljs apps start up in ~30/40 sec max

codefinger23:02:28

and I can always increase the timeout for you (i run clojure stuffs at heroku)

shaun-mahood23:02:22

I tend to fall on the other side, I started with chestnut and then moved to bare figwheel and added dependencies as I needed. Both are really valid and it's worth trying them both to see which you prefer.

shaun-mahood23:02:39

I also ended up splitting my projects into 2, so I have a clojurescript project and then a clojure project that is primarily my rest api. So if you want to just get your project hosted without worrying about future backend needs there are 2 really good paths forward.

josh.freckleton23:02:33

This is a gold-mine of help. So a few questions: 1. So then does a cljs-only project return static assets, and any URL just returns the same assets, and routing is handled by something like secretary, client-side? Then user login, and database-requiring stuff is retrieved through a Clojure-only REST API? I like this setup, hm... 2. Since you've run a lot on heroku, could you give any estimate of how well clojure-stuffs handles a user load? Like, how many simultaneous connections, or requests/sec? Tough question, I'm sure, but I'm curious how much I'll get out of a free/hobby dyno before I start to pay the big bucks.

shaun-mahood23:02:38

1 - exactly, that's what I've got going right now

shaun-mahood23:02:04

Have you tried compiling using :optimizations :advanced before?

josh.freckleton23:02:16

:optimizations :advanced - never, I'm scared, but this is the next thing I'm working on simple_smile

codefinger23:02:30

2 - very difficult to say. if all your clj is doing is read/write to a database (i.e. it's IO bound) then the Free/Hobby dyno can go a long way. But if you start needing more CPU or memory, that's where you will probably hit your first ceiling.

codefinger23:02:45

and to clarify, I work at heroku. and i run stuff on heroku too simple_smile

josh.freckleton23:02:25

@codefinger: Right now, my app is db/IO bound, so that's good to hear it's performant in those situations. If you were to give a rough estimate, in an IO bound situation, are we talking 10s of reqs/sec? Or 100; 1,000? I know it's impossible to estimate for me, I'm just curious about your experience simple_smile And thank you so much, this has all helped me whittle down my decisions to something manageable simple_smile

josh.freckleton23:02:27

@shaun-mahood: I'll check this out, and probably do a SPA like you suggested in my question #1. So, if you're hosting on Heroku, how do you serve the static assets? Like, node? or a super simple clojure app? Or on something like this is php good (I saw that recommended on SO, i think it was)...

codefinger23:02:02

i suspect you'll get into the 100s pretty easily, but ... eh so many variables. http-kit, immutant, etc matter a lot. and are you doing blocking io on the db, etc or async.

shaun-mahood23:02:33

What backend are you using right now for your SPA? Or is it front-end only and has no DB connectivity or other server level concerns?