Fork me on GitHub
#clojure
<
2017-04-05
>
rmuslimov00:04:43

Please help with newbie java-source-paths question: When I’m repl I can easily import java classes from java-source-paths directories, if I restart REPL and leave code importing those classes it fails with Caused by: java.lang.ClassNotFoundException:

rmuslimov00:04:54

What I’m doing wrong?

seancorfield00:04:40

@rmuslimov How are you “restart[ing the] REPL” and how is that different to how you start it the first time?

rmuslimov00:04:03

when I started it for first time there was no import of local java classes

rmuslimov00:04:01

I wrote some code, left few import of local java classes. Check that it were working well, then closed REPL and tried to launch new one.

seancorfield00:04:09

If you’re new to Clojure and the Clojure ecosystem, we might want to move this discussion to the #beginners channel.

seancorfield00:04:33

But I’ll ask: when you launched the new REPL, did you launch it exactly the same way, in the same folder as before?

seancorfield00:04:57

Are you using Leiningen? Or Boot?

rmuslimov00:04:39

but no success, REPL can't import local java classes. If I comment all local java imports - it works

dpsutton03:04:29

is there a way to know what the "root" namespace of an application is, what it's name is, etc? ie, if i do lein new app name1, could i, in clojure code, recover name1?

dpsutton03:04:47

and all of the code would be name1.core, name1.db.users, etc

noisesmith03:04:19

not really - it's valid to have multiple entrypoints for starters

noisesmith03:04:24

and core is just a convention

dpsutton03:04:25

i can't rely on (System/getProperty "user.dir") and just check the last part of the path, etc

dpsutton03:04:36

i'm not worried about core, but about the common beginning string

noisesmith03:04:46

you can look at project.clj if it exists

dpsutton03:04:03

i'm analyzing a stacktrace in cider-nrepl and i'd like to mark whether it came from the user's application or not

noisesmith03:04:00

for a given resource, you can inquire for the path

dpsutton03:04:01

so that the stacktrace can be filtered down to just user code with the click of abutton

dpsutton03:04:34

yeah, the path works but that leaves me with conventions like underscores and hoping that the name of the directory is the name of the application

noisesmith03:04:06

eg if you know 'src' is the only part of the classpath on the local disk, you can use io/resource to ask for the file the namespace asks from, and check if the uri starts with ./src

dpsutton03:04:56

that might be an approach. thanks

noisesmith03:04:06

or wait - not exactly that, but it works

+user=> (.getPath ( "org/noisesmith/coordinator.clj"))
"/media/justin/806084F16084EEEA/clojure/coordinator/src/org/noisesmith/coordinator.clj"

noisesmith03:04:36

really - just check if it's a file!

noisesmith03:04:59

+user=> (.getProtocol ( "org/noisesmith/coordinator.clj"))
"file"

noisesmith03:04:09

if it came from a file. then the user probably cares 😄

dpsutton03:04:50

exactly. unfortunately, it looks all of the file info at this point is the compiled temp files

noisesmith03:04:54

:user=> (.getProtocol ( "clojure/core.clj"))
"jar"

noisesmith03:04:26

oh yuck - yeah, this is a project that doesn't use lein so I have the actual files as the resources

dpsutton03:04:22

ha yeah. i may need to recover it from the var name

dpsutton03:04:31

just making sure that java didn't expose something for me

dpsutton03:04:52

i appreciate you talking this over with me htough

noisesmith03:04:20

also for underscore conversion etc. clojure exposes that as a reusable function

dpsutton03:04:23

{:fn "divi",
  :method "invoke",
  :ns "cider.nrepl.middleware.stacktrace-test",
  :name "cider.nrepl.middleware.stacktrace_test$divi/invoke",
  :file "stacktrace_test.clj",
  :type :clj,
  :line 29,
  :var "cider.nrepl.middleware.stacktrace-test/divi",
  :class "cider.nrepl.middleware.stacktrace_test$divi",
  :flags #{:tooling :clj}}

dpsutton03:04:33

this is the information that i have, and i'm adding to the flags set

dpsutton03:04:51

in the past file was much nastier, so i'm hesitant to rely on that

noisesmith03:04:05

it's guaranteed that the path has to match the full ns name, for require to work at all

noisesmith03:04:35

(not counting the /tmp/init-foo type files of course which you don't require but contain code from the real files)

dpsutton03:04:36

so a reliable test would be ns -> file -> existence?

noisesmith03:04:55

yeah - with the . becoming / etc. and munging parts of the ns name

dpsutton03:04:06

alright. thanks for helping me refine that strategy

dpsutton04:04:54

what guarantees are there on the :file k/v in the meta hashmap for vars in a namespace?

didibus05:04:54

@dpsutton In general I wouldn't assume any meta to be a guarantee. A variety could be interned without even a file existing

mars0i05:04:06

@dpsutton can you run inside the same app? if so then would it be sufficient to parse the value of *ns* to get the first component? Just thought I'd offer another alternative in case it's relevant.

didibus05:04:13

@dpsutton but in the case of file on Vars, I think they're set when interned, and that's the only code path for defining them, so I think it can be true trusted. Just be aware what it does when no file exists.

qqq05:04:40

Is the following intended behaviour ?

(assoc nil 1 2) ==> { 1 2 }
(assoc! (transient nil) 1 2) ==> exception
I know that replacing nil with {} makes it work; its just the difference surprises me.

mars0i05:04:31

wierd that the first one works.

mars0i05:04:09

not the only oddity in what Clojure functions will accept. which I don't mind.

seancorfield05:04:20

@qqq Given what persistent! and transient do, it's not too surprising that they can only operate on concrete collections and not nil...?

qqq05:04:15

@seancorfield : good point, wtf is (transient nil) supposed to return ?

qqq05:04:35

it makes as much sense as (transient 2)

seancorfield05:04:09

If you look at (type (transient [])) you'll see a specific transient vector type -- but (type nil) is just nil. There's no type to transform.

qqq05:04:20

in theory, one could make this work via a (transient nil) => :transient-unkonown, and it stays unkonwn until one uses assoc! or conj! at which point it determines the type; but that is unnecessairly complex, and throwin gexceptino on (transient nil) makes more sense

seancorfield06:04:45

Yeah, the problem is that nil steps outside the type system -- to have a "transient nil" you'd have to cascade it through everything.

gazaxian06:04:18

nil’s a value and a type I guese

qqq07:04:25

besides writing a macro (which screws up debugging info), is there a nice way to use:

(let [ [a 1]
        [ b 2 ]] ...)
instead of
(let [a 1
  b 2] ...)
why would I want this? easier eamcs navigation

qqq08:04:25

@tbaldridge: regarding midje, iirc you mentioned preferring to avoid DSLs; with regards to spec, do you view spec as: (1) a DSL, but worth learning, or (2) not a DSL ?

piotr-yuxuan08:04:45

Hello 🙂 I'm trying to use JRuby binding.pry debug REPL from a Clojure REPL, any idea how to do it?

qqq09:04:47

instead of writing

(defn blah [a b c]
  (assert ::x a)
  (assert ::y b)
  (assert ::z c))
is there a way to write (defn-speced blah [ ::x a ::y b :: z c]) ?

rauh09:04:01

@qqq Don't go overboard with macros. For instance, Cursive users would hate that. You'd lose much of the IDE functionality. Just write a macro that assert multiple values like (assert-s ::x a ::y b)

rauh09:04:35

Same goes for the (let [[]]) idea.

qqq09:04:11

@rauh: you mistake how much I like macros

qqq09:04:21

I'm trying to do this without macros, thus asking if there is langauge support for this

qqq09:04:32

I don't care about cursive users; but macros makes exceptions ahrd to debug, whcih I do care about.

h.elmougy11:04:26

I'm struggling connecting luminus to oracle db using the following URL jdbc:oracle:thin:username/password:@10.29.10.214:1521:orcl I'm getting -- Error creating DB connection for jdbc:oracle:thin....

igrishaev11:04:36

Hi folks! Just in case somebody uses (or going to use) mocks in their tests, here is my small library to mock Clojure functions: https://github.com/igrishaev/mockery

lambder12:04:41

hi all, I need to implement a solution which traverses some data-structure and updates the state on the way. Ideally without taking the state as an explicit parameter. I've checked funcool's cats but they removed the state monad saying _They are not very useful in clojure_ https://github.com/funcool/cats/releases . What is the clojure idiomatic way of dealing with state in distributed set of functions?

fernandohur12:04:11

I’m not sure if this is what you’re looking for but anyway an interesting read: https://clojure.org/about/state

lsenjov12:04:35

Updates some external state while processing it?

lsenjov12:04:32

I mean, you can make a recursive function that processes the first item in a data structure, then updates external state, then recurses to the rest of the list

lsenjov12:04:42

The question though is why you're needing to do this?

tbaldridge12:04:23

@lambder I normally use postwalk and prewalk for that. For simplicity sake I'll keep the state in an atom:

tbaldridge12:04:09

(let [state (atom {})]
  (walk/postwalk
    some-data
    (fn [node]
      (swap! state ...)
      node)))

tbaldridge12:04:48

Or if I really cared about avoiding mutability I would write my own version of postwalk that threaded the state as an extra param to the walk function.

tbaldridge12:04:40

@qqq Yes, I consider spec to be a DSL. So the next thing I have to ask is how much the DSL forces me to learn new semantics and syntax. Here spec doesn't bother me much since the syntax is normal clojure, and the semantics match normal clojure fairly closely. Except of course (s/cat) and other regexes, but that closely matches parser combinator logic.

tbaldridge12:04:36

In fact almost all of Spec could be seen as a form of parser combinators, which really just boil down to function composition.

lambder12:04:45

@tbaldridge one thing, I can't walk my datastrucure in single function.

lambder12:04:42

@tbaldridge I'm thinking if I can have something similar to `(def state {}) (defn foo [x] (altervarroot state (assoc state :a x))) (defn bar [x] (altervarroot state (assoc state 😛 x))) `

tbaldridge12:04:57

no, you don't want to do that

lambder12:04:03

and I have not control on how foo and bar are invoked

lambder12:04:32

I know it's ugly, I want something analogous but functional style

lambder12:04:45

aka state monad

tbaldridge12:04:00

So why can't you walk the structure from one function, or dispatch from one function?

lambder12:04:03

why state monad is gone from cats?

tbaldridge12:04:51

there's no reason to use a monad for this

tbaldridge12:04:21

so why not dispatch from one function?

qqq12:04:04

(s/assert (s/coll-of any?) 20)
==> 20
how does this assertion not fail?

tbaldridge12:04:28

@qqq read the docs on assert

qqq12:04:06

Another option is to use s/assert within your code to assert that a value satisfies a spec. On success the value is returned and on failure an assertion error is thrown. By default assertion checking is off - this can be changed at the REPL with s/check-asserts or on startup by setting the system property clojure.spec.check-asserts=true.

qqq12:04:14

Are you referring to the part where by default assertion checking is off ?

lambder12:04:43

@tbaldridge let me think on this, I'll get back to you. many thanks

tbaldridge12:04:20

@lambder I will say this: monads are very rarely used in Clojure, they don't really offer much benefit for the cost.

qqq12:04:30

@lambder: don't listen to the nay sayers; I'm writing a typed DSL in clojure just so I can get monads 🙂

lambder12:04:34

@tbaldridge I'm not walking the datastrucuture this way.

lambder12:04:24

I use pattern matching lib (the defun) and dispatch on matched values

tbaldridge13:04:06

Well something to consider: 1) store your nodes in a hashmap, those are much easier to work with than vectors. 2) use multimethods. Even using vectors it's fairly trivial to do (defmulti eval (fn [state node] (first node)) 3) thread the state as a parameter. Implicit args just confuse readers

tbaldridge13:04:10

@lincpa do you have a question? I'm not sure why you're posting these images

lincpa13:04:11

just a DSL example

lincpa13:04:31

using defmulti

jaydeesimon15:04:45

i’m generating sql with honeysql and its working out great but i’d like to get a fully-formed sql query as a string with the placeholders resolved

jaydeesimon15:04:16

does anyone know if there are any jdbc classes I can call that can take this: ["SELECT * FROM my_table WHERE time > ?" #inst”1970-01-01T00:00:00.001000000-00:00"]

jaydeesimon15:04:56

to this SELECT * FROM my_table WHERE time > ‘1970-01-01’

jaydeesimon15:04:37

the result being a string

jaydeesimon15:04:03

i’m trying to avoid doing this manually

tbaldridge15:04:49

@jaydeesimon most SQL libraries don't support this directly, instead they'll hand these parameters to a SQL prepare statement, as that's a bit more secure against SQL-injection. What are you trying to accomplish?

jaydeesimon15:04:04

i’m trying to generate select statements that i’m going to wrap in a postgres COPY .. TO statement

tbaldridge15:04:17

Also notice the loss in precision in the conversion you are trying to perform, it's going from a full timestamp (with a timezone) to just a date (with no timezone)

jaydeesimon15:04:32

noted (just an example)

jaydeesimon15:04:40

when i try executing those statements using clojure.java.jdbc/execute! i get an error

jaydeesimon15:04:11

and I think its because postgres doesnt allow me to do the placeholders with COPY .. TO (emphasis on i think)

jaydeesimon15:04:31

passing a string with the placeholders resolved seems to work

jaydeesimon15:04:57

at the moment, i have a function that can resolve placeholders but it occurred to me that this happens already so theres gotta to be a way to reuse that code but i think i ran into what you said about how most sql libraries dont support this

tbaldridge15:04:11

Mind pasting the full query that doesn't work?

jaydeesimon15:04:21

sure, let me scrub it down to something thats easier to understand (that also doesnt work, of course)

donaldball15:04:32

If I have a defrecord with sensitive field values, should I implement both toString and provide a print-method method to help keep its values out of logs, or is one or the other sufficient?

jaydeesimon15:04:54

i could be wrong but i think that error is because postgres doesnt allow placeholders that are not inserts, updates, delete, etc (http://dba.stackexchange.com/questions/121453/error-there-is-no-parameter-1-in-execute-using-statement-in-plpgsql)

tbaldridge15:04:59

Yeah, I don't have any other advice then, besides that wrangling a SQL DSL may be harder than using a stored proc for something like this.

jaydeesimon15:04:45

no problem. thanks for your help though. i’ll just stick with resolving the placeholders manually. the datatypes i need to support are only integers and dates so the code i have written is simple enough. would prob be simpler than reaching into the jdbc driver depths of hell to reuse any potential placeholder resolving code anyway

jaydeesimon15:04:22

side note: i enjoyed your clojure/west talk!

scknkkrer18:04:48

guys, anyone who is using korma ?

scknkkrer18:04:06

I have an issue about utf8mb4.

tbaldridge18:04:42

I don't think many people run Korma at all, most I have talked to have moved on to HoneySQL, or HugSQL, or the like

byron-woodfork18:04:47

We ran/currently run Korma on a previous project I was on. I'm not on that project anymore but I don't recall using the utf8mb4 character set =/

scknkkrer18:04:52

I will too, but now on. I have to fix this.

donaldball18:04:46

There is a #sql room which might be a better place for a discussion, but having spent a good deal of time digging into korma, I would be a little bit surprised to discover that korma had a bad sql charset behavior that clojure.java.jdbc didn’t have

scknkkrer18:04:46

No one any idea ?

scknkkrer18:04:55

But please, if anyone have an idea, just write to me.

noisesmith18:04:50

@scknkkrer I realize this might sound snarky, but the easiest solution to utf8mb4 issues is not to use mysql and the issues just don't come up

noisesmith18:04:15

korma has nothing to do with it, it's about the db config, whether the issue even applies to the db backend, and the db driver

scknkkrer18:04:23

I realized it, my problem is not with korma, it’s jdbc.

scknkkrer18:04:04

but what can I do to fix that.

noisesmith18:04:05

that's going to be specific to your db and adaptor, and it's going to be the same answer you'd get if you were asking about java, so my first step would be to google for answers about configuring that db for java

noisesmith18:04:36

there's maybe a small conversion from the java config to the clojure, but it should be trivial

scknkkrer18:04:39

3 days in google, and nothing found.

noisesmith18:04:02

what is your db and the specific error happening/

scknkkrer18:04:09

not an error. It’s just putting it “some” characters like “?”

scknkkrer18:04:49

my language has some different characters like “ş, ç, ö, ğ, ı“.

scknkkrer18:04:53

the last one, “ı”.

scknkkrer18:04:13

just this one is writed as “?”.

scknkkrer18:04:52

I just tried all my language’s special characters and it’s just “ı” the problem here.

noisesmith18:04:43

what database? what adapter for that database?

seancorfield18:04:07

Take this to #sql — people are already answering there.

hcarvalhoaves18:04:15

@lambder "a solution which traverses some data-structure and updates"-> https://clojuredocs.org/clojure.zip/zipper ?

noisesmith20:04:30

=> (defn trun! "like run! but with a transducing arg" [xf proc coll] (transduce xf (completing #(proc %2)) nil coll))

noisesmith20:04:45

is that silly? is there already something else in core I should use instead of it?

hiredman20:04:38

what if proc doesn't need completing?

noisesmith20:04:49

the completing shouldn't hurt, since it's meant to ignore the reduction and return nil

hiredman20:04:15

what if proc's completing action flushes some kind of batch side effect

hiredman20:04:49

like, imagine xf was something like partition-by

hiredman21:04:43

partion-by builds up batches, then flushes them when a new partition value shows up, and the final batch is flushed by the completion arity

hiredman21:04:49

partition-by

noisesmith21:04:10

=> (trun! (comp (map inc) (filter even?) (mapcat #(vector % %)) (partition-by identity)) println [1 2 3 3 4 5])
[2 2]
[4 4 4 4]
[6 6]
nil
; looks fine to me

noisesmith21:04:58

unless this isn't the kind of usage of partition-by you had in mind? I'm slightly confused

noisesmith21:04:46

@hiredman I wrapped completing around the anonymous function because I got errors for the one argument arity, and I knew that should always return nil anyway, so completing seemed more elegant than making a multi-arity fn

hiredman21:04:11

no, I think I just forget all the corner cases where transduce and transducers either use or ignore the completing stuff

noisesmith21:04:41

OK - thanks for the feedback

hiredman21:04:43

right, and that checks, the proc would always be passed nil, and the ultimate f produced inside transduce (by applying xf to proc) will have the completing arities intact for the transducers

piotr.owsiak22:04:25

hi guys, could you suggest a way to solve this koan?

piotr.owsiak22:04:59

which is about destructuring

piotr.owsiak22:04:52

I'm wondering if it is possible to make it pass by only changing the _ part of the code

hcarvalhoaves22:04:43

@piotr.owsiak (fn [[name surname] {:keys [street-address city state]}] (clojure.string/join ", " [(str name " " surname) street-address city state])) maybe can be shorter

qqq23:04:46

Is there a way to turn s/assert on-off PER FILE ? i.e. I want s/assert to be on for foo.cljc but off for bar.cljc

qqq23:04:40

what about pre-post conditions of functions, i.e.

(defn ...
{:pre ...
 :post ...}
...)

lsenjov23:04:35

You could write an assert macro for each namespace

lsenjov23:04:46

And toggle them individually

Alex Miller (Clojure team)23:04:34

logging systems give you that level of control - maybe that would be a better match

qqq23:04:04

I want the following: is this a canary I'm doing something wrong? For each file, I have public and private functions. For the public functions, I want the assets to always be on. For the private functions, I want one toggle for all theri pre/post conditions (for debugging vs production).

Alex Miller (Clojure team)23:04:42

the built-in assertions don’t give you that level of control

qqq23:04:33

Is there an easy way to do this with reader macros

qqq23:04:46

to toggle the section of my code which says

{:pre ...
 :post ...
}

lsenjov23:04:14

Those are toggled globally on/off, I believe

lsenjov23:04:57

Your best course of action is probably writing a prodassert that's always on, and using assert for dev

Alex Miller (Clojure team)23:04:24

you could write your own assert that looks at a global map in an atom or something

Alex Miller (Clojure team)23:04:39

depends how perf sensitive you are but it’s pretty easy to macro this up

lsenjov23:04:51

If you still need to switch it by namespace, can have it take a boolean/a boolean atom as an argument for when it's checking

lsenjov23:04:26

(defn prodassert [check? assertion message] ...

tmayse23:04:31

if performance were a concern, would it be possible for a macro to return the forms unaltered based on metadata or something like that?