4 ms·
I'm also looking at Elixir and Phoenix (coming from Python/C++), and it looks cool. Doing realtime features with Python requires something like Tornado / async
by chubot 3y ago
I'm also looking at Elixir and Phoenix (coming from Python/C++), and it looks cool. Doing realtime features with Python requires something like Tornado / asyncio, which isn't ideal IMO.
I'm all for the immutable / message-passing architecture in the large, but I wish that you could just write Python-style code within processes. The VM copies all data structures at process boundaries anyway.
I think that language would be very popular!
I wrote Lisp 20 years ago, before Python, but now it feels a little annoying to "invert" all my code, for what seems like no benefit
e.g. from https://learnxinyminutes.com/docs/elixir/ https://learnxinyminutes.com/docs/elixir/
defmodule Recursion do
def sum_list([head | tail], acc) do
sum_list(tail, acc + head)
end
def sum_list([], acc) do
acc
end
end
I would rather just write
def sum_list(L):
result = 0
for item in L:
result += item
return result
But then also have the Erlang VM to schedule processes and pass immutable messages.
There is obviously a builtin in Python that does this, and I'm sure there is a better way to do this in Elixir. But I think the general principle does hold.
- bcrosby95 3y agoBuilt ins aside, I find most uses of recursion to be better served by Enum.reduce.
- chubot 3y agoYeah I knew someone was going to say that (see last sentence), but a for loop is more powerful and general than reduce(). Mutability within the loop is useful, and it can be controlled by processes and message passing.
- bcrosby95 3y agoI assumed you meant something like Enum.sum that completely trivializes the code. In comparison, generic, higher level functions are pretty fundamental to FP.
- sodapopcan 3y agoI'm not sure "powerful" is the right word here, it's more a matter of "what certain people are used to". If you want a counter or whatever, you can use a tuple to give yourself multiple accumulators. You could argue it's uglier, but I wouldn't necessarily agree. It's something that is easy to get used to if you remove the "but I'd rather just do it this way" mindset.
- throwawaymaths 3y agothe problem with a for loop is that it is inexplicit about what from the outer scope can be mutated. Which isn't a problem, for small functions but I have definitely seen monster for loops in professionally written django code with ~500 lines of code in the function. Besides being in that magical sweet spot (executes imperatively but reads declaratively), a reduce forces you to declare ahead of time what things can be carried over and mutated between each iteration. > it can be controlled by processes and message passing. DO NOT DO THIS YOU WILL REGRET THIS SIMCITY MEME
- deleted 3y ago[deleted]
- pythonaut_16 3y agoHave you seen Elixir list comprehensions? iex> for n <- 1..4, do: n*n [1, 4, 9, 16] Or for your example: iex> l = 1..3 # equivalent to [1,2,3] iex> Enum.reduce(l, fn item, acc -> acc + item end) # or iex> Enum.reduce(l, &(&1+&2) # or the built in iex> Enum.sum(l) # all return: 6 https://elixir-lang.org/getting-started/comprehensions.html https://elixir-lang.org/getting-started/comprehensions.html https://hexdocs.pm/elixir/1.12/Enum.html#reduce/2 https://hexdocs.pm/elixir/1.12/Enum.html#reduce/2 https://hexdocs.pm/elixir/1.12/Enum.html#sum/1 https://hexdocs.pm/elixir/1.12/Enum.html#sum/1 None of which take away from your point though: it's definitely a different mental model than you use for Python/Go/Javascript.
- deleted 3y ago[deleted]
- chubot 3y agoYes though Python has list comprehensions too :) I should have picked a different example -- the idea I was trying to get across was that mutability within a loop is useful. Here’s a similar question I asked with Python vs. OCaml and Lisp. Short-circuiting loops seems to cause the code to become fairly ugly in functional languages https://old.reddit.com/r/ProgrammingLanguages/comments/puao1v/im_using_python_now_2013/he2syf8/ https://old.reddit.com/r/ProgrammingLanguages/comments/puao1...
- jclem 3y agoYou can reduce with list comprehensions in Elixir, but it's uncommon to see: sum_list = fn list -> for item <- list, reduce: 0, do: (sum -> sum + item) end sum_list.([1,2,3]) Other comments are correct that `Enum.reduce/2` is probably better: Enum.reduce(list, &(&1 + &2)) Obviously you don't have the flexibility / mutability you refer to in other comments with either of these, but you can always put more in your accumulator: get_sum_and_update_count = fn list, map -> for item <- list, reduce: {0, map}, do: ({sum, map} -> {sum + item, Map.update(map, item, 1, &(&1 + 1))}) end (A contrived function that returns a list sum and an updated map with the count of the values found in the list)
- mfitton 3y agoYou might want to look into Ray. It's a Python library lets you deploy actors (classes) and tasks (functions) and abstracts away the management of resources, message passing, lets you define automatic repairs, etc. that is entailed with deploying an arbitrary amount of intercommunicating processes in Python. Admittedly, I haven't worked with Erlang or Elixir, so their solution to this might be much more usable. Ray is aimed primarily at ML use-cases, though it is quite general.
- ttymck 3y agoIs Enum.reduce not sufficient? Even better, Enum.sum? https://hexdocs.pm/elixir/1.12/Enum.html#reduce/3 https://hexdocs.pm/elixir/1.12/Enum.html#reduce/3