This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-07-15
Channels
- # admin-announcements (2)
- # beginners (93)
- # boot (34)
- # capetown (1)
- # cider (15)
- # cljs-dev (30)
- # cljsjs (9)
- # clojars (8)
- # clojure (199)
- # clojure-austin (3)
- # clojure-france (3)
- # clojure-greece (2)
- # clojure-italy (46)
- # clojure-quebec (7)
- # clojure-russia (2)
- # clojure-spec (76)
- # clojure-uk (16)
- # clojurescript (43)
- # core-async (7)
- # cursive (14)
- # data-science (1)
- # datascript (4)
- # datomic (3)
- # devcards (60)
- # editors (5)
- # funcool (5)
- # garden (3)
- # hoplon (32)
- # immutant (22)
- # jobs (1)
- # lein-figwheel (21)
- # leiningen (1)
- # mental-health (11)
- # mount (2)
- # off-topic (6)
- # om (16)
- # onyx (15)
- # re-frame (43)
- # reagent (20)
- # rum (18)
- # specter (37)
- # sql (2)
- # testing (8)
- # untangled (7)
- # yada (19)
if anyone could point me to a good resource for js interop i would be grateful as well
how would you go from [{:m 1} {:m 2}]
to [1 2]
and at meta level is there a better way to figure this out then ask in #C053AK3F9 ?
also how light weight is specter? does it make sense to pull it in for small tasks like that or only when you feel the pain?
You have a sequence of two things and you want a sequence of two things as a result — and the way to get from each thing to each result is the same "transformation" — so this would be some application of map
.
(if you specifically wanted a vector as a result, use mapv
)
Does that help with the meta question?
yea, im not sure why i didnt think i couldnt do it with map
For something lightweight like that problem, I’d rely on built-in (core) functions.
{:m N}
-> N
is the "function" :m
(realizing keywords can be used as functions is a "lightbulb" for a lot of beginners)
yep! I think its also i sign that i need to get to sleep sense i did that 30 minutes ago for something else 😕
Internalizing how to identify common low-level tasks and work with sequences / collections and the (vast array) of core functions just takes time and practice… Even after five years of production Clojure, I’m still "discovering" new core functions and reading and re-reading a lot of the basic stuff about abstractions and so on.
I wonder if their are non clojure specific ways to train
visual ques
* => & & & map!
sort of strip out the words and parens and just leave the transformations as a visual
maybe that breaks down at some point...
I need to create a bunch of dates of type #inst because I want to insert them in Datomic. I concocted this way but there must be a better way!
(require '[clj-time.coerce :as c])
(defn random-instant [limit]
(c/to-date (c/from-long (long (rand-int limit)))))
Sounds like a job for generators in clojure.spec
🙂
would it make sense for API calls to end with a !
for either query based or an operation that causes an effect on the API end?
frame of mind from ruby it seems that functions ending with !
would imply some kind of state being mutated outside the context of the function
Personally (and I haven't written that much clojure, but I've written a fair bit of Scheme, which has similar conventions) I wouldn't use bang for that.
On some level you program is going to cause side effects in the outside world (unless you're running it to heat up your room a bit in the winter)
That's something you should be very careful about, actually, so bang seems like too much and too little at the same time.
the problem as well is that there is some heavy rate limiting going on, so the code will sleep on a thread to not hit those limits
also if you're going to do something like send a tweet, you kinda have sent a mutation outside your system, and it wouldn't let you call it again
i'm not really sure if that is considered unsafe in STM since i don't fully understand it right now
@naomarik: it is a very tough one to choose, generally I don't mind having !
in functions as general warning that...something is going on within it and I should check the docstring or the source to understand what it is. So in this case I would put it. In this SO thread it cites IO as well https://stackoverflow.com/questions/20606249/when-to-use-exclamation-mark-in-clojure-or-lisp
at the end of the day it is just a convention so you can make your own I guess
the STM bit of it is there because STM code is retried over and over until it succeeds (ok not quite, but bear with me)
so a function like the above, which would do IO (maybe keeping counters) and even block threads, would be considered unsafe in STM
all this, IMHO of course
@pcbalodi: i would have thought so too, but the clojure style guide is pretty specific about the STM
which is something i don't understand myself so i have no clue how to create a mental model of when to use it
@naomarik: The STM reference is along these lines: consider an expression that looks like it calls a function once but behind the scenes it might actually call that function two or three times. Would you be able to detect how many times it called that function? If so, the function should have !
to indicate it is "multi-call unsafe" in some way...
That said, there’s a balance to be struck between sticking !
on everything that might yield a different result on each call vs just those that modify the system in a "destructive" manner.
It’s why, for example, java.jdbc
has query
(no !
) but insert!
and update!
(and execute!
).
Technically, query
could return different data in subsequent calls, and you don’t really want an STM function to call a DB-accessing function repeatedly, but semantically that choice makes more sense.
(so, whilst the style guide is pretty specific about STM, there’s still quite a grey area there)
In case anyone is looking for a good book to help with learning Clojure past the basics, Clojure Applied is on sale right now and is a fantastic resource IMO. https://twitter.com/ClojureApplied/status/754021391565852673
@seancorfield: that's very useful thanks! what would you think about a function that has an effect outside the system (like replying to a user via an API), if all it does is simply one call and we don't care about the result?
@naomarik: What happens if it is called more than once (with the same arguments)?
That would be my determining question.
If it’s idempotent — calling it repeatedly with the same arguments has no additional effects after the first such call — then I would say it’s "harmless" to do so and therefore it wouldn’t need !
. But in general calling "destructive" APIs that change the world sounds like something that wouldn’t be idempotent and would therefore deserve a !
.
Yes, with Om and Reagent, but it was a long time ago… What’s your question?
Best I can point you at, based on my experience, is this: https://github.com/seancorfield/om-sente @krchia
I thought I had the rewritten Reagent version up on GitHub as well but apparently not.
i get "#object[TypeError TypeError: Cannot read property 'ctrlKey' of null]" from (.. js/d3.event -ctrlKey)
That example uses bare D3 in one example and NVD3 in another example, so take a look at the code and see if that helps you.
you want (.. js/d3 -event -ctrlKey)
edited to show .event
as field access followed by .ctrlKey
as field access
i think both versions are equivalent, but i digress. i get the same error from your line of code as well
Perhaps you can put your code in a Gist or on http://refheap.com and share the link here? Sounds like we need to see more of your code to be able to help you.
The error indicates that d3.event
is null
...
doing a human js->cljs translation of http://bl.ocks.org/rkirsling/5001347
I would assume d3.event
is only going to have a value while you are processing an actual (keyboard?) event and so it will be nil
otherwise?
All the cljs code I’ve seen that tries to reference (.. js/d3 -event …)
only does so inside event handlers...
the js code i’m trying to translate to cljs is here http://bl.ocks.org/rkirsling/5001347
maybe i should just chuck it in my code and see what happens later on, instead of trying to verify that it’s a valid cljs expression in the REPL
And in that JS code the reference to d3.event
is inside an event handler .on("mousedown", function(d) { if (d3.event.ctrlKey) return; …} )
Your REPL experiment verified that it is a field (not a function) and it has a null value:
cljs.user> (.-event js/d3)
nil
cljs.user> (.event js/d3)
#object[TypeError TypeError: d3.event is not a function]
So you should not expect to be able to do (.. js/d3 -event -ctrlKey)
(i.e., not at the REPL top-level)
Working with raw D3 in cljs is pretty painful. So much interop.
That’s why I looked at NVD3 instead — dramatically reduced the amount of low-level boilerplate.
just curious, because im translating js to cljs line by line to gain some proficiency in js interop
The usual wins of immutability etc.
Translating JS to cljs is going to seem very painful, and probably produce much more bloated code.
Comparing an app built with cljs / Reagent to one built in JS / React is where you’ll see the big wins.
i’m going to try and be stubborn with this for awhile, and try another approach if nothing’s sticking
Well, if you can subdue D3, that’s probably the worst interop mess you’ll have to deal with… so the rest should be a piece of cake! 🙂