6 ms·
The local-reasoning properties of Elixir (and any other functional language with emphasis on immutability for that matter) make it soooooo much easier to onboar
by ashton314 5y ago
The local-reasoning properties of Elixir (and any other functional language with emphasis on immutability for that matter) make it soooooo much easier to onboard. Meanwhile over in a Rails/Laravel/node-framework-flavor-of-the-month you can get lost in the monkey patching and mutation. It’s nice to be able to look at a single function and know what it does, without having to reason about what might happen beyond getting a return value if you call another function.
- dgb23 5y agoNavigating those kind of frameworks and libraries is also incredibly frustrating. Where are my data structures? It's all hidden, scattered behind idiosyncratic interfaces that provide little observability.
- ashton314 5y agoExactly! In Elixir, structs are just a special case of a map with a little bit of compile-time field checking magic. At runtime it's all the same. It's so easy to see the shape of things and figure out where stuff came from. Also, `|> IO.inspect(label: "...")` is one of my favorite things ever in getting my head wrapped around a new struct I haven't encountered before.
- dnautics 5y agoif you use vscode, you might like this: https://slickb.it/bits/70 https://slickb.it/bits/70
- bostonvaulter2 5y agoNice snippet! I think that snippets are often underrated by programmers, especially debugging related snippets (the code is temporary so "duplication" doesn't really matter).
- dnautics 5y agoThis snippet is my #1 productivity enhancer for elixir. It goes extremely well with multiline cursor. Especially since line numbers are typically the same length so ninjaing out the inspects in a pipeline is usually fast
- ashton314 5y agoOh that's lovely! I'm an Emacs user, and I've got two yasnippets that do roughly the same thing: https://gist.github.com/ashton314/f0a90a46e39b103635f2be8d8e6aeefd https://gist.github.com/ashton314/f0a90a46e39b103635f2be8d8e... The second one adds a pipe in front, which is super handy. Yours gives me some ideas though…
- bostonvaulter2 5y agoDo you know if you can insert the current line number with yasnippet? I have two snippets that look almost identical to yours, although my non-pipe version leaves the cursor at the beginning of the label since I've found that I often want to customize the label because I may be inspecting similar variables at different points in the code. Ah, figured it out. It's very powerful to be able to call elisp inside snippets. Here's my new Labeled Inspect snippet: # -*- mode: snippet -*- # name: Labeled Inspect # key: lin # -- IO.inspect($1, label: "$2$1 (`(buffer-name)`:`(line-number-at-pos))`") and a piped version: # -*- mode: snippet -*- # name: Piped Inspect # key: pin # -- |> IO.inspect(label: "$2$1 (`(buffer-name)`:`(line-number-at-pos))`")
- ashton314 5y agoExcellent! I'm going to have to extend mine. Emacs ftw
- pablodavila 5y agoAlso, if you have piped functions you can now use `|> tap(&IO.inspect(&1.a))`at any point (requires 1.12).
- shubik22 5y agoHave to briefly chime in here to partially defend Rails :) I agree that immutable data structures > mutable data structures, and while I don't have experience working with Elixir, it's high on my list of new technologies to play around with when I have time. However, although in theory you can go wild mutating your objects and monkeypatching in Rails, in practice those features have never really been a pain point in any of the Rails applications I've worked on, both in personal and professional contexts. Unless you're a very new programmer who doesn't know any better, you're hopefully not mutating the request object in Rails in hidden places, or monkeypatching Object#to_json (for example). Rather, the difficult parts have been deciding what logic lives where, and other issues more common to web applications overall than Rails specifically. If anything, Rails' convention-driven philosophy (which it sounds like Phoenix follows as well) makes development significantly easier than it otherwise would be, in my experience.
- krainboltgreene 5y ago> you're hopefully not mutating the request object in Rails in hidden places You have to, that's how rails works.
- Fire-Dragon-DoL 5y agoRails by default monkey patches the entire ruby language, injects 400 methods on any single model, it creates an enormous amount of dynamic methods through metaprogramming and it monkey patches the loading of ruby files itself. Rails does an enormous amount of damage right out rails new.
- tmm84 5y agoI understand this frustration very well. I recall one video on learning Rails, the teacher said it would be better to learn Ruby first and then learn Rails. It wasn't until I actually understood Ruby's deep areas that I could understand what was actually going on in Rails and how Rails accomplished it. The idea of sweep the details under the rug and just do it works if you aren't encountering bugs/runtime errors.
- princevegeta89 5y agoMy biggest gripe with Rails is the magic it has. It's amazing for small projects but once you reach a certain size for the codebase, things go haywire and there's nothing that stops one from writing atrocious code (I've seen that happen a lot). The platform involves no compilation, and if you ship the code without tests (which is more often the case unfortunately), things are going to crap out only in Production. Not just that, development also becomes slow because of increasing codebase size, engineers start to get confused and run in circles when trying to find what came from where. Not to mention the non-existent concurrency model. Elixir, though with a steep learning curve seems to continue to pique my interest and curiosity.
- iudqnolq 5y agoOne data point on the learning curve not being that steep: As a second year college student I did a <3,000 loc toy project to learn Elixir, and then used it (with Phoenix and Phoenix LiveView) for my first job, building a dashboard for a nonprofit. While there are bits I'd definitely rather refactor given infinite budget, overall I'm surprised by how well the project went. The dashboard has been humming along with zero application-level maintaince (just upgrading the Ubuntu version of the server) for months, despite being built by a novice and integrating with an extremely flaky third party API. It was very easy to set up a scheduled ETL job with Oban and add a status page so that they can see if any import has failed recently.
- eweise 5y agoThe Go codebase I'm working on is terrible about mutation. structs get passed into functions which then may mutate them or pass them to yet another function which mutates them. Its impossible to understand what is going just by looking at the code.
- dnautics 5y agoWell, immutable code is imperformant code!! /s
- weatherlight 5y agodebatable, unless you are doing really low level stuff, it's almost negligible. also it harder to get code using mutable data structures to scale horizontally. if you have one CPU on one machine, and your code is cpu bound, your statement is probably true.
- dnautics 5y agoyes, that's why I put two exclamation points and an /s on the end.
- handrous 5y agoMay just be the codebase I'm on (only I've seen from Elixir) but good god there are like 15 hops from function to function before anything actually happens. It's got the same "OK, but where's the code that's doing the work?" problems of a bad (so: average) Rails codebase. Navigating this codebase has strengthened my stance of avoiding languages without static types, whenever possible. I'm beginning to consider them write-only absent heroic efforts & excellent processes. It's not Phoenix, though, and like 95% of discussion about Elixir seems to assume you're using Phoenix, like how so much writing about Ruby assumes you're in Rails, but to an even stronger degree. So maybe that's the difference?
- ashton314 5y agoI'd probably just chalk that up to your code base. That being said, adding typespecs to functions goes a very long way to aiding readability.