0
votes

I'm very confused about this syntax:

create table(:topics) do
  add :title, :string
end

create is a function that takes argument table(), which is another function, correct me if i'm wrong? But then is followed by a function body?

Could someone explain how this works?

2
Good question, I'm personally not sure how to best answer the question but here is where some of the sausage is being made github.com/elixir-ecto/ecto/blob/master/lib/ecto/migration/…Bitwise

2 Answers

1
votes

create/2 is a macro that takes two values. Just because you are calling it like

create table(...) do 
  ...
end

Doesn't ment you have to. table/2 is just a function. You could write the above statement as

table = table(:my_table)
create my_table do
  ...
end

You are not passing a function into the create macro, you are passing a value that just happens to come from a function into the create macro.

0
votes

do ... end is not necessarily a function body. It's generic syntax, which when used with a macro, passes the AST (abstract syntax tree) of its contents to the macro. Here's a demonstration:

defmodule A do
  defmacro a(args) do
    IO.inspect args
  end

  def main do
    a do
      1 + 2
    end
  end
end

A.main

Output:

[do: {:+, [line: 8], [1, 2]}]

So it's just the AST of the body of the block, passed as a keyword list with the key do.

create then is just a macro which accepts two arguments: the first is table, and the second is the do ... end block. The macro then transforms the block and executes it. You can see the source code of the function for more details.