# Typeaware autocompletion

**URL:** <https://discourse.julialang.org/t/typeaware-autocompletion/3268>\
**Category:** General Usage\
**Created:** [April 18, 2017, 4:07pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268 "2017-04-18T16:07:01Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ford](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ford/32/1741_2.png) [@Ford](https://discourse.julialang.org/u/Ford)\
**Post date:** [April 18, 2017, 4:07pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/1 "2017-04-18T16:07:02Z")

</div>

**Is somebody looking into typeaware completion?** I think it would be really nice feature to have:

```julia
array=[1,2]
mean( #if you hit tab / ctrl+space now, 'array' shows between first candidates

```

It would be also nice to have the same thing for objects like OOP languages, but since julia does’t support syntax `object.function`, you cannot easily list all possible functions that can be applied to given object (aka methods). The only thing that comes to my mind is `|>`.

```julia
array=[1,2]
array |> #if you hit tab / ctrl+space now, 'mean', 'sort' etc shows between candidates

```

But that wouldn’t work for functions with multiple arguments…

So in case somebody already explored this a little bit, could you share with us some insights?

1. How complicated is it to implement such a thing?
2. Would it be lightweight enough to be included in REPL?
3. Any workaround for the missing OOP syntax?
4. Anything else that should be mentioned?

---

<div class="post-metadata">

**Author:** ![ararslan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ararslan/32/3825_2.png) [@ararslan](https://discourse.julialang.org/u/ararslan)\
**Post date:** [April 18, 2017, 6:53pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/2 "2017-04-18T18:53:55Z")

</div>

In the first example, do you mean that the variable called `array` would autocomplete when the user types `mean(<tab>`? The issue there is that `mean`, like many other Julia functions, has several methods. As an example, consider the method `mean(f, x)`, where `f` is a function. The REPL can’t know that you want the `mean(x)` method; you could just as easily want `mean(f, x)`, in which case what should it autocomplete? The current behavior of showing methods seems like the most general and useful solution to me.

In order to autocomplete methods from a pipe, the expression on the left hand side would need to be evaluated so that its type could be determined and the appropriate methods suggested. That seems like a waste of computational resources, since the expression would need to be evaluated for the autocomplete then again for the actual call that’s made.

For exploration of applicable methods, check out [`method_exists`](https://docs.julialang.org/en/latest/stdlib/base.html#Base.method_exists) and [`applicable`](https://docs.julialang.org/en/latest/stdlib/base.html#Core.applicable).

---

<div class="post-metadata">

**Author:** ![Ford](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ford/32/1741_2.png) [@Ford](https://discourse.julialang.org/u/Ford)\
**Post date:** [April 18, 2017, 8:20pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/3 "2017-04-18T20:20:18Z")

</div>

> , do you mean that the variable called array would autocomplete when …

Exactly.

> … in which case what should it autocomplete?

I would expect to get list of completions for all viable methods (that means both for `mean(x)` and for `mean(f, x)`). In this concrete case I would get list of all available arrays `x` **with** list of all functions `f` **with** list of all functions and macros which can generate valid `x` or `f` etc. Basically everything that doesn’t lead to type error.

> The current behavior of showing methods seems like the most general …

The current solution offers you all declared variables and functions without blink of an eye even when it is not defined for them (e.g. String). I would say it is way too general.

> That seems like a waste of computational resources…

I am not really an expert on this topic but I think we could look at how other mature languages do this (java, typescript).

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 18, 2017, 8:27pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/4 "2017-04-18T20:27:49Z")

</div>

I think this would be a cool idea for a package. You could write functionality that implements these more sophisticated autocompletions and then you could just easily make the TAB key call this function instead of the default one.

---

<div class="post-metadata">

**Author:** ![ZacLN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zacln/32/2748_2.png) [@ZacLN](https://discourse.julialang.org/u/ZacLN)\
**Post date:** [April 18, 2017, 9:05pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/5 "2017-04-18T21:05:52Z")

</div>

As well as the multiple methods issue mentioned above you have the problem that all function names ought still be included in the list of completions as well as all `struct` types that may have a field of the appropriate type (and their own fields, etc) and any type of variable that could be followed by a binary operator whose return type is the appropriate type for the argument. In the end you’ll probably end up with the same list of variables

---

<div class="post-metadata">

**Author:** ![Ford](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ford/32/1741_2.png) [@Ford](https://discourse.julialang.org/u/Ford)\
**Post date:** [April 19, 2017, 6:42am UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/6 "2017-04-19T06:42:16Z")

</div>

That is a fair point. Functions that take arguments of type `Any` are really getting in the way.

In statically typed languages typeaware completion can’t produce ill typed expression. It can only produce incomplete expression.

```julia
@$%(::String, ::String) -> Int
type Foo
  a :: String
  b :: Int
end
x = Foo(1, "2")
mean(#now the possible candidates will include x.b, x.a @$%, but not x.a and x on its own

```

Therefore if you keep hitting tab long enough, you should get expression that doesn’t throw type error.

The fact Julia is dynamically typed makes this a bit more complicated.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [April 19, 2017, 8:19am UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/7 "2017-04-19T08:19:20Z")

</div>

I have something of the sort in GtkIDE, what I autocomplete is a tuple, basically I ask “what are the methods that can be applied to this tuple”, which I think is the correct equivalent of the dot completion in OOP languages.

So for example if I have

```julia
D = Poisson(1)
(D,1)

```

When I press tab after the ) I get as autocompletion:

```julia
promote{T,S}(x::T, y::S) at promotion.jl:153
quantile(d::Distributions.Poisson, q::Real) at /Users/jbieler/.julia/v0.5/Distributions/src/univariates.jl:328
quantile(d::Distributions.Distribution{Distributions.Univariate,S<:Distributions.ValueSupport}, p::Real) at /Users/jbieler/.julia/v0.5/Distributions/src/univariates.jl:163
rand(d::Distributions.Distribution{Distributions.Univariate,S<:Distributions.ValueSupport}, n::Int64) at /Users/jbieler/.julia/v0.5/Distributions/src/univariates.jl:67
range{T}(a::T, len::Integer) at range.jl:107
entropy(d::Distributions.Distribution{Distributions.Univariate,S<:Distributions.ValueSupport}, b::Real) at /Users/jbieler/.julia/v0.5/Distributions/src/univariates.jl:75
ccdf(d::Distributions.Poisson, x::Int64) at /Users/jbieler/.julia/v0.5/Distributions/src/univariates.jl:324
...

```

Or

```julia
(String,Float64)

poll_file(s::AbstractString, interval_seconds::Real) at poll.jl:409
promote{T,S}(x::T, y::S) at promotion.jl:153
watch_file(s::AbstractString, timeout_s::Real) at poll.jl:389
tex2pango(str::AbstractString, fontsize::Real) at /Users/jbieler/.julia/v0.5/Cairo/src/Cairo.jl:1094]

```

And the when you press Enter it prepends the method name to the tuple. In practice I don’t use it that much, but it’s been a bit buggy, a proper implementation might be quite useful.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 19, 2017, 10:07am UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/8 "2017-04-19T10:07:58Z")

</div>

> [@ararslan](#):
>
> In order to autocomplete methods from a pipe, the expression on the left hand side would need to be evaluated so that its type could be determined and the appropriate methods suggested. That seems like a waste of computational resources, since the expression would need to be evaluated for the autocomplete then again for the actual call that’s made.

I think the REPL autocomplete does something similar already – when you have e.g.

```julia
struct Foo
  a::Int
end
[Foo(1), Foo(2)][1].\tab

```

you get `a` autocompleted. IIRC, Julia looks at the return type of the expression before the dot and then finds its return type, which you could also do for pipes.

---

<div class="post-metadata">

**Author:** ![dhoegh](https://avatars.discourse-cdn.com/v4/letter/d/cc9497/32.png) [@dhoegh](https://discourse.julialang.org/u/dhoegh)\
**Post date:** [April 19, 2017, 8:03pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/9 "2017-04-19T20:03:00Z")

</div>

As already mentioned the REPL do already do autocompletion based on types. Here’s an example from the manual

```julia

julia> max([1,2],[TAB] # All methods where `Vector{Int}` matches as first argument
max{T1<:Real,T2<:Real}(x::AbstractArray{T1,N<:Any}, y::T2) at operators.jl:544
max{Tx<:Real,Ty<:Real}(x::Union{Base.ReshapedArray{Tx,1,A<:DenseArray,MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N<:Any}}},DenseArray{Tx,1},SubArray{Tx,1,A<:Union{Base.ReshapedArray{T<:Any,N<:Any,A<:DenseArray,MI<:Tuple{Vararg{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64},N<:Any}}},DenseArray},I<:Tuple{Vararg{Union{Base.AbstractCartesianIndex,Colon,Int64,Range{Int64}},N<:Any}},L<:Any}}, y::AbstractSparseArray{Ty,Ti<:Any,1}) at sparse\sparsevector.jl:1127
max{T1<:Real,T2<:Real}(x::AbstractArray{T1,N<:Any}, y::AbstractArray{T2,N<:Any}) at operators.jl:548
max(x, y) at operators.jl:78
max(a, b, c, xs...) at operators.jl:119

julia> max([1,2], max(1,2),[TAB] # All methods matching the arguments.
max{T1<:Real,T2<:Real}(x::AbstractArray{T1,N<:Any}, y::T2) at operators.jl:544
max(x, y) at operators.jl:78
max(a, b, c, xs...) at operators.jl:119

```

The code blok is from the manual [https://docs.julialang.org/en/stable/manual/interacting-with-julia/#tab-completion](https://docs.julialang.org/en/stable/manual/interacting-with-julia/#tab-completion)

---

<div class="post-metadata">

**Author:** ![smldis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smldis/32/1735_2.png) [@smldis](https://discourse.julialang.org/u/smldis)\
**Post date:** [April 19, 2017, 9:41pm UTC](https://discourse.julialang.org/t/typeaware-autocompletion/3268/10 "2017-04-19T21:41:08Z")

</div>

For the second case:  
Is it difficult to have a type inference pass and a methodswith call with the inferred type to get possible completions?

Something like:

````julia
array=[1,2]
methodswith(typeof(array),Base,true)```

It gives a 1000+ possible methods with nice performances
````
