# How do you get super() functionality in Julia?

**URL:** <https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 25, 2018, 8:13pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055 "2018-08-25T20:13:14Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [August 25, 2018, 8:13pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/1 "2018-08-25T20:13:14Z")

</div>

For example, let’s say you have

```julia
foo(x::Any) = 1
foo(x::Int) = 2
foo(x::Number) = 3
foo(x::String) = "Nu uh uh. You didn't say the magic word"

```

so that `foo` is a generic function with 4 methods

* * *

Let’s say I have `x = 10`.

How would I get a list of all the `foo` functions applicable to `x = 10` in order of specificity?

// i.e. the first three functions from above

* * *

**edit:** the use case is I want to have some functions that bubble up.

Or in other words, add a concept of the [`super`](https://www.pythonforbeginners.com/super/working-python-super-function) function

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 25, 2018, 8:44pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/2 "2018-08-25T20:44:30Z")

</div>

You might be able to accomplish your actual use case with `invoke`, which doesn’t list methods in order but does let you accomplish something similar to what `super()` does in python.

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 25, 2018, 9:03pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/3 "2018-08-25T21:03:22Z")

</div>

A combination of `which` and `supertype` should do the trick for single argument functions. Try

```julia
function methodhierarchy(name, argtype)
    methods = Vector{Method}()
    push!(methods, which(name, (argtype,)))
    while argtype != Any
        argtype = supertype(argtype)
        method = which(name, (argtype,))
        if methods[end] != method
            push!(methods, method)
        end
    end
    methods
end

julia> methodhierarchy(foo, Int)
[1] foo(x::Int64) in Main at REPL[2]:1
[2] foo(x::Number) in Main at REPL[3]:1
[3] foo(x) in Main at REPL[1]:1

julia> m = methodhierarchy(foo, String)
[1] foo(x::String) in Main at REPL[4]:1
[2] foo(x) in Main at REPL[1]:1

```

---

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [August 26, 2018, 8:12am UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/4 "2018-08-26T08:12:57Z")

</div>

This is what I’m currently working with.

It goes into an infinite loop with nested `super` calls though ☹

And it only works when there’s one argument…

```julia
function super(cur_input)
  cur_function = getfield(current_module(), stacktrace()[2].func)
  println(stacktrace())
    
  cur_type = typeof(cur_input)
  cur_super_type = nothing
    
  cur_method = which(cur_function, (cur_type,))
  is_hunting_super = false
    
  while cur_type != Any
    cur_type = supertype(cur_type)
    tmp_method = which(cur_function, (cur_type,))
     
    if cur_method == tmp_method 
      if is_hunting_super
        cur_super_type = cur_type
        break
      end
    else
      is_hunting_super = true
      cur_super_type = cur_type
      cur_method = tmp_method
    end
  end
    
  @assert cur_super_type != nothing
    
  cur_output = invoke(cur_function, Tuple{cur_super_type}, cur_input)
    
  cur_output
end

```

```julia
function foo(x::Any)
  println("Any")
end

function foo(x::Int)
  println("Int")
  super(x)
end

function foo(x::Number)
  println("Number")
  super(x)
end

function foo(x::String)
  "Nu uh uh. You didn't say the magic word"
end

```

---

<div class="post-metadata">

**Author:** ![saschatimme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/saschatimme/32/10313_2.png) [@saschatimme](https://discourse.julialang.org/u/saschatimme)\
**Post date:** [August 26, 2018, 8:31am UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/5 "2018-08-26T08:31:52Z")

</div>

Can you maybe describe your problem more concrete? I think there is probably a more idiomatic way in Julia to deal with your problem. (Instead of just porting over OO ideas).

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [August 26, 2018, 9:32am UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/6 "2018-08-26T09:32:49Z")

</div>

Yeah, a better description of the problem and the goal to achieve would be a good start.

Parsing the stacktrace text output is smelly anyways 😉

---

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [August 26, 2018, 6:15pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/7 "2018-08-26T18:15:53Z")

</div>

This comes up in web frameworks when you care about how information is sent up and down trees.

It just boils down to being able to call the next least specific function.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [August 26, 2018, 10:23pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/8 "2018-08-26T22:23:17Z")

</div>

> [@djsegal](#):
>
> be able to call the next less specific function

```julia
Julia-0.6.4> x = 1
1

Julia-0.6.4> foo(x)
2

Julia-0.6.4> invoke(foo, Tuple{supertype(typeof(x))}, x)
3

```

---

<div class="post-metadata">

**Author:** ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)\
**Post date:** [August 26, 2018, 10:58pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/9 "2018-08-26T22:58:01Z")

</div>

The problem with that is it won’t chain for abstract types

> `Int (1st call)`  
> `StackFrame[super(::Int64) at In[84]:3, foo(::Int64) at In[84]:41, ...]`

> `Number (2nd call)`  
> `StackFrame[super(::Int64) at In[84]:3, foo(::Int64) at In[84]:46, super(::Int64) at In[84]:30, foo(::Int64) at In[84]:41, ...]`

> `Number ( 3rd call -- BAD!!! )`  
> `StackFrame[super(::Int64) at In[84]:3, foo(::Int64) at In[84]:46, super(::Int64) at In[84]:30, foo(::Int64) at In[84]:46, super(::Int64) at In[84]:30, foo(::Int64) at In[84]:41, ...] Number`

Notice that each of those functions were passed the concrete `(::Int64)` and **not** `(::Number)`

* * *

**edit:** for clarity, the 3rd call should have been to `foo(x::Any)`, not to `foo(x::Number)`.

// although, I truncated it after 3 calls, this is actually an infinite loop

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 26, 2018, 11:10pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/10 "2018-08-26T23:10:39Z")

</div>

> [@djsegal](#):
>
> The problem with that is it won’t chain for abstract types

That is impossible to do with a function. It doesn’t have any access to the context.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 26, 2018, 11:12pm UTC](https://discourse.julialang.org/t/how-do-you-get-super-functionality-in-julia/14055/11 "2018-08-26T23:12:46Z")

</div>

And just to be clear. It’s not possible with a callsite local macro either.
