Fork me on GitHub
#clojure
<
2016-12-26
>
aengelberg07:12:50

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

iku00088807:12:30

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

iku00088807:12:37

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

aengelberg07:12:06

yep šŸ™‚ I can't structurally compare parsers because of the regex inequality

iku00088807:12:15

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?

aengelberg07:12:13

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

iku00088807:12:04

That does sound really challenging. Wishing you the best! Instaparse is awesome šŸ™‚

roelof10:12:57

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

roelof10:12:48

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

roelof10:12:26

and then this in repl :

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

roelof10:12:02

and then :

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

roelof10:12:14

so what have I done wrong here ?

roelof11:12:19

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

pbaille12:12:09

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 https://github.com/pbaille/facets

lvh12:12:55

Today Iā€™ve stumbled on a chance to use juxt, apply apply, and toposort

lvh12:12:58

itā€™s a christmas miracle!

henriklundahl12:12:32

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

andrewtropin12:12:07

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

andrewtropin12:12:38

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: https://github.com/mikera/imagez https://github.com/josephwilk/image-resizer Which one is better? Any suggestions?

roelof12:12:40

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

joshjones15:12:56

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

joshjones15:12:35

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

roelof16:12:31

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

joshjones16:12:56

it should be to use generator functionality

tdantas18:12:03

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 - https://github.com/tdantas/js-clj-challenge how could I make the clojure more performant

tdantas19:12:12

clojure solutions -> https://github.com/tdantas/js-clj-challenge/tree/master/clj and js solution - > https://github.com/tdantas/js-clj-challenge/tree/master/js 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

qqq19:12:44

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

qqq19:12:11

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

qqq19:12:06

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

seancorfield19:12:57

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

tdantas19:12:48

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 ?

qqq19:12:41

@seancorfield : found the google groups thread, thanks!

qqq19:12:16

@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

qqq19:12:27

instead, the whole thing can be done in one go

qqq19:12:33

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

tdantas19:12:31

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

tdantas19:12:07

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

qqq19:12:01

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

qqq19:12:37

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

tdantas19:12:41

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

qqq19:12:24

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

tdantas19:12:55

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

qqq19:12:24

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

qqq19:12:32

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

qqq19:12:41

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

qqq19:12:38

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

tdantas19:12:25

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

qqq19:12:50

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

qqq19:12:43

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

tdantas19:12:54

oh, thank you. would love to know that why ā€œABā€ is 2 lookups and ā€œABCā€ 3 lookups on map data structure?

qqq19:12:48

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

qqq19:12:00

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

tdantas19:12:17

oh, Iā€™m reading that code @qqq

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

tdantas19:12:43

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

seancorfield21:12:32

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

qqq21:12:50

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

neupsh22:12:11

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

neupsh22:12:40

forexample with this:

neupsh22:12:39

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

qqq22:12:44

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

seancorfield22:12:55

fn* is undocumented.

seancorfield22:12:29

(so itā€™s an implementation detail you should ignore)

qqq22:12:08

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

qqq22:12:01

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

seancorfield22:12:54

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

seancorfield23:12:13

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

qqq23:12:06

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

seancorfield23:12:21

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 šŸ™‚

seancorfield23:12:40

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.

qqq23:12:35

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

seancorfield23:12:23

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.

seancorfield23:12:36

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.

seancorfield23:12:24

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

seancorfield23:12:54

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

seancorfield23:12:40

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

qqq23:12:09

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

seancorfield23:12:11

For example, read http://dev.clojure.org/jira/browse/CLJ-1936 ā€” where instrument caused a runtime failure due to lack of test.check in your projectā€™s dependencies.

seancorfield23:12:32

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.