NobbZ

NobbZ

I’m not quite sure what you want to say by linking those 3 files…

0
Post #12
peerreynders

peerreynders

I was just trying to make it easier to investigate the handling of interpolated strings for anyone reading the topic. I guess I should have suppressed the “quote/reply handling” of Discourse.

0
Post #13
peerreynders

peerreynders

The difference is that interpolation invokes a protocol to convert to string, the concat operator does not.

From:

String.Chars

Now in this context we are explicitly using to_string/1 in combination with concatenation anyway.

FYI: to me (from the compiler perspective) “syntactic sugar” implies that there is no runtime (performance) difference between the “sugared” and “unsugared” expression. I’m starting to wonder whether some people are using the term in a much looser sense.

0
Post #14
yawaramin

yawaramin

If you’re outputting this with e.g. IO.puts or send_resp in Phoenix, you don’t have to output interpolated strings as results, you can output iolists. That’s the main trick that I would use. The second trick is to try to unify the handling of ‘x and y’ and ‘x, y, and z’ by realizing that the latter case reduces to the former case if you see that ‘x, y,’ in the latter corresponds to ‘x’ in the former. My version:

defmodule Test do
  def list_str([]), do: ""
  def list_str([x]), do: Integer.to_string(x)
  def list_str([x1, x2]) when is_integer(x1) do
    list_str([[Integer.to_string(x1), " "], x2])
  end
  def list_str([x1, x2]), do: [x1, "and ", Integer.to_string(x2)]
  def list_str(xs) do
    {init, [last]} = Enum.split(xs, -1) # Traverses twice
    list_str([Enum.map(init, &append_comma/1), last])
  end

  defp append_comma(x), do: [Integer.to_string(x), ", "]
end

[] |> Test.list_str |> IO.puts
[1] |> Test.list_str |> IO.puts
[1, 2] |> Test.list_str |> IO.puts
[1, 2, 3] |> Test.list_str |> IO.puts
1
Post #15
net

net 

def join([a, b]), do: "#{a} and #{b}"
def join([a, b, c]), do: "#{a}, #{b}, and #{c}"
def join([a, b | rest]), do: join(["#{a}, #{b}" | rest])
def join(list), do: to_string(list)
0
Post #16
peerreynders

peerreynders

Using

def join([a, b]), do: "#{a} and #{b}"
def join([a, b, c]), do: join([[a, ', ', b, ','], c])
def join([a, b | rest]), do: join([[a, ', ', b] | rest])
def join(list), do: to_string(list)

with

[] |> Demo.join() |> IO.puts()
[1] |> Demo.join() |> IO.puts()
[1, 2] |> Demo.join() |> IO.puts()
[1, 2, 3] |> Demo.join() |> IO.puts()

produces



1 and 2
, , and 3

  def join([]), do: ""
  def join([a]), do: to_string(a)
  def join([a, b]), do: "#{a} and #{b}"
  def join(list), do: join(list, [])
  def join([last], strl), do: to_string([strl, 'and ', to_string(last)])
  def join([h | t], strl), do: join(t, [strl, to_string(h), ', '])

produces the desired result.


1
1 and 2
1, 2, and 3
1
Post #17
net

net

Didn’t realize the inputs weren’t strings. Edited to support integers.

0
Post #18
— All posts loaded —