# Fixing the Piping/Chaining Issue

**URL:** <https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654>\
**Category:** Internals & Design\
**Tags:** proposal, piping, chaining, partial-evaluation, threading\
**Created:** [November 2, 2022, 11:04am UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654 "2022-11-02T11:04:36Z")\
**Posts on this page:** 1\
**Showing post:** 187

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [November 9, 2022, 10:32pm UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654/187 "2022-11-09T22:32:53Z")

</div>

Okay so since working through that example I basically did all the work needed to figure out how to it anyway, I threw together a quick and simple script that does what I described for a simple autocomplete (you knew I would, didn’t you 😤)

> **Code here**
>
> ```julia
> 
> function propose_method_autocompletions(obj, func_name_fragment::String=""; 
> type_depth = 1:typemax(Int), only_same_module = false, 
> prioritize_firstlast = false, github_inference = false, personalized_inference = false)::Vector{Method}
> 
> @assert first(type_depth) ≥ 1 && last(type_depth ≥ 1)
> recs = Vector{Method}[]
> get_type_at_depth(type, depth=1) = depth == 1 ? type : type == Any ? nothing : get_type_at_depth(supertype(type), depth-1)
> 
> for i ∈ type_depth
> stype = get_type_at_depth(typeof(obj), i)
> isnothing(stype) && break
> 
> meths = filter(only_same_module ? methodswith(stype, parentmodule(typeof(obj))) : methodswith(stype)) do m
> length(func_name_fragment) > length(string(m.name)) && return false
> string(m.name)[1:length(func_name_fragment)] == func_name_fragment
> end
> 
> prioritize_firstlast || true # do cool sorting stuff, add later
> github_inference || true # do cool sorting stuff, add later
> personalized_inference || true # do cool sorting stuff, add later
> 
> recs = [recs; meths]
> end
> 
> recs
> end
> 
> ```

To invoke:

```julia
using DataFrames
df = DataFrame(a=1, b=2)

propose_method_autocompletions(df)

```

By default, it returns all available methods that can act on object `df`. As you start to type in a function name, the list gets narrowed down quickly:

```julia
propose_method_autocompletions(df, "p")
propose_method_autocompletions(df, "pu")
propose_method_autocompletions(df, "pushfirst!")

```

You can also change the search depth. By default, it searches specializations on `typeof(df)`, as well as `supertype(typeof(df))`, `supertype(supertype(typeof(df)))`, and so on. This can be changed like so:

```julia
propose_method_autocompletions(df, "p"; type_depth=1:2)

```

This gives methods of `DataFrame` as well as `AbstractDataFrame`, but not `Any`. The iterator can also be reversed `2:-1:1` to show the abstract type’s methods first.

You can also restrict the search to only methods that are defined in the same module as `DataFrame`:

```julia
propose_method_autocompletions(df, "p"; only_same_module = true)

```

And, one day, it’ll work with the `arg_order_inference`, `github_inference` and `personalized_inference` options too. 😉

Someday it could be interesting to make it feed its results into a `Channel`, so that it can offer results with greater immediacy.

_Unfortunately it doesn’t solve \*my\* problem, because the module didn’t export its methods so they don’t appear in `methodswith` 😅_

_Oddly, when calling `methodswith(DataFrame, DataFrames)` (trying this to see if it improves speed over filtering \*after\* the `methodswith` call), it simply doesn’t return a bunch of methods of `DataFrame` that are indeed declared by the `DataFrames` module. For example, `pushfirst!` is missing. Strange._

---

_[View the full topic](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654)._
