Is it possible to use a previously defined value in subsequent definitions of a `Block`?

The values of the variables in a Block are set at definition time, when data has no value:

Clear["data","len"]
TracePrint[
    Block[
        {
        data=Range[5],
        len=Length[data]
        },
        {len,data}
    ],
    _Length
]

Length[data]

{0, {1, 2, 3, 4, 5}}

The difference between using Plus and Length is that when data has no value data + 1 just evaluates to data + 1 while Length[data] evaluates to 0. So, the sum variable still has data in it, and it's value can change when data acquires a value.

One possibility to achieve your goal is to use SetDelayed instead of Set in your Block:

Block[
    {
    data = Range[5],
    len := Length[data]
    },
    {len,data}
]

{5, {1, 2, 3, 4, 5}}

Another, more robust possibility is to use the currently undocumented varargs With syntax:

With[
    {data = Range[5]},
    {len = Length[data]},

    {len, data}
]

{5, {1, 2, 3, 4, 5}}

Support for this syntax is not going away, and I believe the syntax should soon become documented.


It is possible to use Block with normal assignment, but you have to wait until data is available. (See the answer of @CarlWoll for the use of delayed assignment.)

Block[{data = Range@5, len},
 len = Length@data;
 {len, data}
 ]

However in this particular example, it is unclear why Module would not be preferable. Imo, Block should only be used when dynamic scoping is really needed, which is seldom.