Closed zachallaun closed 1 year ago
Hi there!
It is possible to create your own module that contains an implementation of __using__
such that it:
use TypeCheck, maybe: some, options: here
if TypeCheck is available.@/1
if not.It might look something like:
defmodule YourLibrary.TypeCheck do
case Code.ensure_compiled(TypeCheck) do
{:module, _} ->
defmacro __using__(options) do
quote do
use TypeCheck, unquote(options)
end
end
{:error, _} ->
defmacro __using__(options) do
quote do
import Kernel, except: [@: 1]
import YourLibrary.TypeCheck, only: [@: 1]
end
end
import Kernel, except: [@: 1]
defmacro @ast do
case ast do
{name, meta, expr} when name in ~w[type! typep! opaque! spec!]a ->
name = name |> Atom.to_string() |> String.trim_trailing() |> String.to_existing_atom()
quote do
Kernel.@(unquote({name, meta, expr}))
end
other ->
quote do
Kernel.@(unquote(ast))
end
end
end
end
end
(I have not tested this code but it should give you a good start to get this working if you really desire to.)
Be warned that this will only work as long as you are not using any of the extra types or features TypeCheck provides over what is supported by Dialyzer/the BEAM itself. Otherwise you'll get compile-time errors whenever you're trying to build the library without the optional dependency. And this is the reason that I don't really recommend this over including it as proper dependency but configuring it to be off by default.
Closing this issue now. Feel free to open a new one if you have any more questions related to this or other things you encounter while using the library :green_heart: !
Very understandable! Sorry I never got back to you on this but I really appreciate the pattern and direction!
On Fri, Oct 14, 2022 at 6:42 PM Qqwy @.***> wrote:
Closing this issue now. Feel free to open a new one if you have any more questions related to this or other things you encounter while using the library 💚 !
— Reply to this email directly, view it on GitHub https://github.com/Qqwy/elixir-type_check/issues/143#issuecomment-1279554065, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAD3BAWQ62ADZO2PUCLTZPLWDHOTPANCNFSM6AAAAAAQHWPMFU . You are receiving this because you authored the thread.Message ID: @.***>
First off, thanks very much for the effort that’s gone into this project. I think it’s really valuable and helpful and hope to see it continue to thrive.
I wanted to start a conversation about possible strategies for using TypeCheck as a library author with TypeCheck as an optional dependency. I’d love to be able to use TypeCheck as a tool for development aid and for my own projects, but I’m hesitant to “foist it” on others (even if it can be configured to be “turned off”, I rather not impose the dependency).
This is somewhat tricky, I think, as unlike most optional dependencies that are confined to a single module, TypeCheck is generally spread throughout all code.
I’d love to get your thoughts on possible strategies to make this work. One option would be a minimal wrapper module that “calls out” to TypeCheck if the dependency is available, and implements no-ops otherwise. But TypeCheck does some funky stuff with @ that may make it a little trickier to wrap?
This may benefit from making some of the TypeCheck’s “internals” a part of the public API (basically just officially exposing some of the helpers that the TypeCheck macros call out to, so that they can be more easily wrapped).
Anyways, just thought I’d bring it up and see what you think!