Fork me on GitHub
#beginners
<
2018-01-22
>
Vincent Cantin03:01:04

is it possible in cljs to have a map with one of its values being the map itself? If yes, how?

Vincent Cantin03:01:52

Oh, I found it. (assoc! transient-coll key transient-coll)

akiroz03:01:42

@vincent.cantin I don't think that's possible... but it might work if you override the ILookup protocol on a record or something......

akiroz03:01:29

assoc! only work on transient collections and they cannot be persisted recurrsively

Vincent Cantin03:01:42

Ah, that's a good idea, that might be better for my use case. Thank you.

akiroz03:01:14

@vincent.cantin Just out of curiosity, what are you trying to do?

Vincent Cantin03:01:49

I try to have a graph of data with cycles.

akiroz03:01:13

Ahh, I see~

Vincent Cantin03:01:19

For example, a graph of friendships. I wish to present the graph as a plain-ish map.

jaide05:01:14

Hopefully this is a more general problem that is quick to answer but I’m using pprint to print each item in a go-loop. In the repl it works as expected, but when running as a program using clj -m app it doesn’t error but no output is printed. It’s like in the program context it’s exiting before the go-loop finishes.

seancorfield05:01:31

@jayzawrotny Yup, in the REPL evaluation is forced because it needs to print it. If you're not printing it, you'll run into the same problem as with lazy sequences.

jaide05:01:20

@seancorfield Ohhhh is there an equivalent to dorun for go-loops or channels?

seancorfield06:01:24

Not really sure. I don't use core.async much.

jaide07:01:54

Aha! I learned what to do: Whatever your last channel is do (async/<!! ch) that will block until the output which in the case of a go-loop will wait until each item in the input channel has been read.

udit10:01:57

I am trying to create a plugin for a Java application. The plugin must extend a plugin class and implement a constructor with a parameter. This parameter is another class (Say PluginInfo) that comes from the Java app. I have added the namespace which declares the clojure plugin to be aot compiled. However when I try to run repl/clojure-app I get a null pointer exception stating that the PluginInfo was null. I am not sure what I am doing wrong here. The source code for the clojure app can be found here -> https://gitlab.com/yudistrange/josm-clj-plugin

udit11:01:23

If it helps the Java app in question is JOSM and the way to create new plugins for it in Java is documented here -> https://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins

noisesmith17:01:38

@udit why isn’t state defined?

noisesmith17:01:51

you reference it but I don’t see it in the code anywhere

noisesmith17:01:39

oh, never mind, now I get it

noisesmith17:01:21

@udit if you run this -main, where does info come from? who creates it? how?

Rachna18:01:47

Hey Everyone, I have the following function(analyze-data) which takes the data 'vd' in following form: (FAM FAM {:well A1, :name PC, :Ct 20.7274} {:well A1, :name PC, :Ct 20.727} {:well A10, :name , :Ct 0 } {:well A11, :name , :Ct 0}) 'I need to write the code in the following analyze-data function which can clean this data and remove the rows where :name has no data.' (defn analyze-data "Runs the data analysis on the passed validated data" [vd] (println "In analyze-data function ", vd) (try (fx/run! (let [tree-items (build-tree vd)] (fx/at! view (to-id :tableTTV) {:root tree-items})) ) (catch Throwable t (display-message "ERROR" "ERR008: ERROR ") (prn-level :error "ERR008: ERROR" (.toString t) (.getMessage t))(.printStackTrace t) ) )) Any idea/solution? 🙂

seancorfield18:01:36

@rachna.rajput99 Sounds like a basic filter to me: (filter (comp seq :name) vd) -- (comp seq :name) gets the :name element and returns truthy if it is not empty (missing, nil, or empty string).

Rachna18:01:30

Wow. its working. but as you said early: in clojure data structures are immutable. so how can I store this modified data to new data structure say 'vd1', and pass it to the try block.

madstap19:01:38

By using let

(let [cleaned-vd (filter (comp seq :name) vd)
      tree-items (build-tree cleaned-vd)]
  ,,,)

Rachna19:01:07

It worked!!!!. You guys are great. Thank you very much. 😃

Ahmad Nazir Raja19:01:53

Hi everyone, Clojure noob here. I am wondering how to idiomatically implement a function that can handle the following scenarios:

my-fn            ::  a  -> [a]
my-fn-for-vector :: [a] -> [a]
If I try to create a function that is overloaded, where each overloaded function has the same arity, that doesn't work. I am thinking along the lines:
(defn my-fn
  "Function that handles integers and vector of integers"
  [x]
  (cond (vector? x) x
    :else [x]))
Not sure if it is idiomatic.

Ahmad Nazir Raja20:01:00

@U0J9LVB6G Thanks... this was exactly what I was looking for!

seancorfield19:01:18

@ahmadnazir I'd probably just test vector? inside the function... but it depends on what you're really trying to do.

josh_tackett19:01:35

What's the best way to run both a API server and a server with a --main function? right now I'm set up with a working composure project, but I also want a main function to run

seancorfield19:01:37

You could use a multi-method or a protocol or a conditional test or...

seancorfield19:01:20

@josh_tackett Not sure what you mean... what would -main do if not start up the Ring server?

josh_tackett19:01:45

@seancorfield Exactly I want to start a main with a Ring server, but right now my ring server just starts an API

josh_tackett19:01:33

I'm reading here: https://github.com/ring-clojure/ring/wiki/Setup-for-production but not sure what lein command to run to run the server so the --main executes

Ahmad Nazir Raja19:01:57

@seancorfield Thanks for the response. I am just wondering if it is idiomatic? I want one function that can process a vector as well as a single entity.. because it helps readibility of the code (since there are less functions). Are there any disadvantages?

seancorfield20:01:47

@ahmadnazir I would say it's not really idiomatic and you should instead require a vector for the argument in all calls. But if the intent is just to treat a non-collection argument as a vector of one element, you could do this

(defn my-fn [a]
  (let [a (if (vector? a) a (vector a))]
    ,,,))

seancorfield20:01:31

(like I say: not idiomatic but if you really must ... 🙂 )

seancorfield20:01:27

@josh_tackett FWIW, I never bothered with the whole lein ring server thing to start web apps -- I just ran -main and had it start the server explicitly.

noisesmith21:01:00

I think the main advantage there is if you need an uberwar - it streamlines things for that

jaide21:01:00

@seancorfield What if @ahmadnazir created a general as-vec function? That would keep the defn from being too muddy with argument guards wouldn’t it?

(defn as-vec
  "Takes an argument and returns a vector or itself if already vector"
  [x]
  (if (vector? x) (vec x) x))

noisesmith21:01:20

@jayzawrotny doesn’t vec already do that?

jaide21:01:47

Oh, I’ll confirm

noisesmith21:01:05

penguin.babysit-test=> (source vec)
(defn vec
  "Creates a new vector containing the contents of coll. Java arrays
  will be aliased and should not be modified."
  {:added "1.0"
   :static true}
  ([coll]
   (if (vector? coll)
     (if (instance? clojure.lang.IObj coll)
       (with-meta coll nil)
       (clojure.lang.LazilyPersistentVector/create coll))
     (clojure.lang.LazilyPersistentVector/create coll))))
nil

jaide21:01:38

user=> (vec 2)
RuntimeException Unable to convert: class java.lang.Long to Object[]  clojure.lang.Util.runtimeException (Util.java:221)

noisesmith21:01:48

but your code fails the same way

noisesmith21:01:56

if you want vector, use vector not vec

jaide21:01:07

Good catch

noisesmith21:01:11

also, wanting to do that tends to be a symptom of bad design

jaide21:01:11

Agreed, plus I read the https://clojurians.slack.com/archives/C053AK3F9/p1516651087000547 article but was curious if a function like that made the pattern any more tolerable.

jaide21:01:43

;; anti-pattern 
;; but hypothetical solution
(defn as-vec
  "Takes an argument and returns a vector or itself if already vector"
  [x]
  (if (vector? x) x (vector x)))

jaide22:01:28

but in thinking about it I see the problem: It’s less the extra code required & more about the ambiguity it leaves when calling it in the mental or even in an explicit type-system

seancorfield22:01:56

FWIW, clojure.java.jdbc allows this sort of ambiguity -- but mostly because the parameter handling was broken in a long-ago version and I decided not to break code that relied on the bug. For example, these are both valid: (jdbc/query db "SELECT * FROM table") and (jdbc/query db ["SELECT * FROM table"]) -- the second form is the "correct" way to do it (and if you have SQL params, you must do it this way!) but the first form is a useful shorthand. Applies all across the java.jdbc API.

seancorfield22:01:54

(and you can use a PreparedStatement object in place of the SQL string -- in both cases)