Question: I am trying to decode frames with variable length and options (such as the TLV in ethernet frames)
In order to do that, I was thinking about doing a fun recursive function :

```
fun (Fields, Bin) ->
    Parse =
        fun (P, F, <<Length, Rest/binary>>) ->
                P(P, F#{first => Length}, Rest)
        end,
    Parse(Parse, Fields, Bin)
end.

```

So Bin is the input frame for example : `40 02 12 45 01 50`
So first byte is the type of frame, `02` is the length of following data `12 45`, `01` is the length is the following data `50` and so on.

But my function doesn't work as expected using the funny trick

I am returning JSON object because it's send over MQTT.

Answer: 
What you're doing there really is only reading out the length, and don't do much with the `Rest`. You'd need to first declare an exit condition, i.e. when the TLV is empty -> just return the accummulator; And use the pattern match to read out the values based on the `Length`:

```
parse(<<>>, Acc) -> Acc;  %% finished with the list
parse(<<Length, Rest/binary>>, Acc) ->
   <<Value:Length/binary, Carry/binary>> = Rest.
   %% Value for the tag, Carry to be passed back on the recursion.
   %% Assuming that `Acc` is a list of Values.
   parse(Carry, Acc ++ [Value]).

```

You can use the above to read out the values, and can do something similar for getting the type first as:

```
tlv(<<Type, Values/binary>>) ->
   %% Return at tuple with the Type and the values.
   {Type, parse(Values, [])}.

```
You could write the function like this:

```
fun(<<Type, Packet/binary>>) ->
        {Type,
         fun Parse(<<>>) ->
                 [];
             Parse(<<Length, Data:Length/bytes, Rest/binary>>) ->
                 [Data] ++ Parse(Rest)
         end(Packet)}
end.

```

This returns `{40,[<<12,45>>,<<50>>]}` for your sample data.

The outer fun takes the frame type (40 in this case), and returns it along with the list of the data fields. The inner fun takes one length byte and the corresponding number of data bytes, and returns the data and makes a recursive call to itself - until it reaches the end of the binary.

The inner fun is a "named fun": it calls itself `Parse`, and is therefore able to call itself without needing to pass itself as an argument. The name `Parse` is not visible outside the fun. See [this question](https://stackoverflow.com/q/23199177/113848) for details and examples.