# Using vtx[] instead of vtx

There're two ways to generate a random tree as 1 and 2 below. Both work fine here. So what's the reason to use vtx[] instead of vtx?

# 1.

vtx[] := Table[i <-> RandomInteger[{0, i - 1}], {i, 1, 50}];
Graph@vtx[]


# 2.

vtx := Table[i <-> RandomInteger[{0, i - 1}], {i, 1, 50}];
Graph@vtx

• The second way is 10 times faster. All rest looks similar. – Rom38 Oct 26 at 5:22
• It is good to note that the method you linked does not sample trees uniformly. Some trees are generated with higher probability than others. To sample trees uniformly, you can use IGTreeGame[] from the IGraph/M package. – Szabolcs Oct 26 at 10:25
• In 2 you could remove the delay from the assignment, since the LHS is not parameterised. – Shredderroy Oct 26 at 14:05
• @Shredderroy := can be removed either in 1 or in 2 (but notice that the right-hand-side generates a random list, so := is important in this application) – Szabolcs Oct 26 at 17:43

The reason to use 1. is readability. There is no difference in function or performance.

Simply because of established convention, most people when they see f[vtx], they assume that vtx is "a variable", i.e. if it is evaluated twice, it will give the same result both times. vtx[] looks like "a function call", so people will expect that a second evaluation may give a different result (as it is the case here).

Technically speaking, Mathematica has neither functions nor variables (it is a term rewriting system), but it is still useful to think of code in these terms.

Besides the reasons mentioned by @Szabolcs, there's a second advantage of the first method: It is easier to control when evaluation happens.

• With vtx := …, evaluation happens as soon as the symbol appears (as long as you're not using stuff with Hold attributes/Unevaluated)
• With vtx[] := …, you can pass around vtx without having to worry about evaluation. Only when you add the square brackets is the code actually evaluated.

### Example

To see why this can be useful, consider the following example: We want to create a function drawTrees that creates small plots of 5 randomly sample trees, where we can specify how to sample them.

With vtx[] := …, this would look like this:

drawTrees[gen_]:= Table[
Graph[gen[], ImageSize->100],
5
]

vtx[] := Table[i <-> RandomInteger[{0, i - 1}], {i, 1, 20}];
vtx2[] := Flatten@Table[{i <-> i - 1, i <-> f[i]}, {i, 20}];

drawTrees[vtx]


drawTrees[vtx2]


With vtx := …, we need to use a HoldFirst attribute:

drawTrees[gen_]:= Table[
Graph[gen, ImageSize->100],
5
]
Attributes[drawTrees] = {HoldFirst};

vtx := Table[i <-> RandomInteger[{0, i - 1}], {i, 1, 20}];
vtx2 := Flatten@Table[{i <-> i - 1, i <-> f[i]}, {i, 20}];

drawTrees[vtx]
(* same as above *)
drawTrees[vtx2]
(* same as above *)


Of course, the fix is simple in this case. But if you need to pass around the generator a lot and store it somewhere, it will become even more messy with the vtx := … approach.

• I just wonder if you define vtx[] := … then why do you pass vtx not vtx[]? – anhnha Oct 26 at 12:35
• You don't need to pass around vtx instead of vtx[] - the point is that you can. I have updated the answer with an example – Lukas Lang Oct 26 at 12:52
• I see it now. Thanks for the updating. – anhnha Oct 26 at 13:18