so let's talk code No images? Click here We had a lovely chat on BEAM Radio with Zach Daniel and Rebecca Le both about the upcoming Ash book and a bunch about Igniter. Give it a listen :) Hit the pipe?I worked with a guy (he may prefer anonymity, so won't name him) who had some ideas about writing Elixir code that I hadn't run into before. I find them novel enough to share. I don't have a strong preference for this type of stuff which means I am happy to try something if it isn't too onerous. Preferring "single-line" pipelines: def list_widgets, do: So, we use ", do:" instead of do + end and we tail everything together. I think his argument was that it forces you to keep the pipeline style or be very explicit when changing it. I think this works best if you don't mind piping into case statements. For a GenServer he'd prefer a pure module with a struct to wrangle the state. This is fairly common and non-controversial. Make every operation on the struct return the struct, nothing else. This gives you nicely pipe-able operations. But also aggessively hint dialyzer about how the function works. # Don't do this: Match going in, enforce the struct going out. This gives Dialyzer certainty that the return value is a struct and not some other map. And this guy would actually use the type-spec hints in ElixirLS, not to add typespecs to functions but just watch them to make sure that he had enough information to give Dialyzer the right idea. And he'd push this further. def set_headcount(%MyState{} = my_state, count) when count >= 0, do: The typespec of this function can be fully derived. And dialyzer and your editor tooling can warn you about many simple mistakes. This very fun guy also had a bunch of fun hacks with pattern matching instead of guards as well but I don't remember half of them. It was along the lines of pattern matching a non-empty list which you can do with the square butt: [_|_] Fundamentally this type of code-style stuff is a team effort. I've worked with teams that never do ", do:" as a matter of principle. The NervesHub code-base has helpers for pipeable "|> noreply()" at the end of handle callbacks while that'd be a no-no in other circumstances I've worked. Some default to credo, some do their own credo config. Some require typespecs for all public functions. Some have no typespecs. And apparently some only infer typespecs. Some want all the pipes. Some want all the with statements. Some hate a tuple-tagged with, and some love it: with {:web, {:ok, response}} <- HttpLibrary.get("https://u7d.io"), I have a hard time caring personally about which of these ways people do things. Maybe I'm a bit dumb in this regard or maybe I've seen enough variety and am just always The Consultant meaning I don't give answers, I give advice, I don't try to rework all you've done, I try to work harmoniously with it. Some people feel very strongly about these types of things and some will argue unconventional things as being the best. If you've done Elm I do believe the formatter will do the unusual but very nicely structured list approach where you avoid problems with trailing commas: [ "One" Yes, this has advantages. If you argue it heatedly in a language and code-base where it isn't the convention I don't have a ton of sympathy for it. It is neat. It is also odd. What unusual, interesting or terrifying coding style choices have you run into, in Elixir and elsewhere? Do you have strong opinions on it, what are they? You can reach me on the Fediverse where I'm @lawik@fosstodon.org or by responding to this email to lars@underjord.io. Thank you for reading. I appreciate you. |