This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-10-23
Channels
- # announcements (1)
- # architecture (20)
- # babashka (30)
- # beginners (79)
- # calva (27)
- # cider (8)
- # clj-kondo (1)
- # clojure (125)
- # clojure-australia (1)
- # clojure-berlin (4)
- # clojure-europe (62)
- # clojure-france (1)
- # clojure-italy (6)
- # clojure-nl (4)
- # clojure-uk (12)
- # clojuredesign-podcast (5)
- # clojurescript (28)
- # core-async (31)
- # cursive (14)
- # datomic (47)
- # defnpodcast (1)
- # emacs (7)
- # figwheel-main (2)
- # fulcro (10)
- # graalvm (1)
- # graphql (11)
- # jobs-discuss (8)
- # leiningen (2)
- # off-topic (23)
- # rdf (9)
- # re-frame (3)
- # reagent (1)
- # reitit (5)
- # reveal (12)
- # shadow-cljs (12)
- # spacemacs (1)
- # tools-deps (87)
- # vim (22)
- # xtdb (21)
Anybody has idea on how we can run PACT Test as provider for amqp tests in Clojure, I’m using https://github.com/DiUS/pact-jvm
No idea, but have you also looked at the Clojure solutions available? If you need to generate fake requests, there is e.g. ring-mock
I use leiningen and I use pomegranate to add libraries needed when I experiment in the repl to avoid restarting the repl. Any other alternatives? quick google search shows alembic and add-lib
In Rich Hickey’s talk Simple Made Easy he talks about set functions as a source of simplicity opposed to imperative loops/folds as a source of complexity
I believe that's a set, used as a function, like so:
(#{1 2 3} 1)
=> 1
(#{1 2 3} 42)
=> nil
I believe he's referring to mathematical sets and implementations of them in clojure. Functions on sets like intersection/ union / conj / disj are simple because they are idempotent. Sets are simple because ultimately they're only about membership. I do not think he meant Seqs and all the functions that surround Seqs. Those properties of sets allow for declarative expression and manipulation of membership, whereas other data structures may require careful policing and ordering to achieve the same which leads to more complex and imperative code.
it's about what collection functions that complect what's to be done and how that's done. he pointed loop and fold as examples. although both operates on whole collection (what), both operate from first element, one-by-one, to last element (how). like when using map or filter, we don't care the how, the order of things or the order of how things work--whether the work done from beginning-to-end, end-to-beginning, or even worked in parallel. I guess Rich named those 'set functions' because sets don't have ordering in its members.
Right… I have a hard time thinking it relates to clojure.set as you can do so much more in a imperative loop/fold than what clojure.set offers
Best I can make out of it is functions that take sets (in the mathematical sense, which for clojure could be lists, vectors, maps, sets, etc) and apply a function on each element in the set and then returns the output. So map, reduce, filter, etc would all apply
The functions you're quoting here operate on the Seq abstraction, which is a very central Clojure thing. Maybe every seq is a set in the mathematical sense, but I doubt that was the point there.
Is there a variant of concat that allows you to do that (concat '(3 4) (5) 1 6 [3 [6] ]) returning '(3 4 5 1 6 3 [6])
In the Clojure core library, I think that is the most concise understandable way
You can also do the opposite and write a maybe-cat transducer. Just copy cat's definition and add a coll? check which would branch to reduce or rf, I'll find an example later and send it if you're interested
Something like
(defn maybe-cat
"Like [[clojure.core/cat]] but falls through on non-sequential elements."
[rf]
(let [rrf (preserving-reduced rf)]
(fn
([] (rf))
([result] (rf result))
([result input]
(if (sequential? input)
(reduce rrf result input)
(rrf result input))))))
@vfernandez11 While I don't recommend using it, flatten comes close:
user=> (flatten '((3 4) (5) 1 6 [3 [6]]))
(3 4 5 1 6 3 6)
Probably better to just roll your owncljfmt, clj-kondo (both have good support for major IDEs)
@U066U71AR This is a fork of cljfmt which looks pretty great: https://github.com/greglook/cljstyle by @U8XJ15DTK
been a bit of a lull while I’ve been busy with other projects, but I’m planning to get to a 1.0 release later this year with better config and more options 😄
while on the subject, can puget also pprint code or is it more tuned towards EDN @U8XJ15DTK
puget is very much about EDN/data rather than code, though it does do one or two code highlighting things
@U066U71AR @U8XJ15DTK https://bogoyavlensky.com/blog/clojure-formatting-cljstyle/ <- someone blogged today!
Anyone have some solid examples of this library in action by chance? https://github.com/weavejester/ring-oauth2 Perusing Github didn’t bring up much
I'd like to do something like this using spec, and I'm having a hard time.
(spec/def ::int-to-int-fn
(spec/fspec
:args (cat :n int?)
:ret int?))
(defn add-5 [n] (+ 5 n))
(defn subtract-3 [n] (- n 3))
(spec/fdef add-5 ::into-to-int-fn) ;; this draws an error
(spec/fdef subtract-3 ::int-to-int-fn) ;; this draws an error
Is this possible? Or would I need to do
(spec/fdef add-5
:args (spec/cat :n int?)
:ret int?)
And repeat that for subtract-3 and any other function with that signature?You don't get an error on the first attempted call to spec/fdef
on add-5
? I did, in my attempt to reproduce what you see.
Perhaps if you do (spec/def add-5 ::int-to-int-fn)
it achieves what you want (note spec/def
instead of spec/fdef
)
No I got an error for both of them. Typo on my part.
I can spec/def add-5 ::into-to-int-fn without an error, but what I'm looking for to achieve the equivalent of giving :args, :ret, etc. with a single token declaring a common i/o signature
For example if I spec/def add-5, then ask for docs on add-5, the 'spec' section of the output is nil.
I do not know if there is a way to achieve what you want with spec. (I'm not saying there isn't -- just that I'm not enough of a spec expert to give a definitive answer either way)
Yeah it's starting to look like it's out of scope for spec. It'd be cool though. Thanks for your help!
You may get a more expert answer by asking in #clojure-spec channel
While running this from the command line
clj -Sdeps '{:deps {org.apache.pdfbox {:mvn/version "2.0.21"}}}
I get the following errors and a stacktrace
Error building classpath. 3 problems were encountered while building the effective model for org.apache.pdfbox:pdfbox:2.0.21
[ERROR] Failed to determine Java version for profile jdk9 @ org.apache.pdfbox:pdfbox-parent:2.0.21
[ERROR] Failed to determine Java version for profile jdkGte9 @ org.apache.pdfbox:pdfbox-parent:2.0.21
[ERROR] Failed to determine Java version for profile jdk11 @ org.apache.pdfbox:pdfbox-parent:2.0.21org.apache.maven.model.building.ModelBuildingException: 3 problems were encountered while building the effective model for org.apache.pdfbox:pdfbox:2.0.21
[ERROR] Failed to determine Java version for profile jdk9 @ org.apache.pdfbox:pdfbox-parent:2.0.21
[ERROR] Failed to determine Java version for profile jdkGte9 @ org.apache.pdfbox:pdfbox-parent:2.0.21
[ERROR] Failed to determine Java version for profile jdk11 @ org.apache.pdfbox:pdfbox-parent:2.0.21 at org.apache.maven.model.building.DefaultModelProblemCollector.newModelBuildingException(DefaultModelProblemCollector.java:197)
Anyone have any idea how to resolve this?@heykieran That doesn't look like a valid coordinate to me -- you have just the group ID with no artifact ID.
This works:
clj -Sdeps '{:deps {org.apache.pdfbox/pdfbox {:mvn/version "2.0.21"}}}'
Thanks @seancorfield - I was trying to simplify a larger problem where I was getting an error dep’ing a local jar. I ran the cli in the same directory, which merged the deps, and what I was seeing is the original error. Sorry, clj never got to tell me I was an idiot for using bad coords. It had baled already. Back to square one for me.
newer clj will fail earlier with a little better pointer
It’s a long shot, but any obvious things I should look for (and might cause an error like this) while dep’ing a jar that I know can be referenced in Java, its classes imported, and used without issue?
what error are you seeing? that stuff above?
Yup. The only dep in the deps file is a local jar. Even just trying to start the repl throws the error. Not much info there, sorry.
@heykieran Is it anything we can see publicly, to help you debug it?
@seancorfield this is ironic. Once I got it working, I was going to write a blog post about how to merge data to Word files and push to docusign. The jar does the merging. However, I haven’t got the ok on that yet. And I don’t want to color outside the lines. I’ll see if I can reduce it to as simple a case as possible. Appreciate the offer.
can you set JAVA_HOME and see if that helps?
pdfbox parent pom has a property that uses ${env.JAVA_HOME}
I think that's what's failing (and what's not failing for me because I have it set)
Unfortunately, JAVA_HOME is set. I think it’s the way the jar (a kind of Uber jar, with everything included) is being created. I may pull it apart and then reassemble. Even if I take out the pdf dependencies in the jar, I get an error about commons-io. Two funny things, the base jar without its dependencies imports fine (but doesn’t work) and the uberjar works fine in Java. Appreciate your help.
oh, that could be it - uber will sometimes strip or replace things that collide and you can run into some weirdnesses that way
what you're seeing above is almost certainly due to jdk profile stuff in maven - you might need to explicitly pull in one of the classifier jars (maven has a whole system for figuring this out which is not really be used through clj)
Question about polymorphism: should I limit myself to just built-in tools like protocols where they fit, or is it okay to have something in front of protocols that might perform automatic conversion to target type? For example, if there is a map with a special key, I might supply a particular behavior for these maps, while other maps are treated by default protocol impl
as a general practice, I nearly always front a protocol method with a function
that's up to you, but it's often a good place for custom processing to grow
I just worry that might be a source of complexity where easy to use makes it hard to reason
if the API is "it has to be something implementing protocol, and we implement Object and nil for you", that's quite easy and straightforward, but for some common uses there might be wrappings required...
well if you're the one doing the wrapping for an extender at use then you're in control. depends how the wrappings come into play
Users have to do the wrapping, but I can infer that wrapping from what they supply to me from the data they supply, and it will work in 99% of cases. And for remaining 1% where they had the key but "didn't mean it", they will be able to supply the data in a way that I'll be able to treat as if they "didn't mean it"
hello, I want to create a Slack bot where functions react to certain messages on chat depending on regexp matches to call the right function.
i.e: a "cake" message gets dispatched to the (defn cake ...)
method.
I would like to specify the regexp that matches a function next to it in its own source file, but what is the best way to aggregate them all so that the dispatcher fn knows all the available regexps/defn couples?
should I use some kind of reflection code or is there a better way?
there's definitely more than one way to do it. the approach that first comes to mind: • define your cake method and add some meta data with the regexp
(defn ^{:slackbot.ns/regexp #"cake.*"} cake ...)
• have the slack bot receive a dispatch function of regexps to handlers
• create a function that given some namespace, will look up all the functions with the :slackbot.ns/regexp
meta data
• create your bot like:
(make-bot (find-slack-handlers 'my.ns 'my.other.ns))
can I lookup in a wildcard namespace? like myapp.commands.*
?
maybe I'd just lookup all the subnamespaces of myapp.commands.*
?
it's my first clojure project so I'll have lots to learn but I figured metadata was a likely answer
you can, but it's easier if the namespaces are already loaded when you try to find the handlers
another idea I had was to make create a macro that, when called, added a regexp to defn entry to a collection of maps and then defined the defn as well?
the other option that I've used is have a macro like defslackhandler
and that handler will "register" the handler in a global list.
"registering" just means swapping into an atom in the slack namespace
what would be the more idiomatic way?
probably, https://github.com/clojure/spec-alpha2/blob/master/src/main/clojure/clojure/alpha/spec.clj#L440
seems like that's how spec registers specs
alright, thank you very much I'll go the macro route
the def
macro translates to a register
call which adds an entry to an atom
doesn't ns-interns
require that the namespace is already loaded, not just available on the classpath?
so will I need to "preload" all my calls to defslackhandler
?
Do you think you need dynamic loading and multiple namespaces? Maybe single ns with command list would do?
I am reimplementing a bot with thousands of lines of ruby and 50 commands
if it's all in one file it's gonna be a mess...
I think that's fine for a single map from regexps to handlers if handlers are extracted to other namespaces
I like to keep code that works tightly together in the same file, which I why I want the regexp and the defn next to each other
you just need to make sure an load all the namespaces with handlers from the namespace that contains your main
so that I don't have to switch emacs buffers around to make modifications
Having just turned off the bot which was a part of our product's Slack integration: we have centralized all command handling in the HTTP handler function, since you're just going to get a raw message text and you'll have to parse the commands yourself. Disclaimer: that was an old school bot, it had to listen to all incoming messages. I never worked with slash commands, which are newer style and might do some command parsing
Hello. How can i add my_project/src/clj/server.clj
to classpath? Inside my project.clj
i have :source-paths ["src/clj" "src/cljs"]
but it doesn't work and i dont know why:disappointed:
can you give a few more details as to what you are trying and the error message you're receiving?
I try to start backend REPL with `lein run` and get:
Can't find 'grump2.server' as .class or .clj for lein run: please check the spelling.
Syntax error (FileNotFoundException) compiling at (/tmp/form-init3649709 871957213789.clj:1:73).
Could not locate grump2/server__init.class, grump2/server.clj or grump2/server.cljc on classpath.
And it doesn't matter where is `server.clj` file: `grump2/server.clj`, `grump2/src/server.clj` or `grump2/src/clj/server.clj`
do you have (:gen-class)
in your ns declaration?
is it in project.clj should be?
oh seem i understood
i need add this to server.clj?
I would try that, and it's expecting the file in:
<myproject>/src/clj/grump2/server.clj
with the namespace grump2.server
I think. if I'm reading the error messages correctly
i've created src/clj/grump2/ dir and added server.clj file and db.clj because i have import there. And get same error but now it can't find db.clj
do you have the command you're running and the error message you're getting?
excuse me
i'have fixed the error
Can i write to you sometimes for help?
I'd recommend posting in #beginners. if I'm around and available, I'll try to help!
Great! Thank you 🙂