Elixir research projects?

Hi everyone!

I’m currently doing a masters in computer science at Cambridge University and one of the courses that I’m currently enrolled in allows me to pick a {programming language, compilers, interpreter}-related research project that I could get finished in ~1-2 months, part-time.

Being an Elixir enthusiast I decided to come here and ask whether the Elixir community has any potentially interested research projects that I could carry out, for example within the realm of performance improvements or stdlib improvements?

Regards,

Hrafn

2 Likes

Check the LASP project. Some pretty interesting stuff.

2 Likes

Hey there. This may be too far from your aim, but I thought I’d throw it out there. It’s the combination of two technologies, GraphQL and property testing.

GraphQL

I’m one of the authors of the Elixir GraphQL implementation Absinthe: http://absinthe-graphql.org/

GraphQL brings strong typing to your API for both its inputs and outputs. The basic idea is that you have a schema that describes a Graph of the entities and types in your system. So for example you might have a string scalar type, and a user object type. A user is related to the string type via its name, which forms an edge from the user node to the string node. A user node could also have a friends edge which just loops back to the user node.

GraphQL queries are a declarative document that forms a tree starting at some point on the graph and working its way out along the edges as far as is desired. So for example in our hypothetical graph we could start at the user and do

#assume we're at the user here
{
  name
  friends  {
    name
  }
}

Property Testing

  property :square do
    for_all x in int, do: x * x >= 0
  end

Property testing is a way of testing against a myriad of possible cases without having to manually enumerate them. You articulate invariants that ought to be held, and then the range of possible inputs against which they apply, and it goes from there.

I am VERY curious to see if these could be combined. An application’s GraphQL Schema circumscribes the possibility space of queries that can happen against that API. I have a strong feeling that these two could be combined to have automated testing against 100% of an API.

Not sure if this is in your wheelhouse, but GraphQL has interesting theoretical properties, as do property checkers, and it may be interesting to see if they can work together.

1 Like

We recently talked on IRC about a possible compiler optimisation, maybe this would be something that could interest you?

Erlang has the inline_list_funcs compiler option that inlines some functions from the lists module, like lists:map/2. This can sometimes give significant performance benefit, since it’s capable of removing the anonymous function and, at the same time, allows you to maintain clean code without having to do by-hand recursion everywhere.
The downside is that now the lists module can’t be safely reloaded - if the implementation changes, the inlined code won’t and this could lead to various subtle bugs (that’s why Erlang doesn’t do cross-module inlining beside those lists functions, and even that is hidden behind a flag). Fortunately that’s not a big issue if you don’t plan on using hot reloading at all, or you concede that you won’t be able to hot reload the standard library. This is a fair choice in many situations.

The idea is to introduce something similar for Elixir’s Enum module. The problem is that Enum is polymorphic and we’re able only to inline the cases where we operate on lists. Fortunately, there are many situations where we know a value will be a list at compile time - the biggest source of that knowledge are chained Enum calls - they always return lists, no matter what was the initial enumerable. Another case we know we have a list is when faced with a is_list/1 guard.

Since this would give a similar reloading tradeoff, if would need to be hidden behind a compiler flag or, as is the case with Erlang, a module attribute.

Probably the easiest way to implement this would be to turn the Enum calls in places we know will use lists into calls to the appropriate functions from lists module and turning on the Erlang optimisation. There’s also a possibility of experimenting with a more aggressive approach replacing, for example, an Enum.map call with something like:

Enum.map(value, fun)
# turns into
case value do
  list when is_list(list) -> :lists.map(value, fun)
  other -> Enum.map(other, fun)
end

Of course it would be necessary to measure if such changes indeed give the expected performance benefits and check the code bloat that the inlining provokes. Fortunately delegating the bulk of work to the erlang compiler would allow us to follow best practices established there, for free.

A similar inlining could be done for some functions from the Map module - things like Map.get/3 translate cleanly into a single case expression. There is no polymorphism issue in that case, the only thing to consider would be making sure we raise the same errors on bad values.

1 Like

Thanks Michal. This sounds like an excellent suggestion and fits my criteria for a project perfectly. I’m going to pitch this idea to my teacher and hopefully he finds it interesting as well!

1 Like

Thanks Ben, this indeed does sound like a very valid idea and I agree with you that property based testing can probably be applied to GraphQL in interesting ways. As you mention however, this does not quite fit the {programming language, compilers}-criteria. Hope you will have the time to look into this soon. :wink:

1 Like