Poll
Which would you prefer? (see below) (Closed)
Option 1: As is | 12 | 41% | |
Option 2: Prefix | 16 | 55% | |
Option 3: By case | 1 | 3% |
There was quite a bit of spirited discussion yesterday on the subject of how we should resolve name collisions in scripts. Currently, if we have an object definition named "Clonk", we could do a lot of confusion:
(Option 1: As-is)
At which point "Clonk" could possibly mean a lot of things. The way it currently seems to work is that IDs are on the same level as static consts, so you can completely shadow out certain definition IDs by having variables with the same name. It might even be possible that a static const at the wrong place might actually shadow the ID for the whole project.
The only case I can think of where this could be considered desirable behavior would be aliasing definitions like in "
One argument why this could be acceptable is that if we make IDs longer (see also the second poll) name collisions get less likely. Note however that we might not actually want to have to type long IDs - if we implement some sort of namespace import, we will be stuck with the same problems again.
Another option would be to have a prefix mark IDs:
(Option 2: Prefix)
In this case, I used ":" as it's similar to what Ruby uses for symbols. Other possible options could be "$" or "#", or even "ID_".
A third alternative is to distinguish between IDs and function names / variables using case:
(Option 3: By case)
This makes IDs the only thing in script that is allowed to start with an upper-case letter. This applies to all engine functions and engine-defined constants as well.
Please speak up if you feel I left out a valid alternative.
static const Clonk = ...;
local Clonk;
func Clonk() { var Clonk; Clonk = FindObject(Find_ID(Clonk)); }
(Option 1: As-is)
At which point "Clonk" could possibly mean a lot of things. The way it currently seems to work is that IDs are on the same level as static consts, so you can completely shadow out certain definition IDs by having variables with the same name. It might even be possible that a static const at the wrong place might actually shadow the ID for the whole project.
The only case I can think of where this could be considered desirable behavior would be aliasing definitions like in "
static const AquaClonk = Clonk
" - but this wouldn't work very well anyway.One argument why this could be acceptable is that if we make IDs longer (see also the second poll) name collisions get less likely. Note however that we might not actually want to have to type long IDs - if we implement some sort of namespace import, we will be stuck with the same problems again.
Another option would be to have a prefix mark IDs:
static const Clonk = ...;
local Clonk;
func Clonk() { var Clonk; Clonk = FindObject(Find_ID(:Clonk)); }
(Option 2: Prefix)
In this case, I used ":" as it's similar to what Ruby uses for symbols. Other possible options could be "$" or "#", or even "ID_".
A third alternative is to distinguish between IDs and function names / variables using case:
static const clonk = ...;
local clonk;
func clonk() { var clonk; clonk = findObject(find_ID(Clonk), find_OCF(ocf_Alive)); }
(Option 3: By case)
This makes IDs the only thing in script that is allowed to start with an upper-case letter. This applies to all engine functions and engine-defined constants as well.
Please speak up if you feel I left out a valid alternative.
You are very negative about Option 1. But actually, I have seen no piece of C4Script code yet in my life that uses
There might be a definition of that name but it does not matter here, because the scripter is not interested to access it at the same time. Also static variables are normally only used as static const and there exists another naming convention which does not conflict with ids: OCF_Something.
var Capitalized
variables. The common norm is either lowercase_variables
or idHungarian
(old), both start with lowercase characters and thus do not conflict with IDs which start uppercase. I predict that variables will almost never shadow out IDs and even if they do at some very seldom places, no unintentional behaviour is triggered:func DoSomething()
{
var AquaClonk = GetCursor(0);
AquaClonk->GoLeft();
}
There might be a definition of that name but it does not matter here, because the scripter is not interested to access it at the same time. Also static variables are normally only used as static const and there exists another naming convention which does not conflict with ids: OCF_Something.
Well, but constants, on the other hand, are upper-case by convention (yes, all upper case, actually). I do think definitions as script namespaces are special enough both to have special protection against shadowing and to warrant a special syntax. They just aren't the same thing as variables or functions.
I chose 1 and 2. Just to make clear that I don't like 3 ;)
I would like to keep function names with uppercase letters in the beginning and make some variable notation (start with small letter / hungarian (where I'd prefer the first)) mandatoriy for the official code (or even the parser, dunno).
IDs should have some prefix. I am a fan of ::Clonk there, since I am still looking forward to proper namespaces and like the C++ way of doing things. :)
That would make those three types clearly distinguishable
I would like to keep function names with uppercase letters in the beginning and make some variable notation (start with small letter / hungarian (where I'd prefer the first)) mandatoriy for the official code (or even the parser, dunno).
IDs should have some prefix. I am a fan of ::Clonk there, since I am still looking forward to proper namespaces and like the C++ way of doing things. :)
That would make those three types clearly distinguishable
Prefixes in first place were invented to resolve such ambiguities. Using them will result in better and more understandable code, so prefix like ::Clonk will help a lot.
Anyway, why would there be a function named Clonk() ? Shouldn't all the function depict some action (like set*, get*, do*, receive* and others)?
EDIT: By the way, there is a good coding standard for C++ (which is close in syntax to c4Script)
EDIT: By the way, there is a good coding standard for C++ (which is close in syntax to c4Script)
My favourite is #3, because lower case function and variable names are somewhat standard among most programming languages.
Otherwise, I'd say #1.
I'm not really afraid of name clashes if scope precedence is implemented properly. If someone has a function named "Bubble" in his code and later on, someone decides to create a definition named "Bubble", this won't be a problem as long as the function has precedence. If someone wants to create a bubble in the same script, he won't call his function "Bubble". Conflicts are rare anyway, because function names should be verbs while definitions are objects.
Conflicts with variable/local names won't happen as long as they stay lower case. Almost everyone uses lower case for them anyway.
Global names need special consideration. In CR, I usually include the ID in statics to make sure I don't get conflicts (static const MCLK_PrefCombo). Similarly, we might condier putting global functions into the namespace of a definition (Lightning_Launch or Lightning::Launch?).
Otherwise, I'd say #1.
I'm not really afraid of name clashes if scope precedence is implemented properly. If someone has a function named "Bubble" in his code and later on, someone decides to create a definition named "Bubble", this won't be a problem as long as the function has precedence. If someone wants to create a bubble in the same script, he won't call his function "Bubble". Conflicts are rare anyway, because function names should be verbs while definitions are objects.
Conflicts with variable/local names won't happen as long as they stay lower case. Almost everyone uses lower case for them anyway.
Global names need special consideration. In CR, I usually include the ID in statics to make sure I don't get conflicts (static const MCLK_PrefCombo). Similarly, we might condier putting global functions into the namespace of a definition (Lightning_Launch or Lightning::Launch?).
The rules can be as following:
For variables names:
1) lowercase (variable)
2) capitalization (MyVariable or myVariable)
3) better not use _ in variables names
For constants:
1) upper case (CONSTANT)
2) _ as delimiter (MY_CONSTANT)
For global variables (the most difficult part)
1) Generally, the same as local variables (maybe some prefix, though I do not like this idea)
2) Possible use of _ (like global_Variable)
For methods (functions):
1) Unfortunately, the same rules as for local variables apply (myFunction)
2) Can be more distinguishable if actual operations are depicted (doSomething)
3) Better not start function name with a capital letter!
This is only a brief consideration - I'm sure someone will come up with better ideas
For variables names:
1) lowercase (variable)
2) capitalization (MyVariable or myVariable)
3) better not use _ in variables names
For constants:
1) upper case (CONSTANT)
2) _ as delimiter (MY_CONSTANT)
For global variables (the most difficult part)
1) Generally, the same as local variables (maybe some prefix, though I do not like this idea)
2) Possible use of _ (like global_Variable)
For methods (functions):
1) Unfortunately, the same rules as for local variables apply (myFunction)
2) Can be more distinguishable if actual operations are depicted (doSomething)
3) Better not start function name with a capital letter!
This is only a brief consideration - I'm sure someone will come up with better ideas
but it would make understanding the script engine very hard.
an empty will never see the difference between "BLA", "bla" and "Bla"
an empty will never see the difference between "BLA", "bla" and "Bla"
Though using variable_Bla, global_Bla, method_Bla() and CONST_Bla is not an option either :-(
For variables names:
myVariable or
pMyObject, iMyInt
For constants:
FOO_Bar
For global variables:
g_MyGlobalVar
For object local methods:
doThis() (It shouldn't be a problem that these collide with the var-names since the brakes indicates that they are functions)
For global methods:
DoThis()
My suggestion.
myVariable or
pMyObject, iMyInt
For constants:
FOO_Bar
For global variables:
g_MyGlobalVar
For object local methods:
doThis() (It shouldn't be a problem that these collide with the var-names since the brakes indicates that they are functions)
For global methods:
DoThis()
My suggestion.
You can call global methods g_DoThis() as well as global variables (though g_* prefix would not be so understandable). As for variables I personally like it the way you've mentioned (first letter in lower case, second, third and so on word starting with capital letter). As for constants... well, can be FOO_Bar or FOO_BAR, - no big deal.
The more important issue is that everyone uses THE SAME naming conventions (preliminarly defined) to make the code somewhat standartized and easy-to-read by (again) everyone.
The more important issue is that everyone uses THE SAME naming conventions (preliminarly defined) to make the code somewhat standartized and easy-to-read by (again) everyone.
Yes, and players and player is something different too. I don't see your point. Or rather, I see your point, but I don't see how you can argue that it's readable to have three variables with (essentially) the same name: iPlayer, szPlayer and aPlayer. Less confusing variable names might me player_id, player_name, and whatever you want to put in that array there.
I would prefer the ID_-prefix since it indicates it's an constant and is also easy to understand.
The reason I haven't implemented #2 yet is that it would make Definitions defined by a DefCore.txt and those defined by Script different without a clear need. In the long term, I want to eliminate C4IDs and just pass proplists around.
The reason that I write about this now is that another usecase for prefixes occured to me now: The various callbacks and magic properties that are used by the engine could be distinguished from those that are only used by script by having a prefix. :Initialize(), :Parallaxity, :ActMap etc. For some (probably irrational) reason I'm worried about clashes there. Maybe because it hinders introduction of new engine features, whereas the Definition Naming Problem can be solved entirely from script by adoption a naming convention there.
Maybe the thing to do is to allow a bunch of extra characters to occur in C4Script identifiers, to give the script writers more options to solve this on their end, and not introduce any special handling of definition IDs. Anyone care to make a list of possible characters?
The reason that I write about this now is that another usecase for prefixes occured to me now: The various callbacks and magic properties that are used by the engine could be distinguished from those that are only used by script by having a prefix. :Initialize(), :Parallaxity, :ActMap etc. For some (probably irrational) reason I'm worried about clashes there. Maybe because it hinders introduction of new engine features, whereas the Definition Naming Problem can be solved entirely from script by adoption a naming convention there.
Maybe the thing to do is to allow a bunch of extra characters to occur in C4Script identifiers, to give the script writers more options to solve this on their end, and not introduce any special handling of definition IDs. Anyone care to make a list of possible characters?
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill