Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Foo.Bar.baz<tab> – deep tab completion #10091

Closed
StefanKarpinski opened this issue Feb 5, 2015 · 11 comments
Closed

Foo.Bar.baz<tab> – deep tab completion #10091

StefanKarpinski opened this issue Feb 5, 2015 · 11 comments
Labels
REPL Julia's REPL (Read Eval Print Loop)

Comments

@StefanKarpinski
Copy link
Member

We don't generally do tab completion when the thing to the left of the dot preceding the tab is more complicated than a name, since in the general case that would require evaluation of code in order to get the object to lookup names on. In the case where Foo is a module, however, evaluating Foo.Bar can't have any side-effects, so it would be safe to call names(Foo.Bar) in order to complete baz.

As a more general question, do we want to evaluate expressions to the left of dots when tab is pressed in order to do more general tab completion? It seems fairly unlikely that this would cause problems very often. This has come up a couple of times recently.

@StefanKarpinski StefanKarpinski added the REPL Julia's REPL (Read Eval Print Loop) label Feb 5, 2015
@vtjnash vtjnash added the feature label Feb 8, 2015
@vtjnash
Copy link
Member

vtjnash commented Feb 8, 2015

we should be able to utilize Base.effect_free to minimally compute this info. or force a call to typeinf in record mode on a function that just contains the desired code and look at the resulting return type (possibly by calling the function with the code wrapped in Expr(:static_typeof))

@StefanKarpinski
Copy link
Member Author

I should point out that I now can't reproduce the first part of this issue, so it may have been due to odd REPL state. The broader question of what to do when the LHS of a tab completion requires evaluation remains. When type inference can tell us the type of the LHS, then we can compute the type without even needing to evaluate. When the expression is effect free, then we can evaluate it safely. I guess adding those two will cover a lot of cases, so we should probably start there.

@ivarne
Copy link
Member

ivarne commented Feb 10, 2015

When a tab completion would require evaluation of unverified code, we should just give up and don't complete anything.

Inference and effect free will likely catch most situations, and if we are to go further, we'll need more analysis to ensure that the code will not print anything nor change global state (unless it is for logging purposes?). There might be a small number of cases where you can improve with more analysis, but basically I think we're back to the @pure function annotation as a way for a programmer to assert that the function will not rely on global state and will always give the same result for isequal arguments.

@nalimilan
Copy link
Member

Also, even a pure function can take some time to compute, e.g. cor on a big matrix. Maybe we need a simple whitelist of functions from Base that can be evaluated without problems, and do not go beyond this.

@StefanKarpinski
Copy link
Member Author

Or just stop at type inference, which is well bounded in time. If you can't type infer something, my impression is that it's unlikely that you can tell that it has no side-effects.

@vtjnash
Copy link
Member

vtjnash commented Feb 10, 2015

You might almost want to start with an effect-free argument evaluation pass (to handle non-const) then do a typeinf step

True though that effect-free (aka pure) doesn't fully imply fast. But currently effect-free does not accept branches, so that's ok

@dhoegh
Copy link
Contributor

dhoegh commented Jun 10, 2015

Can someone give me a hint on how to do type inference on an expression to get the return type? Then I would give a shot at implementing it into the REPL to close #6338. I know this is a simple example, but how can I make type interference return the return type of the following expression?

a=1
:(a+1+max(1, 2))

@timholy
Copy link
Member

timholy commented Jun 10, 2015

I'm only just learning my way around inference.jl, but I'd recommend starting with abstract_eval.

I put some comments about inference.jl in #10691; if there is interest, I should probably commit that separately.

@dhoegh
Copy link
Contributor

dhoegh commented Jun 11, 2015

I have made a little progress, by looking at return_types. Is there a way to force the inference to make assumptions about a global variable? I would like to be able to tell the return type of the following anonymous function.

a = 1
b = () -> (a + 1*10)
Core.Inference.typeinf(b.code, Tuple{}, b.env)[2]

If there is a way of obtain a list of the global variables in the anonymous function, then I could supply the variable as argument in the function as: (a) -> (a + 1*10). The type of a could then be determined and the return type obtained.

@timholy
Copy link
Member

timholy commented Jun 11, 2015

Presumably you need to get those into the "environment" (see variables named env) or perhaps the StaticVarInfo (see sv), but I can't yet offer any advice about how you'd go about doing that.

@dhoegh
Copy link
Contributor

dhoegh commented Mar 28, 2016

PR #15652 fix this issue, when it is merged.

@vtjnash vtjnash closed this as completed in 2d27919 Apr 6, 2016
vtjnash added a commit that referenced this issue Apr 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

No branches or pull requests

7 participants