clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
souenzzo 2020-10-23T00:04:56.036600Z

I think that "clojure" has a runtime, "clojurescript" dosent Kind of we can implement "clojurescript" on JVM or "clojure" in JS But with this definition in mind, the reader conditional that currently use :clj to "macro time" in :cljs turns wired.

2020-10-23T01:59:46.037Z

Depends what you mean by runtime

2020-10-23T02:01:27.037200Z

Cljs does have a big pile of support code, the main difference is the support code for cljs is a mix of clojure and clojurescript, the support code for clojure is a lot of java

souenzzo 2020-10-23T02:36:37.037400Z

By runtime I mean something like a stateful singleton that hold things like keyword cache and threads.

2020-10-23T04:14:32.037800Z

not sure what threads has to do with it

2020-10-23T04:15:21.038Z

and clojurescript does its best to cache keywords

svt 2020-10-23T07:04:34.039300Z

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

mavbozo 2020-10-23T10:42:14.042100Z

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

dominicm 2020-10-23T10:51:00.042200Z

I'm pretty sure that's it for now.

zilti 2020-10-23T11:08:03.042400Z

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

emil0r 2020-10-23T11:34:27.043400Z

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

emil0r 2020-10-23T11:34:44.043900Z

Does anyone have an idea of what he means exactly when he talks about set functions

emil0r 2020-10-23T11:34:49.044100Z

I’m assuming it’s not clojure.set

emil0r 2020-10-23T11:48:20.044500Z

Hmmm… appears to be

emil0r 2020-10-23T11:52:16.046500Z

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

2020-10-23T11:57:34.046600Z

I believe that's a set, used as a function, like so: (#{1 2 3} 1) => 1 (#{1 2 3} 42) => nil

2020-10-23T11:59:56.046800Z

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.

rutledgepaulv 2020-10-23T12:19:09.047Z

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.

mavbozo 2020-10-23T12:36:22.047600Z

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.

emil0r 2020-10-23T12:39:29.047800Z

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

emil0r 2020-10-23T12:40:14.048Z

map, filter, etc are equivalent power to imperative loop/fold, but are simpler

Valentín 2020-10-23T13:15:56.048300Z

Hi

Valentín 2020-10-23T13:19:24.052100Z

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])

Valentín 2020-10-23T13:19:26.052300Z

??

Valentín 2020-10-23T13:21:16.053700Z

Without doing that (mapcat #(if (coll? %) % (list %) ) '(1 [3 5] (3)))

borkdude 2020-10-23T13:21:45.054300Z

@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 own

2020-10-23T13:21:48.054400Z

In the Clojure core library, I think that is the most concise understandable way

Valentín 2020-10-23T13:22:33.054800Z

You are rigth

Valentín 2020-10-23T13:23:03.055700Z

But I'm solving 4clojure problems and I'm implementing flatten

Valentín 2020-10-23T13:23:17.056200Z

With the restriction of using flatten

gtrak 2020-10-23T14:06:21.056600Z

what do people use for code formatting lately, that works with different editors.

Valentín 2020-10-23T14:12:33.056700Z

Understood, thanks.

Tzafrir Ben Ami 2020-10-23T14:31:47.057100Z

cljfmt, clj-kondo (both have good support for major IDEs)

borkdude 2020-10-23T15:47:12.057300Z

clj-kondo doesn't do formatting

gtrak 2020-10-23T15:58:32.057500Z

I saw zprint and joker do it too, but not sure how widely used they are

borkdude 2020-10-23T16:00:21.057700Z

@gtrak This is a fork of cljfmt which looks pretty great: https://github.com/greglook/cljstyle by @greg316

gtrak 2020-10-23T16:01:02.058100Z

thx, I'll check that out.

greglook 2020-10-23T16:02:39.058400Z

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 😄

borkdude 2020-10-23T16:03:28.058600Z

while on the subject, can puget also pprint code or is it more tuned towards EDN @greg316

gtrak 2020-10-23T16:03:33.058800Z

we're spoiled with prettier, black, and ocamlformat, but trying to get clojure in now.

greglook 2020-10-23T16:04:17.059Z

puget is very much about EDN/data rather than code, though it does do one or two code highlighting things

Grant Isom 2020-10-23T16:18:56.059600Z

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

2020-10-23T18:29:48.061400Z

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?

Ben Sless 2020-10-23T18:47:52.064Z

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

KJO 2020-10-23T18:48:00.064200Z

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?

seancorfield 2020-10-23T18:53:54.064900Z

@heykieran That doesn't look like a valid coordinate to me -- you have just the group ID with no artifact ID.

seancorfield 2020-10-23T18:55:13.065100Z

This works:

clj -Sdeps '{:deps {org.apache.pdfbox/pdfbox {:mvn/version "2.0.21"}}}'

2020-10-23T18:58:03.065200Z

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.

2020-10-23T19:03:43.066100Z

Perhaps if you do (spec/def add-5 ::int-to-int-fn) it achieves what you want (note spec/def instead of spec/fdef)

KJO 2020-10-23T19:10:06.072100Z

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.

alexmiller 2020-10-23T19:10:45.072600Z

newer clj will fail earlier with a little better pointer

2020-10-23T19:16:17.072900Z

No I got an error for both of them. Typo on my part.

2020-10-23T19:18:22.073100Z

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

2020-10-23T19:20:01.073300Z

For example if I spec/def add-5, then ask for docs on add-5, the 'spec' section of the output is nil.

2020-10-23T19:23:20.075Z

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)

KJO 2020-10-23T19:25:15.077700Z

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?

alexmiller 2020-10-23T19:27:47.078Z

what error are you seeing? that stuff above?

2020-10-23T19:27:59.078100Z

Yeah it's starting to look like it's out of scope for spec. It'd be cool though. Thanks for your help!

KJO 2020-10-23T19:29:42.081600Z

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.

seancorfield 2020-10-23T19:32:17.082100Z

@heykieran Is it anything we can see publicly, to help you debug it?

KJO 2020-10-23T19:37:16.087400Z

@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.

2020-10-23T19:37:34.087500Z

You may get a more expert answer by asking in #clojure-spec channel

alexmiller 2020-10-23T19:53:16.090600Z

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)

vlaaad 2020-10-23T19:54:40.092200Z

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

alexmiller 2020-10-23T19:55:38.092600Z

as a general practice, I nearly always front a protocol method with a function

2
vlaaad 2020-10-23T19:56:17.093100Z

and that function can do some automatic conversions?

alexmiller 2020-10-23T19:56:49.093400Z

that's up to you, but it's often a good place for custom processing to grow

vlaaad 2020-10-23T19:57:25.093900Z

I just worry that might be a source of complexity where easy to use makes it hard to reason

alexmiller 2020-10-23T19:58:25.095Z

can you set JAVA_HOME and see if that helps?

vlaaad 2020-10-23T19:58:58.095700Z

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...

alexmiller 2020-10-23T19:59:25.096Z

pdfbox parent pom has a property that uses ${env.JAVA_HOME}

alexmiller 2020-10-23T19:59:53.097Z

I think that's what's failing (and what's not failing for me because I have it set)

alexmiller 2020-10-23T20:01:47.100100Z

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

KJO 2020-10-23T20:06:24.107400Z

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.

vlaaad 2020-10-23T20:08:15.108900Z

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"

alexmiller 2020-10-23T20:09:29.109Z

oh, that could be it - uber will sometimes strip or replace things that collide and you can run into some weirdnesses that way

vlaaad 2020-10-23T20:11:14.109600Z

Hmm, I guess that might be worth it...

Valentín 2020-10-23T20:36:56.109700Z

Yes I'm interested

Ben Sless 2020-10-23T20:52:34.109900Z

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))))))

Ben Sless 2020-10-23T20:55:59.110100Z

then just use it in a transduction

Ben Sless 2020-10-23T20:56:54.110300Z

(into [] maybe-cat coll), or any other API

borkdude 2020-10-23T21:02:39.110500Z

@gtrak @greg316 https://bogoyavlensky.com/blog/clojure-formatting-cljstyle/ <- someone blogged today!

gtrak 2020-10-23T21:03:20.110800Z

oh wow

greglook 2020-10-23T21:04:21.111Z

hah, nice!

Louis Kottmann 2020-10-23T21:09:29.113800Z

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?

lukasz 2020-10-23T21:15:33.115400Z

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

phronmophobic 2020-10-23T21:17:03.115900Z

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))

Louis Kottmann 2020-10-23T21:19:24.116300Z

can I lookup in a wildcard namespace? like myapp.commands.*? maybe I'd just lookup all the subnamespaces of myapp.commands.*?

Louis Kottmann 2020-10-23T21:19:58.116500Z

it's my first clojure project so I'll have lots to learn but I figured metadata was a likely answer

phronmophobic 2020-10-23T21:20:40.116700Z

you can, but it's easier if the namespaces are already loaded when you try to find the handlers

Louis Kottmann 2020-10-23T21:21:55.116900Z

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?

phronmophobic 2020-10-23T21:22:18.117100Z

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

Louis Kottmann 2020-10-23T21:22:42.117400Z

what would be the more idiomatic way?

phronmophobic 2020-10-23T21:24:07.117900Z

seems like that's how spec registers specs

Louis Kottmann 2020-10-23T21:24:34.118100Z

alright, thank you very much I'll go the macro route

phronmophobic 2020-10-23T21:24:55.118300Z

the def macro translates to a register call which adds an entry to an atom

Louis Kottmann 2020-10-23T21:25:35.118500Z

gonna be a fun exercise in demystifying macros 🙂

🦜 1
vlaaad 2020-10-23T21:27:32.118800Z

You can also inspect ns with ns-interns and ns-publics

phronmophobic 2020-10-23T21:28:34.119300Z

doesn't ns-interns require that the namespace is already loaded, not just available on the classpath?

vlaaad 2020-10-23T21:28:41.119500Z

Reveal uses that to build cli command list from defs

vlaaad 2020-10-23T21:28:54.119700Z

Yes, it has to be loaded

Louis Kottmann 2020-10-23T21:29:35.119900Z

so will I need to "preload" all my calls to defslackhandler?

vlaaad 2020-10-23T21:29:49.120100Z

Do you think you need dynamic loading and multiple namespaces? Maybe single ns with command list would do?

vlaaad 2020-10-23T21:30:16.120300Z

Or maybe even a single def with a map...

Louis Kottmann 2020-10-23T21:30:27.120500Z

I am reimplementing a bot with thousands of lines of ruby and 50 commands

Louis Kottmann 2020-10-23T21:30:37.120700Z

if it's all in one file it's gonna be a mess...

vlaaad 2020-10-23T21:31:47.120900Z

I think that's fine for a single map from regexps to handlers if handlers are extracted to other namespaces

Louis Kottmann 2020-10-23T21:32:38.121100Z

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

phronmophobic 2020-10-23T21:32:48.121300Z

you just need to make sure an load all the namespaces with handlers from the namespace that contains your main

👌 1
Louis Kottmann 2020-10-23T21:32:55.121500Z

so that I don't have to switch emacs buffers around to make modifications

Александр Стоянов 2020-10-23T22:02:09.124Z

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:

phronmophobic 2020-10-23T22:06:05.124100Z

can you give a few more details as to what you are trying and the error message you're receiving?

Александр Стоянов 2020-10-23T22:10:13.124700Z

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`

phronmophobic 2020-10-23T22:10:58.124900Z

do you have (:gen-class) in your ns declaration?

Александр Стоянов 2020-10-23T22:11:25.125100Z

no

Александр Стоянов 2020-10-23T22:11:40.125300Z

is it in project.clj should be?

Александр Стоянов 2020-10-23T22:12:03.125500Z

oh seem i understood

Александр Стоянов 2020-10-23T22:12:22.125700Z

i need add this to server.clj?

phronmophobic 2020-10-23T22:12:24.125900Z

I would try that, and it's expecting the file in:

&lt;myproject&gt;/src/clj/grump2/server.clj
with the namespace grump2.server

phronmophobic 2020-10-23T22:12:55.126100Z

I think. if I'm reading the error messages correctly

Александр Стоянов 2020-10-23T22:24:42.126300Z

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

phronmophobic 2020-10-23T22:26:13.126500Z

do you have the command you're running and the error message you're getting?

Александр Стоянов 2020-10-23T22:32:07.126900Z

excuse me

Александр Стоянов 2020-10-23T22:32:14.127100Z

i'have fixed the error

Александр Стоянов 2020-10-23T22:32:27.127300Z

thank you very much:grin:

😄 1
Александр Стоянов 2020-10-23T22:32:45.127600Z

now i have new bugs but it's working now and it's great

🦜 1
Александр Стоянов 2020-10-23T22:34:22.127900Z

Can i write to you sometimes for help?

phronmophobic 2020-10-23T22:35:21.128100Z

I'd recommend posting in #beginners. if I'm around and available, I'll try to help!

Александр Стоянов 2020-10-23T22:36:55.128300Z

Great! Thank you 🙂