Fork me on GitHub
#beginners
<
2018-01-09
>
justinlee03:01:33

A while a go folks here said that I should be able to import macros using plain old :require and :refer instead of :require-macros and :refer. But I can’t seem to be able to import the go macro from cljs.core.async this way. The compiler can’t find the cljs.core.async.macros namespace and it can’t find go inside the cljs.core.async namespace. What am I doing wrong here?

madstap13:01:54

Are you on the newest version of core async?

justinlee16:01:01

@U0J9LVB6G I’m just using whatever comes with cljs 1.9.946. I didn’t realize this was a new(ish) thing

jgh04:01:12

so im messing with clj-pgp a bit and i can get it to decrypt a file…all of the metadata around the decryption seems as expected, but the data component is just giving me this: :data #object["[B" 0x12f08f92 "[B@12f08f92"]. I assume that’s some kind of pointer, how do I access it?

jgh04:01:12

oh i see, it’s a byte array and I can use (String. data) for turning it into a string

jgh04:01:20

or i can use slurp, apparently. neat.

noisesmith17:01:17

@jgh when using String with a byte-array it’s a good idea to provide the encoding option - often “UTF-8” but not always

noisesmith17:01:57

penguin.tracking=> (def s "hello, 🐶")
#'penguin.tracking/s
penguin.tracking=> (String. (.getBytes s) "UTF-8")
"hello, 🐶"
penguin.tracking=> (String. (.getBytes s) "UTF-16")
"桥汬漬⃰龐�"

jgh17:01:37

good to know for the future. In this case I control the data source so can keep it utf8, but yeah if it’s random user data that’s good to keep in mind.

noisesmith17:01:07

even if you know it’s UTF-8 it’s good practice to provide the argument explicitly to the String constructor - I’m not sure that’s the default

jgh17:01:28

would you advise using String over slurp for something like this?

noisesmith17:01:54

slurp also takes an encoding argument, but String is more direct if what you have is an array of bytes

noisesmith17:01:06

providing the optional encoding arg to getBytes to show the other way this can go wrong

penguin.tracking=> (String. (.getBytes s "UTF-16") "UTF-16")
"hello, 🐶"
penguin.tracking=> (String. (.getBytes s "UTF-16") "UTF-8")
"��hello, �=�6"

jgh18:01:35

ok, thanks for the tips..i’ll clarify my code with the specifier.

dadair18:01:24

I'm trying to write some macros to help with spec-ing a graph-like data-structure I work with. The current macro returns a spec expecting certain types of children nodes:

(s/def :node.children/name-mapped
  #(= (keys %) (->> % vals (map :name) (map keyword))))

(defmacro typed-children
  "Returns a spec requiring children of a specific type."
  [node-type]
  `(s/and (s/map-of keyword? ~node-type)
          :node.children/name-mapped))

(defmacro maybe-typed-children
  "Returns a spec allowing either an empty children map, or a map of specific node types."
  [& node-types]
  `(s/or :empty :node.children/empty
         :has-children
         (s/or ~@(flatten
                  (for [t# node-types]
                    [(keyword "child.type" (name t#)) (typed-children t#)])))))
if I macroexpand-1 (maybe-typed-children :node/a :node/b) I get:
(clojure.spec.alpha/or
 :empty :node.children/empty
 :has-children (clojure.spec.alpha/or
                :child.type/a #object[clojure.spec.alpha$and_spec_impl$reify__875 0x7267466d "clojure.spec.alpha$and_spec_impl$reify__875@7267466d"]
                :child.type/b #object[clojure.spec.alpha$and_spec_impl$reify__875 0x10b897ec "clojure.spec.alpha$and_spec_impl$reify__875@10b897ec"]))
and when I try to use the macro I get an exception: Can't embed object in code, maybe print-dup not defined: clojure.spec.alpha$and_spec_impl$reify__875@d0f4161 Can anyone point out what I'm doing wrong in my maybe-typed-children macro?

dadair18:01:58

clearly the objects for each key in the or are the culprit, but not exactly sure how to get the desired spec from within the ~@(flatten ..)

dadair18:01:38

Basically, the desired output would be (s/or :empty .. :has-children (s/or :child/a (typed-children :node/a) :child/b (typed-children :node/b)))

hansw22:01:17

I have this coll: [ {:key "foo" :some 1} {:key "bar" :some 2} ] and want to turn it into: {"foo" {:key "foo" :some 1} "bar" {:key "bar" :some 1}}. What would the idiomatic way to do that be?

noisesmith22:01:02

that’s very similar to what (group-by :key coll) would return

noisesmith22:01:32

though group-by doesn’t assume the keys are unique, so each value is in a vector to make room for others

hansw22:01:26

i am sure there are no duplicate keys beforehand 🙂

justinlee22:01:51

does a double colon in front of a keyword have significance or is it just a convention?

justinlee22:01:18

sorry, nevermind i found a reference

noisesmith22:01:35

for those following along at home, it either namespaces the keyword to the current namespace, or some alias defined in the current namespace

justinlee22:01:49

I saw it in the context of rum. I assume the reason to do this is because its being fed to a macro and by namespacing the keyword it may help avoid some kind of naming clash

noisesmith22:01:55

it’s often used for tokens that are only useful when compared to themselves

noisesmith22:01:25

(similar to how gensyms are used but less gibberish if it leaks out)