Fork me on GitHub
#clojure
<
2015-11-24
>
arohner00:11:14

@davebryand: I don’t know about 'best practice’, but it seems overkill in that app, just because the conn won’t really change. In that case, just use (let [conn (init-conn]), and have init-conn just be (d/connect (:datomic-uri (read-config)). My best practice these days is to use Component

arohner00:11:37

(I don’t really like the term Best Practice), but I recommend Component for most everything now

davebryand00:11:51

Thanks @arohner — is there a good example app out there that you can recommend that I look at to see how things get wired up with Component?

davebryand00:11:59

awesome, thanks!

cfleming02:11:57

Is there an implied contract of any kind for print-method?

cfleming02:11:28

I’m looking at an issue with Instaparse right now, where Cursive will incorrectly print its failure values.

cfleming02:11:37

This is because Instaparse redefines print-method, which means that nREPL returns formatted text in its val field which holds the result of the evaluation.

cfleming02:11:25

Cursive (perhaps incorrectly) expects something that looks more or less like a Clojure object in there.

dvcrn03:11:28

hey guys. I'm writing a desktop app in clojure(script) and want to give the user a option to specify the modules he wants to use

dvcrn03:11:54

in my python version, I generate a tree of directories based on the modules the user enters and fetch a specific python file in that directory

dvcrn03:11:21

everything is lazy loaded. If the user doesn't use a module, it's not even loaded by the app and everything in that modules folder is untouched

dvcrn03:11:17

I want to do something similar in clojurescript but feel like this would get a little bit more difficult. Is a lazy-loaded approach even the right idea here or should I just compile everything together and ignore certain things based on a settings file?

iamjarvo05:11:23

has anyone used kerodon? I am trying to figure out if there is an easy way to check the content type of the response

mikethompson10:11:54

@dvcrn: you may be better asking this in the #C03S1L9DN channel But it sounds to me like you want modules. This link may help: https://rasterize.io/blog/cljs-dynamic-module-loading.html

jonpither11:11:50

Any recommendations for a tool to visualise a clojure codebase?

martinklepsch12:11:09

@jonpither: @bensu made a thing called asterion that might help

martinklepsch12:11:44

also http://www.clojureatlas.com/ but that’s pretty old and I’m not sure if it’s supposed to work with codebases outside clojure.core

jmmk12:11:23

I'm trying to write some runtime assertions for functions that will be passed in (this is library code). I expect a map like {:some-fn some-fn :other-fn other-fn} and I want to verify that these functions accept and return the correct types of values. Is there a good way to do this?

dm312:11:12

you would need to attach some metadata to the functions

jstew12:11:43

prismatic schema if you need to do complex validation of the inputs.

dm312:11:48

otherwise you only have the type to work with, which doesn't say much if it's an IFn

jmmk12:11:14

@jstew @dm3 both of those would require something to be done when the function is constructed right? But assuming it's just passed in as a normal function, could I use something like test.check to validate inputs/outputs? Or a series of assertions?

jstew12:11:20

@jmmk: You would need to know the structure of the inputs with schema, but at runtime you call validate

jstew12:11:01

On the inputs of course.

dm312:11:02

I think he wants to validate the input/output schema of a function that is passed in

dm312:11:58

which isn't really possible unless you invoke it or inspect its metadata

dm312:11:13

or some other data that describes it

jstew12:11:53

And he can't do that when the function is created because it's library code. Got it.

jonpither12:11:30

Thanks @martinklepsch and @malch for source visualisation recommendations

jmmk12:11:16

@jstew @dm3 The options I'm looking at: * I could have macros for creating the functions that would automatically add the schema and run validation * I could just create the schemas and have them available but optional (this one might be easiest) * I could validate them at runtime by testing inputs and outputs (this is the one I'm currently exploring but it sounds like there's not a good way to do it)

dm313:11:33

what will you do with the functions that are passed in?

jmmk13:11:06

they will be stored and repeatedly called during execution

dm313:11:00

so their inputs and outputs need to conform to some shape that you know at the point you store them?

jmmk13:11:26

the functions are used for a specific task

dm313:11:17

I'd probably try to restrict users to define a function through the given means (e.g. macro)

dm313:11:29

anyway, the real validation will happen once the function is run simple_smile

danielcompton13:11:05

@jonpither: lein-ns-dep-graph is good

jonpither13:11:25

@danielcompton: yeah just tried it - is useful thanks

danielgrosse14:11:24

Hello I want to add multiple entries in an map. How can I achive this? My attempt:

(doseq [n [1 2 3 4 5]]
  (let [req-id (clj-wamp.core/new-rand-id)]
    (println req-id)
    [{} {} (assoc {} req-id ["test" #(fn [] (println "test"))])]))

roberto14:11:31

what is the output you expect to have?

danielgrosse14:11:56

[
{}
 {} 
{1212 [„test“ #(fn [] (println „test“))])
{1212 [„test“ #(fn [] (println „test“))])
{1212 [„test“ #(fn [] (println „test“))])
]

danielgrosse14:11:39

I know, the doseq repeats the function and returns nil, so not what I want. But I can’t get the way, how to achive this.

pbostrom14:11:26

@danielgrosse:

(let [req-id 1212]
  (into [{} {}] (map (fn [k] {k ["test" #(fn [] (println "test"))]}) (repeat 3 req-id))))

agile_geek14:11:24

or even

(let [req-id 1212]
  (into [{} {}] (repeat 3 {req-id ["test" #(fn [] (println "test"))]})))

danielgrosse14:11:19

@agile_geek: @pbostrom THanks. But what if I want the req-id to be different on each time?

swizzard14:11:33

you should just be able to substitute a form that returns the req-id

agile_geek14:11:12

yep e.g.

(into [{} {}] (repeat 3 {(rand-int 100) ["test" #(fn [] (println "test"))]}))

pbostrom14:11:13

let me edit mine, @agile_geek's solution is better anyway

pbostrom14:11:18

what he said

agile_geek14:11:54

and you could pass an argument for the number of repeats if that needs to vary.

agile_geek14:11:35

(defn my-collection [n]
  (into [{} {}] (repeat n {(rand-int 100) ["test" #(fn [] (println "test"))]})))

pbostrom14:11:46

@danielgrosse: based on your original question "I want to add multiple entries in an map", are you sure the above is what you want? This creates a separate map for every new random id. maps usually contain multiple keys/values

danielgrosse15:11:02

No, I want to have the entries to extend the third map. And @agile_geek `s solution always generates the same id.

danielgrosse15:11:27

(into [{} {}] (repeat 3 {(rand-int 100) ["test" #(fn [] (println "test"))]}))
=>
[{}
 {}
 {15 ["test" #object[main$eval18372$fn__18373 0x468cf149 "main$eval18372$fn__18373@468cf149"]]}
 {15 ["test" #object[main$eval18372$fn__18373 0x468cf149 "main$eval18372$fn__18373@468cf149"]]}
 {15 ["test" #object[main$eval18372$fn__18373 0x468cf149 "main$eval18372$fn__18373@468cf149"]]}]
(into [{} {}] (repeat 3 {(rand-int 100) ["test" #(fn [] (println "test"))]}))
=>
[{}
 {}
 {29 ["test" #object[main$eval18380$fn__18381 0x35b685b4 "main$eval18380$fn__18381@35b685b4"]]}
 {29 ["test" #object[main$eval18380$fn__18381 0x35b685b4 "main$eval18380$fn__18381@35b685b4"]]}
 {29 ["test" #object[main$eval18380$fn__18381 0x35b685b4 "main$eval18380$fn__18381@35b685b4"]]}]
(into [{} {}] (repeat 3 {(rand-int 100) ["test" #(fn [] (println "test"))]}))
=>
[{}
 {}
 {64 ["test" #object[main$eval18388$fn__18389 0x24587d3a "main$eval18388$fn__18389@24587d3a"]]}
 {64 ["test" #object[main$eval18388$fn__18389 0x24587d3a "main$eval18388$fn__18389@24587d3a"]]}
 {64 ["test" #object[main$eval18388$fn__18389 0x24587d3a "main$eval18388$fn__18389@24587d3a"]]}]

davebryand15:11:19

Would appreciate some help understanding where map->Datomic is defined as used in this line:

(defn new-datomic-db [uri]
  (map->Datomic {:uri uri}))
https://github.com/danielsz/system/blob/master/src/system/components/datomic.clj#L15

agile_geek15:11:17

@danielgrosse: sorry. try this

(into [{} {}] (map (fn [n] {n ["test" #(fn [] (println "test"))]}) (take 3 (repeatedly #(rand-int 100)))))

agile_geek15:11:26

I forgot Clojure will memoize the rand-int function

agile_geek15:11:54

little more succinctly

(into [{} {}]
      (map (fn [n] {n ["test" #(fn [] (println "test"))]})
           (repeatedly 3 #(rand-int 100))))

agile_geek15:11:30

as repeatedly takes an int argument which is the number of repetitions

davebryand15:11:04

brilliant! Thank you @pbostrom

nooga16:11:59

is there a way to get field names from a record without instantiating?

roelof16:11:43

any macro specialist who can help me figure out what must be placed after the other part here : https://www.refheap.com/112028

moxaj16:11:33

@roelof (drop 2 form) would be my first guess

birdspider16:11:57

@nooga: maybe (map :name (:members (type-reflect <you record class>))) - but you'll have to substract with a field-less dummy record to only get the declared fieldnames

nooga16:11:55

thanks @birdspider, I’ll tinker with this

roelof16:11:25

it works well , I see the answer that im looking for

moxaj16:11:26

@roelof well, I assume that the value of others will be everything but the first 2 elements of the form, thus you drop 2

roelof16:11:05

and I fight the whole day against this and you solve it in a few seconds

gtrak17:11:55

could 1.8 have broken clojure.test line number reporting?

gtrak17:11:00

I'm getting -1's

gtrak17:11:43

I think it has to do with changes in the stack due to direct linking, interacting with my use of anonymous functions in test helper macros.

bronsa17:11:42

apparently -1 means invokeStatic

gtrak17:11:11

the invokes are -1, not invokestatic

bronsa17:11:22

yeah, sorry. invokes that get rerouted through invokeStatic

bronsa17:11:44

something similar might happen for invokePrim aswell

gtrak17:11:54

is it possible to keep line numbers on the var .invoke call by a compiler change?

gtrak17:11:16

it ends up looking like this in our code:

FAIL in (parser-test) (test.clj:-1)

gtrak17:11:55

where test.clj I think is clojure.test itself

ghadi17:11:42

I have a patch for that, noticed it in a report from @andy.fingerhut

gtrak17:11:49

thank goodness simple_smile

gtrak17:11:58

how do I upvote

ghadi17:11:33

Make a ticket first :) wasn't aware that it was a problem

gtrak17:11:47

using this pattern within my tests:

(defmacro check-query
  "The extra function wrapper is a stopgap to avoid java's method bytecode size too large limit..."
  [spec]
  `((fn [] (let [spec# (test-spec ~spec)]
              (swap! test-report-state conj spec#)
              (is (expected-es-query spec#))))))

gtrak17:11:46

the helper macro's purpose was to keep line numbers in the first place, without me having to write is everywhere simple_smile

gtrak17:11:16

whoops, there's an extra pprint require in there for no reason, but you get the picture.

ghadi17:11:20

K I'll put a possible patch after lunch

ghadi17:11:34

Unless @bronsa snipes it ;)

roelof18:11:21

Can anyone explain to me what this recepient means : (defprotocol Award (present [this recipient])) and why not a variable name as name

jstew18:11:32

name may not have been chosen because of clojure.core/name

roelof18:11:50

oke, I choose name as a example

roelof18:11:42

but the question stays, why here a variable name with two parts this recpient

roelof18:11:15

I do the clojure koans and try to understand things. This is a chapter about defrecord and deftype

jstew18:11:15

You're confused about the "this" parameter to the function?

roelof18:11:10

I think so, I never seen this before on koans

jstew18:11:20

It corresponds to the "thing" implementing that protocol. This may help clear that up: https://clojuredocs.org/clojure.core/defprotocol

jstew18:11:47

It doesn't have to be called "this", but it's required and refers to the thing implementing that interface.

roelof18:11:46

and in this case its implementing Award ??

jstew18:11:45

No, something else will implement Award. Like deftype or defrecord

jstew18:11:59

A protocol is for other things to implement.

jstew18:11:20

Think of Award like you would an interface.

jstew18:11:01

Sorry, I read your question as "being implemented by Award". So you're correct, it's the thing that's implementing your Award. Sorry about the confusion.

bronsa18:11:05

@ghadi: that bug is all yours to fix simple_smile

timvisher18:11:45

are there any state of clojure surveys that capture location?

roelof18:11:49

jstew: thanks

ghadi18:11:53

@gtrak: Added a patch, let me know if it helps

ghadi18:11:50

Though that example uses walk (which is recursive)...there's probably a more minimal case

andy.fingerhut19:11:08

@ghadi: Updated my tiny test repo with results of trying out your patch, and linked to them from a comment on the ticket http://dev.clojure.org/jira/browse/CLJ-1854. The results look good to me.

em20:11:38

I cannot load datomic.api into my environment, and I'm scratching my head. The thing is, the exception and its message don't give me much information. Does anybody know how to go about troubleshooting this? Error:

user=> (.printStackTrace *e)
java.lang.NoClassDefFoundError: Could not initialize class datomic.api__init
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.loadClassForName(RT.java:2093)
	at clojure.lang.RT.load(RT.java:430)

em20:11:19

I'm pretty sure I have the jar downloaded.

em20:11:03

via leiningen. The error is the result of running below inside lein repl

em20:11:21

user=> (require 'datomic.api)

em20:11:54

I googled around, etc. There were some hits, but none seemed relevant.

chris20:11:26

What's your profile.clj look like?

em20:11:44

:dependencies [[org.clojure/clojure "1.6.0"]
                 . . .
                 [com.datomic/datomic-pro "0.9.5327"]]

em20:11:52

sorry I had to simplify a bit.

em20:11:30

$ find .m2 -iname "*.jar" | grep datomic
.m2/repository/com/datomic/datomic-pro/0.9.5327/datomic-pro-0.9.5327.jar

johanatan20:11:30

Why don't we have better diff tools for LISP? For example, suppose I have a large block of logic (an AST) and I add a single line inside it which refers to a func defined in a newly enclosing letfn block (which refers/uses a few other functions from the same letfn block). A naive diff tool like the ones supplied by git and GitHub will show a huge block of deleted text and a huge block of added text replacing it (covering the entire scope of the letfn). I'm sure we can do better than this given the ease with which LISP can be parsed and manipulated.

johanatan20:11:19

[Reading a style guide for Elm which aims (among other goals) to minimize diffs led me down this line of thinking-- on the surface, naive diff tools can't do very well with this sort of edit to LISP code but a deeper/semantic diff tool is certainly feasible in LISPs (and perhaps more so) than other langs (yet we still don't see them in widespread use)].

roelof20:11:05

can someone explain to me what present does : (defprotocol Award (present [this recipient]))

roelof20:11:22

I can not find a reference in the clojure docs or cheat-sheet ?

swizzard20:11:38

that’s a protocol

rusty-software20:11:50

@roelof: protocols are similar to Interfaces in OO languages. In your example, present is a function specification (but not an implementation).

roelof20:11:44

sorry, can you explain it simpleer. I never learn interfaces in OO languages

Alex Miller (Clojure team)20:11:58

a protocol is a group of function signatures

Alex Miller (Clojure team)20:11:05

present is one of the function signatures

Alex Miller (Clojure team)20:11:25

it takes an instance (named this) and a recipient

roelof20:11:59

oke, that is why i see (this recipient ) as a sort of variable

Alex Miller (Clojure team)20:11:10

yes, it's a parameter to the function

Alex Miller (Clojure team)20:11:22

just like (defn present [this recipient])

Alex Miller (Clojure team)20:11:40

from a caller's point of view, exactly the same as that

roelof20:11:38

oke, I will read that also

roelof20:11:40

thanks all

Alex Miller (Clojure team)20:11:42

some ways you could create an instance that implements the protocol: 1) use reify to create an anonymous instance (reify Award (present [this recipient] (str "Awarded to " recipient))) 2) use extend-protocol to create a concrete extension (extend-protocol Award String (present [this recipient] (str "Awarded " this " to " recipient))) then any String can be "presented". 3) supply a protocol definition inside defrecord or deftype (defrecord FamousAward [title] Award (present [this recipient] (str "Awarded " title " to " recipient))) then (->FamousAward "Best Dad")

em21:11:40

It looks as if I missed at least one step in getting set up with datomic. Sorry about the noise.

andy.fingerhut21:11:01

@johanatan: I don't know if there is a tool specifically for diff'ing Lisp-style languages. There is clojure.data/diff that might help, but it probably isn't as sophisticated as one would like when diff'ing code to find common portions in substructure. 'git diff -w' (-w to ignore whitespace differences) often does better than without the -w

johanatan21:11:33

@andy.fingerhut: ahh, nice. Didn't know about -w. Will try that. Looks like there's a big opportunity here for LISPs to stay ahead of the curve.

triss23:11:17

hey all. if i want to extend + - / * is it still the done thing to extend clojure.algo.generic?