Fork me on GitHub
#beginners
<
2016-11-17
>
gnunes04:11:45

Hi! I'm starting a new project and I'm considering using Clojure, in docker-based microservices. What I'm worried about is, will the JVM and its high memory allocation be an issue in the beginning, when I'm planning to run on small instances with not much RAM? I'm thinking that I'll not be able to put too many containers in the same instances, as every container will run a JVM. Any one has experiences with this? Does fine tuning the JVM mitigate the issue? Should I set a low memory limit, monitor and scale when needed?

pawel.kapala11:11:29

Hey. How to write clojure.spec for a map which keywords match a specific predicate, for example, say I’d like this map to conform spec that validates keys prefixed with foo-: {:foo-1 “value1” :foo-bar “value2” :foo-anything “bar”} Anyone have a clue how to achieve that without enumerating all keys explicitly? Thanks in advance for any clues.

pawel.kapala11:11:25

Should I use map-of somehow maybe?

curlyfry12:11:57

@pawel.kapala Yeah, I think map-of is what you want

curlyfry12:11:12

;; From the spec guide
(s/def ::scores (s/map-of string? int?))
(s/conform ::scores {"Sally" 1000, "Joe" 500})
;=> {"Sally" 1000, "Joe" 500}

curlyfry12:11:53

Here you could change string? to your custom prefix predicate

pawel.kapala12:11:49

@curlyfry Thanks this is the way!

roelofw14:11:42

Why does the category not be printed here :

(deftype Razzie [category]
  Award
  (present [this recipient]
    (print (str "You're really "
                (:category this) " , "
                recipient
                )))) 

alexmiller14:11:09

The (:category this) isn't meaningful for deftype a

alexmiller14:11:31

Just say 'category'

roelofw14:11:52

oke, and why does it work here :

(defrecord Oscar [category]
  Award
  (present [this recipient]
    (print (str "Congratulations on your "
                (:category this) " Oscar, "
                recipient
                "!")))) 

alexmiller14:11:04

Keyword lookup access is built into defrecords by default but deftype has almost nothing pre-built - it's up to you to build it

alexmiller14:11:30

You could just use category in the defrecord too (and you should)

roelofw14:11:45

oke, another exercise for learning the difference between defrecord and deftype

alexmiller14:11:11

The fields are available by name in the scope of both the record or type definition

alexmiller14:11:48

And that is more efficient than anything else in the generated bytecode

alexmiller14:11:59

And easier to read

joshkh15:11:53

admittedly not completely clojure related, but is there a way to reference a file from leiningen that's contained inside a maven dependency? there's a .less file in a dep that i want to include in my own project, and i can see it when i inspect the jar in ~/.m2

seancorfield15:11:05

https://clojurians.slack.com/archives/beginners/p1479393048003420 Good to know -- I've always done (:key this) thinking that would be the most efficient and idiomatic way to do field access in a record. I'll create some tickets in my projects to change that!

alexmiller15:11:28

:key is definitely good outside the record, but inside, using the field name will just be a direct field reference basically rather than a call

alexmiller15:11:04

@joshkh any file inside a jar can be loaded as a resource

alexmiller15:11:24

assuming it’s on your classpath (specified as a dep in your project)

joshkh15:11:29

okie dokie, good to know. thanks.

joshkh17:11:21

speaking of deps, how are different versions handled? let's say dep A relies on clojure 1.8, and another dep on clojure 1.9. are both bundled into the final jar?

upgradingdave17:11:31

@joshkh pretty sure only one version is included. The underlying maven dependency resolution machinery will choose the best version to include (I think in this case it would use 1.9). You can control which transitive dependencies to exclude using :exclusions, check out the example here (where they bring in log4j but exclude some of log4j’s dependencies): https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L48

upgradingdave18:11:44

so, for example, if you wanted to make sure your project uses clojure 1.8, you could use :exclude to exclude the transitive clojure dependency from both dep A and B, and then add an explicit dependency on clojure 1.8 inside your project.clj. Hope that helps and isn’t too confusing 😉

roelofw19:11:13

Can someone explain this one :

"Notice when metadata carries over"
  (= {:foo :bar} (meta (merge '^{:foo :bar} {:a 1 :b 2}
                     {:b 3 :c 4})))  

roelofw19:11:46

is the answer {:foo :bar} because there is a reader ^ before it

roelofw19:11:54

so the rest get ignored ?

roelofw19:11:28

yep, with quote everything stays the same

dpsutton19:11:48

note it's putting {:foo :bar} into the meta data of the first map

dpsutton19:11:04

and then its showing that the end result of the merge has the meta data still intact

dpsutton19:11:10

"Notice when metadata carries over"

roelofw19:11:17

but where stays the {:a 1, :b 3, :c 4} part then ?

roelofw19:11:58

I think I can better do the rest of the koans when Im more familiair with clojure

dpsutton19:11:25

that's in the map

dpsutton19:11:34

but you're asking the map for its meta information

dpsutton19:11:56

(meta (merge '^{:foo :bar} ....))

dpsutton19:11:09

so you're merging maps and then asking for the meta info of the resulting map

dpsutton19:11:22

and your koan is asserting that its equal to {:foo :bar}

roelofw19:11:26

oke, on that way

roelofw19:11:57

very confusing stuff when never working with clojure

roelofw19:11:22

so the part with ^ will become the metadata ?

roelofw19:11:59

oke, I think I begin to understand metadata

roelofw19:11:09

but I wonder when you use it

dpsutton19:11:23

I've used it to check the arity of a function

dpsutton19:11:30

in cider, you can "refresh" your repl

dpsutton19:11:39

and you can specify functions to call after or before refreshing

dpsutton19:11:50

but they can only be functions that take no arguments, as what arguments could cider give

dpsutton19:11:58

but some functions have optional arugments

dpsutton19:11:09

but its not technically a funciton of zero arguments

dpsutton19:11:15

but "could" be a function of zero arguments

dpsutton19:11:25

when you define a function it puts its function args in its metadata

dpsutton19:11:37

so i checked those to see if it could be called with zero arguments

dpsutton19:11:35

so in my case i was looking at the :arglists slot of functions

roelofw20:11:51

Thanks for the info

dpsutton20:11:42

i've seen a library that tucks quite a bit of stuff inside of meta data. Wasn't sure why and it didn't have to be that way, but it was

michaelmrose20:11:26

hey question this is clearly very contrived but suppose you had the form (+ '(1 2 3)) plus expects individual values so I could do (apply + '(1 2 3)) but suppose I had the equally contrived (+ '(1 2 3) 4 5) what is the best way to break the list out of the interior list?

michaelmrose20:11:14

I can do (apply + (flatten (list '(1 2 3) 4 5))) I was wondering if there was a function where I could do (somefn '(1 2 3) 4 5) and do the lot or if I should create one or if I am just doing it suboptimally

michaelmrose20:11:04

wondering if there is a generic function I could wrap '(1 2 3) that would result in it being lifted into the above function

dpsutton20:11:38

if you can change the order, i believe apply can handle the list at the end

dpsutton20:11:56

(apply + 1 2 '(3 4 5))

michaelmrose20:11:03

interesting thanks

roelofw20:11:31

@dpsutton it is wise to include metadata in every big project in every function that you made. Or is it better only to use it in API and that sort of libraries ?

dpsutton21:11:00

its wise to ask that question

dpsutton21:11:16

i have no idea about the answer except that my suspicion is that you should have a good reason to use meta

alexmiller21:11:57

meta is useful only in some pretty narrow use cases

alexmiller21:11:15

note that it can be tricky to know what fns preserve meta and which do not

alexmiller21:11:32

and that meta is not considered when comparing for equality

alexmiller21:11:15

almost every time I have used or seen someone use meta they ultimately found that what they were putting in meta was important enough that it really should be treated as data, not metadata

alexmiller21:11:35

that said, var and ns meta is pretty useful in the language itself

roelofw21:11:59

oke, so almost I do not have to use meta

roelofw21:11:09

Thanks, for the answer

alexmiller21:11:47

the primary reason you will use meta in most Clojure code is to apply things like type hints or ^:private to vars

roelofw21:11:25

Both against thanks

dpsutton21:11:27

i thought i remember either xml or zip using a bunch of meta for some reason

dpsutton21:11:36

might be zip that stored a ton of stuff in meta