other-languages

here be heresies and things we have to use for work
borkdude 2019-03-28T11:18:40.000400Z

Guy who wrote Clojure book in 2012 and wrote many Clojure OSS libs: https://twitter.com/cemerick/status/1111110485510942720

1
orestis 2019-03-28T12:09:09.001600Z

I certainly would like some hand-holding by the compiler, esp. when dealing with code (not data) — arity exceptions or unresolved symbols are examples of this, perhaps though we could have more of those?

borkdude 2019-03-28T12:46:05.001800Z

@orestis 🙂 https://twitter.com/borkdude/status/1111238854525235200

borkdude 2019-03-28T12:46:27.002300Z

The CLJS compiler already warns about this when you compile the code. It would be nice if CLJ did the same

borkdude 2019-03-28T12:46:46.002600Z

The joker linter helps with unresolved symbols.

orestis 2019-03-28T13:26:58.003100Z

Yeah I’m following clj-kondo with great interest 😄

orestis 2019-03-28T13:27:23.003500Z

I had some fun years ago building some prototype of this for Python

orestis 2019-03-28T13:27:59.004300Z

Turns out that while people could write extremely indirect and dynamic code, most of the time they don’t — so covering for the usual use cases with static analysis can be a real time-saver, if you get feedback in your editor.

borkdude 2019-03-28T13:38:19.005200Z

right, that’s what I’m trying. it won’t be perfect, but covers 90% of the cases

john 2019-03-28T15:26:20.005900Z

@borkdude are you going to eventually cover the joker use cases too? or always complement them?

borkdude 2019-03-28T15:27:18.007Z

I’ll prioritize things that it doesn’t do yet, but they may overlap. E.g. the wrong arity only worked in joker for calls within the same namespace, but for clj-kondo they also work across namespaces

john 2019-03-28T15:29:16.008600Z

How far could one go, theoretically, with these static analysis tools?

borkdude 2019-03-28T15:29:43.009Z

80%

👌 1
lilactown 2019-03-28T15:29:45.009100Z

cemerick is a notable troll on twitter (I still like him). OCaml's super cool tho and I do miss the typechecker at times

john 2019-03-28T15:29:58.009500Z

Sounds pessimistic

borkdude 2019-03-28T15:30:25.009900Z

I don’t know. Runtime analysis is always easier

borkdude 2019-03-28T15:30:43.010300Z

I mean, you can do more things.

john 2019-03-28T15:30:47.010500Z

What about about ephemeral runtimes for compile time analysis?

borkdude 2019-03-28T15:31:33.011100Z

Maybe that’s what joker does, kind of, I’m not sure. Since it’s a light weight interpreter

john 2019-03-28T15:32:03.011400Z

right

borkdude 2019-03-28T15:32:39.012Z

I’m mainly focussing on a lightweight tool that I can use to get “stupid” errors really fast. E.g. arity checking while editing CLJS files without a backing REPL

borkdude 2019-03-28T15:33:23.012400Z

I bet eastwood can detect a lot more stuff since it’s a runtime tool, for example

borkdude 2019-03-28T15:33:41.012900Z

but then you need a JVM running

borkdude 2019-03-28T15:34:08.013400Z

so tradeoffs. you can use these tools together in CI for example

borkdude 2019-03-28T15:35:29.013900Z

do you have any experience in OCaml?

john 2019-03-28T15:35:51.014400Z

I guess you'd need some fixture data for a kind of static analyzer that could exercise runtime scenarios

borkdude 2019-03-28T15:36:14.014700Z

do you mean a test set?

lilactown 2019-03-28T15:36:17.014900Z

I wrote some small applications with it a little over a year ago. I participated a lot in the ReasonML community early on

john 2019-03-28T15:36:19.015200Z

yeah

borkdude 2019-03-28T15:36:55.016Z

I already have that. We have a 30kloc app with tons of deps. I just have to analyze the classpath to get a ton of warnings and errors 😉

😜 1
borkdude 2019-03-28T15:38:09.016800Z

30kloc CLJ and 18kloc CLJS actually. And this is only the main app, we have other components too 🙂

john 2019-03-28T15:38:10.016900Z

well, I don't mean test data for tests...

john 2019-03-28T15:38:41.017600Z

I mean, almost like for generative tests, so that a static type system can do some run-time-ish things

borkdude 2019-03-28T15:39:29.017900Z

I don’t really see what you mean

john 2019-03-28T15:39:45.018300Z

Yeah, I'm not sure if it's really a coherent idea

borkdude 2019-03-28T15:40:15.018900Z

I do expand certain macros already, so you can see that (-> 1 (inc 1)) is an arity error.

borkdude 2019-03-28T15:40:24.019300Z

so everything that’s purely syntactic can be done

john 2019-03-28T15:40:43.019700Z

Just wondering how you could maybe capture some dynamicity of the repl for static analysis at compile time

lilactown 2019-03-28T15:40:47.019800Z

I had a similar amount of experience with Clojure at the time, and our team was trying to decide what to build our new system on top of. I debated between Clojure and OCaml and landed on Clojure 🙂

lilactown 2019-03-28T15:40:56.020200Z

been here ever since!

borkdude 2019-03-28T15:41:06.020500Z

I plan to scan fdefs to offer a very limited/basic form of type checking on literals

borkdude 2019-03-28T15:41:21.020900Z

joker takes this a bit further already, but only for core functions

borkdude 2019-03-28T15:41:48.021500Z

but as soon as the arguments are non-literals, it gets very hard

john 2019-03-28T15:41:58.022Z

Yeah, but joker recreates the interpreter in go... why not just use a full clojure interpreter?

borkdude 2019-03-28T15:41:59.022100Z

then you’re basically implementing core.typed and I’m not planning to do that 🙂

john 2019-03-28T15:42:09.022300Z

I mean, joker is faster

john 2019-03-28T15:42:33.022900Z

I guess graal isn't going to help there

borkdude 2019-03-28T15:43:07.023200Z

do you mean, implement a clojure interpreter in clojure and compile with Graal?

john 2019-03-28T15:43:34.023600Z

Well, whatever joker is doing, doing a lightweight interpreter

john 2019-03-28T15:43:51.023900Z

can one get further with a Graal solution?

borkdude 2019-03-28T15:44:23.024300Z

that would be like implementing “eval” which is currently not supported with GraalVM 🙂

borkdude 2019-03-28T15:44:35.024700Z

I mean, you could do the same thing as joker but then in Java.

john 2019-03-28T15:44:40.024900Z

right, that's what I thought

borkdude 2019-03-28T15:45:16.025500Z

I’m not sure which problems the joker currently detects that cannot be done with static analysis

borkdude 2019-03-28T15:45:30.025900Z

BTW, Cursive also uses static analysis, might also be a source of inspiration. I’m not using it ATM

borkdude 2019-03-28T15:45:58.026Z

cool 🙂

john 2019-03-28T15:46:45.027Z

could your re-find utility be used to potentially provide a predictive-next-token thing for an ide?

borkdude 2019-03-28T15:46:46.027100Z

For the “interpreter” bit, why not just use JVM/eastwood for that?

borkdude 2019-03-28T15:47:38.027400Z

I would be surprised if I could use that, since I suspect that will require eval

borkdude 2019-03-28T15:51:30.029Z

I was thinking of a feature like:

(s/fdef foo :args (s/cat :i int?))
(foo "foo") ;;=> invalid argument
(foo _) ;;=> type int expected in hole

borkdude 2019-03-28T15:52:04.029300Z

(like Haskell type holes, but much more limited)

borkdude 2019-03-28T15:53:27.030400Z

I think spectrum is doing this, but much more advanced

john 2019-03-28T15:53:38.030700Z

Yeah, like, if the the thing that follows a thing is expected to be a literal string, maybe the IDE can start the string form for you, with the cursor between the quotations

john 2019-03-28T15:55:32.032200Z

... I don't know... just wondering if re-find's inference system can be used to infer code templates or whatnot for certain code contexts in an ide

borkdude 2019-03-28T15:56:21.032600Z

maybe, who knows what the future holds 🙂

john 2019-03-28T15:58:54.033800Z

I made a toy little utility https://github.com/johnmn3/coal-mine2vec that can find analogies between relations between functions. I've been wondering how I could combine it with your re-find tool to do some interesting kinds of inference.

borkdude 2019-03-28T16:01:31.034400Z

that’s cool! 🙂

borkdude 2019-03-28T16:02:01.034800Z

I guess your tool can be used to give suggestions: “also see …” on clojuredocs for example

borkdude 2019-03-28T16:02:38.035400Z

Or re-find could also use it. It would have to run in JavaScript though. Maybe the result of the analysis could be emitted to some static EDN graph structure

borkdude 2019-03-28T16:04:08.036600Z

Re-find is pretty simple. It just tries to find functions whose specs match the given in/output. There’s not really anything “inferency” to it, or maybe I’m misunderstanding what you mean with inference.

john 2019-03-28T19:24:02.038300Z

Well, the word2vec thing is just looking over swaths of text and if it sees things in similar proximity to one another, but in different contexts, it'll fill in the blank for you... which seems similar to your re-find... Not sure how they could be combined yet though...

borkdude 2019-03-28T19:28:05.038800Z

you can create an automatic network of related functions this way right? and this could be useful in suggesting things

john 2019-03-28T19:40:12.039Z

RIght

john 2019-03-28T19:40:29.039300Z

Like, subdued text of what might come next

john 2019-03-28T19:40:57.039900Z

But in conjunction with your re-find thing, you could eliminate fns that don't work from a type perspective

john 2019-03-28T19:42:13.040200Z

Some kind of predictive coding tool

john 2019-03-28T19:43:10.041100Z

and if you're talking about pure functions, you could interpret some candidate options a priori and see if they're invalid suggestions

john 2019-03-28T22:32:34.043500Z

@borkdude I wonder if it'd be useful to gen-spec a mountain of code using speculative and run it through word2vec... See if it can do fast inference on code relations.

borkdude 2019-03-28T22:39:52.043700Z

you mean generate code using speculative?

borkdude 2019-03-28T22:40:19.044Z

that should work, all the tests are already using generative testing