Examples to explain why binary generator uses `<=`

Map generator use <- just like list generator, why does binary generator use <= instead of <-?

Source = [<<1>>, <<2>>, <<3>>].
[X || <<X>> <- Source].
Source = <<1, 2, 3>>.
[X || <<X>> <= Source].

They return the same result, but compiler need to generate different code for them.

Erlang is dynamic, Source can be any type and compiler does not know that. A different operator <= solves this problem.

And Map generator is not using <-, it’s using K := V <-.

So we can say different type of data always use different generator operators. They don’t share generator operators.

1 Like

The main reason would be intent, I suppose. If you write code that expects a list, you don’t want it to silently take binaries with unexpected results.

2 Likes

Agree :handshake:

1 Like

The description is not good enough, let me describe it another way!

Now we are redesigning Erlang, and we try to use <- on both List and Binary generators.

Since we need to generate different code for list comprehension and binary comprehension, we need a way to figure out the data type we are dealing with.

For map, we (the compiler) can see := always come with `<-`, that’s how we know it’s a map generator.

For binary, can we recognize the pattern <<…>> <- XX and treat it as binary generator?

The answer is no, because if we do that, we will never be able to handle the following situation:

Source = [<<1>>, <<2>>, <<3>>].
[X || <<X>> <- Source].

So, our re-designing failed, we still need <= for binary generators.

1 Like

For what it’s worth, I use three languages in which the equivalent of list generation
is overloaded.
Haskell: [f x | x ← src, p x
Smalltalk: src collect: [:each | each] thenSelect: [:x | x p]
Pop-2: maplist(srx, lambda x; if x.p then x close end)
Haskell does this with compile-time type(class)es.
This compiles OK.
Smalltalk does it by dynamic dispatch on #collect:thenSelect:
This compiles OK.
Pop-2 does it by dynamic type checks, so overloading is not automatic.
This doesn’t lend itself to compilation to byte code.

It is very pleasant to be able to use many data types without caring
which specific type it is.
The problem with binary generators in Erlang is that you do care
because the way you match the elements is different. Being able to
iterate over a sequence of bytes is ho hum. Being able to use the
bit syntax in Erlang is important. You really do care that you can
do this.

What this means is that even at an abstract level, ← and <= in Erlang
simply mean different things. If I wanted to get the effect of <= with
bit syntax in Haskell, Smalltalk, or Erlang, it would take a lot of
extra programming.

The Erlang team made the right choice here.

1 Like