Fork me on GitHub

(= #"a" #"a")
=> false
why are regexes not checked for equality of their contents, like strings are?


I am just imagining because no one bothered until now, but I am curious of usecases for comparing the equality for regex objects.


(I am imagining it is for instaparse...?)


yep 🙂 I can't structurally compare parsers because of the regex inequality


I know you are the pro in terms of this, but comparing the result of .pattern on the regex won't do in your case?


I was hoping I could do some kind of recursive equality function (like =) that would magically handle regexes, but I may have to roll my own function that tests the str of each regex when it tries to compare regexes...


That does sound really challenging. Wishing you the best! Instaparse is awesome 🙂


some one who can help me with my spec problem which I ask a few days ago ?


When I do this :

defn ->long [s] (try (Long/parseLong s) (catch Exception _ ::s/invalid)))

(s/def ::page (s/and (s/conformer ->long) (s/int-in 1 471)))

(s/def ::optional-page (s/nilable ::page))

(defn page-check [page] (let [page page page-num (or (s/conform ::optional-page page) 1)] page-num))

(s/fdef page-check
        :args (string? (::page :page))
        :ret  (number? (::page :page))
        :fn  (s/valid? true?  (::page :page)  )


and then this in repl :

(require '[clojure.spec :as s])
=> nil
(require '[clojure.spec.gen :as gen])
=> nil 


and then :

(gen/generate (s/gen ::page))
Exception Unable to resolve spec: :user/page  clojure.spec/reg-resolve! (spec.  


so what have I done wrong here ?


I want to have a generator which make test-data like this "a" "123"


Hi! just made a lib, would love to have feedback on it, it has README full of examples. it is related to types and polymorphism


Today I’ve stumbled on a chance to use juxt, apply apply, and toposort


it’s a christmas miracle!


@roelof, the exception is due to that ::page resolves to a keyword with the current namespace as prefix. In your file it resolves to :your-ns/page and in the REPL it resolves to :user/page. If you instead type (gen/generate (s/gen :your-ns/page)) (and replace your-ns with your actual namespace) in the REPL the spec should be found. You need to require that other namespace in the REPL as well.


@henriklundahl Probably, it will be easier to find answer about clojure-spec in #clojure-spec channel


Hey, guys. Can someone suggest image processing library for clojure? It's necessary for me to have ability just to resize images. Less dependencies - better, faster - better. I found two options: Which one is better? Any suggestions?


@henriklundahl thanks, I now have this output :

(require '[clojure.spec :as s])
=> nil
(require '[clojure.spec.gen :as gen])
=> nil
`(gen/generate (s/gen :paintings2/page))
=> (clojure.spec.gen/generate (clojure.spec/gen :paintings2/page))
(gen/generate (s/gen :paintings2/page))
Exception Unable to resolve spec: :paintings2/page  clojure.spec/reg-resolve! (spec.clj:68)
(gen/generate (s/gen :paintings2.routes.home/page))
RuntimeException Var clojure.test.check.generators/large-integer is not on the classpath  clojure.spec.gen/dynaload (gen.clj:21)   


@roelof is [org.clojure/test.check "0.9.0"] in your project.clj :dependencies?


@roelof either way, you should be asking the spec questions on #clojure-spec imo, plenty of activity there, sometimes more than this channel


oke, thanks, I will check it but I think it's not in the project.cli


it should be to use generator functionality


hey mates. I’m doing some hackerrank to learn some clojure and I’m failing one challenge by timeout ( clojure timeout is 7 seconds ). the interesting side is that I’ve solved the same challenge with Javascript . The js code and clojure one is here - how could I make the clojure more performant


clojure solutions -> and js solution - > clojure the first solution was trying to use a ‘trie’, but I’m getting very poor time with my solution and the second one I’m using a map with all word prefixes. js solution was using a ‘trie’ like


"add" can be improved; for a string of length $n$, it currently takes O(n^2) map lookups


it can be reduced to O(n) map lookups, by manually walking the map instead of using reductions on prefixes of the strintg


I need a macro which outputs (catch Throwable ...) when expanded in a .clj file and (catcj js/Error ...) when expanded in a .cljs file. How can I do this? I'm looking for the equiv of #+clj and #+cljs, but in macros instead of *.clj files


@qqq check (:ns &env) — it will be nil in Clojure and non-`nil` in ClojureScript.


hey @qqq, thx, > it can be reduced to O(n) map lookups, by manually walking the map instead of using reductions on prefixes of the strintg how it would be ?


@seancorfield : found the google groups thread, thanks!


@oliv: suppose the string i abcdefghijklmnopqrstuvwxyz: the existing code firs tdoes 26 lookups (on the full string), then 25 lookups, then 24 lookups, ... then 3 lookups (ln abc), then 2, then 1


instead, the whole thing can be done in one go


with just 26 lookups, i.e. the initial lookups


yep, that would be awesome, much better big O. but I really don’t know how to improve that


what I have to change the code to use just one pass to create the prefix map ?


here's a starting point; probably buggy edge cases // never tried this code myself: (loop [current-map ... remaining-string ...] (increment current count) (if (not= remainig-string "") (let [first-chart (first remaining-string) rst (rest remaining-string)] (recur (descend current-map first-char) rst))))


the goal is to "walk the trie/string only once, and increment everything along the way"


got it. so the main problem is the way I’m using the reduction function. right ?


the use of reductions is very clever; I think the main problem is that this problem was desitgned to test O(...) rujnning time, and the reductions solution provides a O(n^2) instead of a O(n) solution


that is interesting, I thought the reduction was O(n)


the code makes O(n) updates, but the updates would take 26 lookups, then 25 lookups, then 24 lookuyps, then 23 lookups, etc ...


so this ends up gbbeing O(n^2) map lookups


even though you're only making O(n) updates


@seancorfield : got the (ns &env) trick wsorking -- thanks!


> so this ends up gbbeing O(n^2) map lookups let’s suppose a word with 3 characters “ABC”, the reductions will generate a sequence of “A” “AB” “ABC” where are we going to use quadratic O(n^2) lookups ? here ? (update out current #(if %1 (inc %1) 1)))


the "A" = = lookup, "AB" . = 2 lookups, "ABC" = 3 lookups, so we get 6 lookups total


perhaps someone else can jump in and help, I unfortunately have a deadline


oh, thank you. would love to know that why “AB” is 2 lookups and “ABC” 3 lookups on map data structure?


it's hard to explain; add the string "abc" and print out the data structu4re


you'll see that each 'key" is just a single char, and nested


oh, I’m reading that code @qqq

(defn add [map word]
  (reduce (fn [out current]
            (update out current #(if %1 (inc %1) 1)))
          (rest (reductions str "" word))))


the first one (solution_one.clj) , I agree it has a worst performance than that one ^^


@qqq Glad that worked. I ran across it in a couple of .cljc code bases but haven’t really explored the implications of mixed language macros yet.


in cljc files, what is the right way to :require macros so that it works nicely from both clj and cljs land?


how do i annotate a method argument for a function in a namespace with gen-class which overrides a method with annotated parameters?


forexample with this:


the method and class i am tyring to override is a library class and the annotation in question does some processing on the argument which i dont want to implement myself and just use the annotation if possible


what is the relation between fn and fn*, and where can I find the documentation for fn* ?


fn* is undocumented.


(so it’s an implementation detail you should ignore)


seancorfield: fn* shows up when I do (macroexpand '(...)); and unfortunately there's a bug somewhere in my macro 😞


separate question: I have already done (spec/check-asserts true); however my (s/fdef ...)s seem to be ignored (i..e function returhining things that clearly violate return condition); how do I figure out what I'm doing wrontg


:ret and :fn are only checked via generative testing (`clojure.spec.test/check`), not instrument. The latter only checks :args.


And check-asserts is going to work like instrument I expect.


seancorfield: in other words, 1) check-asserts acts like instrument and 2) instrument only checks :args ? okay, got it; thanks


Yup. See various clojure.spec talks online for why that is — TL;DR: :args is about checking that functions are called correctly during example-based testing or regular code execution, whereas :ret / :fn is about specifying the behavior of a function and verifying its correctness, which needs generative testing. Lots of discussion about this on the mailing list too since it has been a bit … contentious … at times 🙂


Re: fn* — that’s the magic internal name that implements the behavior of the fn special form. So it’s basically how fn is implemented in the underlying Java code of the compiler.


@seancorfield : one thing I do not understand. I imagine "s/fdef" as a "wrapper" around the function which checks the :args before calling the function and checks the :ret after the function returns (but before the wrapper returns); briefly, can you explain what technical decision led to splitting of :args vs :ret for check-asserts? it seems like the overhead for the two is identical (modulo the actual cost of running the :ret checker)


As I said, it’s a TL;DR kinda thing — you really need to watch some of the talks and read the discussion on the mailing list.


The basic premise is that :args checks calling code is correct but :ret / :fn check that the function itself is correct and you need more than just example-based testing for that to be useful.


Generative testing will create valid input and verify that the output is valid (and that the relationship between the output and the input holds).


Given Rich’s preference for not complecting concerns, I would have expected s/fdef to really be two separate pieces — but in early alphas, instrument did check :ret and it was very surprising to people who found that test.check was required because it was using generative testing (and several of us expected just a plain ol’ check of the returned values, not generative testing of the contract of the function itself).


(so it was clear from that behavior that Rich’s intention was definitely that we had two different types of testing at play here!)


@seancorfield: I still don't understand this issue, but I am convinced that I should just go listen to a bunch of talks. (I listened to a few already, but they were more of the 'how to use spec', not 'design and implementation of spec' flavor). Do you have recommendations?


For example, read — where instrument caused a runtime failure due to lack of test.check in your project’s dependencies.


I can’t remember which talks are best for explaining the two different approaches… I think both Stu Halloway and Rich have given talks fairly recently that covered this “two types of testing” aspect, but I don’t remember titles or locations.