I hear you, I am curious to know why it can't be done. "Idiomatic" code 
comes from the capabilities of the language, I don't disagree with you, but 
we didn't have `with` at some point as well.

I notice that we do a lot of macros to initialize module attrs, or include 
other macros, and sometimes, we do it only to use one macro in some way 
(yes, I understand that I can use `require`)

Not sure,  I dont need it 1000%, but it is nice to have it honestly, there 
is more cohesion (sometimes) among why `use` and the intention.

P.S: I may move with what I have today, or do something around what aditya7 
proposed
On Monday, August 9, 2021 at 12:58:14 AM UTC-4 Paul Schoenfelder wrote:

> Sorry, for some reason I completely overlooked that you were doing this 
> with `use`. I would second the recommendation to avoid that approach. Since 
> `use` is a special form, it’s likely you can’t do what you’re trying to do 
> here anyway. The bigger issue is that it’s very unidiomatic - while it 
> might save you one extra line of code versus an explicit macro, it’s very 
> different from how most libraries expose this kind of functionality, and 
> much less composable. 
>
> Ultimately though, I think you’ll be limited by the fact that `use` is a 
> special form (IIRC, I haven’t confirmed that you _can’t_ do what you’re 
> trying to do, but I suspect that’s the thing tripping you up).
>
> On Mon, Aug 9, 2021, at 12:42 AM, Yordis Prieto wrote:
>
> aditya7, I dont disagree with you.
>
> There is always a balance between magic and verbosity. The reason I don't 
> mind "magic" in Elixir is that everything is explicit and macros are 
> expanded at compile time. So my intention is to make the code as simple as 
> possible at the cost of hidden complexity that I am OK with it at the 
> moment. Everything with balance, this is one of those cases where it is 
> just a bag of data and few things, the easier the better.
>
> In the worst case, I will end up doing a version of what you proposed, I 
> am trying to avoid having to import a module and having to call yet another 
> function at the moment.
> On Monday, August 9, 2021 at 12:35:26 AM UTC-4 Yordis Prieto wrote:
>
> Hey Paul,
>
> I can't remove the comma from it thou, I get the following error, `use` 
> macro expects 2 arguments as far as I can tell
>
> ```
> ** (ArgumentError) invalid arguments for use, expected a compile time atom 
> or alias, got: Command[[aggregate_identifier: :id]]
>     (elixir 1.11.2) lib/kernel.ex:5006: anonymous fn/3 in 
> Kernel."MACRO-use"/3
>     (elixir 1.11.2) lib/enum.ex:1399: Enum."-map/2-lists^map/1-0-"/2
>     (elixir 1.11.2) expanding macro: Kernel.use/2
> ```
>
> On Sunday, August 8, 2021 at 8:59:03 PM UTC-4 Paul Schoenfelder wrote:
>
>
> It looks to me like the error is due to a stray comma: `use Command, 
> [aggregate_identifier: :id] do` should be `use Command 
> [aggregate_identifier: :id] do`, which should work as you’d expect.
>
> As an aside, you might be interested in 
> https://github.com/bitwalker/strukt, which looks like it has a lot of 
> overlap with what you’re building (though what you are shooting for may be 
> totally different, I just see some similarities)
>
> Paul
>
> On Sun, Aug 8, 2021, at 7:54 PM, Adi wrote:
>
> I am not sure if supporting use/* is the right way forward here. The 
> `Kernel.use/2` macro is reserved for invoking a module's `__using__/1` 
> macro. To be honest, I don't like the fact that you're setting the module 
> attributes and defining the `embedded_schema` in the same macro. You can 
> easily just define the `@primary_key` in the `__using__/1` macro and 
> explicitly define the `embedded_schema` in `CreateRecurringTransfer` 
> itself, but that's my preference. 
>
> Either way, if you have defined a `__using__/3` macro, you can always 
> invoke it explicitly. Although I would rename it to avoid any confusion for 
> developers reading the code in the future and potentially thinking it has 
> something to do with `Kernel.use/2`.
>
> defmodule Command do
>   defmacro aggregate_schema(opts \\ [], do: block) do
>     unless Keyword.has_key?(opts, :aggregate_identifier) do
>       raise ArgumentError, "Missing :aggregate_identifier key"
>     end
>
>     aggregate_identifier = Keyword.fetch!(opts, :aggregate_identifier)
>
>     quote do
>       use Ecto.Schema
>       @primary_key { @aggregate_identifier_key, :binary_id, autogenerate: 
> true }
>       @derive Jason.Encoder
>        embedded_schema unquote(block)
>     end
>   end
> end
>
> defmodule CreateRecurringTransfer do
>   require Command
>   Command.aggregate_schema [aggregate_identifier: :id] do
>     field(:dtstart, :naive_datetime)
>     field(:dtend, :naive_datetime)
>     embeds_one(:amount, PositiveAmount)
>     embeds_one(:rrule, Rrule)
>     embeds_one(:owned_by, CustomerIdentity)
>     embeds_one(:from_account, TransferAccount)
>     embeds_one(:to_account, TransferAccount)
>   end
> end
>
> On Sunday, 8 August 2021 at 16:15:59 UTC-4 [email protected] wrote:
>
> I am trying to do the following,
>
> defmodule Command do
>   defmacro __using__(opts \\ [], do: block) do
>     unless Keyword.has_key?(opts, :aggregate_identifier) do
>       raise ArgumentError, "Missing :aggregate_identifier key"
>     end
>
>     aggregate_identifier = Keyword.fetch!(opts, :aggregate_identifier)
>
>     quote do
>       use Ecto.Schema
>       @primary_key { @aggregate_identifier_key, :binary_id, autogenerate: 
> true }
>       @derive Jason.Encoder
>        embedded_schema unquote(block)
>     end
>   end
> end
>
>
> Just so I can do something like,
>
> defmodule CreateRecurringTransfer do
>   use Command, [aggregate_identifier: :id] do
>     field(:dtstart, :naive_datetime)
>     field(:dtend, :naive_datetime)
>     embeds_one(:amount, PositiveAmount)
>     embeds_one(:rrule, Rrule)
>     embeds_one(:owned_by, CustomerIdentity)
>     embeds_one(:from_account, TransferAccount)
>     embeds_one(:to_account, TransferAccount)
>   end
> end
>
> But I get `** (CompileError) iex:3: undefined function use/3` which I 
> assume what I am trying to do is not supported.
>
> I am curious to understand why it doesn't work (beside maybe not being 
> supported), and what would be the problem by trying to support it
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/46c25948-b96e-4982-b710-0ebeae1b5e96n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/46c25948-b96e-4982-b710-0ebeae1b5e96n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/9c80199c-ed64-427a-9d67-12847f9ef8efn%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/9c80199c-ed64-427a-9d67-12847f9ef8efn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/35527b5d-d835-491b-ba35-1f61968cca8dn%40googlegroups.com.

Reply via email to