Live data from Hacker News

ElixirNitpicks

wiki.alopex.li

21–30 of 60 posts

Re: ElixirNitpicks

#21
post #2

Interestingly, though I am not a great Rust programmer, nor a great Elixir programmer (I have written programs in both languages). And, gotten a little ways through the amazing Exercism ( https://exercism.org/tracks/elixir ). What I loved about this writeup was the way I could review both by comparing two languages in which I have a moderate understanding. The comparison of imports was very engaging to my brain. I re…

There was something like this a few years ago, "Elixir for Rubyists": https://thoughtbot.com/blog/elixir-for-rubyists

I wrote something similar here:

https://phoenixonrails.com/blog/elixir-for-ruby-developers-t...

https://phoenixonrails.com/blog/elixir-syntax-for-ruby-devel...

Re: ElixirNitpicks

#22
post #15

The following code could be written much better by using the cond operator. with {:is_email, true} {:error, :bad_request} {:is_available, false} -> {:error, :conflict} end cond do !email_address?(email) -> {:error, :bad_request} !EmailAddresses.available?(email) -> {:error, :conflict} true -> {:ok, email} end This gets rid of unnecessary duplication, and I think is easier to understand.

i agree that with statements aren't the easiest to understand, especially for a beginner, but I think the value in having the entirety of the happy path in the initial block is very helpful for understanding the flow of the feature, once you grok the syntax.

Re: ElixirNitpicks

#23
> Unit tests are more of a pain

> …though I really have a hard time expressing why.

This one is interesting, I'm new to Elixir an I really enjoy writing tests for my Elixir app, in a way I kind of never have before.

This might just be an effect of the ecosystem being built more with testing in mind than I would have expected. For instance when I wanted to add email sending to my Phoenix App, the Swoosh library came with a Test adapter and an assertion to use in tests for it. I would have normally expected to have to write some mock of the email library or use some testing SMTP service, but it was so surprisingly painless instead.

Same with testing functions that interact with the database in Ecto, I feel like the way to do this is well thought out as part of Ecto and I never have to work around any testing-specific issues.

Re: ElixirNitpicks

#24
> There’s a cultural split between Erlang and Elixir that makes life harder than it needs to be.

On that note I have witnessed: "Finding Erlang developers was hard. And I hated Elixir. So, we ported everything to Java."

Maybe that was just one such occasion. Maybe there are more.

Re: ElixirNitpicks

#25
Testing is one of the areas that we have felt the most in Elixir while building Batteries Included. ExUnit is pretty good, but bare bones. That combined with Phoenix (most popular web framework in elixir) made for some places we didn't test. So we created a test library that does polaroid snapshot testing of Phoenix components. We called it Heyya and added other utilities to test phoenix live view too.

Does anyone have solutions for Ecto testing with processes?

- https://www.batteriesincl.com/ - https://github.com/batteries-included/heyya - https://hex.pm/packages/heyya

Re: ElixirNitpicks

#26
post #15

The following code could be written much better by using the cond operator. with {:is_email, true} {:error, :bad_request} {:is_available, false} -> {:error, :conflict} end cond do !email_address?(email) -> {:error, :bad_request} !EmailAddresses.available?(email) -> {:error, :conflict} true -> {:ok, email} end This gets rid of unnecessary duplication, and I think is easier to understand.

Keathley did a good job discussing this in https://keathley.io/blog/good-and-bad-elixir.html#:~:text=Av.... The preferred style is to specify the errors in separate functions e.g.

    def main do
      with {:ok, response} 
where call_service, decode and store_in_db return the specific errors like {:error, :bad_request}, {:error, :conflict}.

Re: ElixirNitpicks

#27
post #11

> I do wish migrations were just generated from schemas though, a la Django. This is a weird one to me. I really dislike the magical way Django does this and I'm glad Ecto doesn't. It also allows you to have separate Ecto structs representing different parts of a table in scenarios where that is desirable.

Ash Framework gives you the ability to define the schema in code, via

    mix ash_postgres.generate_migrations --name name_of_my_migration
but of course now you're using a framework (albeit a really good one) that is perhaps a bit less mature than Elixir

Re: ElixirNitpicks

#28
I fully agree about how hard it is to understand what the DSL features of elixir are doing. It was a major pain point for me and I wish that Elixir had a mode where it would expand all macros and output the resulting code so you can just see what your code looks like. I think that would help a lot.

On the flip side, most of these complaints feel like the author is fighting the language and wants it to behave more like a language that makes different tradeoffs. Maybe akin to complaining that Rust is annoying because "you need to use unsafe to code normally."

For example pairing with statements with specific atoms is specifically called out as an anti-pattern in the latest elixir docs[1] (this is an example of the elixir devs trying to talk more about how best to do things!). I don't mean say that the author "should have known not to do that" - I use it from time to time. I mean that the language is not setup to support this code structure well. The language wants you do use different structures for doing a series of things (the Ecto approach of returning a structure with the error embedded in it is an example).

I'm also sympathetic about the confusion around umbrella projects (and other such features) but I kind of feel like the current state is the optimal one? There's a tutorial showing you when you might want an umbrella project, but also showing you a similar structure that avoids using one[2]. On some level choosing which approach you want depends on a ton of details about "how elixir / erlang works"...but that seems pretty unavoidable? I think umbrella projects make very little sense until you grok the application system - but ultimately you can't save people from skimming over why they might use something and diving into learning it. I think this is just an inevitable drawback of languages that have fundamentally different tradeoffs than ones that generate native code with mutability.

[1] https://hexdocs.pm/elixir/main/code-anti-patterns.html#compl...

[2] https://hexdocs.pm/elixir/dependencies-and-umbrella-projects...

Re: ElixirNitpicks

#29
post #17
post #2

Interestingly, though I am not a great Rust programmer, nor a great Elixir programmer (I have written programs in both languages). And, gotten a little ways through the amazing Exercism ( https://exercism.org/tracks/elixir ). What I loved about this writeup was the way I could review both by comparing two languages in which I have a moderate understanding. The comparison of imports was very engaging to my brain. I re…

You bring up something interesting. Structured learning is very helpful but I sometimes hate that I can't or feel I shouldn't skip around. Videos are the worst because it's very linear. I'd love to be able to see abstract concepts such as the interpreter/compiler for a language and it's syntax and important concepts and models etc the way you can just turn a 3d model around in a CAD system. That would be truly amazin…

Edward Tufte advocates handouts over slides in presentations for just this reason. Your audience can refer back to the written and illustrated content of your presentation at their leisure.

Re: ElixirNitpicks

#30
post #27
post #11

> I do wish migrations were just generated from schemas though, a la Django. This is a weird one to me. I really dislike the magical way Django does this and I'm glad Ecto doesn't. It also allows you to have separate Ecto structs representing different parts of a table in scenarios where that is desirable.

Ash Framework gives you the ability to define the schema in code, via mix ash_postgres.generate_migrations --name name_of_my_migration but of course now you're using a framework (albeit a really good one) that is perhaps a bit less mature than Elixir

I'm aware of that, and can see why people like it in Ash, but as with Django I think it makes things less explicit, harder to break up domain specific structures backed by the database, and more magical. It's fine IMHO as an add on with something like Ash, but a data mapper like Ecto shouldn't strive to be an ORM like Django especially in a functional language.
Post reply on HN