Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: do not redefine def macro and use attribute tags #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

x4lldux
Copy link

@x4lldux x4lldux commented May 1, 2016

I've made a mistake making the original pull request (#1) from master branch. This is a fix for this so I can still work on this lib, adding new features.


I've seen your talk yesterday - nice one! DbC is a great concept especial in Elixir/Erlang in creating fault tolerant systems.

This pull request is meant to be of a Request For Comment and initiating a discussion. My implementation, removes the need to redefine def macro (redefining core functions/macros is somewhat iffy and can have side effects, especial if another module does the same thing). Additionally, adding a contract to a functions feels more like it's a meta information about that function, so attributes are more appropriate way of assigning a contract to a function (tagging it with a contract).

By doing this that way, (in the future) we can extend this by adding another attribute for defining how to inform about a broken condition:

@requires contract tank.in_valve == :closed && tank.out_valve == :open
@ensures  contract empty?(result) && result.in_valve == :closed && result.out_valve == :closed
@on_break :error_tupel
def empty(tank) do

which will return a {:error, result}. Or maybe a information what part of contract was broken.

Unfortunately, since attributes require values, their arguments are evaluated first. This is why macro contract is needed, to return AST form of a conditions . It basically works as a quote, but this can change if we'll add more information when raising on broken conditions (maybe similar information to what is returned by ExCase.assert macro).

Pros:

  • not redefining a core Elixir element - def macro
  • tagging functions with contracts feels more correct than calling macros before a definition of a function
  • introspection - Module.info :attributes returns contract_predicates attribute containing information about each tagged functions

Cons:

  • breaking changes (use of attributes instead of macros)
  • need of contract macro

Also, I think we should use singular form ensure and require.

Cheers!

x4lldux added 2 commits March 16, 2016 12:46
Changes the implementation to not redefine `def` macro. Additionaly,
pre- and post-conditions are now attributes, since specifying a contract
for a function, feels more as a "tagging" it with a contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant