This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-02-06
Channels
- # aleph (2)
- # aws (3)
- # bangalore-clj (3)
- # beginners (119)
- # boot (263)
- # cider (13)
- # cljs-dev (16)
- # clojars (2)
- # clojure (114)
- # clojure-austin (1)
- # clojure-chicago (1)
- # clojure-finland (1)
- # clojure-france (24)
- # clojure-italy (6)
- # clojure-russia (28)
- # clojure-serbia (7)
- # clojure-spain (1)
- # clojure-spec (89)
- # clojure-uk (139)
- # clojurescript (216)
- # community-development (3)
- # core-async (135)
- # css (2)
- # cursive (31)
- # datomic (44)
- # emacs (15)
- # hoplon (2)
- # jobs (3)
- # lein-figwheel (14)
- # leiningen (2)
- # lumo (21)
- # off-topic (16)
- # om (7)
- # om-next (1)
- # onyx (53)
- # perun (9)
- # planck (15)
- # portland-or (29)
- # protorepl (2)
- # re-frame (32)
- # reagent (8)
- # ring-swagger (22)
- # rum (51)
- # spacemacs (4)
- # untangled (2)
Is there a cycle-like function where I can hand it a collection of, say, keywords, and returns a function that each time I call it, returns the next item in the collection, cycling back to the start when it reaches the end of my collection?
So, cycle DOES give me the sequence, but i cannot retrieve a single value from that, that will alternate with each call
Whereas I want to be able to do something more like
(def cycle-sequence (cycle [:a :b]))
(take 1 cycle-sequence)
=> :a
(take 1 cycle-sequence)
=> 😛
it might be easier for me to help with a little more context on what you're trying to do
Oh, I was just mucking around with core.async and UI - trying to make a toggle component - instead of merging 2 channels that produced :open and :close messages, I could have a single channel that alternated between the two messages
(ultimately passing this fn to map to create a transducer for the chan to always spit out either of these 2 messages)
something like this?
(defn toggle-chan []
(let [ch (async/chan)
coll (cycle [:open :close])]
(async/onto-chan ch coll)
ch))
user=> (async/take! (async/into [] (async/take 5 (toggle-chan))) println)
nil
[:open :close :open :close :open]
I wonder if that lets me do something like
(def c (toggle-chan))
(<! c)
open
(<! c)
close
I use spec and I use this to say there is a problem.
(throw (Exception. "Something wrong with the detail-page"))
Using this `(defn cycle-chan [coll] (let [c (chan) idx 0] (go (loop [token (nth coll idx)] (>! c token) (recur (nth coll (mod (inc idx) (count coll)))))) c))`
when i consume the values they should be the sequence :a :b :a :b …
but it’s actually :a :b :b :b :b …
any idea?
I have found out that a key can be a collection or a string. Can this spec then work
(s/def ::principalMaker (s/or (s/coll-of (s/keys :req-un [::name] ):min-count 1 :max-count 1)) string?)
(require '[clojure.core.async :as a :refer [<! <!! >! >!! chan onto-chan go go-loop]])
(def c (chan))
(onto-chan c (cycle [:a :b]))
(<!! c)
(<!! c)
(<!! c)
and how do I change this to reflect this :
(let [name (-> art-object
:principalMaker
first
:name
Before I knew about onto-chan
, I had a version that used a go-loop
with cycle
. I deleted the message, but the code is sitll in the slack sidebar under Files.
Yeah, I thought It could just use something like (take 1 (cycle [:a :b]))
but that always gives me :a
Do you understand why cycle works as intended in your example and not mine? What am i not understanding?
Yes, I do. The go-loop starts with (cycle [:a :b])
and on the next iteration, it recurs with (next (cycle [:a :b]))
so each iteration moves 1 step through the cycle.
When you guys started talking about core.async, I thought you guys figured it out, so I deleted my message.
(go-loop [s (cycle [:a :b])] ; initial value (cycle [:a :b])
(>! c (take 1 s))
(recur (next s))) ; next value (next (cycle [:a :b]))
It looks as though the onto-chan solution works more idiomatically because you’re passing the cycle to the function, not messing about with take
like I did
Yeah, I should have realised that cycle
returns a collection, which will have implemented the ISeqable protocol meaning I can call next
to get through it which is what onto-chan
does
@bones Here's another way to do it using atoms.
(defn iterator-fn
""
[series]
(let [s (atom series)]
(fn []
(let [v (take 1 @s)]
(swap! s next)
(first v)))))
Usage:
(def i (iterator-fn (cycle [:a :b])))
(i)
(i)
(i)
Languages like Perl, Ruby, JavaScript, etc that have closures and use mutation would take this kind of approach.
@bones but realize that most of these functions are introducing impure semantics. i.e. if you call a function with the same args twice and it returns different values, you have an impure function.
So I would consider restructuring your code in such a way that you can do something like (next (cycle [:a :b])) and walk the seq as needed. Functional impurity isn't "wrong" per-se but there's often a better way.
but when I do that I see this message :
CompilerException java.lang.RuntimeException: Unable to resolve symbol: javadoc in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init3193066558729895878.clj:1:5)
`@roelof (require '[clojure.java.javadoc :refer [javadoc])
@val_waeselynck thanks , there is a typo but I got it working
many people use clojure.java.jdbc
directly, but there are some DSLs listed here: https://github.com/clojure/java.jdbc
I recommend adding some kind of polymorphism to your external data access functions, i.e. using a multimethod or a protocol. this makes it easier to stub out the DB for testing
here's some code that shows how a production clojure app would use a database: https://github.com/capitalone/cqrs-manager-for-distributed-reactive-services/blob/master/src/com/capitalone/commander/database.clj
I have an ordered sequence where, for each element n
, I want to check it against elements n-1
and n+1
. Is there an idiomatic way to do this in Clojure?
cljs.user=> (def s (iterate inc 0))
#'cljs.user/s
cljs.user=> (take 5 (map #(vector %1 %2 %3) s (drop 1 s) (drop 2 s)))
([0 1 2] [1 2 3] [2 3 4] [3 4 5] [4 5 6])
@rads Awesome, thanks!
what is wrong here :
(group-by count ["hello" "world" "foo" "bar"])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: group-by in this
but also when Im doing this . I see the error :
(in-ns 'koans.22-group-by)
=> #object[clojure.lang.Namespace 0x18682d3 "koans.22-group-by"]
(group-by count ["hello" "world" "foo" "bar"])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: group-by in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init8140862184290506834.clj:1:1)
then I see this :
(ns 'koans.22-group-by)
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol clojure.lang.RT$1.invoke (RT.java:239)
solved :
(ns koans.22-group-by)
=> nil
(group-by count ["hello" "world" "foo" "bar"])
=> {5 ["hello" "world"], 3 ["foo" "bar"]}
@schmee: Thanks!
Can someone give me a hint what is the answer to the last challenge :
(ns koans.23-meta
(:require [koan-engine.core :refer :all]))
(def giants
(with-meta 'Giants
{:league "National League"}))
(meditations
"Some objects can be tagged using the with-meta function"
(= {:league "National League"} (meta giants))
"Or more succinctly with a reader macro"
(= {:division "West"} (meta '^{:division "West"} Giants))
"While others can't"
(= "This doesn't implement the IObj interface" (try
(with-meta
2
{:prime true})
(catch ClassCastException e
"This doesn't implement the IObj interface")))
"Notice when metadata carries over"
(= {:foo :bar} (meta (merge '^{:foo :bar} {:a 1 :b 2}
{:b 3 :c 4})))
"And when it doesn't"
(= nil (meta (merge {:a 1 :b 2}
'^{:foo :bar} {:b 3 :c 4})))
"Metadata can be used as a type hint to avoid reflection during runtime"
(= \C (#(.charAt ^String % 0) "Cast me"))
"You can directly update an object's metadata"
(= 8 (let [giants
(with-meta
'Giants
{:world-series-titles (atom 7)})]
(swap! (:world-series-titles (meta giants)) #(+ 1 %))
@(:world-series-titles (meta giants))))
"You can also create a new object from another object with metadata"
(= {:league "National League" :park "AT&T Park"}
(meta (vary-meta giants
assoc :park "AT&T Park")))
"But it won't affect behavior like equality"
(= ___ (vary-meta giants dissoc :league))
metadata doesn’t affect equality, so if you modify the metadata of an object it will still equal…?
ah-ha! thanks @tbaldridge I ended up doing just that last night ( stumbling into the (next (cycle [:a :b]))
solution )
And realised the solution I had in my head was essentially onto-chan
proposed by @beppu
I realised cycle was returning a collection which I just needed to traverse via next
and first
hi there, just compiled an uberjar for my project (that is basically just dependencies for the moment) and it’s spitting out a 25MB jar, I this normal ?
@clodeindustrie Sounds pretty normal, yes.
Ours range from 20MB up to 34MB. You’d be surprised at how many dependencies drag in a lot of other dependencies. A few compiled Java libraries underneath that and you’ll soon have several MB.