This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-23
Channels
- # beginners (55)
- # boot (37)
- # braid-chat (1)
- # chestnut (3)
- # cider (4)
- # clara (22)
- # cljs-dev (54)
- # cljsrn (3)
- # clojure (114)
- # clojure-italy (12)
- # clojure-losangeles (3)
- # clojure-portugal (1)
- # clojure-russia (1)
- # clojure-spec (30)
- # clojure-uk (67)
- # clojure-ukraine (1)
- # clojurescript (101)
- # core-async (11)
- # cursive (6)
- # data-science (27)
- # datomic (8)
- # figwheel (3)
- # fulcro (59)
- # graphql (2)
- # hoplon (89)
- # jobs (3)
- # jobs-rus (1)
- # leiningen (3)
- # lumo (19)
- # off-topic (9)
- # om (48)
- # pedestal (2)
- # portkey (4)
- # protorepl (19)
- # re-frame (13)
- # reagent (38)
- # remote-jobs (1)
- # ring-swagger (4)
- # spacemacs (10)
- # specter (2)
I have a a JS array of objects that looks like this
const years = [
{ year: 1879 },
{ year: 1643 },
{ year: 1564 },
{ year: 1500 },
];
I am trying to filter values between 1500 and 1600 which I have written like this:
(filter #(<= 1500 (:year %) 1600) js/years)
The above always returns an empty list.
I should note that the js is defined in <script>
tags within an html
file - just to make practising easier š so the js/years
does contain the expected data structure.
I believe my syntax is correct because if I change the object from a JS array of objects, to a clojure list of maps it works as is. Any pointers?@tkjone the error is in (:year %)
, which doesnāt work on js objects
you can either convert the object to clojure with js->clj
, then the filter will work
or you can stay in js and use (aget % "year")
Thanks, shaunlebron - that makes sense. Curious, when developing cljs and doing something like this, is it best practice to stay in js land or convert?
@tkjone if I care about performance or if Iām trying produce js objects, then iāll stay in js
js->clj
can be slow
but obviously, code is going to look more idiomatic when dealing with clojure data
there are still first-class facilities for dealing with js data as is, but itās not going to look or feel as good
I feel this is by design so you always know what youāre dealing with
honestly, if Iām doing heavy JS processing, Iāll just write it in JS if it gets hairy, no point fighting that
Yeah, that makes sense. Cheers!
@tkjone if you want more depth, the question of using keyword lookups on JS objects came up in this twitter thread: https://twitter.com/mfikes/status/882585745424338944
(second comment in the twitter thread)
that might raise more questions than answers, but we are here in slack for more depth when you want it!
would it be correct to say, based on that tweet, that while (aget % "year")
is fine, another option is (goog.object/get % "year")
?
I probably messed up the syntax, but I can research that a little.
aget
is legacy but works well, gobject/get
is recommended, and oget
is my personal recommendation from https://github.com/binaryage/cljs-oops
why the preference on the third-party library?
@tkjone i find gobject
less friendly in this case
oget/oset are easy to remember and they are multiple arity, not true for gobject
it also supports things like ocall so you never have to worry about externs
@shaunlebron @tkjone aget
only works accidentally and might not work in future clojure versions
@noisesmith Woa, what are we talking about? Clojurescript? And do you mean aget for objects only? Why wouldn't it just get fixed to work again for arrays if it gets broken in future versions?
I meant on objects - aget is only meant for arrays, and the question was about looking up keys in js objects
it happens that aget accidentally allowed lookup in objects in cljs, so it became a relatively common thing, but it could break at any time
Is there a good talk about clojure programmers workflow? I started working thru braveclojure literally yesterday and I think the part I'm both most intrigued by, and least knowledgeable about is how to actually "do" dynamic programming.
I assume you donāt actually mean dynamic programming - do you mean programming without static types? https://en.wikipedia.org/wiki/Dynamic_programming
I'm unsure about my terminology here, but I mean the act of programming without static (and explicit) types.
right, OK - just double checking but thatās what I thought.
the real key, if you arenāt doing so already, is to spend a lot of your time using the REPL
Yeah, I've gotten as far as writing stuff in a file and sending it to the REPL for evaluation
this can include using an atom while developing to capture data that you get in a certain context, in order to experiment with it in a repl
yeah, Iām not talking about using a file
@emilaasa Have you watched Stu's talk on the REPL?
for example, this is a pretty great pattern:
=> (-> foo type)
...
=> (-> foo keys)
...
=> (-> foo :bar type)
where at each step you up-arrow and add something new to find out more about the data in question@seancorfield It got me pretty excited! But I feel like I would like to see some actual screencast workflows to understand better how it's done
https://www.youtube.com/watch?v=VVd4ow-ZcX0 and https://www.youtube.com/channel/UC6yONKYeoE2P3bsahDtsimg/videos are pretty good imo
@noisesmith It's pretty much what I'm doing now, except I'm not typing into the REPL but to a file and sending the expression to the REPL after each stumbling step I take
If I didn't spend most of my time working on proprietary code I can't share, I'd probably livecast a lot more...
I've found watching some screencasts can help a tremendous amount with things like workflow, problem solving and similar subjects
I remember being asked to solve a problem in an interview using DP... I was free to choose my language so naturally I just (memoize (solve-sub-problem))
in clojure š¬
Iād expect this to output 1, not 0. why is this?
user> (let [c (atom 0)]
(for [el [1 2 3 4]]
(if (= el 3) (swap! c inc)))
@c)
0
my for
loop itself seems to be working:
user> (let [c (atom 0)]
(for [el [1 2 3 4]]
(if (= el 3) "three")))
(nil nil "three" nil)
but i canāt seem to do anything in the then
clause of the if
statement if i dereference c
after the for
expression:
user> (let [c (atom 0)]
(do
(for [el [1 2 3 3 4]]
(if (= el 3) (print "swap! was called")))
@c))
0
for
is lazy so it doesn't get evaluated here.
Since you only want side-effects, you should use doseq
instead of for
(`for` produces a lazy sequence of results and only realizes as much of it as the consuming code requests; doseq
eagerly processes all elements and just returns nil
)
for
trips up a lot of people new to Clojure because they think it's like a for-loop in non-functional languages.
fixed. yeah. i guess i intuitively thought āmap is for lazy and for is for strict.ā thanks again.
yeah, I kind of wish āforā had a different name, because it isnāt a loop, itās a list generator