Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An optional crate feature to switch from Elixir nil to Erlang undefined? #500

Closed
tatsuya6502 opened this issue Nov 23, 2022 · 3 comments · Fixed by #507
Closed

An optional crate feature to switch from Elixir nil to Erlang undefined? #500

tatsuya6502 opened this issue Nov 23, 2022 · 3 comments · Fixed by #507
Assignees

Comments

@tatsuya6502
Copy link
Contributor

First of all, thank you for creating Rustler! We have been using it since 2019 for Erlang projects, and it is working great.

We are actually using a fork of Rustler because we wanted to use atom undefined instead of nil. We wanted Rultler to encode Rust None into Erlang undefined.

undefined is commonly used in Erlang language and libraries to indicate absence of a value.

For example, if you create an Erlang record (which is just a tuple) without giving values for some fields, these fields are filled with undefined.

%% File: example.hrl
-record(rec, {field1, field2}).
$ erl
Erlang/OTP 25 [erts-13.1.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Eshell V13.1.2  (abort with ^G)
1> rr("example.hrl").
[rec]
2> #rec{field1 = 10}.
#rec{field1 = 10,field2 = undefined}
3> 

Another example is that there are many functions in erlang module that return undefined if the value is not found. For example, erlang:process_info/2 returns undefined if the process is not alive (doc).

In our fork of Rustler, we directly replaced all occurrences of nil with undefined (diff). It was a quick hack, but worked for us.

Now we are thinking of contributing this feature to the upstream Rustler. We are thinking of adding a crate feature something like erlang-style-encoder to switch from nil to undefined. When the feature is enabled, Rustler will encode Rust None into Erlang undefined.

Does this make sense? Is there any better way to do this? Any feedback is welcome.

@evnu
Copy link
Member

evnu commented Nov 23, 2022

Using undefined for None looks useful for Erlang, but a crate feature seems very blunt to achieve this: It disallows mixing nil and undefined, which could be useful when interacting both with Elixir and Erlang records, for example. What do you think about another type, which encodes to undefined? For example, we could have a type struct<T> ErlangOption(Option<T>) which implements AsRef to forward into the inner Option<T>. ErlangOption would then implement Encoder and Decoder itself. Would something like that work for your use case?

@filmor
Copy link
Member

filmor commented Nov 23, 2022

It could also be set on the init! macro. In the end, your NIF DLL will be either used from an Erlang or from an Elixir module, very likely not from both, right?

@tatsuya6502
Copy link
Contributor Author

Thank you guys for the comments. I believe both ways should work for our Erlang case. I think ErlangOption would be more flexible than other way: when you use Elixir with Erlang libraries, you may want to interact Rust with both Elixir and Erlang records.

So please assign this issue to me, and let me work on the ErlangOption way. I will create a PR when it is ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants