beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
sova-soars-the-sora 2021-04-29T00:16:44.221700Z

Hi. I have a vector of vectors of strings ... ^.^

(def vovos [ ["super" "snax" "zero"] ["blastin" "bumpin" "barging in"] ["two" "tamales" "tortillas"]])
And I want to search the [[s+][s+][s+]] for a specific term and return the vector-index. For exampla, desired resultsa: (search-it-real-good vovos "snax")
> 0, 1
(search-it-real-good vovos "tamales")
> 2, 1

sova-soars-the-sora 2021-04-29T00:18:14.223Z

I am thinking map-indexed or maybe reduce-kv ... any insight would be appreciated

2021-04-29T00:27:10.223200Z

Don't use a vector of vectors

2021-04-29T00:27:57.223700Z

Use two maps, one from pairs of indices to strings, another from strings to pairs of indices

seancorfield 2021-04-29T00:29:36.224500Z

Yup, that would likely be a much better representation, depending on what else you’re doing with this data (how you add/remove values, for example).

seancorfield 2021-04-29T00:29:47.224800Z

Otherwise you need something like this monstrosity:

dev=> (defn search-it-real-good [vs q]
 #_=>   (some (fn [[i x]] 
 #_=>           (some (fn [[j y]] (when (= y q) [i j])) 
 #_=>                 (map-indexed vector x))) 
 #_=>         (map-indexed vector vs)))
#'dev/search-it-real-good
dev=> (search-it-real-good vovos "snax")
[0 1]
dev=> (search-it-real-good vovos "tamales")
[2 1]

sova-soars-the-sora 2021-04-29T14:08:26.242400Z

thanks everyone

seancorfield 2021-04-29T00:31:51.225500Z

It would also matter whether the same string can appear in multiple locations — and what search-it-real-good should return in such cases?

sova-soars-the-sora 2021-04-29T16:35:24.256100Z

thanks a lot! uh, in this case they are very long sentences i'm matching against and ought only occur once. if they occur twice, the first occurrence is the desired result -- which is coincidentally how your code already works ^.^ so yeah. @hiredman mentioned to do it differently with reverse-index and primary index, which is the right answer for almost every use case like this, but the sequence of strings as vectors is important to preserve and this operation only needs to be called once in a while to memoize a location so i think it's fine. however, in the future, i'm wondering how to represent, say, chapters of a book split on page (of variable length) that would make sense for doing such searching, and especially when the contents of the pages and their sequence is mutable/ up in the air.

grazfather 2021-04-29T00:48:23.225600Z

but how? A sentinel value at the head of the vector to say if it’s ‘actually’ a vector? That still seems a bit janky, to me

walterl 2021-04-29T00:57:20.225800Z

For interest sake, what do you find monstrous about that?

2021-04-29T01:00:02.226Z

{:data-type :list :contents []}

2021-04-29T01:00:30.226200Z

that plus some multi-methods that dispatch on :data-type should get you pretty far

2021-04-29T01:00:54.226400Z

alternatively, you can use metadata, but I tend to prefer keeping things explicit and visible

grazfather 2021-04-29T01:12:01.226600Z

yeah, fair, I already have my tokenizer like that

seancorfield 2021-04-29T01:24:58.226800Z

It’s repetitive and that, together with the nesting, suggests “you’re doing it wrong”.

walterl 2021-04-29T01:27:10.227Z

Interesting. I clearly need to develop that sense [further]. Thanks for the explanation.

seancorfield 2021-04-29T01:29:50.227200Z

(def vovo-map (into {} (mapcat (fn [i v] (map (fn [j x] [x [i j]]) (range) v)) (range) vovos)))
that produces a hash map from strings to index pairs that would turn search-it-real-good into just (get vovo-map s)

seancorfield 2021-04-29T01:30:34.227400Z

If you have a common access pattern, it’s often better to optimize for it in terms of the data structure you use in the first place.

Franco Gasperino 2021-04-29T03:53:00.228900Z

What is the preferred method of shuttling edn content over http, specifically for data exchange between clojure and clojurescript? Transit or similar?

alexmiller 2021-04-29T04:21:56.229400Z

transit was designed primarily for that purpose

Aron 2021-04-29T06:40:42.230700Z

what is a way to take a specific message from a channel, another specific message from another channel, and when both arrived (in any order) send a message to a third channel?

phronmophobic 2021-04-29T07:09:03.231700Z

actually, I think a layer of nesting can be removed like so:

(go
  (let [x1 (async/pipe c1
                       (chan 1 (filter pred1)))
        x2 (async/pipe c2
                       (chan 1 (filter pred2)))]
    (>! c3 (+ (<! x1)
              (<! x2)))))

Aron 2021-04-29T07:55:44.232Z

+?

Aron 2021-04-29T07:56:07.232200Z

sorry, I know not the most relevant part : )

phronmophobic 2021-04-29T07:56:40.232600Z

you didn't specify what message to send to the third channel, so I just combined them with the shortest operator that came to mind

Aron 2021-04-29T07:56:59.232900Z

yeah, it made sense, i like it

phronmophobic 2021-04-29T07:58:03.233100Z

it's still a little underspecified with respect to how channels should be closed and whether or not c1 or c2 might have other consumers, but it's hopefully a good start

Aron 2021-04-29T07:59:05.233300Z

interesting because it's obvious, but (and I am guessing on my own subconscious here) because in one case i have nothing to combine just the fact that the event happened at all (no content beyond that), I didn't realize it's this straightforward to wait on two channels at once

phronmophobic 2021-04-29T08:00:32.233600Z

:thumbsup: , the only thing to watch out for is to pipe both channels before reading from either channel to make sure messages are being consumed until the expected message shows up

phronmophobic 2021-04-29T08:01:21.233800Z

eg

(go
  (let [x1 (async/pipe c1
                       (chan 1 (filter pred1)))
        x2 (async/pipe c2
                       (chan 1 (filter pred2)))]
    (<! x1)
    (<! x2)
    (>! c3 42))

Aron 2021-04-29T08:02:52.234Z

I am inside a subscription, I think that solves this too?

Aron 2021-04-29T06:51:57.231100Z

so it's like promise.all without the rejection

phronmophobic 2021-04-29T06:59:49.231200Z

I haven't tested it, but I think something like this should work:

(go
  (let [x1 (go (<! (async/pipe c1
                               (chan 1 (filter pred1)))))
        x2 (go (<! (async/pipe c2
                               (chan 1 (filter pred2)))))]
    (>! c3 (+ (<! x1)
              (<! x2)))))

NoahTheDuke 2021-04-29T13:44:25.235Z

is it possible to run a clj -X my-ns/hello style command from another directory than the src directory?

alexmiller 2021-04-29T13:49:12.235700Z

it has to be on the classpath

alexmiller 2021-04-29T13:49:21.236Z

so yes (if the other dir is on the classpath)

NoahTheDuke 2021-04-29T13:56:18.237500Z

i want to use python to run a -main function in a single clojure file with a single dep

NoahTheDuke 2021-04-29T13:58:17.238500Z

i have /usr/local/bin/clojure -Sdeps {:deps {org.clojure/data.json {:mvn/version "2.2.2"}}} but I'm unsure what to write after to call the -main of my target clojure file

alexmiller 2021-04-29T13:59:11.238900Z

-M -m the.ns

NoahTheDuke 2021-04-29T13:59:48.239500Z

-M /path/to/file -m the.ns?

alexmiller 2021-04-29T14:06:14.240Z

if you're loading it as a main class, it must be on the classpath, so there is file path involved

alexmiller 2021-04-29T14:06:43.240800Z

if you need to add to the cp, you can add :paths ["whatever"] to the -Sdeps above

alexmiller 2021-04-29T14:07:29.241500Z

/usr/local/bin/clojure -Sdeps '{:paths ["path"] :deps {org.clojure/data.json {:mvn/version "2.2.2"}}}' -M -m main-ns

alexmiller 2021-04-29T14:07:55.242Z

I'm guessing as you have not described the file structure, but if you did then I could be more specific

alexmiller 2021-04-29T14:09:11.243300Z

if the file is a script (no -main, no ns, just run top-level functions to be run), then you could skip adding it to the classpath or using -m: /usr/local/bin/clojure -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.2.2"}}}' -M path/to/file.clj

NoahTheDuke 2021-04-29T14:09:51.243600Z

oh that's an interesting idea, i'll try that

NoahTheDuke 2021-04-29T14:10:06.243900Z

is it possible to pass in args in that case?

NoahTheDuke 2021-04-29T14:11:40.244100Z

ah yes, *command-line-args*

NoahTheDuke 2021-04-29T14:21:51.245Z

if i run my command myself, it works: /usr/local/bin/clojure -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.2.2"}}}' -M /Users/noah/Personal/JSONTestSuite/parsers/test_clojure/src/test_json.clj /Users/noah/Personal/JSONTestSuite/test_parsing/y_array_empty-string.json

NoahTheDuke 2021-04-29T14:22:33.245700Z

if i use the python script (which prints that out before using subprocess to run it), i get an Error building classpath. Don't know how to create ISeq from: clojure.lang.Symbol error

NoahTheDuke 2021-04-29T14:22:49.245900Z

(this is the python script: https://github.com/nst/JSONTestSuite/blob/master/run_tests.py)

alexmiller 2021-04-29T14:26:36.247600Z

given that the command runs by itself, I'm going to guess it's in how you're calling it from python. I would be most suspicious of the escaping/quoting/spaces in the -Sdeps. Is there more to that error or an error file?

NoahTheDuke 2021-04-29T14:34:08.248800Z

sadly, no. after doing a bit of digging in how python does this stuff, it seems i can't/shouldn't quote the {:deps } map. removing the single quotes solves it, which is surprising to me

NoahTheDuke 2021-04-29T14:34:26.249Z

thanks for the help

2021-04-29T15:01:34.250800Z

Hi everyone, I have a question regarding java interop : how can I type hint java method calls with variable length arguments ? (using ^"ClassName[]" did not seem to work) The method's signature : handleEventsWith(EventHandler<? super T>... handlers)

ghadi 2021-04-29T15:07:49.252200Z

please provide an example of the signature you're trying to call

borkdude 2021-04-29T15:07:59.252400Z

@ho0man you can get this type by doing (type (into-array ClassName [])),e.g:

user=> (type (into-array java.nio.file.Path []))
[Ljava.nio.file.Path;
And then you can use "[Ljava.nio.file.Path;" as the type hint.

borkdude 2021-04-29T15:11:36.253300Z

(btw, if this question arises from the usage of java.nio.file interop, take a look at babashka.fs which solves most of this using a clojure API)

2021-04-29T15:16:07.253400Z

Thanks a lot @borkdude

Eric Ihli 2021-04-29T22:22:42.258200Z

(-> [1]
       zip/vector-zip
       zip/down
       (zip/replace [2])
       zip/path)
  ;; => [[1]]
I was expecting that path to be [[2]]. Once I replace a node, how do I get zip/path to reflect the new path? I see I could use https://clojuredocs.org/clojure.zip/root, but how would I get back down to where I was in the zipper after using root?

2021-04-29T22:45:45.258700Z

you have to zip/up and then zip/down again

2021-04-29T22:46:59.259600Z

the path records the tree you walk through to get where you are, and even though you replaced a node, when you walked down to it it was the previous value

👍 1