5 ms·
After seeing Elixir pop up so many times on Hacker News these last few months, I deicded to give it a go for the Advent of Code. It's been pretty amazing actua
by marcus_cemes 5y ago
After seeing Elixir pop up so many times on Hacker News these last few months, I deicded to give it a go for the Advent of Code.
It's been pretty amazing actually, it takes a little getting used to, but it really feels like a language that was designed in every way possible to be ergonomic and productive. I'm still not sure whether it's easier to read purely functional code over a few mutable variables and simple loops, especially with a lot of filter, reduce, scan, zip, etc.
It's been pretty amazing so far, I haven't gotten further than IO.inspect()ing yet. The language server is still leagues even behind something like Rust analyzer (even renaming symbols is still a work in progress), but it's amazing that such a language already has one of the leading web frameworks (Phoenix), and despite being very network orientated, it's also excellent at solving AoC problems that involve a lot of clever manipulation of strings, binary, integers, and the sorts!
- brightball 5y agoYea, my experience has been that after getting deep with Elixir and understanding how and why it (and the BEAM) works the way it does, everything else feels very limiting. Like I know all of the problems I’m willingly setting myself up for long term.
- clessg 5y ago> I deicded to give it a go for the Advent of Code. That reminds me: in case anyone is curious how that looks in practice, it just so happens the creator of Elixir (José Valim) has been streaming Advent of Code exercises using Elixir (and Livebook): https://www.twitch.tv/josevalim https://www.twitch.tv/josevalim
- peoplefromibiza 5y agoMy 2 cents I've been an Elixir developer for years now, loved it immediately and still loving it after all this time. About refactoring: I've been working as a Java developer for the past couple of years and I must admit thaat Intellij does a pretty impressive job at helping you refactoring code and their code sense is top notch. But, there's a but. I've never found myself having to make nuclear refactorings in Elixir, not because I don't refactor my code, but because modules are self contained and not tied with anything else, most of the times it is faster to abstract something over what you already have than to refactor all the things. For example, if you decide that you need a struct instead of the old map, you advd a new function that pattern matches on the struct and pass it down. If the struct has a different structure, you process it and pass it down. The "treat data as something that is constantly transformed" mentality can take you a long way. When I can code in java in a way similar to what I do in Elixir, things get easier in Java as well. I miss symbol renaming in Elixir too, but it's never been a big stopper in the 6 years I've used it as a primary language. edit: biggest strength of Elixir is Jose Valim himself. If you watch his videos you can see him finding a bug while doing something, actually explaining why that's a bug in Elixir (or some library) open an issue and ask for PRs All while showing you complex software patterns that I though I could never face before using Elixir.
- michaelterryio 5y agoAh, yes, this is how I refactor in Elixir too. I feel icky about it from a DRY standpoint but I’m training myself to ignore the scolds that held me back from being productive for so long.
- marcus_cemes 5y agoI understand, but a lot of my refactoring is within functions to simplify and improve legibility once they work, renaming variables with generic names from "result" or "data". It's a lot faster to do a cheeky F2, knowing that it's not a blind find/replace but a static code analysis with the ability to understand variable shadowing. Definitely not a show stopper though, and it feels more old-school, where every letter you type is more meaningful, if that makes sense. And a huge +1 for José Valim and the whole community behind him!
- dnautics 5y ago> It's been pretty amazing so far Wait till you learn about async tests that are pinned to single database checkouts. And -- how async is composable with respect to resource pinning. AFAICT no other language does this (not even erlang).
- stonecharioteer 5y agoI want to try, I've been doing AoC in Python, but that's only so I can improve my problem solving skills. I want to do it in Elixir, among other languages but I have never written or read a line of elixir in my life. How did you begin? Did you start learning elixir side by side AoC or did you go through a tutorial or book _before_ December?
- marcus_cemes 5y agoThat's great! I very briefly went through the introductory docs, but otherwise I just dove right in. The language is really simple, the tough part is wrapping your head about immutability. There's an awesome repo with examples in pretty much every language [1], I go there afterwards to learn how other people did it. It's amazing to see so many different ways of approaching the problem. My solutions are also public [2], but bear in my I'm still only a few days in to learning Elixir! If you do want to try attacking AoC with Elixir, I suggest you research and understand these concepts, it's more than enough to get you going: - Pattern matching. The "=" sign is _not_ an assignement, it's trying to fill the shape of the variables on the left with the stuff on the right. - The pipe operator "|>", the return value of the previous function is implicitly as the first paramter of the next function, it makes it easy to build chains. - There is no "return". Use small functions with `case` statements, or function overloading. The last value in a function is implicitly the return value, like in Rust. - Enum.map(), filter(), reduce(), zip(), chunk(), these functions largely get you through the manipulation of data. The first three are very popular in JS. - Immutability. There's no mutating data, hence why you need reduce() for example. - There are no loops, instead, get used to doing recursion. hd(), tl() are useful for this. - Anonymous functions `fn a, b -> a + b end`, there is also a shorthand form `&(&1 + &2)`, and you can also pass functions by reference `&sum/2` - The "/1", "/2", ... after a function is the arity, it's not scary, it just means the number of paramters that it takes. - Function overloading is amazing, it's like pattern matching. If you provide constants in the function declaration, it will only be called if those constants match: ``` def factorial(0), do: 1 def factorial(n) when n > 0, do: n * factorial(n - 1) ``` I find the above really elegant. It's correct, the special case for "0" is very explicit, and if you try a negative number, Elixir will simply be unable to match the given problem to a function definition (n < 0), which makes more sense than throwing "BadArgument" errors/exceptions. If you really want to just solve problems, I advise sticking with Python, there's nothing wrong with it. Most languages also provide a lot of functional concepts, I'm sure Python is no exception (with some libraries). Be prepared that functional languages require you to think differently, but it is really fun to do things in a functional way! Good luck! [1]: https://github.com/Bogdanp/awesome-advent-of-code https://github.com/Bogdanp/awesome-advent-of-code [2]: https://github.com/MarcusCemes/advent-of-code-2021 https://github.com/MarcusCemes/advent-of-code-2021