Skip to content

2022 05 09 report

Artem Pelenitsyn edited this page Mar 1, 2023 · 1 revision

Report 2022 05 09

Another failing case: overloaded ()

I was diverted a bit by a remaining failing case in processing and worked mostly on it. This is a curious one, at least, I didn’t know before that Julia allows overloading the function call operator. In a nutshell, if you define a structure S with an integer field, you then can define something like:

function (s::S)(x::Int)
    print("Hi $x+$s.x!")
end

which will make any object if type S callable (e.g. (S(2)(3) will print Hi 5!).

I currently can’t see how to feed this kind of thing to Julia’s type inference. This should be possible, but it seems like esoteric enough corner of the language that there’s not much documentation of it and also it’s quite rare (I found it only once in the 10 packages), so I currently skip it.

Support module names different from package names

One of the 10 packages, DifferentialEquations, deviate from the usual Julia pattern when a package X has the main module named X. DifferentialEquations doesn’t have the correspondingly named module, and instead provides several specific modules. I have to work around such packages manually, and I added some code to handle this. In the type-stability paper this wasn’t as critical, as we basically scraped all the data we could find after a test suite was executed, but here I need a specific module to iterate over. Unfortunately, there’s no (simple) way to programmatically find out which modules are exported from a package, so it has to be hardcoded, I believe. And right now I only process exactly one module per package (a fairer deal would be to process “all manually hard-coded” modules in a package).

Current State: Numbers

Below are the numbers I currently have. These are along the lines we discussed last week I believe: a fair number of things (“~50% on average across packages”) are deemed stable (look at columns 2 and 3).

Module Methods Stable Unstable Any Vararg Generic TcFail NoFuel
DifferentialEquations 1404 601 3 697 45 54 2 2
Flux 561 114 1 191 102 151 0 2
Gadfly 454 277 24 60 44 47 0 2
Gen 997 486 22 293 3 191 0 2
Genie 113 84 6 14 3 6 0 0
IJulia 174 101 8 54 6 0 0 5
JuMP 696 372 36 167 11 103 2 5
Knet 160 39 2 66 24 29 0 0
Plots 1711 673 142 478 226 173 2 17
Pluto 265 146 28 63 16 9 0 3

Meaning of Stable in the Table

After talking to you and looking into my code some more, I realized I didn’t convey all the truth about these numbers. The Stable statistics allow some omissions due to existentials, so it’s not bullet-proof stable. E.g. if I can’t enumerate something because descending down the lattice I hit into an unbounded existential, I simply record that fact in raw results and proceed with other branches of the lattice. I haven’t figured how to incorporate information about these omissions in a digestable way into the aggregate table. I’m thinking, I may need a separate table for Stable methods. What do you think?

Plans: Work on Any

I believe we came up roughly with two ideas about analyzing Any-signatures last time: 1) manually sample them and try to spot any pattern; 2) pull up results of dynamic analysis and see what it has to say about those methods (their instances).

One thing we discussed but weren’t satisfied with is the possibility to enumerate some concrete types starting from Any. This suffers from possibly being too imprecise and not adding much to what is already there.