Fork me on GitHub
#beginners
<
2018-09-04
>
sasha50400:09:27

problem is im not sure what I'm looking for

lilactown00:09:30

under Maps, in the “Examine” row, it shows the three most common ways

sasha50400:09:32

how to phrase it, rather

lilactown00:09:19

e.g. if your map’s keys are keywords, you can do (:some-key my-map)

lilactown00:09:02

if they’re not, you can do the opposite: (my-map "some-key") or (my-map 10001)

lilactown00:09:58

those are quick shorthands for accessing maps. you can also use the get function, which does about the same thing. for deeply nested maps, there’s also get-in where you can give it a path of keys to look up

sasha50400:09:26

oh great now i have a null pointer exception

sasha50400:09:50

can I create a new instance of the list, but without the last item in it?

lilactown00:09:18

yep (drop-last list)

ericcervin00:09:27

any idea how that differs from (butlast list)?

sundarj00:09:26

drop-last is lazy, butlast is strict

ericcervin00:09:11

aw yes. I see that running type on each

sasha50400:09:07

does (drop-nth exist?

lilactown00:09:42

(drop n list) does

lilactown00:09:49

ah, you want to drop the nth item

lilactown00:09:37

the top solution is the one you should go with if you want it to be lazy like drop/`drop-last`

jarvinenemil11:09:52

Anyone with some experience regarding batch-ques with rabbitmq? I am currently trying to implement a "User-notification-que" where they can Accept/Cancel. Grouping users together. I want to try and not save info in a database since they're not important to me if all 10 of them don't accept.

jarvinenemil11:09:40

I was thinking about batching 10 - 100 users together at a time in my api and then send their Id to a consumer, but it's also this thing if 1 cancels, then I have to reque all of them. so it would be like: 1. 10 requests to my api from users who wants to que up [Batch them here.. if possible] 2. Produce an event which a consumer is listening to. 3. Send "Accept" - notification to the users 4. If accept : do something, If 1 user presses cancel or doesn't click accept within 15 minutes -> Send the remaining 9 users to the que again)

jarvinenemil12:09:09

Will use LinkedBlockingQueue

jarvinenemil12:09:31

or look at pre-fetch.

troglotit11:09:32

Hey! I want to use data_readers.clj in my project, but I get Attempting to call unbound fn: #'equipage.data-reader/money:

bronsa16:09:35

the namespace must be loaded

troglotit11:09:07

My file layouts look like this:

mario.cordova.86216:09:37

Question: I am trying to move environment variables from profiles.clj into the project.clj file. The only thing I want to keep in the profiles.clj is passwords/credentials. In my project.clj I have :profiles { :dev [:shared :project/dev :profiles/dev] } where :shared is defined as :shared { :env { :mysql-port "1433" } }

mario.cordova.86216:09:03

When I run lein with-profile clj,dev run I get an error

mario.cordova.86216:09:18

Error encountered performing task 'run' with profile(s): 'clj,shared,dev,dev'

mario.cordova.86216:09:22

I noticed that there are two dev profiles. Why is this?

mario.cordova.86216:09:55

It is my understanding that the two dev maps defined would get merged into one.

seancorfield17:09:21

I suspect that is just the way Leiningen prints them (using name on :project/dev produces just "dev").

seancorfield17:09:07

Leiningen prints the fill list of profiles being applied. Behind the scenes, they are merged into a single "profile".

seancorfield17:09:51

@mario.cordova.862 Do you have the lein-environ plugin in your project.clj? (per this SO Q&A: https://stackoverflow.com/questions/21517583/cant-access-environment-variables-in-leiningen-project-clj-with-environ )

mario.cordova.86217:09:54

@seancorfield I do have that plugin installed but I got it working by changing the profile name to something else. So it became :profiles { :develop [:shared :project/dev :profiles/dev] }

mario.cordova.86217:09:25

profile name became :develop from :dev

seancorfield17:09:47

Ah, interesting...

seancorfield17:09:37

(there's a #leiningen channel if you get stuck with quirks of Leiningen and no one here seems to be able to help -- caveat: I don't know how active it is since I don't use lein)

dadair18:09:47

@seancorfield apart from the confidence of using an “official” tool; have you found a tangible benefit since switching from lein/boot -> clj?

dadair18:09:02

debating whether to take that leap

seancorfield19:09:00

@dadair I like the simplicity and consistency of it (sorry for the slow reply -- was in a meeting from 11am).

seancorfield19:09:21

I like that it adds less "weight" to the dev/test/build process.

seancorfield19:09:27

We're looking at migrating at least some of our dev/test/build process at work from Boot to clj but we have a lot of machinery in Boot right now so that has proven challenging so far (I think I've had that branch open for a few months now!).

gold8820:09:35

hey! I am trying to filter using or and two predicates but it doesnt work

gold8820:09:57

(defn calcMultiples [limit n] (take n (filter (or multipleOf3 multipleOf5) (range limit))))

seancorfield20:09:22

or takes two Boolean (or at least truthy) values...

gold8820:09:34

okay, i see

gold8820:09:13

looks like I have to work on the predicate

seancorfield20:09:50

You could either write it out explicitly -- (fn [v] (or (multiple-of-3 v) (multiple-of-5 v))) -- or look at some-fn

seancorfield20:09:31

And a word on style: in Clojure we use kebab-case for most names, rather than camelCase (like Java etc).

seancorfield20:09:06

And "Welcome to Clojure!" @gold88

gold8820:09:32

Thank you for your feedback and helpful advice on my first lines of clojure 🙂 happy to be here @seancorfield

gold8821:09:08

How would I impose an upper limit to a lazy sequence?

gold8821:09:59

>whose values do not exceed four million. I just added a predicate like before but It can't be the right thing.

gold8821:09:30

since the filter is called after the number has been calculated, i probably wanna check that before

gold8821:09:25

take-while 🙂

seancorfield21:09:15

(although, in this case, don't you just want to ensure limit is no bigger than four million?)

gold8821:09:22

https://projecteuler.net/problem=2 it's talking about the computed fibonacci values which are even

gold8821:09:39

so i guess, I can't limit it in another sensible way 😕

dpsutton22:09:33

ralf what was your solution?

dpsutton22:09:47

wait, what do you mean in a sensible way?

gold8822:09:07

(defn fib ([] (fib 0 1)) ([a b] (lazy-seq (cons a (fib b (+ a b))))))
(defn even-fib [n] (take-while #(> 4000000 %) (filter even? (fib))))

dpsutton22:09:05

nice. very similar to what i did

gold8822:09:31

fib was not my original idea, I looked at the clojuredocs

gold8822:09:41

even-fib is mine tho 😛

dpsutton22:09:56

yeah. it's a good one to get used to the lazy-seq macro.

gold8822:09:03

my first idea was to just use a loop

dpsutton22:09:21

nice. you can also just piece everything together like

(->> (fibs)
     (take-while (fn [v] (< v 4000000)))
     (filter even?)
     (reduce + 0))

dpsutton22:09:58

clojure is very good at making these expressible chains

gold8822:09:27

right now im scared of anything that has a ->

dpsutton22:09:39

the threading macros ->> and -> can really aid in readability

dpsutton22:09:21

yours is (->> (fib) (filter even?) (take-while #(> 4000000 %)))

mfikes22:09:25

I think I avoided the threading macros for the first month or two

dpsutton22:09:57

they'll come when they come 🙂

mfikes22:09:09

And, like anything else you will soon be overusing them :)

mfikes22:09:07

The main trick, IMHO is to realize they are lexical.

gold8822:09:34

I do prefer reading code left to right

gold8822:09:41

thanks for the example @dpsutton

mfikes22:09:08

In other words, they don’t pass the result of one function to the next like you might imagine.

gold8822:09:37

they dont?

mfikes22:09:09

They end up behaving that way, but you’ll see, with some corner cases, that they are best thought of as macros that rearrange your code.

mfikes22:09:40

(I misunderstood them for quite a while.)

sundarj22:09:31

try evaluating (-> [a 2, b 3] (let (+ a b)))

dadair22:09:13

Inline anonymous function declarations bite me occasionally

noisesmith22:09:17

that's my favorite example (the ->> version is almost like where in ml / haskell)

mfikes22:09:18

The canonical problematic example is if you have an anonymous fn in the chain

gold8822:09:32

@sundarj i dont even understand that line

gold8822:09:59

i thought , is whitespace

noisesmith22:09:13

=> (->> (+ lexical demo) (let [lexical 11 demo 31]))
42

noisesmith22:09:28

@gold88 yes, , is whitespace, that has nothing to do with what's happening there

sundarj22:09:32

, is whitespace, i used it for readability

noisesmith22:09:15

the thing shown in these examples is that it isn't passing a result to the next form - it's injecting the literal form into the other literal form before compiling

sundarj22:09:17

(-> [a 2, b 3] (let (+ a b))) expands to (let [a 2, b 3] (+ a b))

gold8822:09:47

thanks for clarifying

gold8822:09:01

i guess threading is something when I have a solid grasp of 'things'

noisesmith22:09:33

if you use threading in the normal way it's fine for a beginner - this is a sample that helps you when an unexpected bug happens

noisesmith22:09:13

eg. (-> 2 (fn [x] (* x x))) - that expands to (fn 2 [x] (* x x))

gold8822:09:32

okay, i'll be cautious 🔎

gold8822:09:41

by the way, clojuredocs is a blessing

gold8822:09:02

i just copy paste commands that i dont know yet in there and i dont need to do (doc fname)

gold8822:09:23

(defn ->host
  [{:keys [domain repo-name branch-name]}]
  (str (sanitize-name repo-name) "-" (sanitize-name branch-name) "." domain))

(defn subdomain->host
  [domain subdomain]
  (str subdomain "." domain))
i saw these in a github project

gold8822:09:46

is this naming style or does it actually mean something?

sundarj22:09:04

it's a naming convention. ->host means 'make a host', and subdomain->host means 'convert a subdomain into a host'

noisesmith22:09:15

if someone has (defrecord foo ...) clojure will create ->foo and map->foo automatically. we also use names like that directly

noisesmith22:09:53

-, >, +, *, |, and many others are not "special" in clojure, they are just part of a name

noisesmith22:09:25

(`.` and / on the other hand do have some "magic" to them in the reader so aren't as free)

gold8822:09:48

map->foo = convert a map into foo?

noisesmith22:09:57

into a foo, yeah

gold8822:09:18

(def ^:dynamic *buffer-size* 1024) okay this one has two question: ^: ? and asterisk wrapped strings?

seancorfield22:09:12

*ear-muffs* is a convention to indicate dynamic variables -- names that can be bound to new values at runtime using binding

seancorfield22:09:49

And ^:dynamic is metadata for the var and is shorthand for ^{:dynamic true} which marks the var as dynamically rebindable

seancorfield22:09:44

(binding [*buffer-size* 2048]
   ... execute this code with *buffer-size* bound to 2048 ...
  ... )
;; and now *buffer-size* is back to 1024

seancorfield22:09:07

You'll also see

(def ^:private foo 42) ;; make foo private to this namespace
...
;; but it can still be accessed as #'the-ns/foo outside that namespace

seancorfield22:09:16

@gold88 If you haven't already seen it, this is very helpful for the syntax stuff https://clojure.org/guides/weird_characters

gold8822:09:51

thats helpful, thanks @seancorfield

gold8822:09:08

but i would guess that dynamic variables are frowned upon right?

gold8822:09:09

>This page explains the Clojure syntax for characters that are difficult to "google".

noisesmith22:09:52

they are more common in older code in my experience, but sometimes they are much nicer than the alternative of a shared mutable value

noisesmith22:09:22

since binding changes the view of the variable inside a specific scope, but is invisible outside that scope

noisesmith22:09:21

and some things like *out* for example are always going to be dynamic so it makes sense to alt least know how to use them well

gold8822:09:53

i am grateful for the explainations 🙂 sometimes I feel like im treading on eggshells here