Fork me on GitHub
#beginners
<
2020-02-12
>
pdmct02:02:39

A quick question about java interop, say I have a method that returns its results into one of its args, how do I call this via java interop? eg.

//java
obj.transform(src, result) 

mark54002:02:05

I assume the object used to return results probably has a getter method for the result info, is that right? if so you would create the object and pass it, then use the getter method to get the result info. So just normal Java interop (object creation and method calling) would be needed.

pdmct02:02:17

thanks, yes it does, I'll give it a try

emmanueloga08:02:33

hey, as I keep working with a namespace in the repl I rename functions, etc, eventually the namespace in the repl gets really polluted with functions that don't exist anymore in the source file, etc... I was wondering what's a nice way to reset/recreate the namespace, without having to restart the repl, if there's one. Thanks!

andy.fingerhut08:02:22

I have not personally used it much, so I don't have wealth of experience to tell you any known possible pitfalls or warnings about using this, but there is remove-ns

emmanueloga08:02:24

Hmmm I found cider-refresh, although I'm not exactly sure what it does yet.

andy.fingerhut08:02:47

followed by require of that namespace again

andy.fingerhut08:02:41

e.g. I don't know what happens if you remove-ns while one or more other namespaces have been loaded, that refer to names in the removed ns

emmanueloga08:02:34

I tried cider-refresh and it worked nicely... but I'm not sure what it does exactly. I'd have to go through the docs [*] more carefully really soon 😄 *: https://docs.cider.mx/cider/usage/misc_features.html#_reloading_code

andy.fingerhut08:02:57

There is a #cider channel here where you can ask about that, if you cannot find docs, and/or the source code you find not easy to follow (I have not looked at it to know how it works)

emmanueloga08:02:31

gotcha thx! right that would be a better place to ask about cider specifics

jumar08:02:10

@ cider-refresh basically uses tools.namespace refresh: https://github.com/clojure/tools.namespace#reloading-code-motivation It's quite heavy tool to refresh a whole project. (As Andy suggested) you may use

(remove-ns *ns*)
but that has some corner cases like when other ns-es depend on that namespace (then you might need to remove and reload them too )

emmanueloga08:02:15

cool thx! since I'm working with a super small test project for now seems like the overhead is not that much

seancorfield18:02:34

I have a hotkey bound to remove-ns (and a hotkey bound to load-file) so if my current ns gets "stale" like that -- and is actually a problem (not all staleness is) -- then two key chords gets it back to being fresh.

seancorfield18:02:55

That's with Atom/Chlorine but it should be easy enough to program that up with Emacs too.

seancorfield18:02:29

(and I'll note that I don't use that remove-ns command very often -- and I have no other "refresh/reload" aspects to my workflow at all)

jr0cket15:02:05

Using cider-undef`` before deleting a def or defn ensures you dont pollute you namespace. I added , e u in spacemacs as I found this function so useful, especially for tests

ramon.rios13:02:23

Hello everyone. I had a small doubt: I tried to create a function with optional arguments. In my head, i remebered that i need to declair this way : (defn foo [val1 & val2]) and it did not worked as i expected. Did i miss something?

jaihindhreddy16:02:03

Clojure(Script) fns inherently don't have a concept of "optional arguments". What they do have, is multiple-arities, including variadic ones. Meaning one fn may take any number of arguments. What you do, when your fn gets called with n arguments for any given value of n, is completely up to you.

jaihindhreddy16:02:52

What you defined here is a fn foo that takes 1 or more than 1 arguments. In the fn body, the first arg is available with the name val1, and the rest of the arguments are available with the name val2.

jr0cket15:02:54

Example: (defn add-arguments [& args] (apply + args))

ramon.rios15:02:10

Thank you friend

peb.brzezinski13:02:42

@ramon.rios What about (defn foo [val1 &val2] ())?

mark54013:02:34

Instead of (defn foo [val1 & val2]) you probably want to name the last arg something else, for example (defn foo [val1 & more]) . The arg after & is a sequence of the remaining args, not a single arg.

mark54013:02:12

Were you expecting it to be a single arg?

ghadi14:02:04

If you're asking for help, say what you tried, and what your expectations were, what you did to validate your expectations, and what happened when you validated those expectations

ghadi14:02:26

Otherwise people try to mind-read

ramon.rios17:02:08

i truly sorry not respond at the time, i was in a sprint planning that took a long time. So i'll check the folks suggestions.

ramon.rios17:02:36

On my case, i have a function wich need to have 1 optional argument

ramon.rios17:02:06

What i tried to do is the code that i put in my first message, but i had arity issues

ramon.rios17:02:23

I was thinking about using multiple arity for solve this

ramon.rios17:02:44

but i remembered that i had this option, so that's why i asked.

seancorfield18:02:14

@ramon.rios If you just want a single argument to be optional:

(defn foo [val1 & [val2]] ...)
then you can check if val2 is truthy without having to pick apart a sequence of "additional arguments"

seancorfield18:02:06

Caveats: you can still pass more that 2 args to foo as written; you can't tell the difference between val2 being passed nil explicitly versus not being present.

seancorfield18:02:37

(you can handle val2 being false by testing (some? val2) if that's a use case you need)

seancorfield18:02:07

Or you can use multiple arities:

(defn foo
  ([val1] ... do stuff without val2)
  ([val1 val2] ... do stuff with val2))
now you can only pass one or two arguments, not more, and that first arity could just call (foo val1 nil) if nil is a suitable default value, much like the & version above.

heatonsam22:02:32

Hi everyone. Mind of I ask a super newbie question?

chepprey22:02:01

( @heatonsam ) This is the place

heatonsam23:02:47

Thank you! I'm doing something right now where I modify the values of a hash-map that's contained with other hash-maps in a seq. I do this by filtering by the value of a specific key to get the correct element. Of course by doing so I am returned only that element in the seq and lose the rest of the hash-maps. Example that is more or less what I'm doing:

(defn edit-element-by-id
  [id query-parameters data-from-file]
  (let [element (filter #(= (:vector %) id) data-from-file)]
    (let [args (walk/keywordize-keys query-parameters)]
      (map #(merge % (select-keys args (keys %))) element))))
However, what I really want is to get back the entire seq of hash-maps, with the element in question and its values changed.. I know I should be thinking bigger, but I've hit a slight conceptual roadblock...

michael.e.loughlin23:02:31

do you have an example use how you use that function?

heatonsam23:02:03

It's going to be called in a PUT request, I just separated out from the :body of the function.

michael.e.loughlin23:02:15

(have you checked out update-in?)

heatonsam23:02:48

I was originally trying to do this using update but I had trouble; I'll try update-in.

hiredman23:02:56

there are things you can do for that with clojure.zip or a library like specter

hiredman23:02:27

but I would structure data-from-file as not a seq

heatonsam23:02:51

Oh yeah, what form would you use and why?

hiredman23:02:43

well, from your example you could make a map of {(:vector m) m}, which would make it very easy to update the one you care about

hiredman23:02:36

the kind of ultimate end of that approach is to flatten all your data out and basically build a little in memory relational database, but there are a number of stops along the way between using a seq and that

hiredman23:02:20

a seq is basically the worst(lowest common denominator) datastructure, so structuring your data some other way is pretty much always going to give you more power

hiredman23:02:38

even just making it a vector would allow you to assoc in a new updated version of the map if you know the index

heatonsam23:02:58

I'm not sure I understand. data-from-file (which was originally from csv, but I dealt with all that crap...) looks like:

({:vector 1
  :name aname
  :otherfield other}
  {:vector 2
   :name othername
   :otherfield nother}
  ...)
So what you are saying is to make the outer data structure also a map, and use the id as the key for each element? 

noisesmith23:02:16

yes - you can do this directly with group-by

heatonsam23:02:45

In my code example ":vector" is the name used for the primary key in the godawful csv file provided by my professor, so sorry if that causes confusion.

heatonsam23:02:04

Ah ok, that makes sense. Then I can select the element easily

noisesmith23:02:54

user=> (group-by :vector [{:vector 0 :item :a} {:vector 1 :item :b} {:vector 0 :item :c}])
{0 [{:vector 0, :item :a} {:vector 0, :item :c}], 1 [{:vector 1, :item :b}]}
group-by does add extra structure

noisesmith23:02:02

but it's often a good start

noisesmith23:02:44

one thing to mind is this approach loses your original order - you can use map-indexed with assoc to capture that as data if needed

heatonsam23:02:41

Ok. The order of the outer map doesn't matter, just within each element in this case. I'm going to play around with these ideas - helps a lot.

michael.e.loughlin23:02:26

is there a checksum fn in clojure.core?

noisesmith23:02:38

hash isn't really meant to be a checksum, what are you trying to do?

michael.e.loughlin23:02:55

calculate a simple checksum for arbitrary clojure datastructures and save it to disk to be loaded and compared later. It doesn't need to verify authenticity.

nate_clojurians23:02:02

in the past I've used walk to convert all the clojure data structures to ordered versions, serialized using nippy, then hashed that

michael.e.loughlin23:02:31

I am using nippy to write to file in fact

michael.e.loughlin23:02:50

were you using Java interop?

nate_clojurians23:02:49

and I used clojure's walk stuff to convert the values in the structure to ordered versions

michael.e.loughlin23:02:24

hmm, I haven't thought that far ahead yet. I am using my checksum to weed out values corrupted on disk so hopefully I can just re-SHA before deserialize?

michael.e.loughlin23:02:32

I realise I actually formulated my original question badly