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

ben-pr-p
In general I’ve been sticking to this community style guide GitHub - christopheradams/elixir_style_guide: A community driven style guide ...
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
acrolink
How does the two languages compare when it comes to server side application development? Any experiences or ideas? Thank you.
New
pdgonzalez872
If this has been asked here before, please point me to where it was asked as I didn’t find it when I searched the forum. Maybe a mailing ...
New
nburkley
AWS re:Invent is on at the moment with some interesting announcements. One new feature in particular is the Lambda Runtime API for AWS La...
New
thojanssens1
It would be nice to be able to define a redirect from one route to another from the router.ex file. E.g.: redirect "/", UserController, ...
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

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
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
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement