News for hackers. Stuff that matters.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sodapopcan on Sunday August 13, 2023 @11:27PM (#37117155)
Very solid article with many points I agree with.

Some notes:

Keywords are not simply "another pragmatic solution that won over finding a more elegant way to support named arguments" and they are inherently different than maps and serve different purposes. Maps are unordered hashes, keyword lists are constant time, ordered list that can have duplicate keys. For example, in the language core, duplicate keys are used:

    import Foo, only: [bar: 1, bar: 2]
Ecto's query syntax makes use of both duplicate keys and ordering:

    from q in query,
      join: t in assoc(q, :table),
      on: q.table_id = t.id,
      join: o in assoc(t, :other),
      on: t.other_id = o.id
Everyone complains about the f.() syntax. It's necessary as explained in the guides in the Anonymous Functions section [0]. There is also a nice little parallel to Erlang in that a regular function call looks like `f()` whereas an anonymous function call looks like `F()`.

Contexts can be confusing, unfortunately. They're based off of bounded contexts from Domain Driven Design. I wouldn't say there is one right way to use Phoenix contexts, though reading up on DDD's bounded contexts really helps. I already had DDD experience before I learned Elixir, though, so it's easy for me to say and maybe more of a pain for others who don't want to do that.

Comprehensions can be much more concise in certain situations. You can certainly get away with avoiding them, but they can really come in handy sometimes. Not gonna give examples as this is getting too long. A short example would be Cartesian products.

Finally, I don't quite understand the gripe with `on_mount` or even `live_session` but that's been addressed in another comment.

[0] https://elixir-lang.org/getting-started/basic-types.html

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by jkhdigital on Sunday August 13, 2023 @11:45PM (#37117246)
Another note:

The “inconsistent” naming is actually a way to distinguish between guard and non-guard functions: is_map can be used in guards while empty? cannot.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by SupremumLimit on Monday August 14, 2023 @12:35AM (#37117488)
I know that keyword lists are different from maps, but I think their superficial similarity to maps isn’t ideal, and I don’t think that they’re the best possible solution (eg consider pattern matching on keyword lists which is order dependent, it’s not intuitive in the case of named args). They’re confusing to newcomers because of these things.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sethcalebweeks on Monday August 14, 2023 @01:27AM (#37117773)
Keyword lists were certainly confusing as a newcomer. But, FWIW, they existed well before maps. The AST is made up of only tuples and keyword lists on top of atoms and other literals. (Actually, if I'm not mistaken, keyword lists themselves are just lists with tuples of atom/value pairs. If you dig far enough down, it's incredible just how much of the language is built on top of a tiny number of primitives. Almost every bit of syntax you can think of is probably several layers of macros.)
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by bobwaycott on Monday August 14, 2023 @03:04AM (#37118279)
> Actually, if I'm not mistaken, keyword lists themselves are just lists with tuples of atom/value pairs.

You are correct. A keyword list is `[{atom, any}]`.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by rkangel on Monday August 14, 2023 @11:41AM (#37122340)
Keyword lists are from Erlang's history really. Erlang didn't have maps or records for a long time and used keyword lists to perform a similar function.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sph on Monday August 14, 2023 @04:25AM (#37118697)
> They’re confusing to newcomers because of these things.

Then they learn how they work and stop being confused.

I struggle to see why we are so terribly afraid of people learning. Programming is not an innate instinct after all.

A programmer that doesn't understand linked lists yet is basically a newbie, but it's a topic you learn in one day and makes you a better programmer.

This should be encouraged, rather than listed as a con.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by foldr on Monday August 14, 2023 @04:41AM (#37118795)
The main problem with them in Elixir is that you can't pattern match on keyword arguments without imposing an arbitrary order.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sph on Monday August 14, 2023 @05:38AM (#37119116)
Of course, they're linked list, they have an inherent order. Once you understand how they behave, you understand where the abstraction leaks.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by foldr on Monday August 14, 2023 @07:02AM (#37119594)
Yes, I understand why this is the case. However, it is still a mild annoyance that you cant (sensibly) write e.g.

    def foo(x, opt1: opt1, opt2: opt2)
If optional arguments were first-class citizens in the language, then you'd presumably be able to use patterns along these lines.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by josevalim on Monday August 14, 2023 @07:36AM (#37119829)
It is unfortunately much trickier because keyword lists are also optional. So what happens if opt2 is not given? We could raise but... since they are optional, we wouldn't want it to raise but rather have a default value.

Of course, we could then say "let's allow a default value to be given when pattern matching keyword lists". The problem is that no other pattern works like this and it would be inconsistent.

I think optional arguments are fundamentally incompatible with pattern matching (in Elixir). I understand why we would want that but, if we did have it, we would be adding tons of complexity and it would stand out as a sore thumb. I am also wary of going towards the same direction as Ruby and Python which have way too much complexity on its argument handling (albeit we have slightly different feature sets).

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by di4na on Monday August 14, 2023 @08:20AM (#37120189)
I think there is a possible design for them that is not too bad, but it would need named parameters. I think the time o encountered that idea was part of a longer post about solving a different problem in Rust.

But i doubt it would be an urgent thing to change.

Tldr: add named arguments (optional). You can call with anon names, in which case it is positional as it is today. If you use named arguments to call, you have to use them in the order they have been declared, just like with positional, but you _can_ omit some. These get the default value.

There are ofc combinations that could be allowed, like anon until the first optional one, whatever.

It was part of this post, but don't it was a solution to a different problem kinda (and kinda not technically) https://faultlore.com/blah/defaults-affect-inference/

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sph on Monday August 14, 2023 @07:34AM (#37119821)
I get that. But it's built on top of the Erlang VM, neither Erlang nor it's VM support these. All languages have their own leaky abstractions, and stuff that should in theory work, but doesn't.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sodapopcan on Monday August 14, 2023 @06:48AM (#37119499)
--DELETED--

I said suggested you could pattern match on keyword lists with guards but that isn't true—I should not respond to things first thing in the morning.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by foldr on Monday August 14, 2023 @07:01AM (#37119581)
I mean pattern matching in the sense of binding a variable to each option.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by josevalim on Monday August 14, 2023 @05:18AM (#37119007)
Both can happen at the same time, they can get confused and be learning.

It would be best if there was no confusion whatsoever, but given that it is most likely impossible (in any language), it is important to learn from where the confusion comes from, so we can continue improving the docs. It is a positive loop to have, as long as we listen. :)

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sodapopcan on Monday August 14, 2023 @07:23AM (#37119741)
Ah yes, sorry, you did say you understood them in the article but wasn't obvious you understood cases where one was better suited than the other.

Otherwise very nice article and sorry I only focused on the rebuttal points! I absolutely agree about grouped alias/import/require. I know those weren't always in the language and I always assumed it was a community request (but maybe not). I personally prefer to avoid `alias` and `import` whenever possible! There a handful of scenarios where I use them but I love how Elixir is big on locality. Any jumps I can avoid, even to the top of a file, is a win in my book.

Otherwise the focus on pragmatism is apt. Possibly my favourite thing about Erlang is that it is the only currently widely adopted general purpose language that was built to solve an actual business problem, and that problem so closely resembles web programming. All of the language decisions were made in support of their business goal as opposed to trying to come up with a beautiful, academically sound, language. Something about that really resonates with me so I kinda enjoy and embrace the "warts". Call it Stockholm Syndrome if you must :)

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by rapnie on Monday August 14, 2023 @01:22AM (#37117731)
> Contexts can be confusing, unfortunately. They're based off of bounded contexts from Domain Driven Design. I wouldn't say there is one right way to use Phoenix contexts, though reading up on DDD's bounded contexts really helps. I already had DDD experience before I learned Elixir, though, so it's easy for me to say and maybe more of a pain for others who don't want to do that.

Jenny Shih gave a talk comparing Phoenix contexts with DDD bounded contexts.

https://www.youtube.com/watch?v=vr-qhHrN5_4

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by foldr on Monday August 14, 2023 @02:02AM (#37117964)
> keyword lists are constant time, ordered list

Unless there’s some kind of behind-the-scenes magic that I’m unaware of, keyword list look up is O(n), not O(1).

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by bitwalker on Monday August 14, 2023 @02:43AM (#37118175)
No, you’re exactly right, they are just regular singly-linked lists of tuples, nothing more.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sodapopcan on Monday August 14, 2023 @06:36AM (#37119432)
Oops yes, typo sorry, meant non-constant.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by boxed on Monday August 14, 2023 @03:35AM (#37118411)
Maps can be ordered though. In Python they are, and keyword arguments in Python are implemented as these ordered maps (dicts), and they disallow duplicate keys. So I do understand how it can be confusing coming from another language for example.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by sph on Monday August 14, 2023 @04:16AM (#37118644)
It's just a matter of algorithmic complexity. A hashmap, ordered or not, is more complicated than a linked list, which is what Keywords are built upon.

The former requires turning an arbitrary piece of data, hashing it to an integer, and indexing a cell based off this value, dealing with potential collisions on the way. In C terms it's 50 lines long.

The latter is a simple iteration and string comparison. In C terms it's 5 lines long.

It is confusing if you've never programmed close to the metal and only know high level languages. Maps are good for data that you need to access in random order, linked lists/keyword lists for data that either you access in linear order, or it is so small the overhead of a map is too much.

If you have less than 10 elements, a linked list will always be faster than any hashmap on modern CPUs.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by boxed on Monday August 14, 2023 @07:56AM (#37120005)
> It's just a matter of algorithmic complexity. A hashmap, ordered or not, is more complicated than a linked list, which is what Keywords are built upon.

You mean implementation complexity right? Anyway, I was talking about semantics, not performance or implementation.

> If you have less than 10 elements, a linked list will always be faster than any hashmap on modern CPUs.

Citation needed. That personally sounds totally bonkers to me. Faster HOW? If the pointers of each node in the linked list are far apart in memory the L1/L2 cache misses will absolutely destroy the performance.

I think you're talking from a ton of assumptions that you haven't stated. If the list is that short, why isn't it a contiguous array in memory? That's going to be way smaller and way way faster in every way.

Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by hinkley on Tuesday August 15, 2023 @12:47AM (#37130310)
Ordered maps are usually a hybrid linked list. When iterating you can traverse the linked list data, rather than the buckets.
Re:Thoughts on Elixir, Phoenix and LiveView after 18 months ... by jolux on Monday August 14, 2023 @10:19AM (#37121325)
I’d also like to add that the Access module provides generic access to key-value collections just like Enum does for sequences.