Macro would not “see” anything. You just need to generate something like:
is_nil(term) or is_list(term) or …
In AST
representation it looks like:
# single call:
{:is_nil, [], [term])
# "or" call:
{:or, [], [x, y]
# "or" with two items:
{:or, [], [{:is_nil, [], [term]}, {:is_list, [], [term]}]}
# nested "or" is in the first argument:
{:or, [], [{:or, [], [x, y]}, z]}
You can preview AST
using quote/2
and preview generated code using Macro.to_string/2
Well … this is generally 100% right, but in Elixir
only ingenuity (and of course implementation time) limits you. For example nothing stops you from forking ex_doc
and check for optional extra attribute:
defmodule Example do
Module.register_attribute(__MODULE__, :special_spec, persist: true)
@special_spec quote do: not is_integer(term)
@spec unquote(MyApp.spec_macro(@special_spec))
end
In such way you can keep ex_doc
output clean and have valid @spec
(for example for dialyzer
). If I remember correctly hex
uploads .html
files, so there is no need to worry about forking ex_doc
if you really want to.
As said generally it’s just more work and in typical case it’s simply not worth. However if you for any reason really want to have such thing then nothing stops you. As long as your code stays clean and you would follow good practices then nobody would complain.
So if you ask if you can do something like inverse typespec then answer is yes. However how it would look like depends on how much time and effort you are able to spend. You can just generate @spec
and it would be 100% valid (dialyzer
should not complain), but it would not look good in ex_doc
. You can fork ex_doc
and support extra module attribute, but it would take some extra time. You can …, but keep in mind that … etc.
Also if you have a good idea for implementing something in Elixir
feel free to propose it here or on mailing list. You just keep in mind that Elixir
core follows some rules. If you propose something which does not conflict with them it would be accepted. Like @hauleth said some things are hard in general. If you however find a good implementation solution then community is open to your idea.
As I have already said in another thread. Programmers don’t think like computers i.e. only 0
and 1
cases. Of course we have good and bad practices, but everything else is up to us. Look at documentation, check what you need to do (here specific AST
) and in which way you can provide it (here macro). As long as code would be clean (I recommend credo
here) it’s definitely ok. Only you have a right to limit yourself.
It’s why I said that’s generally possible, but also I don’t recommend it. At end it’s your decision what and how much you want to do. Compare cons with pros and choose your preferred way. It’s nothing bad if it’s generally not worth, but you would implement it anyway. Even if it would be a coding challenge as long as you have fun with programming there is nothing wrong about it.