dimitarvp

dimitarvp

I think he meant to reply to me, maybe. But yeah I looked at the library and I find it nice on a second look.

2
Post #11
spacebat

spacebat OP

I definitely want to know more on the tradeoffs with this stuff, and this thread has been very informative. The feedback has been constructive, thanks :slightly_smiling_face:

2
Post #12
sodapopcan

sodapopcan

For me I usually want it all with typing or I just use Keyword.get, which I do not agree is “harmful”. I don’t want to get to into it, though, otherwise @dimitarvp and I might get going :sweat_smile: I could actually see your lib as a nice middle ground. I bookmarked it and will try to remember to try it next time I go to use Keyword.get.

EDIT: Maybe I do consider it a little harmful :rofl:

0
Post #13
D4no0

D4no0

As with everything else we use, it is considered harmful when it expresses the wrong intent.

I use Keyword.get/3 in situations where an option might be missing and I have a default value for it. For example:

Keyword.get(opts, :option, default_value)

Using it in cases where having that key missing is invalid logic, you are just propagating a bug further into the system. This is especially bad when you leave the default value to nil and propagate it further, hard to debug and trace down.

3
Post #14
sodapopcan

sodapopcan

Noooo arguments here!

It’s mostly I’m starting to somewhat buy @dimitarvp’s argument that it doesn’t make a distinction if the key is there or not. Now, this is not news to me, not by a long shot! My of use Keyword.get is for simple options where I don’t want to break out NimbleOptions, but I still operate under the idea that there is a contract in place. IE, I create a world where nil is never going to be passed (which is the whole “parse don’t validate” thing I love to talk about ad nauseam). I would never use Keyword.get for user-passed data!!! However, in the “real world” where juniors are running rampant on your dynamic-language codebase, maybe a nil slips in there. AFAIC, if you’re using nil for its intended use to mean “nothing”, when it comes to options there shouldn’t be a difference between nil and “key wasn’t specified.” If you buy that (and maybe you don’t!), Keyword.get is actually dangerous:

Keyword.get([some_list: nil], :some_list, []) #=> nil

Undoubtedly to @dimitarvp’s horror, one conclusion I draw from this is that Access is actually better:

some_list = options[:some_list] || [] #=> []

Of course this sucks if your option is a boolean. You can’t do:

some_bool = options[:drop_database] || true

We could always exploit truthiness there but even as a fan of truthiness I don’t like this one bit.

Circling back, having what should be a list become a nil should fail pretty fast but I guess you never know in this scenario.

So really I’m starting to think I just always want typed options. Even the other day I passed a non-existant option to a well-known library and it didn’t yell at me and I was pretty annoyed. There certainly is a difference between library and application code, though, so I’ll see :grin:

2
Post #15
D4no0

D4no0

This is true 100%. It is strange to me how OTP has checks for options from long ago, but elixir never adopted that convention until lately.

1
Post #16
spacebat

spacebat OP

On a tangent, Perl5 has a // operator, which is like the logical or || but only treats undef as falsey. Useful for disambiguating nil/null/undefined/missing values from defined but false ones.

3
Post #17
RobertDober

RobertDober

Maybe a little bit of scope might help here. How long do you think keyword lists will get in the context of passing them into functions? 10, 100 but even if it had 1000 I would not consider optimizing and simply do the following

opts
|> Keyword.validate!(...)
|> Enum.into(%{})
|> Map.values

and similar for Keyword.validate/2 (with a with, I guess :wink: )

0
Post #18
RobertDober

RobertDober

Have to correct myself, (bad Ruby influence :angel: ) Map.values will not get us the correct order

0
Post #19
— All posts loaded —