Exclusive Range

260 views
Skip to first unread message

Joshua Nussbaum

unread,
Jul 18, 2014, 1:13:47 AM7/18/14
to elixir-l...@googlegroups.com
Hey,

Any chance there will be support exclusive ranges? (ranges that dont include the end) like 0...10

# includes end
iex> 1..3 |> Enum.map &(&1)
[1,2,3] 

# excludes end
iex> 1...3 |> Enum.map &(&1)
[1,2]

Maybe something like:

  defmacro first ... last do
    {:%{}, [], [__struct__: Elixir.Range, first: first, last: last, exclusive: true]}
  end
 
- Josh

José Valim

unread,
Jul 18, 2014, 5:38:29 AM7/18/14
to elixir-l...@googlegroups.com
No, there are no plans for now to support exclusive ranges, even more because the token ... is already taken. 

Joshua Nussbaum

unread,
Jul 18, 2014, 10:23:16 AM7/18/14
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
Cool

Was just trying to fill a string, and it seemed useful.

# fill(5, "a") == "aaaaa"
def fill(count, string), do: Enum.map_join(0...count, fn _ -> string end) # wont work

Ended up just pattern matching on the zero case

# fill(5, "a") == "aaaaa"

def fill(0, string), do: ""
def fill(count, string), do: Enum.map_join(1..count, fn _ -> string end)

Greg Vaughn

unread,
Jul 18, 2014, 10:32:58 AM7/18/14
to elixir-l...@googlegroups.com
Are you aware of String.duplicate/2 ?

-Greg
> --
> You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Joshua Nussbaum

unread,
Jul 18, 2014, 1:41:11 PM7/18/14
to elixir-l...@googlegroups.com
I am now :D

Thanks!

Levi Aul

unread,
Jul 18, 2014, 1:43:36 PM7/18/14
to elixir-l...@googlegroups.com
There are two ways to think of a Range type:

1. A simple way to define a Stream that starts with the opening value (of a type that has a successor function defined), and produces successors until one matches the closing value. In this definition, Ranges are Enumerable, and can be converted to (finite, but maybe huge) Lists.

2. A compact representation of a functional predicate that does ordering comparisons. 0..1 is another way to say &((&1 >= 0) && (&1 <= 1)). In this definition, ranges can range over *continuous* quantities. For example, 0.1..0.5 selects all real numbers between 0.1 and 0.5.

Under definition #1, exclusive ranges are an extraneous concept, as you can pretty simply construct an exclusive range from the successor of the opening value and the antecedent of the closing value.

Under definition #2, though, exclusive ranges are how you specify continuous quantities that don't include their boundaries—in other words, comparisons which use > instead of >=.

If you still want a minimal range syntax, though, there's another way to encode exclusivity: define a "discontinuity decorator" which takes a value and a direction, and acts like the asymptote of that value "coming from" that direction, in the calculus sense. Example (presuming that epsilon is the smallest representable floating-point number):

zeroplus = inexact(0, :+)
true = (zeroplus > 0)
true = (zeroplus >= 0)
false = (zeroplus == 0)
false = (zeroplus <= 0)
false = (zeroplus < 0)
true = zeroplus > -epsilon
true = zeroplus < +epsilon
true = (zeroplus == zeroplus)

And then you could have your exclusive range like so:

# (0, 1] in mathematical notation
inexact(0, :+) .. 1

I'm not sure whether it'd be possible to make inexact() objects work on an general Erlang VM level, but Ranges (and maybe Streams) could certainly do special-case logic for them.
Reply all
Reply to author
Forward
0 new messages