njichev

njichev

GSoC 2018: StreamData generators out of type specifications.

Hi everyone!

I’m Nikola and I’ll be working on the following google summer of code project.
I plan on updating you folks in this thread to check out the progress and maybe return feedback :slight_smile:

Week 1 13.05-19.05

I started working on generation of the basic types. Progress for this week can be seen in this branch.
Added most basic types with the exceptions of the likes of functions/pids/ports and some builtin types.
When I say basic types, I mean the basic/built-in and literals that elixir supports, check them out here.

Week 2 20.05 - 26.05

For this week - I mostly experimented with different approaches to recursive data types reading some papers and how I would implement function generation.
Some stuff that might be interesting:

And a branch where I experimented on recursive data types.

Week 3 27.05 - 02.06

Set up a new mix project, so that tests and reviews can be easier, you can find the project here.
Also create function generation, you can (git) check out the branch.

Week 4 03.06 - 03.10

Mostly getting help from mentor to get the basic types merged and review what we’ve been doing.
I plan on adding support for pids/ports this week.

Most Liked

njichev

njichev

Hi folks, another update from me :slight_smile:

Week 5-6 11.06 - 24.06

Busy with personal trips, university finals, so mostly reading code and learning statistics with R.
Began with the basics union type support, stuff like:
integer | atom, detecting those types and separating them from recursive types such as:
list :: nil | {integer, list}

Week 7 25.06 - 01.07

Start working on recursive types - added support for basic stuff like unions:
data = nil | {integer, data} for example.

A great help was this thread by alfert bow:

Other work includes doing some support stuff, for example raise when people try to
reference protocol types. So if you try generating a stream for Enum.t, you’ll get an error
that will tell you to use the data that implements the protocol instead(lists for example).
The reason this is done is because the Enum.t written by elixir after expansion is equivalent to
any() which is in no way useful. You can check the PR here: Raise on protocols. by NJichev · Pull Request #15 · NJichev/type-generators · GitHub

Another thing is raising when you have a pid/port type in your types, reason for this is simple,
we can’t know what kind of processes you need, hence just show an error message how you could achieve what you want.

Week 8 02.07 - 08.07

Finish work on recursive types(without parameters).
Let’s take this type as an example:

@type operator :: :+ | :- | :* | :/
@type expr :: integer() | {expr(), operator(), expr()}

Here the expr type will have 3 user defined types in the type signature it returns.
The user types will look something like this:

union:
  integer
  tuple:
    {user_type, ..., expr, }
    {user_type, ..., operator, }
    {user_type, ..., expr, }

Because the operator is not inlined as a union of the 4 operations, this caused problems

  • the fix was to just manually inline all types until only those with the name expr remain.
    That way the type tree only has user types such as {:user_type, ..., expr, ...} making it easy
    to detect the recursive ‘nodes’ later on.
  • a bonus is that the module name doesn’t have to be passed around after that

Other work was for other kinds of recursive types, the working example is the following one:

@type forest :: {integer, [forest]}

After inlining - checking for such recursive types is something like: okay it’s not a union recursive type, let’s check if there is any user_type inside, if so it’s of this kind.
The reason this is a valid recursive types is that the list definition is recursive in itself: list = cons a list | [], which means that our types would look something like:

{-4, [
    {0, [{1, [{1, []},
    {2, [{1, [{-5, []},
    {-68, []}]}]},
    {-3, []}]}]}
  ]
}

So in a way the leaves in the forest example are the implicit nils from the list type that works as a container.

Also I experimented with how the API for the function validation would work,
You can check the WIP branch here: WIP · NJichev/type-generators@8c2871a · GitHub

In a nutshell, what would be the rest of the work:
a function’s type signature in the beam code is something like:

product:
  argument types
  return type

The solution’s algorithm is the following:

  • map type generation to get stream data generators out of the argument types
  • get a function that checks if a certain type is of the return type
  • do a check all that feeding the arguments returns the return type.

A possible API could be something like:

  • check_function_specification(&ModuleName.function_name/arity, opts \ )
  • check_function_specification(ModuleName.function_name/arity, opts \ )
  • check_function_specification({ModuleName, function_name, arity}, opts \ )

I like the tuple one the most, the name is TBD :smiley:

This will be a macro that will expand to:

is_return_type = generate_member_function_for(return_type)
check all x_1 <- arg_1, ..., x_n <- arg_n, expand(opts) do
  assert is_return_type(Module.function_name(x_1, ..., x_n))
end

Leave a comment if you have suggestions for what the API could look like.

Where Next?

Popular in Libraries Top

tompave
Hello there, I would like to share a feature toggles library (AKA feature flags) I’ve been working on. The main package is FunWithFlags...
New
treble37
Just looking for a little feedback on a tiny helper library I built - Sometimes I find the need to convert maps with atom keys to maps...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
kelvinst
Hey everyone! Well, we made this lib a while ago and now we decided to finally go out and public with it! It’s a tool for creating and m...
New
mbuhot
Leverage Open Api 3.0 (Swagger) to document, test, validate and explore your Plug and Phoenix APIs. Generate and serve a JSON Open API ...
New
achempion
Hi, I would like to tell about my initiative to further maintain and develop Waffle project which is the fork of Arc library. The progre...
New
ahamez
Hi everyone, I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
Antrater
Hi everyone! I’m thrilled to announce a huge thing. We have been developing Elixir Moon Design System for quite a while. We are finally ...
New
Qqwy
While not as prevalent as in imperative languages, arrays (collections with efficient random element access) are still very useful in Eli...
New
vic
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

Sub Categories:

We're in Beta

About us Mission Statement