The Dink Network

SEMICOLONS ARE THE SPAWN OF BEELZEBUB

February 19th 2013, 01:16 AM
spike.gif
So stop adding them in scripts right now.
February 19th 2013, 01:25 AM
custom_msdink.png
MsDink
Peasant She/Her New Zealand
Tag - Umm.. tag, you're it? 
lol not even.... numbers are the spawn of the devil scary bleedin things
February 19th 2013, 03:03 AM
knightg.gif
DackFight
Peasant He/Him United States
Making Topics off-track faster then you can say it 
who is BEELZEBUB, also to me Scratcher seems to[ be like Abs n[ow.
February 19th 2013, 05:08 AM
goblins.gif
Really? I always use them... It would take a while to get rid of all my semicolons.

Why are they the spawn of Beelzebub, other than likely being kind of useless in DinkC? If you can give a good enough reason, I'll stop using them (but I refuse to edit them out of all my existing scripts).
February 19th 2013, 06:52 AM
spike.gif
Just a colourful expression, sorry; I was feeling kind of restless.

It's as you say, they're [totally] worthless: imagine the amount of typing saved if you never wrote them in the first place... They also waste disk space and uglify scripts, although the former is negligible in this day and the latter is kind of subjective.

I originally intended to write a post about all the stuff that's needless in DinkC, although semicolons are by far the most glaring one. The ( void ) part in procedure titles is also totally unneeded, and interestingly, wrapping a procedure in brackets doesn't do much of anything.* For example, the following works perfectly fine:
void hit
{
sp_target(&current_sprite,&enemy_sprite)
playsound(30,21050,4000,&current_sprite,0)
//lock on to the guy who just hit us
//playsound
}
say("I laugh at your foolish brackets, silly pillbug!",1)
(As an aside, sp_target(&current_sprite,&enemy_sprite) is needless in that example, because enemies will automatically target &enemy_sprite.)

* Brackets are useful for a few reasons though, so I don't really advocate not having them.
February 19th 2013, 07:06 AM
slimeg.gif
metatarasal
Bard He/Him Netherlands
I object 
And there was me believing that the opening parenthesis in procedure titles was necessary.
February 19th 2013, 07:09 AM
goblins.gif
Well, I think I'll keep brackets for procedures, just because they look cleaner to me. But I do believe you are right, semicolons don't actually do anything and the brackets aren't really necessary.

Once I took a look into your Lost Forest romp story folder, and I saw how you scripted everything. I was surprised that the scripts even worked with how different they looked from the normal conventions. If I was used to it, I might code like that too. But with how long I've read it like:
void procedure( void )
{

}


It's a very jarring adjustment that makes it harder for me to read to remove the brackets. I also like to use big indents for every bracket like:

void main( void )
{
     if (&quest == &cheese)
     {
          //go on a quest for cheese
     }
}


It's just something I've got used to and is easiest for me to read. But you should continue using whatever format is easiest for you, and it's true you will save on a few KB or so of disk space every megabyte by removing the unnecessary things.

I'll think about not typing the semicolons anymore, though.
February 19th 2013, 07:37 AM
spike.gif
I more or less agree about brackets; Lost Forest Romp was the first time I tried that, to see if there would be any related problems.

There weren't really, but I did notice a few quirks. Firstly, the last line in any script doesn't seem to run, and a closing bracket at the end of a script is a simple way to avoid accidentally encountering that. I also had a few freeze bugs that were fixed by adding a last bracket into a script, although I wasn't able to make sense out of why it would happen sometimes and not at other times.

But just a final closing bracket (to symbolically close the script, or something ) fixed all my problems, so the lack of brackets around procedures wasn't strictly the problem.
February 19th 2013, 10:11 AM
wizardg.gif
leprochaun
Peasant He/Him Japan bloop
Responsible for making things not look like ass 
I feel like people should just script in the way they're most comfortable with.
February 19th 2013, 05:03 PM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
Da computor doesn't know when to excectute next statement without semicolons. Besides having a distinct character as a separator is far more comfortable than none imo and you can cram in lotsa code on one line with semicolons:

int b; int a = b + c; int x + c = d;

int b int a = b + c int x + c = d <- dafuq



I know that DinkC really isn't that advanced, but the semicolons are simply inherited from C and Java and the likes and it is not readable code to a seasoned C/Java programmer if it doesn't include semicolons.
February 19th 2013, 08:10 PM
wizardb.gif
Kyle
Peasant He/Him Belgium
 
For a complete noobie to programming putting the semicolons behind a line of code is the number one most common debugging cause.

So, it's good practice to use them in DinkC in case you ever tackle a real programming language
February 19th 2013, 08:34 PM
knightg.gif
DackFight
Peasant He/Him United States
Making Topics off-track faster then you can say it 
who is BEELZEBUB?
February 19th 2013, 08:41 PM
knight.gif
KrisKnox
Peasant He/Him United States
The site's resident Therian (Dire Wolf, Dragon) 
February 20th 2013, 02:29 AM
spike.gif
I know semicolons serve a purpose in C, but it doesn't make sense to me to stick to habits that result in less than optimal code simply because it's needed in another language, or because it's something you're used to; you need to adjust to new conditions when you change the language you're writing in.
February 20th 2013, 04:14 AM
dinkdead.gif
I spend my days using Visual Basic. You can keep your silly problems

---

Are semicolons really useless in DinkC?
I thought a lot of bugs have been caused by missing one sometimes.

Anyway... given the fact that DinkC does funny things sometimes I don't think I'd be comfortable leaving them out, just in case.

I do quite like the braces ({}) though and find they can make the code easier to read, especially in DinkC where many people don't indent properly (grrr).
February 20th 2013, 04:52 AM
goblins.gif
It will cause problems if you put a semicolon on an "if" statement (I think it just ignores the statement in this case). As for not using a semicolon I don't know for sure, but based on the scripts I've looked at in the lost forest romp and the fact that they work, I'm inclined to believe any possible problems would be rare to non-existent. But still, it's also harmless to use semicolons as long as you don't use it on an "if" statement, and it's a good convention for other languages.

So, I don't see anything wrong with using semicolons. However, I also don't see anything wrong with not using them. So do whatever you like. Game Maker which I've also spent a lot of time using has the same arguments going with it's scripting language because it, like DinkC, doesn't require semicolons but simply ignores them when they are there, except for on "if" statements where it will return an error.
February 20th 2013, 05:26 AM
spike.gif
Yeah, I'm certain leaving semicolons out can't cause any problems, although it would be just my luck to find some situation that does require them right after saying that. Help threads and such on the board are another matter, I've probably told people to add semicolons in their scripts myself, back when I still thought they were there for some good reason.
February 20th 2013, 07:58 AM
custom_skull.gif
Skull
Peasant He/Him Finland bloop
A Disembodied Sod 
Semicolons are somewhat necessary in commands, but whether it works with or without them, is at pure random. I always tend to put semicolons at the end of commands, so I won't run into any problems, that I know I could have avoided from the first place.
February 20th 2013, 08:09 AM
spike.gif
Can you give some example of when leaving them out might cause problems? I've had my fair share of bugs that seemed pretty random, but I've always traced them to something other than semicolons.
February 20th 2013, 09:46 AM
custom_skull.gif
Skull
Peasant He/Him Finland bloop
A Disembodied Sod 
Well, I don't remember any specific times when this has happened, but I can remember it has, many times. Just try putting &global += 1; without the semicolon and I am quite certain it won't work. I'm pretty sure commands don't work without them, but if I'm wrong, then awesome and good for you. I'm probably still gonna be using semicolons though, out of pure instinct.
January 8th 2016, 07:15 PM
dinkdead.gif
millimeter
Peasant He/Him Canada
Millimeter is Wee-Lamm, Recording Artist. :-) 
This thread is a couple years old, but still a relevant topic, imo.

I humbly disagree with not needing semicolons, and brackets certainly are essential, especially if there is some "optional" code segments which precede mandatory segments.

Semicolons:
If I remember correctly, the parser looks for white space greater than 1 space, to indicate the end of a line. This explains why only 1 white space can exist between elements in an equation, for example.

i.e. &num == 1;
would fail at the '1' because it is a set value which cannot be changed or referenced as a variable.
&num == 1
is likely to fail, because the assignment isn't complete and the actual value of &num may not be properly defined, even if it seems to be, "sometimes".

At the same time, there are different flavors of whites pace; a space, hard space, CR, LF, CRLF, TAB... though these may appear to look the same in your favorite editor, they would each result in a different amount of spacing in a text.

Using a Semicolon indicates that the assignment is complete, and requires at least 1 white space to allow the parser to click to the next interval. Extra spaces following a semicolon are ignored.

i.e.
&num == 1; //A number
&num == 1; //A number

are identical to the parser.

I would suggest using semicolons, "at least" to end each assignment statement, as well as any statement which signifies the end of the script, or would relinquish control back to the que. The semicolon would also serve as a return point for when the script gets it's next turn in the cycle. imho, it would be less likely to fail if you used a semicolon to complete a statement that maybe did not require one, than to fail because you omitted one that was required. Also, in Seth's original notes he said, that including multiple assignments on one line would likely work fine, but there were occasions the parser didn't read them right, and suggested to put one per line just to be sure. There are examples in his own scripts that assign 2 on the same line, though only a few times this occurs.

i.e.
&strength = 3; &defense = 1;
"should" work, though more complex assignements that deal with references may be quirky.
sp_seq(&mouse, 0); sp_brain(&mouse, 13); sp_pseq(&mouse,10);
May be a challenge and should be coded as,
sp_seq(&mouse, 0);
sp_brain(&mouse, 13);
sp_pseq(&mouse,10);


Another point worth mentioning, when using compress to make .D files, it uses a pairing system to accomplish much of it's compression. White space within quotes will be packed as a literal string counting how many spaces there are, outside a string it is likely to choose the option that provides the most compression. That is, if you purposely leave extra white CRLF white space in a section, which should be parsed as a nop and allow the engine a few more slices to handle housekeeping chores, they may be ignored in the compression pairing, unless they have been marked with ; or { - } or //

Curly Braces:
If you are writing QBasic, in which line numbers not used by virtue of parsing CRLF to indicate a new line, then you could simply code without encapsulating your functions. However, in scripts that provide a function for multiple events: main(), talk(), hit(), for example, it can become important to identify where talk() ends, to prevent it from falling through and running hit(), as well. Sometimes it may function well but there is no guarantee it will continue to do so. We should not presume the parser will remember to compensate for our omissions every time, just because it did a few times. Do not code scripts to take advantage of a bug in the engine, such scripts could fail if that bug is fixed in an updated engine.

Again, we can always code using the goto format, which for specific things can be the best way to ensure that all paths are followed appropriately, but we must remember that a parsed language must read through the entire branch of code until it reaches the part it is to execute. In fact, imagine that line numbers are still required, for the sake of this discussion.

If we are on line 100 and "goto 250", it can count forward from 100 to 250. If however we are on line 250 and "goto 100", the parser cannot count down to 100, rather it starts counting from line 0 until it reaches 100, then executes. Though the parser uses white space and coding punctuations instead of line numbers, the process is the same. Goto is a command that allows a linear program to "appear to" mimic an oop object, but it is a much slower method than a true object.

The purpose of having a script refer to only 1 object and handle all of it's own properties, is to allow the message que to trigger the object to do it's own processing, rather than having a single script that must keep track of everything.

Anyone not encapsulating every object, as well as each of it's internal functions, within curly braces, is risking the introduction of bugs they couldn't imagine, including variable bleed through.

I'm open to be corrected on any part of this,

Mm.
January 9th 2016, 05:48 AM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
Let's try finding an instance where a "missing" semicolon fixes something in DinkC!
January 9th 2016, 12:12 PM
dinkdead.gif
millimeter
Peasant He/Him Canada
Millimeter is Wee-Lamm, Recording Artist. :-) 
Dinkvar.h
bool get_parms(char proc_name[20], int script, char *h, int p[10])
{
{

[Mm - snip]

line 5442 in notepadd++ reads,
if (h[0] == ';')
{
// Msg("Found ending ;");
h = &h[1];
} else
{
//Msg("Missing ; in %s, offset %d.", rinfo[script]->name, rinfo[script]->current);
// h = &h[1];
return(true);
}
return(true);
}
//got a parm, but there is more to get, lets make sure there is a comma there
strip_beginning_spaces(h);



Though in some cases, returning True "might" allow the absence of the ";" to "seemingly" go unnoticed, this is not assured. In this case, the ";" is not simply discarded but intended to be found. I would suspect if Seth wanted to simply discard it as unneeded, he would have coded it as;
replace(";", "",ev[1]);

in the same manner as he dealt with CR LF in

bool locate_goto(char proc[50], int script)
{
[mm - snip]
while(read_next_line(script, line))
{
strip_beginning_spaces(line);
get_word(line, 1, ev[1]);
replace("\n", "",ev[1]);


Further in the same file,
int process_line (int script, char *s, bool doelse)
{

the pass: label is at line 8740.
January 9th 2016, 07:40 PM
spike.gif
I'm coming at this from the perspective of a dirty greasemonkey who works with the car every day, rather than the fancypants engineer that designed the engine. The engineer might say putting little rivets everywhere could be a good idea, but goddammit, fancypants, I ain't got no tolerance for that crap that don't even do nothing!

...or in other words, while semicolons and brackets might serve a function in theory, in practise such cases never seem to come up. There's a limit to how much you should bend over backwards just to be on the safe side; adding hundreds of redundant symbols to every script is well over that threshold, IMO. 'Course, should the car ever actually break down because I'm not adding the rivets everywhere, I'd immediately stop this negligent practise.

Also, in Seth's original notes he said, that including multiple assignments on one line would likely work fine, but there were occasions the parser didn't read them right, and suggested to put one per line just to be sure. There are examples in his own scripts that assign 2 on the same line, though only a few times this occurs.

This is extremely limited. If I remember right, it only works with if>then statements, like 'if (&result == 1) &strength = 1' or 'if (&result == 2) unfreeze(1)'. '&strength = 3; &defense = 1; ' doesn't work, even adding a comment after a command often doesn't. (Although Seth does that a lot in his scripts. Something like '&strength = 10; //STRENGTH' seems fine, while 'say("a cat goes to town",1); //a cat, dammit' doesn't work.)

Another point worth mentioning, when using compress to make .D files, it uses a pairing system to accomplish much of it's compression. White space within quotes will be packed as a literal string counting how many spaces there are, outside a string it is likely to choose the option that provides the most compression. That is, if you purposely leave extra white CRLF white space in a section, which should be parsed as a nop and allow the engine a few more slices to handle housekeeping chores, they may be ignored in the compression pairing, unless they have been marked with ; or { - } or //

That's an interesting point. I've never tried .D compression on my scripts (since no one usually does that anymore when releasing dmods), but having tested it just now with my test dmod, it seems to work fine.

Curly Braces:
If you are writing QBasic, in which line numbers not used by virtue of parsing CRLF to indicate a new line, then you could simply code without encapsulating your functions. However, in scripts that provide a function for multiple events: main(), talk(), hit(), for example, it can become important to identify where talk() ends, to prevent it from falling through and running hit(), as well.


But brackets for opening and closing procedures don't seem to fulfil that role in DinkC. The line about herrings gets said in this script:
void talk
{
say("a cat goes to town",1)
wait(1500)
}
say("the cat eats a herring-flavoured curry sandwich",1)
void hit
say("AAAAA",1) 
blargh

As it does in this:
void talk
{
say("a cat goes to town",1)
wait(1500)
}
}
}
}
}}}}}

say("the cat eats a herring-flavoured curry sandwich",1)
void hit
say("AAAAA",1)
blargh

If the brackets had any actual function in closing the procedure, I would think the procedure should at least close when you DO use them. Instead, DinkC just ignores the brackets.

Sometimes it may function well but there is no guarantee it will continue to do so. We should not presume the parser will remember to compensate for our omissions every time, just because it did a few times. Do not code scripts to take advantage of a bug in the engine, such scripts could fail if that bug is fixed in an updated engine.

I haven't wrapped procedures in brackets for years and years, and haven't encountered one problem yet. I think it's a pretty safe assumption that it won't suddenly stop working. Furthermore, as long as we don't use brackets to close procedures, it couldn't possibly be changed in a future engine, because that would break backwards compatibility. It's a feature, not a bug.