How to assist the LSP when it comes to function outputs, and Julia Language "Good Code"

One of the key features of an LSP is auto-completion based on the type.

Suppose this code:

struct Foo
    x
    y
end
Foo_constructor(i) = Foo(i,i)
a = Foo_constructor(3)

Now, the LSP does not recognize a as an object of type Foo, if you type a. you don’t get auto completion, now a simple analysis of the code shows that no matter the i given, you’ll always get an object of type Foo so it would’ve been nice if that was automatic.

Now suppose this new example here:

Foo(i) = Foo(i,i)
b = Foo(3)

Now, the LSP does recognize b as of being of type Foo, and you get auto-completion; as b. gives the option for both x and y. This may seem “good”, so “constructors” should preferably be named after their output type.

However, now consider this example: (which I admit is terrible ambiguous code)

Foo(i::Float64) = 10.
c = Foo(2.3)

Now, the LSP thinks that c is of type Foo! And when prompted for auto-completion it will show x and y which is erroneous, a fact more apparent if Foo(...) gives an object of type Bar with different attributes.

When dealing with projects which feature loads of structs (I’m now working on a Compiler after finishing the Interpreter, check out: GitHub - lucifer1004/MonkeyLang.jl: "Writing an Interpreter in GO" and "Writing a Compiler in GO" in Julia. for a similar implementation) auto-completion of variables assigned as the output of a function is mighty useful.

Now, how to go forward with this? Not sure, though in my mind a more elaborate static code analyzer might do it.

Yeah, this is a bit tricky. Generally, the closest we can possibly come to a correct answer is to ask the Julia compiler, but even that will fail for sufficiently complex cases.

The fact that constructors are not guaranteed to return their type widely considered to be a mistake though [citation needed].

1 Like