This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-09-21
Channels
- # admin-announcements (17)
- # aws (19)
- # beginners (28)
- # boot (103)
- # cider (5)
- # clojure (183)
- # clojure-art (46)
- # clojure-russia (25)
- # clojure-sg (2)
- # clojure-uk (1)
- # clojurescript (342)
- # clojurex (3)
- # core-matrix (1)
- # cursive (1)
- # datascript (2)
- # devcards (77)
- # devops (15)
- # emacs (4)
- # funcool (8)
- # hoplon (15)
- # immutant (47)
- # jobs (1)
- # ldnclj (10)
- # lein-figwheel (4)
- # off-topic (2)
- # om (23)
- # onyx (10)
- # re-frame (1)
- # reagent (23)
- # yada (7)
It helps to have the actual values used for and
and or
because you can then do stuff like:
I use (or (wanted) default) all the time
I also read somewhere a while ago that strictly boolean return values are indicated by a ‘?', i.e. nil?
ok, it seems in both the cases @mikera mentions, you could use when/when-not? (when-not (some-computation) default-value) (when (some-condition-check) (thing-to-execute-if-true))
For me it is a style thing: I prefer when
and when-not
for situations where you want some kind of action (mutating state, throwing an error etc.) but prefer and
and or
when you are computing a result from a pure expression. Also as @luxbock points out and
and or
generalise better for multiple tests.
Just to add, this composes well with Clojure's nil punning on sequences
I read that defn- was considered a mistake and that’s why we never got a def-. I tend to agree that having functions you can’t call is rarely a good thing, but have a clear distinction between the public stable API and internal implementation details of my library is useful. How do I properly communicate that?
@luxbock @mikera @danielcompton Cool, thanks for the feedback, it cleared things up a bit
I am doing transduce
with +
and the transformation consists of map
. map
can take multiple collections, can I use this in my case? transduce
just takes one coll, how can I give it more?
pupeno: potemkin is useful for separating public/private API... but you can call defn- functions (@#'some.private/fn) does the trick
I want the private functions to be callable, I’m not interested in proper private. I just want it to be clear which ones are which.
lol I woke up and had this word in my mind 'potemkin', now I sit at the computer and what I read first in #C03S1KBA2? ..maybe is some kind of sign
@borkdude you can do that with map ala "(map (fn [a b i] [a b i]) [:a1 :a2] [:b1 :b2] (range))"
(def ^:private ipm-print-method
(get (methods print-method) clojure.lang.IPersistentMap))
(defmethod print-method clojure.lang.PersistentArrayMap
[o ^java.io.Writer w]
(.write w "#array/map ")
(ipm-print-method o w))
@alexmiller: maybe select-keys should throw when not called with a map? (both in clojure and clojurescript) now: (select-keys [:a :b] [:a]) ;;=> {}
this may be weird but select-keys will work with associative things and vector is an associative thing - from index to value
I guess it still can't return anything but {} in that case but it falls through the cracks a bit
if you pass it something that doesn't implement a Map, you will get an IllegalArgumentException
feel free to file a ticket - there is not one about this that I know of
the more I think about it, I don't think it's feasible to change this - I suspect there is code that relies on the current behavior
I apologize for asking you to log that
I'm going to close it
I want to run a generated js file (from cljs) with node. How should I call node to find that file? The js file is in the uberjar, but node cannot see into jars.
Anyone got a better solution to (map - xs (cons 0 xs))
? I want to return a list of the subtraction of the item in before itself
err, I think I don’t understand the question, and I meant to leave out the first coll there
I am mostly wondering about the cons
, my xs is a vector, but I guess that wont matter since cons returns a seq?
hi guys... when you use UUIDs as keys for maps... do you just turn them into strings? and use that?
thomas: keep them as java.util.UUIDs. UUIDs in java are value based rather than identity based, so perfect for usage in a map
You can use any UUID to lookup in the map with a get
operation or similar. Being value-based rather than identity-based means that you can use equivalent Objects (their .equals()
returns true) rather than have to access with the same Object (`obj1 == obj2`)
yeah check the Java UUID apidocs http://docs.oracle.com/javase/8/docs/api/java/util/UUID.html
I have been using https://github.com/danlentz/clj-uuid
@thomas clj-uuid has clj-uuid/as-uuid for conversions - https://github.com/danlentz/clj-uuid/blob/master/src/clj_uuid.clj#L702
@thomas: also if you are using prismatic schema, schema coercion does uuids too - https://github.com/Prismatic/schema/blob/master/src/cljx/schema/coerce.cljx#L87
(and yada does HTTP parameter conversion automatically, using schema coercion)
anyone using/familiar-with lein-resource
? I cannot for the life of me figure out how to get it to run properly.
ugh. there are a lot of thorns in the interaction of profiles between :uberjar
and ring uberwar
. It's very opaque.
How do I run another lein task when running lein uberjar automatically?
how can I read a serialized array-map?
"#array/map {0 0, 1 1, 2 2, 3 3, 4 4,}"
read-string results in
(read-string "#array/map {0 0, 1 1, 2 2, 3 3, 4 4,}")
CompilerException java.lang.RuntimeException: No reader function for tag array/map, compiling:...
@denik how did you get the #array/map to begin with?
(pr-str (array-map 0 0, 1 1))
;; => "{0 0, 1 1}"
(type (edn/read-string "{0 0}"))
;; => clojure.lang.PersistentArrayMap
I've always thought the type of map was an implementation detail to not include in serialization...
but curious how you came to the scenario, and why it matters?@timothypratley: here’s how, by adding a tagged literal
(def ^:private ipm-print-method
(get (methods print-method) clojure.lang.IPersistentMap))
(defmethod print-method clojure.lang.PersistentArrayMap
[o ^java.io.Writer w]
(.write w "#array/map ")
(ipm-print-method o w))
(let [m (apply array-map (interleave (range 100) (range 100)))]
(spit file-name m))
oh I see, does this help: https://github.com/clojure-cookbook/clojure-cookbook/blob/master/04_local-io/4-17_unknown-reader-literals.asciidoc it seems you need to pass the tag reader to edn/read-string
@timothypratley: it has a type of PersistentArrayMap b/c that’s how clojure implements short hash-maps
@timothypratley: now I get something that looks like a unordered hash-map of type serialize_array_map.core.TaggedValue
(type (edn/read-string {:readers {'array/map #(into (array-map) %)}} "#array/map {0 0}"))
;; => clojure.lang.PersistentArrayMap
seems to work fine?
I don't really recommend this, just trying to show how to get tagged reading
FWIW Clojure chooses when to use array-maps for good reason IMO, so overriding that seems like an anti-optimization that I don't really understand the use case for.
However I'm sure there are good reasons to prefer a particular type.
I don't know whether into will work for large collections either
> (type (into (array-map) (map vec (partition 2 (range 100))))) clojure.lang.PersistentHashMap
right, so if you want to force it we will need to write a better function
but it might be better to simply change the writer to be more convenient
so instead of serializing #array/map {0 0} serialize #array/map [0 0]
then you can just apply array-map
and get the type you want.
Will try, thanks @timothypratley @ghadi !
(let [m (apply array-map (interleave (range 100) (range 100)))]
(spit file-name (seq m))
(apply array-map (edn/read-string (slurp file-name))))
this works, are there performance considerations I should be aware of?Should be fine. Tho don't explicitly do array-map
.... let the reader return you any map it sees fit...
(and a tiny nitpick, (apply array-map (interleave s1 s2))
is better expressed as (zipmap s1 s2)
@ghadi yep I know about zipmap but that would return a hash-map, right? I wanted to make sure it will be an array-map
@denik can you describe a bit about why you need ordering? It sounds like you might benefit from using a vector or a sorted-map instead? what sort of data are you dealing with?
for accessing the fields of a record defined using defrecord, what's more idiomatic: (:foo record)
or (.-foo record)
?
from what I've read I expected the field derefing to be faster than the keyword, but using criterium it appears that keyword is actually faster
@timothypratley: I want to store something similar to a time series, however also preserving the ability of inserting later events at earlier points (ordering). Without that it would work as a sorted-map
'As soon as you want your names to be accessible from outside, or you want to access names set outside, use only aset/aget'
and the concept of protocols is function based and there is no notion of something satisfying a protocol-like-thing by having a field of a certain name, right?
in fact it will have a 'field of a certain name' that the protocol looks up to find an impl, or at least I think it did.
somewhere, I remember a special path for keyword access on records in the jvm clj compiler
I think It's this but I can't explain it to you https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core_deftype.clj#L191
I had thought that satisfying a protocol by calling a function that had to be implemented by a type or record might be slower than just expecting the type or record to have a field of a certain name and then accessing that field, but that also doesn't seem to be the case - calling the function seems as fast as direct keyword access, but I didn't test it extensively.
one thing that's slower about records is using extend/extend-type instead of inline impls of protocol methods.
which is cached
I also thought it might be easier on the writer of the deftype to just declare a field with a specified name, rather than having to define a function, but oh well, a small price to pay.
aha: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/KeywordLookupSite.java
@alexmiller: thanks for pushing me in the direction of deftype and defrecord - that turned out to be just what I needed to improve my L-system code - I actually just specify a protocol. Works great.
that's where it grabs the keyword-lookup thunk which does the field access on the record.
What's the naming-convention-du-jour for protocols these days: AProtocol or just Protocol?
Next I need to provide support for cellular automata. For that I want something like a Cell protocol and I want the hash and equality of the implementers of the Cell protocol to be based on the x and y value alone, not any additional fields. So I've got to learn more to work that out, but I think that should be doable.
seems like a smell unless you're passing it to third-party code that relies on hash/equals
@gtrak: I'm probably not expressing myself well as this is the first time I've been using type/record/protocol in Clojure.
but what I want to do is have a set of cells that are basically represented by their [x y] position
but now I want the user to be able to do a deftype/defrecord that contains fields beyond just x and y, like [x y age color]
except I still want to check instances of these against a set
where set membership is based on just the x and y values
I guess my point is more subtle, why is this not okay? (defn equal? [cell1 cell2] (= [(:x cell1) (:y cell1)] [(:x cell2) (:y cell2)]))
It allows cells to have other fields, and it lets you check equality with only x and y.
additionally it allows them to have equals/hashcodes that are less specific to your use-case.
not having to do so is part of what's nice about using clojure and persistent data structures.
so, what I have is a rewriting system here: https://github.com/decomplect/ion/blob/master/src/ion/ergo/l_system.cljc
To allow the items to carry extra parameters I added a Module protocol and then I have code that does:
(defn modulate
"Returns the module or the module supplied by an object implementing the
Module protocol."
[m]
(if (satisfies? Module m) (module m) m))
So it knows how to pull out the module to use in the next step of the transducing that does the lookup/replacement
I've already done Conway's Game of Life in clojure using sets and also (just for fun) using core.async channels.
I just need to figure out how to do this in a really generic fashion using protocols and type/record
The CA stuff is just a little more tricky than the rewriting system because you want to take the set of living cells and get their neighborhood and count living neighbors and such so it makes sense to use sets and I figured I'd need to override their hash values, but I've only just started on this so I'm quickly getting into an area I don't have any experience with yet. So I'll keep reading.
Here's an example of using deftype for parametric data in the rewriting rules:
(deftype TModule [key age]
ls/Module
(module [_] key)
Object
(toString [_] (str "<" key " " age ">")))
(defmethod clojure.core/print-method TModule [x writer]
(.write writer (str x)))
(defn type-module-example
[]
(let [axiom [(->TModule :A 0)]
rules {:A (fn [g w i m]
[(->TModule :B 0)
:-
(->TModule (.key m) (inc (.-age m)))
:-
(->TModule :B 0)])
:B (fn [g w i m]
[(->TModule :A 0)
:+
(->TModule (.key m) (inc (.-age m)))
:+
(->TModule :A 0)])}]
(ls/parametric-context-sensitive-system axiom rules)))
(comment (take 5 (type-module-example)))