This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-07
Channels
- # bangalore-clj (1)
- # beginners (255)
- # boot (29)
- # cider (16)
- # cljs-dev (13)
- # cljsrn (6)
- # clojure (200)
- # clojure-berlin (1)
- # clojure-dev (13)
- # clojure-dusseldorf (6)
- # clojure-greece (1)
- # clojure-india (1)
- # clojure-italy (1)
- # clojure-russia (33)
- # clojure-spec (28)
- # clojure-uk (27)
- # clojurescript (47)
- # cursive (32)
- # data-science (3)
- # datascript (1)
- # datomic (40)
- # emacs (39)
- # events (4)
- # fulcro (55)
- # graphql (16)
- # immutant (2)
- # luminus (2)
- # lumo (5)
- # off-topic (142)
- # onyx (50)
- # portkey (1)
- # re-frame (45)
- # reagent (80)
- # remote-jobs (2)
- # ring-swagger (3)
- # rum (9)
- # schema (3)
- # shadow-cljs (184)
- # spacemacs (3)
- # test-check (4)
- # unrepl (2)
- # yada (5)
Hey all, I'm trying to build a function that takes a string and returns a vector of characters that occur more than once in the string. I'm using "into []" to turn the string into a vector of characters, then I'm trying to use reduce on that vector.
But reduce only has one accumulator collection. I feel like I need one collection to hold chars I've already seen and another to be the collection that I return. Am I doomed? :(
not at all
(reduce (fn [[unique even-count] num]
[(conj unique num)
(if (even? num)
(inc even-count)
even-count)])
[#{} 0]
(range 10))
here’s an example that keeps track of all the unique numbers
and also counts the number of even numbers seen
which isn’t really useful, but is similar to your example
the accumulation doesn’t have to a collection
it can be anything
If you’re not intent on doing it in one pass, you could do one pass to build the frequencies and another to build the results
@donaldball’s suggestion is probably a better way to do it if you’re reducing to two quantities that have nothing do with eachother
as in my example
but you can use a similar approach to my example if you had to keep track of two quantities that do depend on eachother
Ah thanks @smith.adriane well the accumulation is a vector isn't it? 😛 but I guess it can be a collection of other collections? Is that a huge way to do it. Is it as they say idiomatic clojure?
yea, can be a map, number, string, vector, etc
(reduce + 0 (range 10))
i’m actually not sure if using a collection of collections would be considered idiomatic
maybe someone else could weigh in
here’s an example of the same pattern in core async, https://github.com/clojure/core.async/blob/f8e87e1625b1660b7f3b0aea044aad1327441741/src/main/clojure/cljs/core/async/macros.clj#L25
Clojure is my first programming language. everyone says to pick up Clojure for the Brave and True but to be honest i'm not having a good run of it.
what would Clojurists/Clojurians recommend as an alternative?
i've even thought about abandoning the pursuit for Racket but as an art-student i'm really into Clojure as a tool for abstract programmatic art (Quil).
also not sure if abandoning my first language is the correct move so early on.
Hey friend, what are you interested in doing with Clojure? Or programming in general
at this juncture: maybe a static site art-text in the vein of what Pollen allows and abstract art with Quil.
Examples?
specific examples: something like https://practicaltypography.com/ and http://nils-blum-oeste.net/generative-art-with-clojure-via-quil-and-processing/
Nice. What made you choose clojure?
i use Emacs every day and came across this quote you're probably familiar with that learning a Lisp was an "enlightenment experience". i'm heavily invested in meditation so that tickled me.
Emacs is in fact my entire desktop environment. 🙂
You've configured emacs, yes? So you are familiar with emacs lisp?
i started with Spacemacs but recently tore off the training wheels and set up my own config with evil-bindings and all of the Ivy/Counsel packages. i'd say familiar insofar as i can tell use-package what to install and set variables with (setq)
i still have trouble. my mind is not "in the vein" of a classic programmer's i think.
i write screenplays and spend a lot of time thinking about film mostly. 🙂
That should not be a problem. These insights will likely make you a stronger developer.
oh that's comforting to hear!
right now it feels like i'm struggling to grok even the most basic things and that really hurts my confidence
As for learning clj/s, I have been on the same journey myself. A good starting point is these forums. Perhaps something like https://github.com/ClojureBridge/curriculum will be helpful
what sort of background did you come from?
have you heard of http://sarabander.github.io/sicp/ ? there is also a corresponding lecture series: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/
Some books I also found useful https://funcool.github.io/clojurescript-unraveled/
and Quick Clojure
Agree with sundarj - that series is excellent
@U61HA86AG oh yes! in fact SICP was the first thing i tried to work through but it's intensely math-oriented.
when i hit the third exercise, i spent hours on it and had to bail, it was so frustrating.
http://www.catb.org/~esr/faqs/hacker-howto.html this is the document that got me into programming, maybe you'll find it helpful
@U61HA86AG thanks for the compassion. it is this dense sheet of murk right now. i'll check out your link.
i've heard good things about http://landoflisp.com/ and https://mitpress.mit.edu/books/little-schemer too (plan to read them eventually)
@U61HA86AG the author of Brave actually mentioned Land of Lisp was his first intro to lisps in general on Cognicast.
programming is more about the way you think than the language you happen to use, so don't sweat it if it doesn't come to you at first
you may also find the courses on http://purelyfunctional.tv helpful: https://purelyfunctional.tv/courses/introduction-to-clojure-v2/
Yes, Eric is boss
@U61HA86AG this looks interesting.
ah they're video casts.
even better
don't forget to play, experiment, explore - have fun with it! don't worry about the end goal for now, just do things, see what happens 🙂
think about how you learnt screenwriting, it's going to be a similar process with programming (and they're both just forms of writing language, to boot)
ah yes, this is a great, approachable series of blog posts: https://aphyr.com/tags/Clojure-from-the-ground-up
also, welcome to programming! it's fun once you get the hang of it, i promise. don't be afraid to ask any questions you might (will!) have here in #beginners
@U61HA86AG thank you so much! i have a forest of links to sort and prioritize now. 🙂
also https://clojurecademy.com/ http://riemann.io/clojure.html https://day8.github.io/re-playground/
Clojure for the Brave and True was/is pretty tough for me too. The code examples weren't the way that I would have thought to do it so it thew me for a loop on the end-of-chapter project things. So if that's your problem with it I wouldn't worry too much. It ended up clicking for me without even realizing it until I actually had to use it on something of my own.
Hello, I need help! I really appreciate your time an help. Problem: I want to format the response of a get request. Currently, I am able to return a generic JSON response from a RESTAPI ( http://localhost:3000/users ) and return all the JSON data returned from my Query (Select * from Users). However, This is not what I want. Instead, I would like to query the data from my database and then transform and format the data. I would like the data to be return in an object that looks like this {data: [ {name: "mike", last: "call" } ] }. Question. how do I manipulate and format the response of my query (Select * from users)? for example, how can I run my query and then format the response with ( :row-fn (fn [row] {:row (row :first-name)}) ) and then push the response to the frontend with a Json format or just a useable format for the frontend. what middleware, libraries, or response information am I missing? I feel that I have tried everything. Please check out my code and see the libraries and code structure I have. It should be super simple. Please follow the flow in my snippet. and check out the github repository (https://github.com/mcall25/shouter) to understand the flow of the code.
@smith.adriane @derpocious It is idiomatic to use a vector of collections in reduce (I'm not really an authority on the subject, but it is widely used, personally I consider it clearer than the alternatives, and it's apparently really fast)
good to know!
is there a function like group-by
that returns a 2-tuple for a boolean test function?
#(reduce (fn [[t f] e] (if (% e) [(conj t e) f] [t (conj f e)]) [[] []] %2)
might be worth making it into a transduce with transients actuall
it wouldn't necessarily preserve order, if that's what you mean (then again, maybe it will... hmm)
it is not guaranteed to preserve order between clojure versions
i checked- it's consistent in clojurescript and clojure for booleans, but that's blind luck 🙂
yeah, it's fine for my purposes, i was just wondering if there was a builtin i'd missed
oh, actually another noob question, can I put a native javascript object in a map as a key?
i'm thinking in particular, things like DOM elements, keyed on identity but it's a bit scary
+user=> (load-file "/tmp/foo.clj")
#'user/t-f
+user=> (t-f even? (range 10))
[[0 2 4 6 8] [1 3 5 7 9]]
(defn t-f
[pred? coll]
(transduce identity
(fn
([] [(transient []) (transient [])])
([[t f]] [(persistent! t) (persistent! f)])
([[t f] e]
(if (pred? e)
[(conj! t e) f]
[t (conj! f e)])))
coll))
about core.async, all go blocks share the same pool size?
example
(go …..)
(thread (go ….))
even if I do that, they still share the same pool size and the same concurrency (thread)? or the first is in main thread and the second is in a second thread?
that thread call is just a waste of a thread
thread is for when you want a blocking operation to return a channel
all go blocks use the same small thread pool, the reason to use thread is so that you don't block one of those small number of go threads
because otherwise you can block up all the go blocks in the whole program easily
but its kind of that, rmq consumers (thread (consumer/start)) inside of that i will use go for on-mesasge
OK - sure - but if all you are doing is putting a message on a chan, use (put! c msg) instead of (go (>! c msg))
or, better yet, just return msg, and then let the one who started the thread read it from the chan thread returns
none of this applies if it's more than just putting a message on a channel of course
you are saying instead of
(fn [ch {:keys [message-id delivery-tag reply-to]} ^bytes payload]
(>!! chan {:ack #(rmq/ack rmq-state ch delivery-tag)
:company (protobuf/<-bytes CompanyProto$Company payload)
:message-id message-id
:reply-to reply-to}))
i do
(fn [ch {:keys [message-id delivery-tag reply-to]} ^bytes payload]
(put! chan {:ack #(rmq/ack rmq-state ch delivery-tag)
:company (protobuf/<-bytes CompanyProto$Company payload)
:message-id message-id
:reply-to reply-to}))
For external communication I will use rabbitmq, but for internal I will use core.async
right, and if that fn is being called directly in a thread call, you can just use more like:
(let [result (<! (thread (ack-fn m payload)))] ...)
inside a go blockand inside the fn, you just return the map, instead of putting it on a channel
my on message is like this
(defn- on-message [rmq-state mongo-state chan service]
(go-loop [message (<! chan)]
(let [[errors ok] (valid? (:company message) true)]
(if (true? ok)
(save mongo-state (:coll service) (:company message))
(send-error rmq-state (:message-id message) (:reply-to message) 400 errors))
((:ack message)))
(recur (<! chan))))
oh, so that fn is being invoked multiple times and keeps returning messages to that chan
So… doesn’t matter where I put go-blocks (if its inside a (thread) call), they will always share the same pool size and thread
@rcustodio also, another issue entirely, never do a go-loop like that without checking the return value of <!
it's valid to close chan, and if that happens, your current loop goes very very fast
(doing nothing useful)
you can change (recur (<! chan))
into (some-> (<! chan) (recur))
and it fixes that issue
I don’t know what you mean… closing the chan mean that I would have to stop this consumer, right?
closing a chan means that every time someone reads from it, they instantly get nil
since you are not checking the return value from reading the chan, you'll get nils as fast as you ask for them
probably you'll get an NPE on ((:ack message))
of course, so this one would blow up instead of hot looping
but in general, check <! for nil
also check >! for nil btw
i see, do you mean here i would get nil very fast
(>!! chan {:ack #(rmq/ack rmq-state ch delivery-tag)
if chan was closed, yes
that some-> change would stop that and checking the message value would stop that??
(some-> x (f)) means (f x) if x isn't nil, or nil (without calling f) if it is
it's like -> with nil checks at each step
not without some->
as written, it gets a nil, and justgoes with that - if nil breaks something, it blows up and stops for that reason
in some cases that can mean it loops fast on nil
So would be like this
(defn- on-message [rmq-state mongo-state chan service]
(go-loop [message (<! chan)]
(let [doc (mongo/find-one-as-map mongo-state
(:coll service)
{:_id (:_id message)})]
(rmq/publish rmq-state
nil
“”
(.toByteArray (protobuf/<- CompanyProto$Company doc))
{:content-type “application/octet-stream”
:headers (merge (into {} (:headers message)) {“out” (:reply-to message)})
:message-id (:message-id message)})
((:ack message)))
(some-> (<! chan) (recur))))
yeah, that's safer
isnt the first loop message (<! chan)
safer as well if i do message (some (<! chan))
well no because that way message is still nil if chan is closed
but if you compare, getting a nil once and getting an error because it's nil, vs. repeatedly processing nil until you get an error
(when-some [msg (<!! chan)] (go-loop [message msg] ...))
might be safer?
but also consider that the channel is less likely to close right as you start this loop
I will let <! chan
Since I’m using put! chan
, what is the diff from <!
and also take!
put! is async, and always returns immediately, unlike <! which parks, and take! which is async but also allows a callback
really you can pair them up, >! / <!, >>! / <<!, put! / take!
take! doesn't use go or go-loop
it's like put! in that it doesn't use that stuff at all
(defn on-message [state1 state2 chan] (take! chan (fn [message] process)) (recur state1 state2 chan))
like this?
well - the recur will go out of control
since take! doesn't block
it takes one message, and does nothing
perhaps you would want (take! chan (fn [m] (process m)))
- which will consume one value and process it
right
of course that last one is just (take! chan process)
right, that is why we have go blocks
Thanks @noisesmith, that helped a lot
I plan to try to make an react native app and I will use re-natal, so I have 3 choices for react wrappers: reagent, om.next or rum. Which do you guys recommend?
I'm a beginner, but I had a bit of fun with rum and figwheel. The bonus from my perspective is rum is extremely small and simple, so you can at least decide if it is not enough quickly. The #rum slack channel is rather quiet though :(
I'm a fan of reagent, and you've got re-frame on top of it to simplify things further, if your app fits well into a functional-reactive approach.
reagent itself is also pretty simple (although not AS simple as rum). It's got one core concept that you need to fully absorb, the ratom.
I think it might be a good idea to start with rum and if it's not enough I'll move to reagent. My app will (probably) be simple so I hope it'll be enough. Thank you for your input!
Before I spend much more time on this, I am trying to create a macro that when called does this:
(.-style element )
This is what I have:
(defmacro get-attr
[el attr]
`(let [element# ~el
attribute# ~attr]
(attribute# element# )))
which would be called like this:
(get-attr highlight '.-style)
I am putting the syntax-quote infront of .-style
so it does not try to evaluate the symbol. Any pointers would be appreciated. Again, this is only out of interest, not because this is a solution to a real world project(defmacro get-attr
[el attr]
(list '-> el attr))
(defmacro get-attr
[el attr]
`(-> ~el ~attr))
that’s two different ways to write it
used like (get-attr highlight .-style)
oh, you changed example of what you wanted
no, thats pretty much it
one way to check see how your macro is coming along is to using macroexpand-1
I thought the reorder would make it clearer
so for the macro you started with
> (macroexpand-1 '(get-attr highlight .-style))
(clojure.core/let [element__30398__auto__ highlight
attribute__30399__auto__ .-style]
(attribute__30399__auto__ element__30398__auto__))
Just to understand this better, does clojure think, because .-
is a special form, that when I do this
(let [local-bind .-style])
That I am trying to access an instance method? vs doing this:
(let [local-bind "string"])
Which is just a simple data type, which evaluates to itself, being bound to local-bind
..-style
is just a symbol
so in the first case, it’s going to try to look up the value of .-style
since that’s how symbols are evaluated
(.-style obj)
is the full special form
the symbol by itself isn’t a special form
hmmm, is there a way to bind .-style
like I was trying to do? so it could be passed around as a variable?
I am hoping that seeing a distinction will make this clearer
anyway, with macros, the big idea is that you’re writing code that writes code
so if you want (.-style obj)
you’re creating a list where the first item is the symbol .-style
and the second item is the symbol obj
(list '.-style 'obj)
would be one way to do that
with a macro you’re getting passed the arguments as data
i’m not sure i’m making any sense
macros are kinda tricky at first
It is. I see that part. I think they become tricky because, for myself, I am still figuring out the mechanics of clojure itself. e.g. If you did this:
(def name .-style)
The above fails. I am not sure why that fails though...Understanding the above, explains why my code fails, I believe
the evaluator is trying to lookup the value of .-style
Ah! I get it now
.-style
only makes sense in the context of (.-style obj)
its a symbol which is trying to evaluate to something that is not there
Symbols reference something else - like a var. In this case, there is nothing that it references.
even (-> obj .-style)
is expanded into (.-style obj)
Why is the error message Uncaught SyntaxError: Unexpected token .
?
is the .
evalutated separate?
the .
is a special form too
used for interop in both cljs and clj
haha in that case its because there are no spaces, which made me think the whole thing is evaluate together
so if you a macro get-attr
that is used like (get-attr obj .-style)
, then it will be passed in two arguments. the two arguments will be symbols with the above usage
To go back to the original question, is it possible to assign .-instanceField
to a var? What would that look like? My thought is no because it would just expand to (. your-var -instancefield)
and fail
it doesn’t really make sense to assign .-instance
field to a variable
true. more of a "how would you do it in clojure?" kind of thinking
you can assign the symbol to a var
like you could do
(let [prop-sym (quote .-instanceField)]
prop-sym)
which is equalivalent to
(let [prop-sym '.-instanceField
obj-sym 'obj]
(list prop-sym obj-sym))
you could also write it like
(let [prop-sym (symbol ".-instanceField")
obj-sym (symbol "obj")]
(list prop-sym obj-sym))
which might look more familiar
Nice, so altogether:
(defmacro get-attr [i e]
(let [prop-sym i
obj-sym e]
(list prop-sym obj-sym)))
(get-attr .-style element)
exactly
Thanks! A huge step forward for me 🙂
it’s really fun to play with macros
and once you play with them a bit, it helps you understand macros that you might end up using better
like if you ever use core async, the gotchas aren’t as bad because you develop a mental model of what’s going on under the hood
For sure and at a minimum it forces you to understand clojure way better
I promise this is the last question, how can I see what this expands to (def hello .-style)
if this happens:
(.-instanceField instance) ==> (. instance -instanceField)
would the above expand to (. def hello -style)
?
the special dot syntax has to match a whole list form
so it won’t get expanded
> (macroexpand-1 '(def hello .-style))
(def hello .-style)
so it only matches if the evaluator gets a list where the first item is a symbol and the symbol starts with .
or .-
and the list has to have at least 2 elements
for (def hello .-style)
it’s a list with 3 items
the symbol def
, the symbol hello
, and the symbol .-style
since def
doesn’t start with “.-“, then it doesn’t match
ah, so its trying to evaluate that item but looks at it and just breaks because it sees .-
on a third item
I don’t have a clojurescript repl handy
but in clojure you get CompilerException java.lang.RuntimeException: Unable to resolve symbol: .-style in this context, compiling:(*cider-repl websheet*:508:24)
basically, it just sees a symbol
and the evaluation rule for symbols is to try to look up its value
I guess I’m not using the precise terminology. the evaluation rule for symbols is that they are “resolved”
this actually works in clojure
> (do
(def .-style 1)
(+ 1 .-style))
2
although I really, really don’t recommend it
hahaha that's scary
you can see it’s trying to bind the attribute__30399__auto__
from .-style
which isn’t exactly what you want
a more fun example is trying to create a macro that works like (get-attr window.location.host)
into (-> window .-location .-host)
Good stuff. I will read into this a little more. Thanks! Would a macro be the only way to do the above? I know I asked this yesterday, but I am a little thrown that it would not work.
for this particular type of syntactic sugar, I would use the goog.object/get
function
(goog.object/get highlight "style")
Yes, and than you could just wrap the above in a function if really desired. Good call
yea, I think the adage is “Don’t write a macro if a function will do”