[Proposal] Create maybe(t) typespec

130 views
Skip to first unread message

Yordis Prieto

unread,
Feb 27, 2018, 7:11:39 AM2/27/18
to elixir-lang-core
Introducing `maybe(t)` it will reduce the boilerplate code for `nil | something` 

It is more convenience to write it this way, at least for me.

What are your thoughts about it?  

Ben Wilson

unread,
Feb 27, 2018, 7:31:22 AM2/27/18
to elixir-lang-core
maybe(t) is traditionally `Some(t) | None`, which isn't really the same as `nil | t`. The closest analogue would seem to me to be `{:ok, t} | :error` although that doesn't quite communicate the same thing.

Andrea Leopardi

unread,
Feb 27, 2018, 5:50:08 PM2/27/18
to elixir-l...@googlegroups.com
I second what Ben said. {:ok, t} | :error isn't doable as it isn't "universal", sometimes you have just :ok and sometimes just :error for example. I think both as far as clarity goes as well as as far as conciseness goes the best solution is to use nil | t.

--
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 elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/3b39e876-4286-4602-955a-de513d4dfc27%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Andrea Leopardi

Yordis Prieto

unread,
Feb 28, 2018, 9:12:42 AM2/28/18
to elixir-lang-core
I am more interested on the solution of `nil | t` I dont mind changing the name to `nillable(t)` or whichever other word in English.

The needs come from Ecto schemas and most of the struct fields will be nillable(t), I thought it would be good to have something that represent that common use case.

Ben Wilson

unread,
Feb 28, 2018, 9:43:51 AM2/28/18
to elixir-lang-core
Is nillable(String.t) less boilerplate than String.t | nil ?

Austin Ziegler

unread,
Feb 28, 2018, 10:51:18 AM2/28/18
to elixir-l...@googlegroups.com
Whenever I end up defining an `maybe(t)` typespec, I always use it for tagged tuples (`@type maybe(t) :: {:ok, t} | {:error, any}`), although I might be more specific in that `any`, although I’ve found myself defining a `result` typespec for a module far more often (because most of the functions in the module return the same or similar values).

I think what’s being described here is closer to `option(t)`, so `@type option(t) :: t | nil` (although that’s also a tagged value in Rust, but `t | nil` seems closer to the spirit of `option` than `maybe`).

-a

--
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 elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/c0d589bc-951d-4b5d-afef-d652d8a84310%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Josh Adams

unread,
Feb 28, 2018, 11:33:43 AM2/28/18
to elixir-l...@googlegroups.com
`{:ok, t} | {:error, any}` is more like `result(t, any)` than `maybe(t)`. I'd define `maybe(t)` as `t | :nothing`


For more options, visit https://groups.google.com/d/optout.



--
Josh Adams

Yordis Prieto

unread,
Mar 3, 2018, 6:31:54 PM3/3/18
to elixir-lang-core
Ben it is not about the boilerplace and less typing or more typing, 

but I found myself having a hard time parsing those | for reading different types, because of that, having something like this, when you brain sees this automatically understands 
what is that type about, the parsing becomes easier.

Also from language perspective, I like to embrace this as type, like Haskell or Swift those with those Optional types (I dont need a optional type itself on elixir btw, just the typespec)

but, that is just me, I can't speak for others.


On Tuesday, February 27, 2018 at 4:11:39 AM UTC-8, Yordis Prieto wrote:

Rafael Willians Moraes

unread,
Mar 30, 2023, 12:21:08 AM3/30/23
to elixir-lang-core
I agree

Although one could simple define their own `@type result(t) :: {:ok, t} | {:error, term}`, having this built-it IMO would be great for the ecosystem.
Maybe biggest problem with :ok|:error tuples right now is that lib (including standard Elixir libs) are inconsistent on that from. Therefore, having this type built-in could be a way of encourage people to use it throughout the ecosystem.

Take returns from modules DateTime and Integer for example:
  • `DateTime.convert/2`
    ```
    {:ok, t}
    | {:error, :incompatible_calendars}
    ```
  • `DateTime.from_naive/1` returns
    ```
    {:ok, t}
    | {:ambiguous, first_datetime :: t, second_datetime :: t}
    | {:gap, t, t}
    | {:error, :incompatible_calendars | :time_zone_not_found | :utc_only_time_zone_database}
    ```
  • `DateTime.from_iso8601/1`
    ```
    {:ok, t, Calendar.utc_offset}
    | {:error, atom}
    ```
  • `Integer.parse/1`
    ```
    {integer, remainder_of_binary :: binary}
    | :error
    ```
If one just wants to assert if the result is a success or failure, they have to know implementation detail of the given result value (not to mention that I'm not even sure if those `ambiguous` and `gap` from `from_naive` are success or failure).

Therefore, IMO, having a result type is a starting point to have some consistency across the ecosystem.

I'd suggest the following types
```
@type result(t, s) :: {:ok, t} | {:error, s}
@type result(t) :: {:ok, t} | :error
```

José Valim

unread,
Mar 30, 2023, 1:30:02 AM3/30/23
to elixir-l...@googlegroups.com
The point of returning gap or ambiguous is exactly that they may or may not be errors and it is up to you to handle them. For example, some application may choose to surface those to the user and ask more information to resolve the ambiguity. In a statically typed language would have to handle those as well.

The “with” special form provides all flexibility to handle those cases without tying the ecosystem to a shape which may not be sufficient.

--
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 elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/c839c36e-300d-4ba0-b460-8427121b600fn%40googlegroups.com.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages