smolcatgirl

smolcatgirl

Allow specifying the type when defining structs

Hi,
I think it would be cool to be able to require a certain type for my fields when I create structs. Like specifying one field should be a integer and another a list. So I am not talking about Ecto schemas but regular structs with type checking. What do you think?
Thanks for reading!

Most Liked

tme_317

tme_317

I use GitHub - ejpcmac/typed_struct: An Elixir library for defining structs with a type without writing boilerplate code. · GitHub for all of my structs. The built-in dialyzer integration provided by the Elixir LS editor plugin does the checking.

al2o3cr

al2o3cr

What specific operations would this provide? “Type checking” can mean a lot of things in Elixir:

  • compile-time success-type checking, as provided by Dialyzer

  • runtime pattern matching and guards, like:

def some_function_that_wants_a_list(x) when is_list(x) do
  • field enforcement on structs; a mostly compile-time guarantee that specified keys will be in a map tagged with the __struct__ key. For instance, this will fail if the target struct doesn’t have a foo key already: %{target | foo: "bar"}

typed_struct (recommended in this thread) is ultimately just a shorthand for writing a Dialyzer typespec and defstruct; the compiler ultimately sees the same code.

To return to my original question, what kind of “type checking” behavior are you looking for? For concreteness, let’s imagine we have a “typed struct” called Blog that expects its tags field to be an array of strings. What should the following do:

  • %User{tags: 1234} - wrong type
  • %User{tags: ["a", 1234]) - mixed types in a field
  • %{some_user | tags: 1234} - update with wrong type
  • %{some_user | tags: ["a", 1234]} - update with mixed types
  • %{some_user | tags: value_that_might_be_a_list_at_runtime} - compiler has no information
  • Map.put(some_user, :tags, 1234) - structs are maps too

Dialyzer will catch some of these, when it has enough information to prove things are the wrong types - but it’s going to struggle with things like the value_that_might_be_a_list_at_runtime case and give up ENTIRELY on the Map.put one.

Communicating typing failures out of these constructs is going to be difficult - they don’t normally “fail”, so the only available option is to crash the process.

Also note that all of these constructs are used extensively in Elixir’s implementation - so any overhead added will be significantly amplified. That’s one reason to prefer an opt-in library like Ecto.Schema, which layers the additional functionality onto bare structs instead of adding more complexity directly to them.

mat-hek

mat-hek

Membrane Core Team

What are you worried about? A several dozen of kilobytes extra on your drive?

Maybe about

  • the need for keeping track of updates of that dependency
  • potential conflicts delaying updates of other dependencies
  • introducing potential vulnerabilities
  • extended compilation time
  • waking up when a dozen kilobytes turns into hundreds of megabytes, as in case of NPM and node_modules

So definitely having as little unused stuff in your deps as possible is a good approach :wink:

Last Post!

dimitarvp

dimitarvp

I surely was a little blunt there but hey, nobody took offence and we kept discussing.

And I was arguing more about the technical merits and not so much about cultural or philosophical. As I myself mentioned, I too minimise dependencies in personal projects.

Where Next?

Popular in Discussions Top

scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31707 143
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
wmnnd
The Go vs Elixir thread got me thinking: Would it be too hard to implement a simple mechanism for creating Go-style static app binaries f...
New
PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
opsb
We’re considering our architecture from a viewpoint of scaling our traffic heavily over the next 6 months. Our current deployment is runn...
New
fireproofsocks
I’ve been working on an Elixir project that has required a lot of scripting. I usually reach for Elixir because I like it more (and in th...
New

Other popular topics Top

hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49134 226
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New