speculative

https://github.com/borkdude/speculative
borkdude 2018-10-24T08:36:32.000100Z

PR for range.

borkdude 2018-10-24T08:49:37.000100Z

PR for partial.

borkdude 2018-10-24T09:10:47.000100Z

Made a branch of yada with speculative tests. Found no errors. https://github.com/borkdude/yada/tree/speculative-tests

borkdude 2018-10-24T09:24:34.000100Z

maybe we can do PRs to projects to make use of this project in their tests. 🙂

slipset 2018-10-24T09:35:02.000100Z

Seems like the partial PR has a conflict. On phone so can’t resolve.

borkdude 2018-10-24T09:36:14.000100Z

did you already merge range? I’d like to make one tweak

borkdude 2018-10-24T09:36:40.000100Z

maybe:

:args (s/or :arity-0 nil?
              :arity-1 (s/cat :end int?)
              :arity-2 (s/cat :start int? :end? int?)
              :arity-3 (s/cat :start int? :end int? :step int?))
is a little bit cleaner, so the names will match the docstring?

slipset 2018-10-24T09:36:41.000100Z

Also, in the case of range, it would be an interesting exercise to see if we could name the args in the spec

slipset 2018-10-24T09:37:01.000100Z

Great minds think alike :)

borkdude 2018-10-24T09:37:08.000100Z

doing it in one s/cat won’t work

borkdude 2018-10-24T09:37:34.000100Z

it will work, but then e.g. the end argument will match the :start alternative

borkdude 2018-10-24T09:37:42.000100Z

so I think this is the cleanest

borkdude 2018-10-24T09:38:22.000100Z

I made the PRs independent of each other, so merge conflict would be expected, np

borkdude 2018-10-24T09:41:24.000100Z

OK, if you could merge the new range spec @slipset, I’ll fix the other PR

borkdude 2018-10-24T09:48:39.000100Z

@slipset both PRs are mergeable now

slipset 2018-10-24T10:43:22.000100Z

and 🙏

slipset 2018-10-24T10:44:57.000100Z

🐼

slipset 2018-10-24T10:45:00.000100Z

For more detailed failure reports, use JUnit XML formatting. Failing command: clojure -A:test:cljstests Exit code: 1 Output: WARNING: Wrong number of args (4) passed to cljs.core/range at line 190 /home/circleci/repo/test/speculative/core_test.cljc Testing speculative.core-test ERROR in (range-test) (Error:NaN:NaN) expected: (range) actual: #error {:message "Call to #'cljs.core/range did not conform to spec:\nIn: [1] val: 1.7976931348623157e+308 fails at: [:args :arity-2 :end?] predicate: int?\nIn: [1] val: 1.7976931348623157e+308 fails at: [:args :arity-3 :end] predicate: int?\nval: (0 1.7976931348623157e+308 1) fails at: [:args :arity-0] predicate: nil?\nIn:

slipset 2018-10-24T10:45:29.000100Z

Seems like circle didn’t like all the range tests?

borkdude 2018-10-24T11:11:10.000100Z

I’ll take a look

borkdude 2018-10-24T11:18:55.000100Z

cljs fails, but plk succeeds

borkdude 2018-10-24T11:26:16.000100Z

so I guess we need to assert number? instead of int?

borkdude 2018-10-24T11:29:09.000100Z

PR should fix the tests

borkdude 2018-10-24T11:29:44.000100Z

if you can wait, I’ll also write some tests with non-int numbers

borkdude 2018-10-24T11:31:12.000100Z

done

slipset 2018-10-24T11:39:17.000100Z

thanks!

slipset 2018-10-24T11:39:43.000100Z

BTW, interesting that cljs fails and planck succeeds

slipset 2018-10-24T11:40:22.000100Z

I seem to remember there was a discussion in #cljs-dev (or a Jira ticket) with issues around the semantics of int? integer?

slipset 2018-10-24T11:40:35.000100Z

and their differences between clojure and clojurescript

mfikes 2018-10-24T11:41:12.000100Z

For these kinds of things, if we end up supplying patches to ClojureScript, it has tests involving spec that run on both JVM and self-hosted ClojureScript that could be expanded in coverage.

slipset 2018-10-24T11:42:45.000100Z

wow:

slipset 2018-10-24T11:42:56.000100Z

(range 1.1 10.3 3.3)
;; => (1.1 4.4 7.7)

mfikes 2018-10-24T11:44:01.000100Z

@slipset The int? / integer? stuff ended up being in here https://dev.clojure.org/jira/browse/CLJS-2921

borkdude 2018-10-24T11:55:47.000100Z

what’s the tl;dr on int? integer? with regards to spec?

borkdude 2018-10-24T11:57:24.000100Z

cljs accepts: (range \a \b \c) but that’s Hyrum I guess

slipset 2018-10-24T11:58:42.000100Z

chars are numbers 🙂

slipset 2018-10-24T11:59:03.000100Z

and in cljs chars don’t really make sense since javascript has no chars

borkdude 2018-10-24T12:00:40.000100Z

apart from the implementation standpoint, clj doesn’t accept the input

borkdude 2018-10-24T12:01:28.000100Z

I guess because on the JVM they’re boxed java.lang.Character instances

mfikes 2018-10-24T12:10:26.000100Z

I think the TL;DR on int? / integer? for spec is that oftentimes you will want to use int? for argument specs. where the function isn't really an arbitrary-precision function, which integer? would imply. Also, int? was introduced around the time with spec with other useful functions for spec, like nat-int?, and friends. But, ClojureScript unfortunately will allow arbitrary precision goog integers to satisfy int?. You could just use int? presuming it will all be sorted in the end and that's probably good enough.

mfikes 2018-10-24T12:11:58.000100Z

@slipset You said chars are numbers, but consider (number? \A) evaluates to false

mfikes 2018-10-24T12:12:37.000100Z

(range \a \b \c) is an incorrect program, so, the frog could appear 🙂

mfikes 2018-10-24T12:13:26.000100Z

This is what Stu meant when he said "Clojure is optimized for correct programs." To me, this means, that undefined behavior is allowed in the name of perf.

borkdude 2018-10-24T12:17:51.000100Z

Very experimental branch with orchestra, just to see if I could get :ret checking to work: https://github.com/borkdude/speculative/tree/orchestra

borkdude 2018-10-24T12:19:44.000100Z

probably too fragile, can’t get it working properly

slipset 2018-10-24T12:20:19.000100Z

@mfikes re chars/numbers I was wrong 🙂

slipset 2018-10-24T12:20:40.000100Z

In js chars are strings it seems:

slipset 2018-10-24T12:20:46.000100Z

cljs.user=> \a
"a"
cljs.user=>

borkdude 2018-10-24T12:22:43.000100Z

one risk of writing :ret specs is that we don’t have a way to test them thoroughly atm

borkdude 2018-10-24T12:23:06.000100Z

unless we use generative testing

borkdude 2018-10-24T12:23:20.000200Z

so maybe we should try that instead 😉

borkdude 2018-10-24T12:25:07.000100Z

one funny thing about spec: in Haskell you can say, the return value is a (possible infinite) list of ints. In spec you could assert it, but the checking never finishes

borkdude 2018-10-24T12:25:33.000200Z

that’s why I chose seq? for :ret in range, and not something else

mfikes 2018-10-24T12:25:51.000100Z

Places in ClojureScript that enforces the notion that characters are length-1 strings is in char and char?

borkdude 2018-10-24T12:27:44.000100Z

@slipset just merged a trivial PR. Should I check if they have signed the CA before I merge, even with README improvements?

mfikes 2018-10-24T12:27:59.000100Z

I suppose if you wrote a spec for char you would allow number? or char?

borkdude 2018-10-24T12:28:34.000100Z

and if so, where do you check this?

mfikes 2018-10-24T12:29:35.000200Z

You can check for the CA at https://www.clojure.org/community/contributors

mfikes 2018-10-24T12:30:02.000200Z

But to be honest, I would love it if we took that list, put it in a file, and set up one of those GitHub CA-checking robots.

mfikes 2018-10-24T12:30:51.000100Z

(This would serve as an excellent example of how this can be much much better than the current manual process used in Clojure/Script with JIRA.)

borkdude 2018-10-24T12:31:12.000100Z

:thumbsup:

mfikes 2018-10-24T12:31:31.000100Z

If we did that, then we could announce that Speculative is ready for PRs.

mfikes 2018-10-24T12:32:38.000100Z

Those robots look fairly easy to use. For example https://github.com/cla-assistant/cla-assistant / https://cla-assistant.io

borkdude 2018-10-24T12:33:03.000100Z

could we also set the project up to test check PRs before they are merged?

mfikes 2018-10-24T12:33:51.000100Z

Yes... I think React and Google projects end up looking like that. Let me find an example.

mfikes 2018-10-24T12:34:13.000100Z

Oh, sorry I thought you were still asking about CAs.

mfikes 2018-10-24T12:34:55.000100Z

There is configuration in the settings of a GitHub project where you can flip a switch and require CI to pass before a merge can be done.

mfikes 2018-10-24T12:36:22.000100Z

(You protect the main branch and then add a rule that indicates "Require status checks to pass before merging")

borkdude 2018-10-24T12:46:27.000100Z

that’s something for Erik to configure then

borkdude 2018-10-24T12:51:03.000100Z

Is this CLA assistant something that we could use from a third party (the .io) domain, or do we have to setup something ourselves?

mfikes 2018-10-24T12:52:09.000100Z

I don't know... there seem to be quite a different ones out there

borkdude 2018-10-24T12:53:12.000100Z

we could write a simple script to begin with. just scrape the contributors page and check. with some webhook maybe?

borkdude 2018-10-24T12:54:01.000100Z

or not even scrape, but download it statically into a list once every while

mfikes 2018-10-24T12:54:18.000100Z

There is also the ability to simply set up a template that gets shown when a PR is submitted, which indicates you need to sign the Clojure CA if you haven't already.

borkdude 2018-10-24T12:55:49.000100Z

That would be a good thing to start with. https://blog.github.com/2016-02-17-issue-and-pull-request-templates/

slipset 2018-10-24T12:57:15.000100Z

I think I might have set up protection of master now 🙂

mfikes 2018-10-24T12:57:23.000100Z

Yeah, the template idea is a no-brainer. It essentially communicates what you want with respect to CA.

mfikes 2018-10-24T12:57:37.000100Z

The robots would be slick, assuming they are easy and free to use.

mfikes 2018-10-24T12:58:09.000100Z

Or, as you suggest Michiel, roll your own

borkdude 2018-10-24T12:58:13.000100Z

@slipset I’ll test with my orchestra branch which fails. Don’t merge 😉

borkdude 2018-10-24T12:58:42.000100Z

https://github.com/slipset/speculative/pull/40

slipset 2018-10-24T13:02:06.000100Z

🙂

slipset 2018-10-24T13:02:30.000100Z

It should be fairly easy to set this up actually.

slipset 2018-10-24T13:02:55.000100Z

Set up pr-building in circle,

slipset 2018-10-24T13:03:11.000100Z

Do a check before building that the gitub-user is listed on

slipset 2018-10-24T13:03:14.000100Z

https://www.clojure.org/community/contributors

slipset 2018-10-24T13:03:17.000100Z

fail if not.

borkdude 2018-10-24T13:03:55.000100Z

this could be a simple planck script, since it has an http client right? 😛

slipset 2018-10-24T13:03:55.000200Z

And I believe we have plk available on our build-server 🙂

borkdude 2018-10-24T13:05:30.000100Z

takes a while with that PR it seems

borkdude 2018-10-24T13:06:11.000100Z

CIRCLE_PR_USERNAME

slipset 2018-10-24T13:08:33.000100Z

(-&gt;&gt; (get "<https://www.clojure.org/community/contributors>") :body (re-find #"slipset"))

slipset 2018-10-24T13:09:06.000100Z

(require '[planck.http :refer [get]])

slipset 2018-10-24T13:10:45.000100Z

Btw cjohansen has a CLA

borkdude 2018-10-24T13:11:34.000100Z

(slurp "<https://www.clojure.org/community/contributors>") also works

borkdude 2018-10-24T13:11:50.000100Z

afk

slipset 2018-10-24T13:12:11.000100Z

yeah 🙂

slipset 2018-10-24T13:12:52.000100Z

It was a very pleasant side-effect when I implmented the http-stuff for planck-1.x back in the day.

slipset 2018-10-24T13:31:42.000100Z

@borkdude could you push another commit to the DONT’ MERGE thingy?

slipset 2018-10-24T13:32:56.000100Z

I pushed a commit to it (I think on your branch, and it failed the build.

slipset 2018-10-24T14:02:13.000100Z

https://github.com/slipset/clj-ca-checker

slipset 2018-10-24T14:04:23.000100Z

Very crude, but seems to work. Will add html parsing.

borkdude 2018-10-24T14:58:25.000100Z

Seems to work.

$ clj -Sdeps '{:deps {clj-ca-checker {:git/url "<https://github.com/slipset/clj-ca-checker>" :sha "a0ea916eb606c048227f03f2c7d02ef851075f00"}}}' -m clj-ca-checker.clj-ca-checker "borkdude"
Borkdude@borkdude ~ $ echo $?
0
Borkdude@borkdude ~ $ clj -Sdeps '{:deps {clj-ca-checker {:git/url "<https://github.com/slipset/clj-ca-checker>" :sha "a0ea916eb606c048227f03f2c7d02ef851075f00"}}}' -m clj-ca-checker.clj-ca-checker "borkdude2"
Borkdude@borkdude ~ $ echo $?
1

borkdude 2018-10-24T15:43:00.000100Z

isn’t it a bit weird that PRs can change the circle code though? they can still make the tests pass by tweaking it 😉

borkdude 2018-10-24T15:43:20.000100Z

but we have to be careful in what we merge anyway, so that’s ok probably

borkdude 2018-10-24T15:46:53.000100Z

cool, Alex is now chiming in: https://github.com/slipset/speculative/issues/42

slipset 2018-10-24T15:52:30.000100Z

Yeah, I guess you could tweak the circle-config, but then you’re obviously malicious.

slipset 2018-10-24T15:52:57.000100Z

That Alex is chiming in is super cool!

borkdude 2018-10-24T15:53:39.000100Z

I wonder if this inlining happens in user code as well: https://github.com/slipset/speculative/issues/44 Our tests do seem to work with / for example.

alexmiller 2018-10-24T16:27:58.000100Z

user=&gt; (def non-zero? (complement zero?))
#'user/non-zero?
(s/fdef clojure.core//
          :args (s/or :single-arity (s/cat :non-zero-number
                                           (s/and number? non-zero?))
                      :multi-arity (s/cat :number
                                          number?
                                          :non-zero-numbers
                                          (s/+ (s/and number? non-zero?))))
          :ret number?)
clojure.core//
user=&gt; (stest/instrument `/)
[clojure.core//]
user=&gt; (/ 5 0)
Evaluation error at clojure.lang.Numbers.divide (Numbers.java:188). ArithmeticException Divide by zero

alexmiller 2018-10-24T16:28:04.000100Z

¯\(ツ)

alexmiller 2018-10-24T16:29:24.000100Z

not sure if I’m crazy or you are

slipset 2018-10-24T16:31:28.000100Z

Prolly us :)

alexmiller 2018-10-24T16:31:55.000100Z

I’m going to suspect your test infrastructure until proven otherwise :)

borkdude 2018-10-24T16:32:16.000100Z

hmm, who wrote that test 😉

slipset 2018-10-24T16:32:40.000100Z

I did

borkdude 2018-10-24T16:33:17.000100Z

maybe some .cljc issue there. thanks for the heads up @alexmiller

alexmiller 2018-10-24T16:34:43.000100Z

it does seem like the test is getting run. If I comment it out, the test and assertion count goes down.

borkdude 2018-10-24T16:35:34.000200Z

maybe we have to do something like this there: https://github.com/slipset/speculative/blob/master/test/speculative/test_utils.cljc#L24

alexmiller 2018-10-24T16:35:40.000100Z

oh, I can get the error to happen on (/ 0)

alexmiller 2018-10-24T16:36:32.000100Z

ah, inlining is set for arities >1

alexmiller 2018-10-24T16:36:49.000100Z

so only getting picked up for single arity

slipset 2018-10-24T16:37:13.000100Z

The reason I added the spec for / in the first place was basically as an answer to Tim Baldridge complaining about Clojures error messages on division by zero.

alexmiller 2018-10-24T16:37:16.000100Z

user=&gt; (source /)
(defn /
  "If no denominators are supplied, returns 1/numerator,
  else returns numerator divided by all of the denominators."
  {:inline (nary-inline 'divide)
   :inline-arities &gt;1?
   :added "1.0"}
  ([x] (/ 1 x))
  ([x y] (. clojure.lang.Numbers (divide x y)))
  ([x y &amp; more]
   (reduce1 / (/ x y) more)))

slipset 2018-10-24T16:38:18.000100Z

And, although it’s to specific, since division accepts all numbers, it’s a cool example of stuff that’s (relatively) easy to do with spec, that would be fairly hard with a type system.

alexmiller 2018-10-24T16:38:59.000100Z

@slipset bleh

alexmiller 2018-10-24T16:39:18.000100Z

0 is a valid number :)

slipset 2018-10-24T16:39:56.000100Z

Yeah, but even just between Clojure and Clojurescript, division by zero seems to be somewhat undefined 😛

slipset 2018-10-24T16:40:28.000100Z

I even seem to remember a ticket on this in the Clojure Jira…

alexmiller 2018-10-24T16:40:51.000100Z

I don’t think it’s undefined in Clojure at all. I blame JavaScript for all problems. ;)

slipset 2018-10-24T16:41:54.000100Z

Oh, but I do. All the time. Unfortunately my cow-workers are getting tired of that 😕

slipset 2018-10-24T16:44:04.000100Z

Lucky thing I only checked for integers:

slipset 2018-10-24T16:44:04.000300Z

https://dev.clojure.org/jira/browse/CLJ-1142

slipset 2018-10-24T21:49:46.000100Z

Michiel hot tip: If you prefix your commit msgs with [Fix #41], you automatically close issue 41 and you make me, who’s slightly OCD wrt commit mgs, very happy :)