Skip to content

Method lookup does not traverse beyond the first clause found. #150

Open
@faultyserver

Description

@faultyserver

Consider this code:

defmodule Foo
  def read
    :foo_read
  end
end

deftype Bar
  include Foo

  def read(something)
    :bar_read
  end
end

%Bar{}.read

I would expect this code to return :foo_read, since the read clause defined in Bar does not match the arguments given in the Call at the end of the sample.

What actually happens, though, is a "No clause matches" error is raised, because the method lookup does not continue into the Foo module.

The reason for this is that Bar and Foo have separate TFunctor objects representing the read method. Each has one clause, and exists in its respective scope.

When method lookup starts, the interpreter will check Bar and find its TFunctor for the method. The only clause here requires a parameter, but the Call itself does not provide any arguments. As such, the Invocation of the method fails and the error is raised.

I think there are probably a few good ways to resolve this. The first that comes to mind is changing how Invocation works to allow multiple TFunctor objects to be bound, and it will iterate them in order to find a matching clause.

Another option I thought of was cloning the TFunctor object from the included module into the object that included it, allowing that object to have a single functor with all of the clauses together. However, this approach would still have an issue where re-opening the module and adding a clause would not add that clause to anything that includes that module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugGeneric label for bugs. Every bug should have this tag in addition to the more specific bug tagbug.interpreterA bug specifically relating to the interpreter source codesemanticsGeneric label for semantics issues. All semantics issues should have this tag.semantics.interpreterAny issue relating to changing the semantics of interpreter code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions