Fork me on GitHub
#beginners
<
2017-01-30
>
eslachance00:01:06

Hmm. Thank you Sean. Is there any way I can serialize this easily? I have 6 or 7 things to remove from the same hashmap. unless I can just make a temp variable in let and overwrite it along the way?

eslachance00:01:48

Actually let me try instead of asking ^_^

seancorfield00:01:50

Well, you can (dissoc thing :lots :of :keys :to :remove)

eslachance00:01:06

Ahhh yes that is helpful

seancorfield00:01:19

And that doesn’t change thing so you can still access those elements of it later.

eslachance00:01:59

It's an incoming websocket packet so it'll be discarded anyway, but yes I understand immutability.

seancorfield00:01:08

(let [smaller-thing (dissoc thing :bar :blah :whatever)]
      foo (:blah thing) ;; still works because thing hasn’t changed

eslachance00:01:04

I'm in the very awkward position of knowing for a fact that I'm a clojure newbie, and yet I'm using datascript, aleph and other pretty advanced things to make my own library.

eslachance00:01:24

At least I know exactly what I need though, I guess.

seancorfield00:01:43

If you’re going to discard the packet anyway, why bother removing keys from it? Is that just for intermediate processing that would do the wrong thing if those keys were still present?

eslachance00:01:36

Well this is for a discord bot library - the packet I'm getting is for a guild, and within that are roles, channels, users, etc

eslachance00:01:57

I want to separately insert these thigns into datalogics, so to get the guild alone I'm removing its sub-properties

eslachance00:01:16

*datascript , not datalogics

seancorfield00:01:42

Perhaps select-keys would be more practical here? So you could create a (sub-)map with just the keys you care about and throw away all the rest?

eslachance00:01:17

That would be a good solution but there are only 7 kewords I want to remove from it - whereas there's about 50 I want to keep

eslachance00:01:59

Perhaps select-keys might be more efficient but certainly doing dissoc will be more readable (for me at least)

seancorfield00:01:48

(apply dissoc thing list-of-keys-to-remove) 🙂

seancorfield00:01:11

(def list-of-keys-to-remove [:bar :blah :whatever])

eslachance00:01:51

How does this look?

(defn guild-create [packet]
  (let [guild (dissoc (packet :d) :emojis :channels :roles :presences :members)
        emojis (get-in packet [:d :emojis])
        channels (get-in packet [:d :channels])
        (...)]
    ; insert into datascript
    ))

eslachance00:01:02

And by the way thank you for helping me again (I was here a few months back, finally picked this project back up), I really appreciate it.

seancorfield00:01:13

That code seems reasonable. You might want (let [data (:d packet) … so you can just have (:emojis data) etc instead of those get-in calls.

eslachance00:01:56

True. Would that just make it easier to read, or is there a difference in performance between get and get-in?

seancorfield00:01:35

It’s more idiomatic to use (:kw data) than (get data :kw)

eslachance00:01:51

Best practices are fine with me!

seancorfield00:01:23

And get-in is going to navigate from the top each time — and since you’re always navigating into :d why not factor that out to a local symbol?

eslachance00:01:31

Thank you 🙂

mdtsoy09:01:00

I've recently starting learning Clojure. Can someone with some experience in it tell me about tools that are convenient to use? I mean text-editors and some useful plugins to them. LightTable is often recommended in tutorials and books. However it does not seems to be well maintained. Mostly I am using Atom editor. Can you suggest some plugins for Repl and/or syntax highlighting (ainbow parenthesis)? p.s. on windows platform:grimacing: Thanks in advance

ejelome09:01:32

you have some really good editors, e.g. spacemacs+clojure layer, intellij+cursive plugin, or lighttable

ejelome09:01:59

I use the first one, but the rest are also good, esp. if you're comfortable on using the mouse

mdtsoy09:01:49

I looked at cursive but using intellij for some small exercises is quite strange.

akiroz09:01:25

I've heard good things about the parinfer plugin for lisps (havent used it myself because I'm used to typing both parens then moving inside to continue typing)

mdtsoy09:01:44

maybe some lightweight and comfortable plugins and editors for doing small things

mdtsoy09:01:06

the same issue with parinfer

mdtsoy09:01:41

parens autocomplete does not suit me

ejelome09:01:52

I think any editor will do as long as they know how to balance the parens, brackets, and braces

mdtsoy09:01:20

got the point and how about connection to repl

mdtsoy09:01:55

actually atom has nRepl plugin but i can not specify port number

sveri11:01:49

@mdtsoy cursive comes with everything included and you can choose between parinfer / paredit / structural mode.

mdtsoy11:01:01

Thank you, gonna try it

kasuko16:01:38

Hey I am working on a problem. I have a flat map of parents (eg for a tree) and I want to find the full list of parents. So I have to lookup in the map an unknown number of times until nothing is returned. I have this working using loop/recur but I was wondering if there was a more functional way to do it?

kasuko16:01:50

(defn recursive-lookup
  [key lookup-map]
  (loop [c []
         k key]
    (if-let [v (get lookup-map k)]
      (recur (conj c v) v)
      c)))
(def parents {:a :x, :b :x, :x :y, :y :z})
(recursive-lookup :a parents)
;; => [:x :y :z]
(recursive-lookup :y parents)
;; => [:z]

akiroz17:01:50

hmm... I think this is a perfectly functional solution and it makes sense since its a recurrsive problem.

poooogles18:01:56

Bit confused about https://clojuredocs.org/clojure.core/with-redefs-fn. Can I redefine a function that's imported with a require?

poooogles18:01:49

(ns baz.blah
  (:require [lib.module :as module])

(defn do-thing
  [blah]
    (module/function blah))

(ns baz.blah-test
  (:require [clojure.test :refer :all]
            [baz.blah :refer :all]))

(deftest test-normalise-wrapper-return
  (testing "Blah."
    (with-redefs-fn {#'lib.module/function #((vector %)}
      (do (is (= (do-thing "blah") ["bar"]))))))

poooogles18:01:19

seemingly that doesn't work as module/function is called, so pointers would be good.

poooogles18:01:33

Switched to dependency injection, but that doesn't feel right

schmee18:01:42

poooogles there are a whole heap of DI-like things for clojure you can use if you want

schmee18:01:03

it’s perfectly idiomatic

schmee18:01:48

but there is also Mount, Mount-lite and Integrant, each with their own pros and cons

7h3kk1d18:01:11

If you can make the function pure using DI I usually think that’s best

poooogles18:01:48

Kind of just pushes the issue up another level though as I'm a bit stuck for testing the function I have the level up.

poooogles18:01:59

I guess I'll just make a one liner helper function and redef that.

schmee18:01:07

I’m not a fan of with-redef myself, I’d rather just pass it in as an argument

schmee18:01:24

then you can use partial to set it up with the right dependencies

tbaldridge18:01:13

Yeah there's about 20x ways with-redef will shoot you in the foot, given the chance.

pcbalodi18:01:49

with-redefs to mock dependencies in test-cases are fine imo, they are bad everywhere else.

donaldball19:01:02

I vastly prefer reifying protocols for tests to with-redefs

donaldball19:01:10

But I’m very aggressive about putting side-effecting things behind protocols

tbaldridge19:01:15

You can even shoot yourself in the foot with testing. For example, if your test uses threads things can break, or if it uses lazy seqs, or ....

eslachance19:01:47

Is it normal that I still get a little fangirlish from seeing all these great, knowledgeable people like Timothy, Nikita and Sean taking the time to interact with us beginners and teach us stuff? ^_^

schmee19:01:19

clojure has the best community 💪

eslachance19:01:50

I would tend to agree. I've been hanging out on Discord in Javascript communities for so long, sometimes I forget how to interact with adults.

eslachance19:01:10

But, I've taken upon myself to attempt to lift those teenagers into a better worlds. My plan is to make a great series about learning Clojure on youtube. I have a... good following actually in the node/js community on Discord so people listen.

eslachance19:01:19

Every time I look at my stats I'm surprised. 20k+ views of my 5 videos...

schmee19:01:37

cool, best of luck! :+1:

eslachance19:01:56

I'm not doing it for me I'm doing it for the people ❤️

ghadi19:01:36

@eslachance + @donaldball to that list. He is the http://bomb.com

donaldball19:01:40

😊 oh, you

sveri19:01:56

Ist that a kind of a joke? http://bomb.com failes to load the page content for me

ghadi19:01:45

yeah sorry just an english phrase

sveri19:01:33

ah, ok 🙂

eslachance20:01:56

I'll have to look into what he does ;)

sifou20:01:01

Hi! I can't wrap my head around this behaviour, can someone please explain why is it the case. ('s 3 3) eval to 3 (last in list) but ('s 3 3 3) we get ArityException, and why with Symbol in front of list we don't get ClassCastException?

eslachance20:01:02

Sometimes it's hard not to feel like a noob when another beginner asks a question I understand nothing about. >.<

eslachance20:01:15

Except the word "arity"

7h3kk1d20:01:29

Not even sure what ‘s does.

eslachance20:01:13

seems to return the last item in a list as described?

eslachance20:01:38

@sifou may I ask where you got that from and how it's documented? Personally I'm very bad at looking through the clojure docs.

7h3kk1d20:01:48

So it’s not just s

7h3kk1d20:01:50

(‘a 3 3)

sifou20:01:40

@eslachance I've encountered the behaviour while trying to solve #135 from 4clojure

eslachance20:01:47

' prevents clojure from evaluating what's right after it... so it's not evaluating 'a...

eslachance20:01:24

What the result of "not evaluating" is I'm not yet sure

alexmiller20:01:50

you are invoking the symbol

alexmiller20:01:17

invoking a symbol is like invoking a keyword - it turns around and does a get on the first argument with the symbol as the key

alexmiller20:01:29

like (get 3 ‘a)

alexmiller20:01:58

in this case you also supplied a “not-found” value (the last value), which makes it like (get 3 ‘a 3)

alexmiller20:01:35

here the first 3 is being treated as a map. get handles this (confusingly) not as an error, but by returning nil on the lookup. when the key is not found, it returns the not found value instead, which is in this case the last 3

alexmiller20:01:55

I suspect what you actually wanted though was a literal non-evaluated list

alexmiller20:01:01

with: '(a 3 3)

eslachance20:01:32

I was 2 seconds away from coming back with http://stackoverflow.com/questions/12281631/what-do-clojure-symbols-do-when-used-as-functions where the answer kind of explains that but you came in with something better ^_^

sifou20:01:07

@alexmiller @eslachance Aha! Thank you for clarification, it's feels great when everything makes sense 🙂 this is not JS after all ^^

alexmiller20:01:12

well, I think it’s totally reasonable to feel weird about (get 3 ‘a) => nil :)

eslachance20:01:53

No, this is definitely not JS 😄

alexmiller20:01:57

that’s been a long-standing argument

beppu22:01:18

Style question. When defining records, do you like to give each record its own namespace or do you define many records in one namespace?

beppu22:01:57

In a recent project, I chose to give each record its own namespace, but I ended up w/ one unfortunate name. timer.timer/Timer - https://github.com/beppu/timer/blob/master/src/timer/timer.clj#L11-L23

beppu22:01:05

I also had timer.alarm/Alarm and timer.app/App, but I'm OK w/ those.