6 ms·
While true, I think the larger problem is that it is not intuitive (at least to me) when I can expect a function to be of the `is_` vs `?` form. It's a leaky ab
by Munksgaard 3y ago
While true, I think the larger problem is that it is not intuitive (at least to me) when I can expect a function to be of the `is_` vs `?` form. It's a leaky abstraction.
- bitwalker 3y agoThe only time `is_` is used, is with functions permitted in guards. These are functions defined in Erlang, and only a small handful exist, and you learn them very early on. With the advent of `defguard`, it is conventional to use `is_` with custom guards as well, but that’s the intuition - guards vs general predicates.
- Munksgaard 3y agoSure thing. My point is that, if I want to check whether an argument is a keyword list, I have to do extra mental work to guess whether the correct function to use is `is_keyword` or `keyword?`. There also doesn't seem to be a consistent rule I can apply to figure out whether it's one or the other. Conversely, I also get tripped up every time I want to add a guard to a function like, "is the thing I want to test written as a macro or not?". I understand the reasoning for the distinction and its roots in Erlang, it's just not very elegant to work with.
- bobwaycott 3y agoIf you’re having to do extra mental work to guess, it means you don’t have enough familiarity with the language, its type checks/guards, and the standard library. That’s not the language’s fault. If you want to check the type of a thing, you always want the matching `is_<type>`. It can be used anywhere in your code, including guards. There’s no guesswork involved here. That is the consistent rule. When you see a function with a `?`, look at the typespec and the function name—give it the argument(s) it expects and it will answer the question on the tin with a boolean. Again, there’s no guesswork. These functions can be used anywhere except guards—that is the consistent rule for boolean functions. > Is the thing I want to test written as a macro or not? I have never had to ask myself this question, and I struggle to parse it. Is the “thing” you want to test referring to the value or to the test you wish to perform on that value? Since you’re asking about macros, I’m assuming you mean the guard test. For that, just learn what guards are available[0] (you can also write your own :D ). [0]: https://hexdocs.pm/elixir/1.15.4/Kernel.html#guards https://hexdocs.pm/elixir/1.15.4/Kernel.html#guards
- out_of_protocol 3y ago> If you’re having to do extra mental work to guess, .... That’s not the language’s fault. Depends. In this case there are definite rule in place which you can learn. Overall, that's definitely language's fault. On other note, Elixir actually very good at consistent naming - standard library is designed, not meshed up and grew layer by layer like js/php abomination (erlang one is not consistent and it leaks sometimes) - Pipe operator by its mere presence enforces correct order of arguments, even in 3rd party code
- bobwaycott 3y agoIt is not a tool’s fault that, upon providing the relevant material that describes its usage and helps a user learn how to use it, the user ignores that and then blames the tool for not working how they want it to work.
- out_of_protocol 3y ago*Assuming naming rules are consistent. After spending 5 years on php, i've never learned its function names and order of arguments. Even daily stuff like `strpos` requires looking at documentation, dozens time per day
- bobwaycott 3y agoThe larger problem is not reading the docs to understand and learn language conventions. If one reads the docs, it is immediately clear that the `is_` prefix denotes a function that returns a boolean and can be used in guards. The `?` form is for all other functions that return a boolean. Which means one will gain an intuitive sense of every function you see in the `is_` and `?` forms. It’d be immensely more helpful and productive if coming into a language meant one would spend the time to read, learn, and understand that language’s conventions and standard library—and read the source code for it! It pays serious and continuous dividends, and is the fastest way to gain an intuitive sense for the language.
- Munksgaard 3y agoThere's no need to be rude. My point is that it is not obvious, given some arbitrary value and some property to test for, whether that property can be expressed using a guard or not.
- bobwaycott 3y agoI was not being rude. What you say is not obvious is, to me, a result of not reading the docs, guides, and source code of the language and its standard library. I have seen this pattern repeatedly—those engineers who have learned the language find these things obvious. It’s not an insult, but a push to fill in those gaps. Elixir and Phoenix both have some of the best documentation you will find.
- Munksgaard 3y agoThen explain to me, purely by referencing the Elixir documentation, why URI.char_reserved?/1 is not instead called URI.is_char_reserved/1 such that I can use it in a guard. There's nothing intuitive about memorizing dozens of built-in functions that are (for opaque reasons) different from all the other built-in functions.
- bobwaycott 3y ago