Fork me on GitHub
#other-languages
<
2019-03-28
>
borkdude11:03:40

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

4
lilactown15:03:45

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

borkdude15:03:29

do you have any experience in OCaml?

lilactown15:03:17

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

lilactown15:03:47

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

lilactown15:03:56

been here ever since!

borkdude15:03:58

cool šŸ™‚

orestis12:03:09

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?

borkdude12:03:27

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

borkdude12:03:46

The joker linter helps with unresolved symbols.

orestis13:03:58

Yeah Iā€™m following clj-kondo with great interest šŸ˜„

orestis13:03:23

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

orestis13:03:59

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.

borkdude13:03:19

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

john15:03:20

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

borkdude15:03:18

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

john15:03:16

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

borkdude15:03:43

80%

šŸ‘Œ 4
john15:03:58

Sounds pessimistic

borkdude15:03:25

I donā€™t know. Runtime analysis is always easier

borkdude15:03:43

I mean, you can do more things.

john15:03:47

What about about ephemeral runtimes for compile time analysis?

borkdude15:03:33

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

borkdude15:03:39

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

borkdude15:03:23

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

borkdude15:03:41

but then you need a JVM running

borkdude15:03:08

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

john15:03:51

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

borkdude15:03:14

do you mean a test set?

borkdude15:03:55

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 šŸ˜‰

šŸ˜œ 4
borkdude15:03:09

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

john15:03:10

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

john15:03:41

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

borkdude15:03:29

I donā€™t really see what you mean

john15:03:45

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

borkdude15:03:15

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

borkdude15:03:24

so everything thatā€™s purely syntactic can be done

john15:03:43

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

borkdude15:03:06

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

borkdude15:03:21

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

borkdude15:03:48

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

john15:03:58

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

borkdude15:03:59

then youā€™re basically implementing core.typed and Iā€™m not planning to do that šŸ™‚

john15:03:09

I mean, joker is faster

john15:03:33

I guess graal isn't going to help there

borkdude15:03:07

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

john15:03:34

Well, whatever joker is doing, doing a lightweight interpreter

john15:03:51

can one get further with a Graal solution?

borkdude15:03:23

that would be like implementing ā€œevalā€ which is currently not supported with GraalVM šŸ™‚

borkdude15:03:35

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

john15:03:40

right, that's what I thought

borkdude15:03:16

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

borkdude15:03:30

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

john15:03:45

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

borkdude15:03:46

For the ā€œinterpreterā€ bit, why not just use JVM/eastwood for that?

borkdude15:03:38

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

borkdude15:03:30

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

borkdude15:03:04

(like Haskell type holes, but much more limited)

borkdude15:03:27

I think spectrum is doing this, but much more advanced

john15:03:38

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

john15:03:32

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

borkdude15:03:21

maybe, who knows what the future holds šŸ™‚

john15:03:54

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.

borkdude16:03:31

thatā€™s cool! šŸ™‚

borkdude16:03:01

I guess your tool can be used to give suggestions: ā€œalso see ā€¦ā€ on clojuredocs for example

borkdude16:03:38

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

borkdude16:03:08

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.

john19:03:02

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

borkdude19:03:05

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

john19:03:29

Like, subdued text of what might come next

john19:03:57

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

john19:03:13

Some kind of predictive coding tool

john19:03:10

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

john22:03:34

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

borkdude22:03:52

you mean generate code using speculative?

borkdude22:03:19

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