This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-12
Channels
- # adventofcode (67)
- # announcements (8)
- # babashka (46)
- # beginners (154)
- # calva (5)
- # cider (9)
- # clara (5)
- # clj-kondo (34)
- # cljdoc (31)
- # cljsrn (4)
- # clojure (146)
- # clojure-europe (5)
- # clojure-italy (3)
- # clojure-losangeles (2)
- # clojure-nl (149)
- # clojure-spec (22)
- # clojure-uk (73)
- # clojured (6)
- # clojurescript (95)
- # clojureverse-ops (3)
- # cryogen (7)
- # cursive (12)
- # data-science (1)
- # datomic (9)
- # docker (1)
- # emacs (1)
- # figwheel-main (1)
- # hyperfiddle (1)
- # jobs (3)
- # malli (29)
- # nrepl (2)
- # off-topic (61)
- # pathom (6)
- # pedestal (1)
- # planck (1)
- # reitit (19)
- # shadow-cljs (52)
- # spacemacs (5)
- # tools-deps (24)
- # vim (30)
- # yada (6)
What’s the elegant way of doing something like:
(or
(get m :foo)
(get m :bar)
(get m :zap))
I see it often, and although it’s clear that way, I don’t like it (for some reason)yeah, it’s tricky because it’s kind of opposite of every-pred
but the name is not similar
The Clojure cheat sheet puts them in the same group with each other, so if you remember one, you can find the other: https://clojure.org/api/cheatsheet
I'm working on a library to be called from both clojure and clojurescript. I'd like to write unit tests in .cljc files and have them work in both clojure and clojurescript, though I expect I'd invoke them differently (via different repls or test runners). Are there examples of others doing this I can study?
The latest core.rrb-vector library is almost ready to do this, as soon as the primary author agrees they are willing to require Clojure 1.7.0 and later, when clic files were introduced. It has several test files that are nearly identical to each other for clj and cljs, and ready to be merged into common clic files with only a small use of reader conditionals in a few places. It also has a debug.clj and debug.cljs file nearly identical similarly ready to be merged into a common clic file. It has a deps.edn file that can run tests for each clj or cljs from the command line, and a Leiningen project.clj file that can run tests for either clj or cljs. https://github.com/clojure/core.rrb-vector Note that this was my first project I worked on using cljs at all, so I don't claim it is necessarily the best way to do things here.
The README of that project gives several commands you can use to run the included tests.
@UDF1WUJTH I have lots of examples on my Paprika library: https://github.com/mauricioszabo/paprika/tree/master/test/paprika
It also have a CI script (.travis.yml) to run tests on both Clojure and ClojureScript
@U3Y18N0UC @U0CMVHBL2 Thank you!!
08:58:24.138 INFO: ------------------------------------------------------------------------ 08:58:24.138 ERROR: Error during SonarQube Scanner execution org.sonar.api.utils.command.CommandException: http://java.io.IOException: Cannot run program "lein": CreateProcess error=2, The system cannot find the file specified at org.sonar.api.utils.command.CommandExecutor.execute(CommandExecutor.java:102) at org.sonar.plugins.clojure.sensors.CommandRunner.run(CommandRunner.java:36) at org.sonar.plugins.clojure.sensors.CommandRunner.run(CommandRunner.java:50) at org.sonar.plugins.clojure.sensors.eastwood.EastwoodSensor.execute(EastwoodSensor.java:47) at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48) at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85) at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:62) at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:387) at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:383) at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:346) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:141) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72) at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66) at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60) at com.sun.proxy.$Proxy0.execute(Unknown Source) at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189) at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138) at org.sonarsource.scanner.cli.Main.execute(Main.java:112) at org.sonarsource.scanner.cli.Main.execute(Main.java:75) at org.sonarsource.scanner.cli.Main.main(Main.java:61) Caused by: http://java.io.IOException: Cannot run program "lein": CreateProcess error=2, The system cannot find the file specified at java.base/java.lang.ProcessBuilder.start(Unknown Source) at java.base/java.lang.ProcessBuilder.start(Unknown Source) at org.sonar.api.utils.command.CommandExecutor.execute(CommandExecutor.java:74) ... 31 more Caused by: http://java.io.IOException: CreateProcess error=2, The system cannot find the file specified Even the lein is added to the PATH variable. $ which lein /c/Users/XXXXXX/lein
This is the setup I am trying in local windows machine. and we are trying to run the sonarqube code analysis for clojure projects
:jvm-opts ["-Xmx15g" "-server"] is the memory settings in my project.clj file
Thanks in advance
I have opted into keeping the lein script in my repos, as it installs itself on the go if needed. Doing the same with gradle wrapper for java projects.
Lein bash script is pretty tiny. It fits.
And i actually want to write code and make products/services work, not spend my life configuring and tracing issues of various build agents & platforms 🙂
are nested syntax-quotes a feature or undefined territory?
(println
`(+ 1 2 3 `(+ 1 2 3)))
fwiw, they appear in "joy of clojure" and other places. coincidentally, trying to wrap my head around reading them :)
@UG1C3AD5Z I mean nested without an intermediate unquote
i haven't found that to be too common, but that does appear in the aforementioned book.
ha ha ha fwiw, i haven't thoroughly digested the book -- the place i saw it was in 8.1.1 in a side bar. not so sure there are that many real-world uses for such things.
Someone mentioned this code in #clj-kondo:
(defn example
[name]
`(defmacro ~name [& args#]
`(foo ~(keyword '~name) ~@args#)))
if stuff gets scary then people tend to bring out pitchforks ... and this is getting slightly scary yes 😄
is there any not-too-hacky way to use an existing third-party clojurescript library (in my case com.taoensso/sente) from a client-side (webpacked) javascript (vuejs) project?
I have an example here: https://github.com/borkdude/sci/blob/master/src/sci/impl/js.cljs
The channels #announcements and #news-and-articles are a better place for posting links like this one.
Thanks for next time!
Hello, I'm trying to get a simple redirect middleware to work with compojure-api, while my middleware indeed seems to be getting called, the redirect isn't working. Any ideas? Here's what my code looks like:
(defn redirect [handler]
(fn [req]
(let [uri (:uri req)
fixed-req (assoc req :uri "")]
(handler fixed-req))))
(def app
(api
{:swagger
{:ui "/"
:spec "/swagger.json"
:data {:info {:title "Dice-api"
:description "Compojure Api example"}
:tags [{:name "api", :description "some apis"}]}}}
(context "/api" []
:tags ["api"]
:middleware [redirect]
(GET "/roll/:n/:s" []
:path-params [n :- s/Int
s :- s/Int]
:return Result
:summary "Rolls :n dice of sides :s"
(ok (roll-dice n s)))
(POST "/roll" []
:body-params [num :- s/Int
sides :- s/Int]
:return Result
:summary "Given a correct request body with keys :num and :sides, returns result of roll"
(ok (roll-dice num sides))))
(undocumented
(route/resources "/")
(route/not-found "404 Not Found"))))
@amalantony to always redirect, you could:
(defn redirect [handler]
(fn [req]
(see-other "")))
@U055NJ5CC That actually works for redirection. Thanks.
is there a clean way to modify multiple items at the bottom of a deeply nested series of hash-maps and sequences?
without a bunch of nested maps/updates
If you do that often, consider using https://github.com/redplanetlabs/specter
Hi everyone, running into a weird compiling error. Getting the following message:
Syntax error compiling at (report_logic.clj:1:1).
Unable to resolve symbol: in this context
it happens when I am trying to evaluate my entire project.
yes that seems to be the case
yeah, seems if i add a zero width space i get the same error. I would assume simply removing it/them it would solve the issue
My guess as to why it fails is because java doesn’t treat Zero width spaces as ‘whitespace’, and it seems that Clojure uses java’s definition of whitespace while reading files. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L130-L132
yea, i am just a little confused as to where the error comes from... there is no whitespace as far as i can tell
it definitely seems to be there in the message you pasted. you can check by highlighting and moving the cursor with the arrow keys
@ablazevix hexdump -C
or something like that is your friend.
awesome thanks guys, i'll try some things
can you help me with walkable
library? I managed to get a "floor-plan" that is created correctly (though i'm not sure, at least it doesn't cause an exception). I wrote a simple query:
(def my-query [{(:person/all {:limit 5}) [:person/name :person/surname]}])
When I try to print it I get
[{nil [:person/name :person/surname]}]
What should I do to get a query string to pas it to jdbc/query? Or does it work other way? I suppose there should be some function for that in walkable library but there is nothing about executing queries in it's docsmy-query
is a vector of one map.
That one map's key is (:person/all {:limit 5})
.
Since you're using parenthesis and are not quoting anything, it because a call of function :person/all
on map {:limit 5}
. The map doesn't have that key, so the result is nil
, which you see when you print my-query
.
This particular error has nothing to do with the walkable
library itself.
Alas, I cannot answer your other question about turning this vector into a string.
But the answer to that question is probably here, in the documentation: https://walkable.gitlab.io/emitter.html
There's a #walkable channel if you need assistance with it @UEQDV142J
I have values in my program that are sorted-map-by
with a custom comparator. Up until now I used a reader tag to read back those values in EDN but now I want to read/write in transit. All those values have a :type
metadata (say :foo
). Providing a write handler with {:foo foo-write-handler}
seems that it doesn’t work and I can understand why. My question is what is the preferrable approach if one wants to read/write in transit a value that has type metadata?
"doesn't work" == what ?
have you seen http://blog.cognitect.com/blog/2015/9/10/extending-transit example ?
Yes I read that. By doesn’t work means that in the handlers map
{:handlers {clojure.lang.PersistentTreeSet sorted-set-write-handler}}
correct, you cannot.
transit-clj is built on transit-java, and relies on concrete classes, not metadata (as Java doesn't have it)
use clojure.lang.PersistentTreeMap ?
hmm yeah you are right I can use that and emit a custom tag if the value has my :type
metadata so as to use the custom comparator to construct the value
because t/write-handler
accepts a function that given the value returns the tag to write for that value
thanks @alexmiller
I don't know which is best supported or featureful/working, but these exist: https://github.com/walmartlabs/vizdeps. https://cljdoc.org/d/lein-hiera/lein-hiera/1.1.0/doc/readme
Quick try with lein hiera:
java.lang.IllegalArgumentException: "Unparsable namespace form:" ["parinfer-codemirror"]
💥 😉
can anyone recommend a way to get a value out of a hash-map? I tried (vals #{:shoes})
but i believe vals
only works on maps
Value out of a set or a hash-map?
sorry, I meant hash-set #{:shoes}
Could you provide a slightly more detailed example? Are you trying to convert a set into a list/vector?
I have a map in which there is a KV pair
:interests {#:shoes}
:interests {#:clothes}
:interests {#:watches}
im slurping out interests, and the values are coming out as {#:shoes} {#:clothes}
instead would like to have them come out as strings
was thinking of doing that with mapping vals
but that won't work I think
You could just call seq
on the set.
But the set itself is a collection, so you can pass it to map
.
(map name #{:shoes :pants})
=> ("shoes" "pants")
right on, thanks gentleman
newbie question -- how often do you use seq
?
all sequence function seq their input, so generally you don't need to use it that often
I mostly only use it for checking whether some collection or sequence is non-empty...
good to know! thanks again folks
I just searched our codebase for calls to seq
(90K lines of Clojure) and there are maybe half a dozen places where we call seq
outside of a conditional context (`if`, when
, etc) -- and those half dozen are all in really old code and seem to be unnecessary so they could be removed... indicative of days when we were still very new to Clojure!
Is it possible in Java (and thus Clojure), from a Java program running in a TTY, to run a subprocess with access to that same TTY (or some kind of pseudo-terminal to the same effect, so that the user can interact with that subprocess as though it were running in the same TTY)?
The closest I've gotten is using ProcessBuilder.inheritIO
, but that just redirects stderr, stdout, and stdin, without giving real terminal access to the subprocess (vim, for example, will warn that "Output is not to a terminal" and "Input is not from a terminal" and will not be usable).
I don't know, but you may get better results than the following maybe-useful page, which I found using Google with search terms: java subprocess inherit tty https://jonisalonen.com/2012/runtime-exec-with-unix-console-programs/
which links to this thing that was added in JDK 7: https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.Redirect.html#INHERIT
yes, ProcessBuilder.inheritIO
which I mentioned is just a shorthand for that. It might work for simple tools like less (the example on that page), but it is not sufficient for curses-type tools which need to control the cursor, determine window size, etc.
It looks like the only way to do this is a kludge using bash, which I'm trying now: https://stackoverflow.com/questions/29733038/running-interactive-shell-program-in-java
I wonder if that kluge is possible without bash, since you can pass a file for the child to use for io - or maybe bash does something "magic" for /dev/tty
this successfully runs vi with full tty from OSX:
justin.smith@C02RW05WFVH6: ~$ clojure vilaunch.clj
0
;; viluanch.clj
(def vi-ret
(let [vi-command (ProcessBuilder. ["/usr/bin/vi"])
tty (.File. "/dev/tty")]
(doto vi-command
(.redirectError tty)
(.redirectOutput tty)
(.redirectInput tty))
(-> vi-command
(.start)
(.waitFor))))
(prn vi-ret)
running that file gives you a normal vi session, then prints the return value of the vi process before exiting
I was skeptical, but that code also works inside a repl that uses readline via clj!
hmm, for me (OSX, http://terminal.app, clojure cli tool) this works too:
(-> (ProcessBuilder. ["/usr/bin/vi"])
(.inheritIO)
(.start)
(.waitFor))
hmm. that second one didn't work for me with vim. I didn't try with plain vi, though. The first approach looks interesting, I will try that as well.
note that the waitFor is mandatory - vi and the repl both become unusable without the waitFor, as they take turns stealing input and neither gets coherent input
Is there a way to get :extra-deps
to resolve using :default-deps
? Usecase is I want to have an eastwood alias across many modules, but I don’t want to repeat the eastwood version
@favila You want :override-deps
for that, not :default-deps
Then you can say :extra-deps {some.group/artifact {}}
(which is what we do at work)
I don't think :default-deps
really works...?
i.e. versions not explicitly required via a deps.edn, but required via a transitive dependency
My reading of what Alex has said about :default-deps
is that they really aren't fully fleshed out so I've avoided them. In answer to your question about transitive deps, yes, :override-deps
will pin those too (we rely on that a lot).
this successfully runs vi with full tty from OSX:
justin.smith@C02RW05WFVH6: ~$ clojure vilaunch.clj
0
;; viluanch.clj
(def vi-ret
(let [vi-command (ProcessBuilder. ["/usr/bin/vi"])
tty (.File. "/dev/tty")]
(doto vi-command
(.redirectError tty)
(.redirectOutput tty)
(.redirectInput tty))
(-> vi-command
(.start)
(.waitFor))))
(prn vi-ret)
I need help with the following. I am composing transducers. The input data is a vector of tuples of three things: an integer, a string and a map. The first couple of transducers in the composition reshape only the maps and leave the integers and the strings unchanged. Only the last transducer combines all the data. I managed to do this, but I wonder if there is a better way. If the composition were a defn, I would use let to put the unused string and integer aside; alas transducer compositions are defs.
Are you re-using this transducer chain on a lot of different datasets? Otherwise just make a function out of it.
I use it in an core.async pipeline to process REST API json responses. The different transducers do the following: extract body from the http response, parse json, extract some data from the json (several steps), combine the extracted data with the parameters I used initially for the API call. I prefer the transducers over functions because of the performance gain (no intermediate sequences between calculations) and the ease of use with the pipeline function I run the whole thing in a loop over hundreds of API calls. The responses all have the same structure.
@nick.romer what specifically would a defn do here that a def wouldn't be able to?
As far as I understand (noob,first heard about clojure 2 months ago) def allows to compose transducers using comp, while defn doesn't. Inversely, defn has access to the data being transformed (the function arguments), while def doesn't. Only the individual transducers being chained together do have access.
What do you mean by "defn has access to the data"? defn
is just a syntactic sugar for (def (fn ...))
.
I should have said fn. A function has arguments. A composition of transducers doesn't.
If you're worrying that you have all these transform-third-map
functions lying around not being very generic, just extract transform-map
functions from them and wrap them in something like (fn [[x y m]] [x y (transform-map m)])
(assuming that you're fine working only with vectors).
Strictly speaking, a composition of transducers has arguments - it's a reducing function. But I probably see what you mean. And how would having the arguments help you?
Maybe it would be easier for us to understand what you want if there was a concrete example.
I actually did what you proposed above. What bothers me is that I have to let the non-map values trickle down the chain of transducers. I'd rather put them somewhere temporarily and fetch them when I need them. Is it possible to have 2 parallel chains of transducers and to join them at some point?
> I'd rather put them somewhere temporarily and fetch them when I need them You need transducers only to do half of the job. Just do exactly as you have yourself told - extract the not relevant values under some name, run the transducers chain over the stripped down data, join the result back with the extracted values.
If you have all sorts of different extractions, mappings, and joins throughout your projects, you can find https://github.com/redplanetlabs/specter useful.
You understood my problem correctly. I guess I'll have to let go of the pipeline function and put / retrieve my data on / from the channels with <! And >! . I didn't know about specter. I'll look into it. Thank you very much!
I use it in an core.async pipeline to process REST API json responses. The different transducers do the following: extract body from the http response, parse json, extract some data from the json (several steps), combine the extracted data with the parameters I used initially for the API call. I prefer the transducers over functions because of the performance gain (no intermediate sequences between calculations) and the ease of use with the pipeline function I run the whole thing in a loop over hundreds of API calls. The responses all have the same structure.
As far as I understand (noob,first heard about clojure 2 months ago) def allows to compose transducers using comp, while defn doesn't. Inversely, defn has access to the data being transformed (the function arguments), while def doesn't. Only the individual transducers being chained together do have access.