Interspersing types and functions

Is it considered bad form to intersperse types and functions, e.g. below?

I usually keep all my types at the top but Rules and Scanners are only applicable to 3-4 functions below in a file of many functions.

        }
    }
    rule.actions = try statements.toOwnedSlice();
}

const Rules = ArrayList(IR.Rule);
const Scanners = StringHashMap(*IR.Scanner);

fn inlineRules(ir: *IR, scanner: *IR.Scanner) Error!void {
    var new_rules = Rules.init(ir.alloc);
    for (scanner.rules.items) |rule| {
        const rules = try inlineRule(ir, rule);
        try new_rules.appendSlice(rules.items);
    }
    scanner.rules = new_rules;
}

Depends on which school of thought you ask. There are tradeoffs that come with either style, so ultimately, it’s a style choice.

2 Likes

I personally prefer to avoid aliases like this, it’s not that hard to write, but it’s much easier to read. If you just see Rules as the type, then it could be anything.

Also side note: Aren’t you leaking memory everywhere? rules is never freed, neither is the old value of scanner.rules.

1 Like

This is a compiler and I’m using the arena allocator.

I’ll deallocate the whole thing when I’m done with the syntax tree and intermediate forms.

Hmm, makes sense. By the convention of the standard library is to name all variables arena instead of allocator if that’s the case.

But you could still reduce the needless allocations a bit if you pass new_rules to inlineRule() instead of returning a new list.

2 Likes