8 ms·
I disagree with so much of this! Though I can tell the author is coming from a lot of experience. How often is it that you don't know if you're expecting a map
by aeturnum 5y ago
I disagree with so much of this! Though I can tell the author is coming from a lot of experience.
How often is it that you don't know if you're expecting a map or a keyword list? I don't think I've ever intentionally put myself in that situation (though it's nice that access supports both).
They say to avoid piping result tuples, but I actually think their example code shows the strength and weaknesses of both approaches. I use pattern matching on tuples when you want more complicated behavior (that might be hard to read in a big else block for a with) and a nice with statement when there's 'one true path.'
In general, I think one of my favorite things about Elixir is that they've done a good job of avoiding adding features you should never use. These all feel like personal judgements about tradeoffs rather than actual hard rules.
- mattbaker 5y agoYeah, I disagreed with a decent amount, but I tried to read it as “here are the patterns and practices I feel passionate about” and that made it an interesting read for me. The sort of declarative good/bad language worries me a bit because people new to the language may take it as gospel, but overall I’m glad to see people putting their thoughts out there with explanations and examples :)
- aeturnum 5y agoI do think that being opinionated about code style leads to code that's easier to read and maintain. I was just delighted to find someone whose tastes diverged so distinctly from my own in a smaller language community.
- bcrosby95 5y agoAside from using an automated formatter/linter, I think being opinionated about code style is only really sustainable for single person projects. Otherwise it leads to inconsistent code reviews where people are making changes for reasons they can't understand.
- innocentoldguy 5y agoIt's one thing to be opinionated about code styles, but I would argue that doing so when those opinions go against standard idioms is a recipe for disaster. If I ran across a lot of these suggestions in code, I'd refactor them to be more idiomatic/practical.
- jackbravo 5y agoBut how do you take this to a code review scenario? Are these suggestions that you can take or ignore?
- pdimitar 5y agoMost of those in the article you can ignore and get away with it for a long time. Some of them start to become problematic once the code grows quite a lot, others are not a problem ever because they are very dependent on the context.
- pawelduda 5y agoThe benefit of Map/Keyword is that you look at the code and you know right away what type it takes. Access is more universal but you look at it and have multiple possibilities.
- jolux 5y agoI would recommend writing specs for your functions and using Dialyzer, too :)
- arthurcolle 5y agoI've never been able to figure out how to write custom types in Erlang. Any resources in particular that you recommend? I am not trying to be obtuse but the Erlang docs are unreadable and I have admittedly written quite a bit of Elixir code. Most of the time I have to just figure things out ad-hoc from my own interactions with the shell.
- jolux 5y agoDepends what you mean by “custom types.” Elixir supports structs, but they’re not really as rich as classes in another language, for example. If you just want to write type signatures for your functions though, this is a pretty good guide: https://hexdocs.pm/elixir/1.12/typespecs.html https://hexdocs.pm/elixir/1.12/typespecs.html
- arthurcolle 5y agoRight, using structs for things I'm doing have been extremely painful, to say the least. Let's say I'm trying to create a module that represents a European option and I want to encapsulate things like "strike price", "expiration date", and the various Greeks in a way that are subsequently modifiable (FWIW, it would be perfectly fine to then just respawn a new proc to have the new data if that is absolutely necessary...). I haven't been able to identify a way to even reference other PIDs that exist which might be able to (with some wizardry) solve some of these problems. Right now I'm basically wrapping basically all my data in Agents with maps inside, but that is so lame. Thanks for the quick response. Maybe I'm trying too hard to use a saw to hammer a nail. EDIT: I don't care about type signatures on functions. I'd just like to be able to have a real time system that updates based on ingested values, that I can distribute easily. It seems like it's possible, even close, but the structs just don't get me quite where I want them to be.
- joshribakoff 5y agoAlso disagree with the author! > You should not use else to handle potential errors (when using with) Yes you should! Otherwise the with statement could return something that is not :ok and also not :error. I think therefore it’s good practice to put else {:error, error} -> {:error, error} especially because Elixir is not strongly typed so this helps constrain the possible types the statement can return. If you omit the else, your construct can return any number of types from values produced downstream.
- jimbokun 5y ago> How often is it that you don't know if you're expecting a map or a keyword list? It's just programming to the interface and not the implementation, which often has advantages and very rarely has any downsides.
- gamache 5y agoIMO it's not as simple as "just use Access". In addition to maps and keyword lists, there are structs in play. Access works with maps and keyword lists, but not structs. There are pieces of code I've written that reasonably accept map or struct, but not keyword list. Map.get/3 also has a default value; Access only lets you use `nil` for that. OTOH, the nil-eating behavior of Access is terribly convenient sometimes. It's all about what you need at the time. There is more than one way to do it, for a reason.
- keathley 5y ago> These all feel like personal judgements about tradeoffs rather than actual hard rules. I'm glad it came across this way. These are all ideas that I believe have helped me build more maintainable systems. But that's just my experience and opinion. I'm happy people are finding stuff to disagree about because I also want to grow and improve my own ideas. I regret titling the post with the words "good" and "bad". This started as an internal memo for my new team, grew into blog post and I didn't change the title. The title adds connotations that aren't very useful to the reader and sets up a more confrontational tone then I want. Live and learn. Either way, thanks for taking the time to read through it and for providing feedback.
- aeturnum 5y agoThank you for writing it! It was a pleasure to read and I appreciate you contributing to the community.
- mercer 5y ago> I regret titling the post with the words "good" and "bad". The title struck me as exactly what I would expect from you (based on various articles/comments and your podcast), and fwiw, I personally really appreciate it. You're one of the people in the community that communicates in a way that often strikes me as 'overly' opinionated, but the combination of that and your actual experience tends to lead to fruitful discussion (see this thread). Plus, I often find myself wanting to 'prove you wrong' and then I end up doing a bunch of equally fruitful research. So keep doing your thing, is what I'm saying, I suppose. It's appreciated :).
- theonething 5y ago> I disagree with so much of this! Though I can tell the author is coming from a lot of experience. I bit off topic, but this sums up a lot of my experience with code reviews. People have opinions on what is the "one right way" and if I differ, we go through this drawn out discussion on Github about it. Most of the time, I see it as there are different ways to do it with different trade offs. I find myself just giving in so I can get the damned PR approved without a few days of back and forth. Granted there are times when there is a much better way. In those cases, I very much appreciate the feedback. It's truly educational. In my experience though, most of the time, it's senior developers insisting their style/way is best.
- arthurcolle 5y agoAgreed, this was a huge pain in the past for me. Then, the even MORE senior engineers are just like "Ok do the tests work? Yes? Ok whatever, approve" So there's this middle section of "senior" (but still in age terms relatively junior in their lifecycle) that are just trying to exert dominance over a dumb web app that controls the flow of the spice (errmm.. code) in the org. It's really silly and deeply counterproductive.
- 0xFACEFEED 5y agoI think it's important for teams to establish best practices and enforce them. It's good for team cohesion and culture. For example I've worked on teams that blocked PRs on minor typos in code comments. The signal this sent to me was "a little goes a long way, we care about the little things". Sure enough that ended up being the cultural norm and the team benefited from that mentality. There were also downsides though! That's part of the trade-off, but the benefits of a unified "culture" outweighed the downsides by far. What's reeeaaally bad is when you have competing points of view between tech leads and they passively enforce their own idea of what's "right" without regard for the other lead.
- travisgriggs 5y agoI agree with this. There doesn't have to be One True Way, but within the scope of shared work it's useful if there's a sense of "around her we all..." especially if the multitude of ways compliment each other so that sum is greater than whole. Where this gets hard for me, is in transitioning between teams, contributing to open source projects etc. The dialects can get kind of discordant. At least with Elixir, I find these differences are more palatable because the basic paradigm is consistent. In the "hybrid" languages, you get competing language models in the same code base.
- tym0 5y agoI'm not familiar with Elixir but I'm surprised that the "functional way" wouldn't be to use the pipes in conjunction with a map function that only applies each steps if it's a success and skip them/pass the value if it's an error.