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.

Eccentric J05: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.

Eccentric J05: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.

Eccentric J07: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. 😃

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

Eccentric J21: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?

Eccentric J21: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

Eccentric J21: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

noisesmith21:01:11

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

Eccentric J21: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.

Eccentric J21: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)))

Eccentric J22: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)