andreyvolokitin
- If we want to introduce common reusable type, should we introduce separate
Typesmodule like so?:
defmodule App.Shared.Types do
@moduledoc """
Common reusable types
"""
@type generic_id :: non_neg_integer() | String.t()
end
- Also if we have a struct type defined for some entity, and then we want to reuse a type of a field from that struct — can we directly refer to the field type using something like
Struct.t().field()(this and[:field]notation does not work though)? Or reusing field types like this is impossible and we need to define custom public type within a struct module, and then reuse this type for a struct type and in other modules?
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Hello,
I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter).
The diffic...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
Anyone here using Honeybadger?
My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of
Bandit.HTTPError...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Aludel - LLM Evaluation Workbench
Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
arcyfelix
Your idea sounds oddly familiar to inheritance (correct me if I am wrong).
From my observation of bigger projects, reusing your types makes them clearer and more readable.
Eiji
Try to imagine similar way of thinking … Would you like to write dozens or hundreds of
Ecto.Schemajust to have them in one place? For sure there is no rule to cover all edge cases, but in general we rather avoid such practices.Firstly all
structrelated types should be defined in struct’s module. It’s no shame to have a public type for a single field just to reuse said type somewhere else as long as we speak about same data i.e. it’s fine to use field’s type somewhere in code especially when we write typespec for private functions fordialyzertool or so.However using same type just because it’s typespec matches specific needs (like a generic
keyword()type) is incorrect as developer working with your library would think that only data from saidstructare seen as valid / supported.In example above I would move the type definition from
MyLib.UtilstoMyLibifMyLiborMyLib.OtherModulewould use it. Otherwise it’s in good place.Of course there may be an edge case. Let’s say that you document an
APIand thenUtils(more generic code) would use types from it.That’s why there is no one rule to write typespec. Generally you put types in order:
Utils-like module as in above exampledimitarvp
I am not sure if we’re talking actual types or the fields themselves?
If it’s just the types, that’s easy enough. Following your example the user module would look like this:
christhekeele
I would encourage you to think hard about what module should own a type before placing it in a catch-all drawer. Typespec types are used at function boundaries: inputs and output. Modules tend to group functions around specific input/output themes. So if you have a type that doesn’t feel like it has a clear module owner, you probably have a leaky abstraction popping up all over your code base, involved in perhaps too many function input/outputs. It would suggest you are missing a module to handle that type in particular.
Of course that is idealistic and impractical in many applications. I encourage placing these sorts of global types at the toplevel module of your project; ex:
App.generic_id. If they are truly global to your domain, they will read well there. Otherwise, as you carve out a niche for them in future modules it will be easy to shift their location.Correct, you cannot index into struct type’s field types. What you propose instead is fine, flexible, and common:
Again this idea of which module should own the type comes up. In the example above, we’re saying that
App.Entityreally owns what an id even means, and other modules referencing that type are using its understanding. You could just as easily define (for example) anApp.idtype and use it inside theApp.Entity.tif you think that somebody else really determines what a functioningidshould look like in your system.andreyvolokitin
Not sure about inheritance, but since we only can define types within modules, means we need to use modules as containers for types
My intent is to only write truly reusable things in one place, maybe meaningfully grouped in multiple places, in order to prevent “bad” duplication (aka knowledge duplication), as opposed to “ok”/coincidental duplication, which I’m ok with. So it seems like these types are better reside somewhere meaningful
E.g. when I work with data which has specific shape/types defined for this data, then I handle this data in some other place — it is useful to be able to refer to a type of a specific field for this data and not to duplicate the type and then keep it in sync
For when to write typespecs — I figured it’s a whole new topic, which I’ll investigate further, e.g. I read it is recommended to only write typespecs for public functions
That’s practically what I imagined
Actual types. This is what I expected, but wanted to confirm. The 2nd case is more vague though: we already export struct type, but we can not refer to a field type of this struct, this requires defining it in a separate public type near this struct (but maybe in practice it is not an issue at all)
Great points! For sure I’ll be keeping details to where they belong