I've been writing introductory text, and Alexander and I having some
interesting creative differences, raising the question of what style
to follow, and how strictly.
The line in question is this, when introducing some oddiities of
variable usage in Lua:
x,y = 1,2
Alexander thinks that there should _always_ be a space after commas
and similar punctuation, but I reckon that this is an established
convention, even though I agree totally that code needs plenty of
whitespace to breathe properly. (It's how Roberto does it in his
book, if appeal to authority can be allowed here ;)))
His other point is that declarations without 'local' are likely to
teach bad habits. I take this point, since I remember being slack at
first when writing Lua until I got the light. My point was that I did
not want to immediately complicate the issue by discussing 'local',
which requires a discussion of scope. So I wished to postpone the use
of 'local' until that could be properly explained, and then lay down
the law about globals being a road of pain for anything other than
'Hello, World'.
Also, I think it's good to encourage people to play with Lua
interactively, and that is a context where 'local' should not be used.
So this one line raises the question of guidelines. I don't disagree
with the guidelines here, I just think that the context allows for
some latitude and freedom.
steve d.
My opinion would be if you really worry about which of those two options to
follow, you'll get very few authors.
>
> His other point is that declarations without 'local' are likely to
> teach bad habits. I take this point, since I remember being slack at
> first when writing Lua until I got the light. My point was that I did
> not want to immediately complicate the issue by discussing 'local',
> which requires a discussion of scope. So I wished to postpone the use
> of 'local' until that could be properly explained, and then lay down
> the law about globals being a road of pain for anything other than
> 'Hello, World'.
Do as I say, not as I do. My personal opinion is you should go local from the
start. The only explanation they need at first is "local is a good habit to
get into and use it unless you specifically want to use the variable all over
the program, and doing so is usually a bad habit.
Of course, in Litt's Lua Laboratory, I started out not using local :-) I'm
proud to be a hippocrit.
>
> Also, I think it's good to encourage people to play with Lua
> interactively, and that is a context where 'local' should not be used.
Speaking just for myself, I've never found a case past Hello World where it's
at all convenient to use the interactive environment. Vim is just too easy.
>
> So this one line raises the question of guidelines. I don't disagree
> with the guidelines here, I just think that the context allows for
> some latitude and freedom.
Once again, in my opinion, if you make your conventions too inflexible, nobody
will write chapters, and that kind of defeats the purpose.
SteveT
Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt
Well, it's true that strictness is counter-productive. We are not
getting together to write a large enterprise class application. And we
have all learned about 'local' and are freely contributing adults ;)
> Of course, in Litt's Lua Laboratory, I started out not using local :-) I'm
> proud to be a hippocrit.
I started with Lua by writing scripts for SciTE, and SciTE had a bad
habit of depending on globals ;)
Globals are not evil in the context of the proverbial ten line script,
but such scripts have a habit of sneaking into a codebase...
> Speaking just for myself, I've never found a case past Hello World where it's
> at all convenient to use the interactive environment. Vim is just too easy.
Hah, vim gives me a headache - the modal thing I guess. But I've
always used the interactive prompt to try things out without having to
actually create a file. It becomes a conversation - and makes a handy
desktop calculator.
> Once again, in my opinion, if you make your conventions too inflexible, nobody
> will write chapters, and that kind of defeats the purpose.
This is very true. I would not vote for more than the accepted
conventional wisdom (a) indent, dammit! and (b) use local.
Notice nothing about _how_ to indent, since people have strong
opinions. But for publishing purposes it would be useful to convert to
spaces, since the width of a space is not open to debate ;)
steve d.
Another option is to have a person dedicated just to formatting - let
the authors write as they like, and then make a review and repair
formatting (this can even be done automatically) and also maybe review
the code itself, like adding locals.
Regarding locals, the right balance has to be found. On one hand, you
need to explain scopes and why local doesn't work in interpreter
(every line is it's own scope, unless you write 'do .. end'), on the
other hand, local is the right thing to do...
> My opinion would be if you really worry about which of those two options to
> follow, you'll get very few authors.
> Once again, in my opinion, if you make your conventions too inflexible, nobody
> will write chapters, and that kind of defeats the purpose.
Um. Come on, if we'll have conventions, this does not mean that we
will not accept contributions until they conform. We will accept any
contribution.
On to the other hand, we *must* have some conventions — we have a lot
of authors (I hope so!), all with different styles. The book must have
one, consistent style.
We should agree to that style and, before we call book ready, to edit
contributions to fit.
The boring task of tuning contributions can be done by book editor
"group" (well, that would be our whole community, I guess) not
necessary by the contribution author themselves. (Although others are
always welcome to help.)
I suggest that someone create a wiki page with coding guidelines, and
start writing there all rules that we will discover and agree upon.
My personal pet favorites, for a discussion:
* Max line width 80 chars.
* No tabs.
* No trailing spaces.
* Indentation width 2 chars (though for a book a larger value may be
necessary, please advise).
* Space after all punctuation, before and after all binary operators.
* No redundant semicolons
* No redundant braces (e.g. in "if" condition)
* No lifting braces on function call (no foo{}, foo"") except in
declarative code. Do lift them in declarative code.
* No space before function call: (no foo (bar), but foo(bar))
* Separate table constructor items by "," on single line, by ";" when
on multiple lines
* No global variables unless absolutely necessary.
* No function foo() and function foo:bar() sugar except where explaining it.
I will conform to whatever style we will agreed upon, the rules above
are just to start the discussion.
But beware! If you will be silent, the rules will eventually get
accepted by default. Better say your opinion now, when we will have a
lot of text, it will be harder to change a rule :-)
Alexander.
Exactly. And scope is one of those concepts you have to introduce. We
have to assume some programming experience, but often it comes from
languages that have poorly defined ideas of scope (like Python). It's
an interesting exercise teaching a language; you realize that there's
a whole set of terms (like scope,precedence,operator,...) which exist
as a metalanguage to speak about programming languages.
Does it make sense to say that a variable is 'undefined'? I think so,
but there is this argument that the concept is foreign to Lua since
undefined variable access is global lookup that returned nil (whether
the variable was set or not). The various 'strict' implementations in
fact have to explicitly keep tracked of 'defined' globals so that this
distinction can actually be made.)
steve d.
I would say, 2 <= indent <= 4.
> * Space after all punctuation, before and after all binary operators.
I tend to follow this, except where there is convention to the contrary:
local i1,i2 = string.find(s,sub)
> * No redundant braces (e.g. in "if" condition)
You mean parens? I see no harm, but it's good to show confidence in
the language operator precedence rules ;)
> * No lifting braces on function call (no foo{}, foo"") except in
> declarative code. Do lift them in declarative code.
Nah, nothing wrong with fun "hello" - it's idiomatic Lua.
> * No space before function call: (no foo (bar), but foo(bar))
Ah, but space after 'if'? A minor point really.
> * Separate table constructor items by "," on single line, by ";" when
> on multiple lines
Not very standard, is it? I tend to use ';' to indicate a different
section, e.g. array vs hash part.
> * No global variables unless absolutely necessary.
We are all agreed on that. But what about 'math' and 'io' ?
> * No function foo() and function foo:bar() sugar except where explaining it.
You mean, always write 'foo = function() ... end' ? That would be odd
and non-idiomatic.
> I will conform to whatever style we will agreed upon, the rules above
> are just to start the discussion.
Consider this my attempt not to be silent ;)
steve d.
> >> * No redundant braces (e.g. in "if" condition)
> > You mean parens? I see no harm, but it's good to show confidence in
> > the language operator precedence rules ;)
> Parens, right, sorry.
> Braces for operator precedence is fine.
Aargh! Same mistake in the next sentence!
Sorry, this mistranslation is stubborn, and does not want to get out
from my head. I will beat it eventually.
Alexander.
>>> * No space before function call: (no foo (bar), but foo(bar))
>> Ah, but space after 'if'? A minor point really.
> Well, we need agree on one of the options to be consistent. No minor points
> here.
But I do not mean that we must agree right now and stop writing articles. :-)
All decisions rules what are not self-evident can be delayed until the
end of work on the book, where we will have to make a decision to make
code look consistent and finished.
Alexander.
Well, how about everyone uses tabs, and mechanically adjust
afterwards? Sounds like a job for a machine.
> local i1, i2 = string.find(s, sub)
OK, I take the point - it generally does look better. But the 'local
i1,i2 = ' part is not necessarily evil. Maybe another job for a
machine?
> I mean that we should bane this abominable imitation of C:
>
> if (foo == bar) then
> end
Totally unnecessary and shows insufficient weaning ;)
On hello "dolly":
> Can't agree that this is idiomatic. Please prove. :-)
The fact that you automatically said "local name = require 'name'" ;)
> One argument for ";" on multiple lines is that dangling "," on the last line
> looks ridiculous.
Does it? Lua is not a particularly line-end sensitive language - we
have no problems with such commas in C.
> The point here is to serve as a reminder that functions are first-class
> values. function foo() makes them look like some magical symbols.
Hm, still it's very eccentric, IMHO. We make the point, and make it
hard, and then live with the sugar that everyone else uses.
> * String quotes:
Well, obviously it is useful to have such rules in a big codebase. But
it feels like a minor point in this context. Some people like T"hello"
or even _"hello" for localization. I am prepared to break the habit
of a lifetime and prefer double quotes, if that helps...
I fear we are getting into meta-book territory again, like the
entertaining but ultimately boring thread about documentation
toolchains.
We are basically sharpening our pencils when the important thing is
text and code. Trying to remember rules and documentation formats
will put people off the actual writing.
I have a great confidence in the ability of Lua to process text and
code into the desired format...
steve d.
> Well, how about everyone uses tabs, and mechanically adjust
> afterwards? Sounds like a job for a machine.
I hate tabs, and normal indentation is just as adjustable.
>> local i1, i2 = string.find(s, sub)
>
> OK, I take the point - it generally does look better. But the 'local
> i1,i2 = ' part is not necessarily evil. Maybe another job for a
> machine?
Like I said before, it is a job for editors (or correctors). Not for
author. If author conforms — good, if not — no problem at all, we will
fix it later.
Once again: we will need to have, eventually, consistent an agreed
upon style guide.
This does *not* mean that authors have to follow this style when contributing.
> On hello "dolly":
>> Can't agree that this is idiomatic. Please prove. :-)
> The fact that you automatically said "local name = require 'name'" ;)
Not enough: I view this as an exception. :-)
>> One argument for ";" on multiple lines is that dangling "," on the last line
>> looks ridiculous.
> Does it? Lua is not a particularly line-end sensitive language - we
> have no problems with such commas in C.
I said it *looks* ridiculous — at least to me. It works fine, of course.
>> The point here is to serve as a reminder that functions are first-class
>> values. function foo() makes them look like some magical symbols.
> Hm, still it's very eccentric, IMHO. We make the point, and make it
> hard, and then live with the sugar that everyone else uses.
Well, get someone from our community to second this and I'll agree. :-)
>> * String quotes:
> Well, obviously it is useful to have such rules in a big codebase. But
> it feels like a minor point in this context. Some people like T"hello"
> or even _"hello" for localization. I am prepared to break the habit
> of a lifetime and prefer double quotes, if that helps...
See above: please write as you're used to.
> I fear we are getting into meta-book territory again, like the
> entertaining but ultimately boring thread about documentation
> toolchains.
Right.
> We are basically sharpening our pencils when the important thing is
> text and code. Trying to remember rules and documentation formats
> will put people off the actual writing.
I agree.
> I have a great confidence in the ability of Lua to process text and
> code into the desired format...
Of course, we will fix format to whatever we will agree upon later.
Alexander.
On Thu, Jan 27, 2011 at 13:06, steve donovan <steve.j...@gmail.com> wrote:No, sorry, this will not do. We should pick a fixed size.
> On Thu, Jan 27, 2011 at 11:57 AM, Alexander Gladysh <agla...@gmail.com> wrote:
>> * Indentation width 2 chars (though for a book a larger value may be
>> necessary, please advise).
> I would say, 2 <= indent <= 4.
>> * Space after all punctuation, before and after all binary operators.And this makes me mad when I read it! :-)
> I tend to follow this, except where there is convention to the contrary:
> local i1,i2 = string.find(s,sub)
Much better! (Also, this is a book, it ought to be readable, space = readability)
local i1, i2 = string.find(s, sub)
<snip>
I mean that we should bane this abominable imitation of C:
if (foo == bar) then
end
and similar.
>> * No lifting braces on function call (no foo{}, foo"") except inCan't agree that this is idiomatic. Please prove. :-)
>> declarative code. Do lift them in declarative code.
> Nah, nothing wrong with fun "hello" - it's idiomatic Lua.
>> * No space before function call: (no foo (bar), but foo(bar))Well, we need agree on one of the options to be consistent. No minor points here.
> Ah, but space after 'if'? A minor point really.
Not very standard, these are my personal guidelines. They may be strange in places.
>> * Separate table constructor items by "," on single line, by ";" when
>> on multiple lines
> Not very standard, is it? I tend to use ';' to indicate a different
> section, e.g. array vs hash part.
One argument for ";" on multiple lines is that dangling "," on the last line looks ridiculous.
We need more opinions here. Everyone, please join our discussion! :-)
>> * No global variables unless absolutely necessary.In large listings, alias them on top. In small, use them right away.
> We are all agreed on that. But what about 'math' and 'io' ?
Also:
* Use local name = require("name") whenever possible.
(Note that I would write require 'name', that's a strange exception in my personal no lifting parens rule.)
>> * No function foo() and function foo:bar() sugar except where explaining it.Right.
> You mean, always write 'foo = function() ... end' ?The point here is to serve as a reminder that functions are first-class values. function foo() makes them look like some magical symbols.
> That would be odd and non-idiomatic.
More rules for discussion:
* Indentation of long function calls:
foo(
bar, -- two indents
baz
) -- one indent
* Indentation of long string concatenation:
foo(
"very long string"
.. " continued" -- `"` right above `"` on the prev. line
)
* String quotes: use " for longer strings like messages, use ' for single-word strings. Use ' for longer strings with " inside. Use [[]] for localizable text and in codegeneration.
>
> I personally prefer a 2-space indent, and my PiL copy agrees :), so 2 should
> be fine for a book.
>
I've been using 2 spaces and that looks good.
>>
>> >> * Space after all punctuation, before and after all binary operators.
>>
>
> I also find this spacing more pleasant to read.
>
I agree with this spacing and readability however old
listing habits (e.g. CSV) are hard to break.
>>
>> <snip>
>> I mean that we should bane this abominable imitation of C:
>>
>> if (foo == bar) then
>> end
>>
>> and similar.
>
>
> Agreed.
>
Skipping parens where unnecessary has been refreshing.
>>
>> >> * No lifting braces on function call (no foo{}, foo"") except in
>> >> declarative code. Do lift them in declarative code.
>>
>> > Nah, nothing wrong with fun "hello" - it's idiomatic Lua.
>>
>> Can't agree that this is idiomatic. Please prove. :-)
>
> I'd say so. require 'something' is quite widespread. Functions with a single
> table argument to emulate keyword parameters aren't uncommon either. Newbies
> will come across this pretty fast, so this is something that should be
> mentioned in the intro anyway. Readability is the key concern here.
>
No opinion.
>>
>> >> * No space before function call: (no foo (bar), but foo(bar))
>>
>> > Ah, but space after 'if'? A minor point really.
>>
>> Well, we need agree on one of the options to be consistent. No minor
>> points here.
>
> Well, I prefer no spaces before function calls too, except when one writes
> in a more declarative style, such as Lua Ropes with push's function
> chaining.
>
I think function names need a left paren right after the word with no space.
>>
>> >> * Separate table constructor items by "," on single line, by ";" when
>> >> on multiple lines
>>
>> > Not very standard, is it? I tend to use ';' to indicate a different
>> > section, e.g. array vs hash part.
>>
>> Not very standard, these are my personal guidelines. They may be strange
>> in places.
>>
>> One argument for ";" on multiple lines is that dangling "," on the last
>> line looks ridiculous.
>>
>> We need more opinions here. Everyone, please join our discussion! :-)
>
> Most Lua code I've read uses ',' on the last line, no problems there.
>
No preference on this one.
>>
>> >> * No global variables unless absolutely necessary.
>>
>> > We are all agreed on that. But what about 'math' and 'io' ?
>>
>> In large listings, alias them on top. In small, use them right away.
>
> Agreed.
>
Declaring local is probably a good habit to begin early.
>>
>> Also:
>>
>> * Use local name = require("name") whenever possible.
>>
>> (Note that I would write require 'name', that's a strange exception in my
>> personal no lifting parens rule.)
>
> Common usage is require "name".
>
This looks good to me too.
>>
>> >> * No function foo() and function foo:bar() sugar except where
>> >> explaining it.
>>
>> > You mean, always write 'foo = function() ... end' ?
>>
>> Right.
>> > That would be odd and non-idiomatic.
>>
>> The point here is to serve as a reminder that functions are first-class
>> values. function foo() makes them look like some magical symbols.
>
> Nah, I think we can all agree that function foo() ... end is most certainly
> idiomatic Lua :) The first-class reminder should be made in the intro, maybe
> again in the Functional Programming section, where the first-class value
> status of functions will really be exercised.
I like
function foo()
...
...
end
but not function foo ()
No comment on these.
Dick S.
--
Dick Seabrook
Anne Arundel Community College
http://vader.aacc.edu/~rhs
Speed the Net!
It is interesting how many different semantics people give to various
quotes. I use the following:
* 'single' - identifiers (modules, classes), enums
(w:setState('maximized')), flags (io.open(fn, 'w'))
* "double" - strings to be seen by user, other general strings
* [[long string]] - for generated code, code in other languages,
verbatim strings
Maybe this whole discussion should go to a Wiki page at GitHub?
> My personal pet favorites, for a discussion:
>
> * Max line width 80 chars.
That's pretty much necessary for a book.
> * No tabs.
Personally, I'd have trouble with that. A lot easier to press tab than 3 or 4
spaces, plus unless you set Vim right it "helpfully" turns multiple spaces
into tabs (yeah, I know this is vim's fault, but...)
> * No trailing spaces.
Yeah, that's just a sed command. It's easy and nobody would argue with it.
> * Indentation width 2 chars (though for a book a larger value may be
> necessary, please advise).
As a reader, I can't fathom 2 char indents. Even 3 char indents are hard to
for me to fathom. If you really want the structural intent to "pop out" at the
user, I'd recommend a minimum of 4.
> * Space after all punctuation, before and after all binary operators.
Thank you, thank you, THANK YOU for putting some order into this. I
indescriminately use x+y and x + y. The one thing I'd argue is that you
shouldn't put a space after a (, [ or { -- that's just plain weird, and I'd
rather save the space so we can have 4 char indents.
> * No redundant semicolons
Sounds good to me.
> * No redundant braces (e.g. in "if" condition)
> * No lifting braces on function call (no foo{}, foo"") except in
> declarative code. Do lift them in declarative code.
> * No space before function call: (no foo (bar), but foo(bar))
Sounds good. Save the space for larger block indents.
> * Separate table constructor items by "," on single line, by ";" when
> on multiple lines
What about when you have multiple constructor lines on multiple lines. If you
have twenty constructor items, you don't want them on one line, nor do you
want them taking 20. Personally I'd just recommend "," for everything.
> * No global variables unless absolutely necessary.
Amen!
> * No function foo() and function foo:bar() sugar except where explaining
> it.
I'd recommend the opposite. From the reading I've done, the most frequent
declaration is
function foo(args)whatever end
not
foo = function(args)whatever end
Also, in certain recursive situations whose implications I don't fully
understand, the latter can backfire if not done just right, whereas the former
"just works".
But when it comes to explaining the fact that functions are just one more
piece of data, nothing does that job as well as
foo = function(args)whatever end
so that's where I'd personally recommend using it.
:-)
Well, the first notation can sometimes backfire on you, whereas with
the second one, you alway know what is going on. For example, with the
following simple code:
do
local foo
function foo() print("Hello") end
end
print(foo)
you get "nil" as a result. Why? Because foo was declared as local to
the block, and the "function foo()" is translated to "foo =
function()". When using locals, it is better to make it explicit as an
assignment. When declaring global functions, I think the "function
foo()" style is OK.
>> * No tabs.
> Personally, I'd have trouble with that. A lot easier to press tab than 3 or 4
> spaces, plus unless you set Vim right it "helpfully" turns multiple spaces
> into tabs (yeah, I know this is vim's fault, but...)
AFAIR, you can configure vim to use whatever indentation you want for
a *specific file*, using special formatting. (Have to lookup in the
docs how exactly to do that.)
That being said, write using whatever indentation you're used to. We
will fix all text when we will finalize the guidelines. (Should happen
closer to the finish.)
>> * Indentation width 2 chars (though for a book a larger value may be
>> necessary, please advise).
> As a reader, I can't fathom 2 char indents. Even 3 char indents are hard to
> for me to fathom. If you really want the structural intent to "pop out" at the
> user, I'd recommend a minimum of 4.
I agree. For a book 2 char indents are too blind. Also, I, personally,
consider 3 char indents to be an unhealthy deviation, to be avoided.
But see above about fixing up texts later.
>> * Space after all punctuation, before and after all binary operators.
> Thank you, thank you, THANK YOU for putting some order into this. I
> indescriminately use x+y and x + y. The one thing I'd argue is that you
> shouldn't put a space after a (, [ or { -- that's just plain weird, and I'd
> rather save the space so we can have 4 char indents.
Yes, of course. No spaces after (, [ or {. (Almost) the same rules as
for the natural language.
>> * Separate table constructor items by "," on single line, by ";" when
>> on multiple lines
> What about when you have multiple constructor lines on multiple lines. If you
> have twenty constructor items, you don't want them on one line, nor do you
> want them taking 20. Personally I'd just recommend "," for everything.
This is what my personal guidelines say:
local foo =
{
{ a, b, c };
{ d };
{
e, f, g;
h;
};
i;
}
I have no problem with replacing ";" with ",", if we ban trailing ",".
Alexander.
> Maybe this whole discussion should go to a Wiki page at GitHub?
Can someone move the summary of this coding style discussion to Wiki please?
If not, I will do this myself once I will have more time.
Thanks,
Alexander.