What would you remove from Elixir?

Indeed it would, but that is only because of the current patterns that are used. Following your example but with a monadic style (from this thread) it would change from:

content =
  Enum.find_value(sources, fn source ->
    File.exists?(source) && File.read!(source)
  end) || raise "could not find #{source_file_path} in any of the sources"

To if Enum.find_value’s callback an option tuple ({:ok, blah}|:error) (using module helpers as stated should be made in the above linked thread):

{:ok, content} =
  Enum.find_value(sources, &Option.from_result(File.read(&1)))
  ~> fn _ -> raise "could not find #{source_file_path} in any of the sources" end
  # Or do `|> unwrap()` here and replace the binding above with just `content =`

And for the other example of:

Enum.find_value(headers, fn({k, v}) -> k =~ ~r/^origin$/i && v end)

To if Enum.find_value’s callback an option tuple ({:ok, blah}|:error) (using module helpers as stated should be made in the above linked thread):

Enum.find_value(headers, fn({k, v}) -> Option.wrap_if(k =~ ~r/^origin$/i, v) end

And the third example of:

defp check_operations_valid(operations) do
  Enum.find_value(operations, &invalid_operation/1) || {:ok, operations}
end

defp invalid_operation({name, {:changeset, %{valid?: false} = changeset, _}}),
  do: {:error, {name, changeset, %{}}}
defp invalid_operation(_operation),
  do: nil

To if Enum.find_value’s callback an option tuple ({:ok, blah}|:error) (using module helpers as stated should be made in the above linked thread):

defp check_operations_valid(operations) do
  Enum.find_value(operations, &invalid_operation/1)
  |> Result.from_option(operations) # Takes the optional error value, only evaluated if an `:error`
  |> Result.flip() # Flip the `:error` and `:ok` cases
end

defp invalid_operation({name, {:changeset, %{valid?: false} = changeset, _}}),
  do: {:ok, {name, changeset, %{}}}
defp invalid_operation(_operation),
  do: :error

Which although a bit longer I find more readable rather than the easily missed (since I did originally miss it) trailing || {:ok, operations} bit.

Tagged Tuples are far superior, especially with conditional piping as well.

Entirely true, and gets back to what I say should be properly named return values. Although if we could drop the erlang heritage and big erlang style I’d say the option type should be {:some, value}/:none and the result type should be {:ok, value}/{:error, result} or something along those lines, but {:ok, value}/:error is definitely more erlang’y and there is a lot of history and code there.

I’ve also been for that too, doing the option as {value}/:error (or :none or whatever) would make sense, but there is no precedence for that either.

That example would be significantly better with cond, yet another reason I encourage either purging if as-it-stands from the language, or forcing an else clause, always. I really do not like this magically appearing nil from invisible else’s.

Agreed yep, hence why I want some construct that forces the else to exist, no magically appearing nil’s and such.

Which gets back to my wanting to fix the scoping brokenness. :-V

1 Like

I really don’t see what’s so bad about foo? && bar || baz. If anything, it’s often easier for me to parse than if as I find it less visually complex (either vertically, or by characters). I don’t spend any extra time parsing it because I already know what it does—it’s a familiar pattern.

1 Like

It is easy to me because overwhelming perl-work in last job, but I still do not like it. Even C’s pred ? true : false is clearer to me for some reason…

1 Like

Can you point me to some alternatives? :slight_smile:

I would remove discussions from the community’s main forum about what to remove from the language :microphone: :droplet:

13 Likes

If you’ve ever worked in a language without short-circuiting boolean expressions, this is relying on side-effects.

I would remove discussions from the community’s main forum about what to remove from the language :microphone: :droplet:

Eh it happens for every language, it is not a bad thing to see how a language can be improved, it’s not a personal attack, people just care about it is all, if they didn’t they would not be here. :smile:

3 Likes

Interesting. It once again show how strange my own learning was. I never touched an if before like… the second or possible third year of my programming journey. And i have yet to teach to a complete beginner.

3 Likes

Hm, this one spawned few interesting discussions that I enjoyed reading.

There is not much negativity and all in all one can conclude that elixir is in a good place, why remove them? Without critique the community would feel religious, “elixir way is the only true way” style which is not cool imo :slight_smile:

6 Likes

I already posted a link further up the thread. The library I use is called OK and you can find it on hex. The readme has some links to a few further alternatives if needed

This issue is these threads almost immediately devolve into:

  1. removing conditionals
    and 2) rehashing discussions that we hashed out and implemented in the mailing list 2 years ago pre 1.0. Then folks argue for or against features without any true context why things are the way they are

The language is young enough that talking about what to remove is actually not productive at all. Also keep in mind every time we see folks like @michalmuskala here doing a fantastic job around fielding feedback on language features and why they are the way they are, we’re taking away useful feedback time from other threads/slack questions/irc.

4 Likes

I’ve found this thread really interesting, new people can relive past discussions as need be to flesh out their understanding.

There is no requirement for people who have seen such a conversation before to provide any input. If they feel they have the time, a quick link to previous threads is appreciated.

Thinking about the tradeoffs present in some tool is a very effective way to understand the best uses for it. In my experience.

5 Likes

Really!? I started with standard conditional jumps in assembly, which is an if anyway. I’m curious about your experiences! Perhaps a new thread and/or blog post? :slight_smile:

I’ve used it. :slight_smile:

Plus once hashed out it can be linked to and searched far more easily. :slight_smile:

Very very much so!

3 Likes

I think macros are more of a hindrance than a help 90% of the time.

Confusing.

Suspect plain polymorphism could be used in many cases which macros are used…

I would remove the end from anonymous functions. For example:

Enum.map([1, 2, 3], fn x -> x * x)

Instead of:

Enum.map([1, 2, 3], fn x -> x * x end)
2 Likes

Actually, I take that back. I wouldn’t remove anything. I mean, what the hell do I know? Yeah, not having to “end” anonymous functions would be nice, but I’m sure the language designers evaluated their decisions far better than I can.

2 Likes

Do you use pipes? Do you use structs?

Many of the features that are ‘built-in’ into Elixir, are actually themselves written in Elixir, using the macro system. So even if you would want to use them yourself, they are very useful!

1 Like

Nothing without good, valid reason, and support from José and other Elixir experts such as Chris :003:

Now that we have the new #community:suggestions-proposals section all serious proposals should go through the process there :slight_smile:

1 Like

Absolutely not. There is no way polymorphism can perform, for example, for style code generation without significant overhead, nor generate compile-time constant DSEL interfaces, etc… etc… Even the |> macro is not possible with polymorphism, it just makes no sense as a comparison construct.

I personally see polymorphism of the OOP variety way WAY overused in places that it absolutely does not belong.

1 Like
Enum.map([1, 2, 3], &(&1 * &1))

:wink:

3 Likes