Fork me on GitHub

This may be the dumbest question ever but, does having both Leiningen and Clojure CLI Tools installed cause any conflicts?


perfectly sensible question.


lots of projects have a project.clj and a deps.edn


@luishendrix92 deps.edn for Clojure CLI tools and project.clj for Leinignen do not have relationship with each other. I've added a deps.edn configuration to leiningen projects before so I could use Clojure CLI tools instead. It is usually just adding the :dependencies from project.clj to :deps in deps.edn , along with any aliases for tools or paths. One caveat, if the code relies on Leiningen plugins, like lein-ring , which injects code into the codebase to be able to run a server, then you would need to add that code to make Clojure Cli tools work. This might cause a conflict with Leiningnen plugins.


:validate = ( clojure.core/fn [ % ] ( clojure.core/contains? % :condition ) )
I have the above in a hash map, I want to access parts of the value but I get Don't know how to create ISeq from: clojure.lang.Symbol how can i run (last (last (:validate data))) on the above ?


I feel like it should be easy but I am missing something


(last (last '( clojure.core/fn [ % ] ( clojure.core/contains? % :condition ) )))


I figured out that does what I need, it just does not work with the version inside the hash map


lots of quoted stuff going on and a random =. Can you show a bit more concretely what you have? it sounds like you have {:validate (fn [s] (contains? s :condition))} is that true?


yeah that's correct, the equals is from cider inspect ๐Ÿ™‚


ok. given this map, what would you like to do?


I am basically after :condition which last last would give me


I understand its because the value is basically a fn just not sure how to make it a list that i can manipulate


it's not though, it's a list


in my example i've put the key :validate is mapped to a function and at that point its opaque. You can't get into it


oh so regex out the value is my only hope at that point


if you just have a funtion, no, you cannot regex it either


please correct me if you aren't dealing with a function though


okay thanks for clarifying well i can str the function


(str +) -> "clojure.core$_PLUS_@3478c93b"


(str (:validate data)) for example


it seems to give me the string version of it


functions are compiled jvm code. they don't have string representations beyond a bit of munged name and an address

Alex Miller (Clojure team)16:11:54

clojure.repl/demunge may be useful if demunging class names


you do not have a function then. can you show some example code of how you're making this map?


@dpsutton it's a quoted list


that would be a function if it were evaluated


that's the only way the inspector would show that


it could be a quoted list, but should last not work on a quoted list ?


@oliver.marks what's your goal here? what do you want function shaped lists for?


is this parsing spec output?


yes I am parsing spec, I do know about expound but it's not flexible enough


at my last job we had some clever core.match usage to pattern match on those


so if its a quoted list should I be able to manipulate it / treat it as data


(take 3 (iterate (fn [x] (if (seqable? x) (last x) x)) '( clojure.core/fn [ % ] ( clojure.core/contains? % :condition ) )))
((clojure.core/fn [%] (clojure.core/contains? % :condition))
 (clojure.core/contains? % :condition)


so that works like in the example where its quote '() but when it comes from spec it errors on clojure.lang.Symbol


which is what i don't 100% do i need to run it through another fn first


the error message above is saying it cannot create an ISeq from a Symbol. It sounds like you're calling last on a symbol which obviously can't work


there are many function forms that you can't call (comp last last) on without that error


I guess its back to using str and regex then for now ๐Ÿ˜•

Alex Miller (Clojure team)16:11:05

you could use the spec for fn to s/conform the list representing a function

Alex Miller (Clojure team)16:11:10

it will "parse" it for you

Alex Miller (Clojure team)16:11:42

user=> (s/conform (:args (s/get-spec `fn)) (rest '(fn [x] (if (seqable? x) (last x) x))))
{:fn-tail [:arity-1 {:params {:params [[:local-symbol x]]}, :body [:body [(if (seqable? x) (last x) x)]]}]}


nice I will give that a try and see what happens ๐Ÿ™‚

Alex Miller (Clojure team)16:11:01

clojure is doing exactly that to verify the spec for all registered spec macros


it a shame spec errors using (s/keys) does not store the key that's missing in an easier to access format

Alex Miller (Clojure team)16:11:14

you can also use spec specs to s/conform a spec :)

Alex Miller (Clojure team)16:11:58 has some work on spec specs, although really the map data forms in spec 2 are probably more useful as a future direction

Jim Newton16:11:49

question about comparing symbols. I have two symbols. I have required [clojure.spec.alpha :as s] into my namespace. But when I try to compare s/and with clojure.spec.alpha/and using = it returns false. Are these really two different symbols? I thought they were the same symbol? I suspect I'm asking the wrong question, but how can I compare s/and to clojure.spec.alpha/and to get true?

Alex Miller (Clojure team)16:11:37

they are literally different symbols. you could resolve both and see if they refer to the same var

Alex Miller (Clojure team)16:11:57

whether s = clojure.spec.alpha depends on your current *ns*

Alex Miller (Clojure team)16:11:18

if I alias s to clojure.string then ...

Alex Miller (Clojure team)16:11:14

the namespace object is the one that holds alias mappings and ns is what tells you which namespace object to use for resolution right now


@jimka.issy if this helps, there's a hash-map that the namespace owns, that maps from symbol to var, and the "namespace" part of a namespaced symbol is used to decide which map to look in when resolving

Jim Newton16:11:36

This seems to work. I've never used condp before, and I was surprised that I need to quote the clause "tests" ('s/and 's/or), which is not the case with case.

(condp (fn [x y] (= (resolve x) (resolve y))) 'clojure.spec.alpha/and
                        's/and 1
                        's/or 2)


case is super weird

Alex Miller (Clojure team)16:11:02

case works with compile-time constants. b/c they're constants, they don't need to be evaluated

Alex Miller (Clojure team)16:11:58

a lot of weirdness in case is due to the special circumstances of the switch bytecode it's trying to leverage


right - there's so many special-case situations for case that don't apply to the rest of clojure


like how it treats lists, and symbols for classes off the top of my head

Alex Miller (Clojure team)16:11:03

well, if anyone ever bothered to read the docstring...


I'm not saying the special cases are secret, just that it has a lot of them

Jim Newton16:11:44

case is normal. Every lisp treats it pretty much the same way. clojure, emacs lisp, scheme, common lisp. No surprises there. That condp looks like case, but acts differently was a surprise. It's clear why the main expression needs to be evaluated, but not yet clear to me why the clauses need to be evaluated. Not exactly clear from the docstring either. At least with a casual reading.


Hi all. Newbie here ๐Ÿ˜„ I have a spec generator question. I was trying (-> ::expression s/gen g/generate) and I ran into the sample limit issue. ::expression is a recursive spec of simple arithmetic-like calculator with def and if like additions. I have been digging around and it seems my naive use of s/or just makes it worst. I was wondering if anyone has any pointer on how to understand/debug why the generator struggles. (I found s/*recursion-limit* suggestions online, but did not help much). Thanks for your time in advance!


@xllora generators are quite naiive, and if your spec has an arbitrary function to test, it will create random inputs until one passes


usually I'd use a custom generator with the help of things like gen/fmap to create things the spec actually accepts


@noisesmith does that mean that the default generator would be generating values for all the leave predicates and then just check if valid?


(fmap helps especially if there's two parts of the input data that have to "agree" in some way)


@xllora if I understand what your asking yes, it's not clever


it looks at the types you accept, and creates things that might fit, and uses yours spec to filter


it's not hard to make a spec such that no appropriate example would be created after 1000 tries


especially in your case where it sounds like you are parsing an expression language


I see. Then s/or is not actually selecting a branch and expanding it, but both hence making impossible to satisfy? Yes

(s/def ::data-primitives 
  (s/or :number number?                                                                                 
        :symbol symbol?
        :char char?
        :string string?
        :bool boolean?)) 


this two-column output displays very badly in the slack client


Sorry, jumped the gun accidentally hitting return ๐Ÿ˜ž

๐Ÿ‘ 3

I notice from the error message though, it's not ::data-primitives that fails to generate, it's ::expression


Then there is the usual recursive definition on expression around +, -, ... around it


yeah, that's your problem, not s/or


the error, which you deleted because it was formatted weirdly, was about generating ::expression


Execution error (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 100 tries.


If I understood your point, your suggested is to check fmap to generate a custom generator for the recursive path. I guess adapted versions of something like


yeah, more specifically you'd use with-gen to attach a custom generator to the spec for ::expression, and inside that use gen/fmap to create sample expressions that would actually pass the spec


the advantage of fmap is it lets you use random generation while still respecting the generator state, so the seed for recreating the failure works


Interesting. Thanks @noisesmith. Let me go do some more reading ๐Ÿ˜„

ryan echternacht19:11:00

When I boot up my repl, and eval my โ€œmainโ€ namespace (what lein could call core.clj) Iโ€™m getting FileNotFoundExceptions on the other files in my project. If I eval those files then everything is fine. any ideas what I may be doing wrong? I think I have the files/namespace mapping correct

ryan echternacht19:11:24

This project is using deps/clj, not lein


@ryan072 Are there any - or _ in any of the filenames and/or namespaces?

ryan echternacht19:11:21

- in namespace, _ in files


(also, is this a project we can look at on GitHub?)

ryan echternacht19:11:17

it is, but private


And when you say "eval my "main" namespace", what exactly do you mean? (require '[my-project.core])

ryan echternacht19:11:00

specifically, eval the (ns my-toplevel (:require [ โ€ฆ ]))


If you're on macOS/Linux, could you share what tree . displays when run inside your project, and also what that complete ns form contains?


(it's hard to debug something we can't see ๐Ÿ™‚ )

ryan echternacht19:11:33

(ns yardstick.yardstick-jobs
  (:require [mount.core :as mount]
            [next.jdbc :as jdbc]
            [yardstick.process-channel :as pc]
            [yardstick.fetch-jobs :as fj]))

ryan echternacht19:11:32

I donโ€™t have tree , which is weird because i remember using it in the past

ryan echternacht19:11:01

(ns yardstick.channels
  (:require [clojure.core.async :as async]))
^ one of the other fileโ€™s namespace dec


What is the exact FNF exception you're seeing when you try to (require 'yardstick.yardstick-jobs) in the REPL?


(or whatever it is you are typing into the REPL that throws an exception)

ryan echternacht19:11:40

โ€ฆ and now it works fine

ryan echternacht19:11:19

whelp, sorry for wasting your time. I recreated the issue like 2x before posting here

ryan echternacht19:11:26

and now everything is peachy

ryan echternacht19:11:18

in general tho, if files match the directory structure under src things should be fine, yes?


the actual rule is that the path to the namespace must match a file on classpath or a resource on classpath with a path matching the ns parts


src is a classpath root by default


I find it somewhat surprising that require would give "file not found" as it can use files, or resources inside artifacts, (or even rare things like URLs...)


oh, it does say 'FileNotFoundException", wow

user=> (require 'aokldsjflas.asdfkjlasdf)
Execution error (FileNotFoundException) at user/eval290 (REPL:1).
Could not locate aokldsjflas/asdfkjlasdf__init.class, aokldsjflas/asdfkjlasdf.clj or aokldsjflas/asdfkjlasdf.cljc on classpath.

ryan echternacht19:11:09

That is roughly what I saw

Cas Shun20:11:08

I'm trying to learn core.async and I'm having somewhat of a difficulty understanding what "parking" is and its implications. (I understand blocking). Could someone provide me a quick overview or some search terms that might help me?

Alex Miller (Clojure team)20:11:48

Parking means that no thread is blocked and work stops until data is available

Alex Miller (Clojure team)20:11:30

The arrival of data unparks the operation and it is queued to run again

Cas Shun20:11:50

When something is 'unparked', I assume it waits for the next available thread in the pool?

Alex Miller (Clojure team)20:11:10

Which is why go blocks should never do blocking io (which can block a thread in that fixed size pool)

Cas Shun20:11:01

Thank you Alex