Fork me on GitHub
#clojure
<
2018-05-11
>
devn00:05:38

Ran into a bug in my code where I macroexpand-all some code and then walk across the nodes. When I come across a symbol? I deref it. This works until I hit a place where I try to deref a clojure.lang.PersistentHashMap, and it yells at me for trying to cast a java.lang.Class to a java.util.concurrent.Future. Thing is, I am walking the code to find java.lang.Class instances that have a particular namespace.

devn00:05:10

I could reject this particular case as a precondition or try/catch around it, but I'm wondering if there's a more graceful way of detecting this kind of thing earlier. Maybe a better condition than just symbol??

andy.fingerhut00:05:21

Not sure of your intended purpose of using deref on all symbols, but looking at the source for clojure.core/deref shows some class names like clojure.lang.IDeref that you could try doing (instance? clojure.lang.IDeref my-thing) checks on.

Bravi10:05:38

is there a shortcut to this?

(defn make-user [username reward time id]
  {:username username :reward reward :time time :id id})

danm10:05:17

A shortcut how? I mean, if that is all it is doing what's the point in having the function?

👆 4
Bravi11:05:50

I ended up creating a record and then using

(map ->User fields)

Bravi11:05:16

like so

(defrecord User [username reward time _id])

(let [fields [:username :reward :time :_id]
      picked (-> u :lst (map fields))]
  (apply (partial map ->User) picked))

danm12:05:47

That's not a syntax I've seen before. What does the leading -> do on ->User? I assume it's not just a thread macro with no space

sobel12:05:34

It can be tempting to see something like ->User as special but ->User is just a regular symbol

danm12:05:27

Yes, but I couldn't see it defined anywhere.

rickmoynihan17:05:21

->User is the name of the User records positional constructor, whilst map->User is the constructor to convert a map into a User record. Clojure constructs these automatically for records. It looks to me like the (partial map ->User) is a typo and should be (partial map->User)

rickmoynihan17:05:16

also prefixing -> to a var or symbol can be quite common in Clojure code. You should read it aloud in those cases as being “to”, e.g. “to-User”.

rickmoynihan17:05:25

or “map to User”

rickmoynihan17:05:48

ok just seen someone else replied

danm17:05:24

Yeah, we use X->Y quite a lot, but that’s a defn. I need to poke defrecord, I was just confused by the ->User being called when I couldn’t see a definition for it. Didn’t realise defrecord made one automatically

rickmoynihan18:05:54

yeah you can’t override its implementation though; deftype’s differ from defrecords in that they lack these extras… which is useful if you need different behaviour on them; though deftypes are pretty minimal, so typically require more work.

schmee12:05:54

it’s a record constructor that gets automatically generated for each record

danm12:05:41

Aah, I had somehow missed that User was defrecord

noisesmith17:05:36

@bravilogy there's a fun macro for that

user=> (defmacro keyed [] (into {} (map (juxt (comp keyword name) identity)) (keys &env)))
#'user/keyed
user=> ((fn [a b c] (keyed)) 1 2 3)
{:a 1, :b 2, :c 3}
user=> (let [a :a b :b z :z] (keyed))
{:a :a, :b :b, :z :z}

noisesmith17:05:26

or a little closer to your existing logic, (map->User (select-keys m (keys (map->User {}))))

seancorfield18:05:35

Any Selmer users here that know how to "escape" {{ inside a template so Selmer doesn't think it's introducing a variable?

seancorfield18:05:26

I don't see anything in the docs. I guess I could use an HTML entity for it...?

hiredman18:05:49

maybe &lcub;&lcub;

Frank Henard19:05:44

Does Clojure have something where I can do both non-blocking and multi-threaded. In other words, could I run multiple database queries on separate threads, and each thread is using non-blocking io?

hiredman19:05:32

clojure's io story is the jvms, and the jvm has both threads and blocking and non-blocking io, and you can mix and match it all

hiredman19:05:13

jdbc's iterface (the main interface people use for databases) is decidedly blocking

Frank Henard19:05:25

thanks @hiredman. Does that seem like a silly idea to you? As in, does it make any sense to not block a thread if that's the only thing running on it?

hiredman19:05:38

but there are async alternatives (none of which are very popular)

hiredman19:05:45

it is silly

Frank Henard19:05:47

> jdbc's iterface (the main interface people use for databases) is decidedly blocking that's good to know

hiredman19:05:57

jvm threads are good and cheap

👍 4
hiredman19:05:35

not as cheap as not having a thread, but you can have a ton before you notice any issues

cjsauer20:05:02

Is it necessary/possible to type-hint generics?

ghadi20:05:45

it is not necessary

ghadi20:05:57

everything is "erased" to Object under the hood. (It's possible that will change in the future pending the JVM "generic specialization" efforts)

cjsauer20:05:49

@ghadi ah ok, thank you. What about importing? Can I :import a generic class? Instantiate one..?

ghadi20:05:26

yup. (import java.util.List)

cjsauer20:05:56

Cool, appreciate the help 🍻