Log In  

no, I'm not referring to giving the do in for loops and while loops a free pass. rather, I'm referring to the rarely-used naked do block. the primary function of the do block by itself is to arbitrarily introduce a new scope. for example, a code snippet I just wrote:

 local yclp=127-17*pizzapower

this makes it clear to the reader that I do not intend to use yclp at any other point in the program. In this case, it becomes fairly obvious that I lifted an inline expression to its own line for clarity's sake. however, the do construct here eats up a token, making using it disadvantageous. considering that the do block's only real use has to do with usage of local variables, and the local keyword already has its cost annulled to encourage its use, I think it would make sense if there was a similar exception for the by-itself do block. what do all of you think?

P#82897 2020-10-13 20:54 ( Edited 2020-10-13 20:56)

You could say the same about parentheses. They're really both just hints to the parser about what goes where and what's associated with what. Nevertheless, even if they don't really have a runtime functionality once parsed, they're still a part of your cart, since the parsing happens at runtime. So, even though I'm usually one for reducing unnecessary token costs, I'm not sure I can get behind this one.

P#82899 2020-10-13 21:06 ( Edited 2020-10-13 21:07)

@Felice the difference is that parens have a lot of uses and as such you can't really avoid using them. plus, changing the cost of parens would have a lot of knock-on effects since they are used in so many constructs anyway, so that's a much more complicated subject.

naked do blocks on the other hand are completely avoidable-- if they have a cost, almost nobody will use them. it's the same reason the local keyword has no cost to it.

P#82901 2020-10-13 21:15 ( Edited 2020-10-13 21:16)

I explicitly used them in Poom to free large chunks of memory when reading the level - other than that, agree with Felice, not sure to see the point to make an exception 🤔

P#89426 2021-03-24 06:30 ( Edited 2021-03-24 06:30)

@freds72 the purpose would be to encourage more use of the do block in order to facilitate cleaner code. as it stands pico's rules encourage that if you don't need a do block, you should go without, which leads to poorer code hygiene, especially in large functions which effectively contain several "subroutines" that could each be neatly delineated with a do block.

P#89433 2021-03-24 07:43

if you go this way, tbh, the whole token concept goes to the bin!
pico point is not clean code, is balance between features/readability/performance/...
you want clean code, you get less features 🤷‍♂️
(ok local is the exception here...)
(and for this case, a comment will do!)

P#89434 2021-03-24 07:53 ( Edited 2021-03-24 07:54)

local is the comparison I'm trying to make here, I suppose. it feels like if binding a variable to a scope is free, creating a new scope should also be free. especially since, outside of super-advanced use cases like yours, there really isn't much reason to use do blocks outside of code hygiene-- in fact I'd argue the primary function of the do block is to guard against accidental variable shadowing, which is something that can always be trivially worked around.

it comes down to taste, I suppose-- but I also think compared to a lot of other potential token exemptions one could argue for, the do block is one of the least complicated to implement with the fewest potential non-obvious side effects.

P#89435 2021-03-24 08:13

As much as I'd love token count reductions, I don't find the argument compelling.

The main weakness is that I don't consider it appropriate to draw a comparison between naked do...end vs local. They are related, but different.

do..end creates a scope for cost of 1 token. In this sense it should be compared to other scope creation costs:

if <cond> then <body> end

if: 1 token for the branching construct
then+end: 1 token for scope creation

if <cond> then <body1> else <body2> end

if: 1 token for the branching construct
then+else+end: 2 tokens for scope creation ×2

while <cond> do <body> end

while: 1 token for the looping construct
do+end: 1 token for scope creation

repeat <body> until <cond>

1 token for looping construct
1 token for scope creation

function(<params>) <body> end

function+end: 1 token for scope creation
parentheses: 1 token for demarcation of params
[note that function name is not relevant to this discussion: since functions are first class values, 1 token cost for function name in 'function name() ... end' is analogous to variable name in 'name=function() ... end']

By contrast, local is used within a scope to flag vars that should be confined to that scope, rather than global. The cost for creating the scope has already been paid, so presumably the rationale is that there is no need to pay a token cost again for each 'local' keyword.

P#89444 2021-03-24 15:00 ( Edited 2021-03-24 15:03)

[Please log in to post a comment]