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

lib/ecto/adapters/myxql/connection.ex: refactored improper lists #587

Closed
wants to merge 5 commits into from

Conversation

bradhanks
Copy link
Contributor

refactored 10 lists

5 had a string literal as the tail
1 was a variable with a is_binary guard
4 were Integer.to_string functions

@greg-rychlewski
Copy link
Member

Hi @bradhanks ,

Improper lists are 100% intentional. They save some bytes when sending the query string to the database.

@bradhanks
Copy link
Contributor Author

Hi @bradhanks ,

Improper lists are 100% intentional. They save some bytes when sending the query string to the database.

oh nice. learned something new :)

@bradhanks bradhanks closed this Jan 12, 2024
@greg-rychlewski
Copy link
Member

greg-rychlewski commented Jan 13, 2024

Sorry I mixed up the adapter behaviour with the driver behaviour (Postgrex, etc.).

In this case it's not about sending it to the database but rather this construct will be immediately passed to IO.iodata_to_binary to create the query string. And iodata can work with improper lists. So basically there is no need to wrap the value in a list.

@bradhanks
Copy link
Contributor Author

bradhanks commented Jan 13, 2024

Sorry I mixed up the adapter behaviour with the driver behaviour (Postgrex, etc.).

In this case it's not about sending it to the database but rather this construct will be immediately passed to IO.iodata_to_binary to create the query string. And iodata can work with improper lists. So basically there is no need to wrap the value in a list.

Just to solidify my own understanding, if you don't mind, are there issues with the below statement?

There's really no issue using a cons operator to add a string to the end of an iolist. The list isn't improper if all the elements are binaries.

@greg-rychlewski
Copy link
Member

It looks like there is a slight misunderstanding in it.

An improper list isn't about whether the elements are binaries but whether the last element's tail is the empty list. Every proper list can be represented as [head | tail] where tail is another list. So for example, [1, 2] is actually [1 | [2 | []]]. If you built a similar improper list it would instead be just [1 | 2] (the last element is not a list).

Where binaries play a special role is in iolists. This is the definition from erlang:

iolist ::= []
        |   Binary
        |   [iohead | iolist]
        ;
iohead ::= Binary
        |   Byte (integer in the range [0..255])
        |   iolist
        ;

So when creating an improper list inside of an iolist, the last tail can be a binary but not an integer.

@bradhanks
Copy link
Contributor Author

It looks like there is a slight misunderstanding in it.

An improper list isn't about whether the elements are binaries but whether the last element's tail is the empty list. Every proper list can be represented as [head | tail] where tail is another list. So for example, [1, 2] is actually [1 | [2 | []]]. If you built a similar improper list it would instead be just [1 | 2] (the last element is not a list).

Where binaries play a special role is in iolists. This is the definition from erlang:

iolist ::= []
        |   Binary
        |   [iohead | iolist]
        ;
iohead ::= Binary
        |   Byte (integer in the range [0..255])
        |   iolist
        ;

So when creating an improper list inside of an iolist, the last tail can be a binary but not an integer.

It looks like there is a slight misunderstanding in it.

An improper list isn't about whether the elements are binaries but whether the last element's tail is the empty list. Every proper list can be represented as [head | tail] where tail is another list. So for example, [1, 2] is actually [1 | [2 | []]]. If you built a similar improper list it would instead be just [1 | 2] (the last element is not a list).

Where binaries play a special role is in iolists. This is the definition from erlang:

iolist ::= []
        |   Binary
        |   [iohead | iolist]
        ;
iohead ::= Binary
        |   Byte (integer in the range [0..255])
        |   iolist
        ;

So when creating an improper list inside of an iolist, the last tail can be a binary but not an integer.

ok so an iolist can be improper or proper depending on if it ends in an empty list or binary.

@greg-rychlewski
Copy link
Member

Yeah that is correct.

@bradhanks
Copy link
Contributor Author

Yeah that is correct.
Thanks for taking the time to explain that to me! 👍

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 this pull request may close these issues.

2 participants