ID:152023
 
Well I recently had a conversation about code examples and I want to understand why some people prefer completely "grammatically correct" code over shorter code that, to me, does the exact same thing. I myself prefer the shorter the better as long as (to me) it doesnt sacrifice what I consider to be the integrity or function of the code.

I'm calling it grammatically correct code but I don't know what the actual term would be.

I dont claim to be a professional at dm by far even though Im pretty sure I could make anything I wanted in it, but let me bring an example over here.

This is the typical code:
mob
proc
Attack()
for(var/mob/A in get_step(src,src.dir))
if(!src.KO&&!A.KO&&!src.attack)
src.attack=1
var/Damage=(src.Str/A.End)*rand(1,15) //Does 1 to 15% damage if equal strength and endurance
var/Evasion=(A.Spd/src.Spd)*50 //A 50% evasion chance if equal speeds
if(!prob(Evasion)) //Successful hit
step_away(A,src) //They are moved back by the force of your blow.
A.dir=turn(A.dir,180) //They automatically face you again after recovering from the blow
if(prob(src.Skill)) //Does a warp beside them if you can score successive hits and have the skill
src.loc=get_step(A,turn(A.dir,pick(-90,90,180))) //put them to the left/right/back of the target
step_towards(src,A) //Shortest method I know to have them now face the target
A.Health-=Damage
if(A.Health<=0)
A.KO()
else
flick('Dodge.dmi',A) //If not a successful hit, a successful dodge by them
sleep(20/src.Spd)
src.attack=0
mob
var
Spd=1 //speed allows you to land or dodge hits easier and faster
Str=1 //strength inflicts damage
End=1 //endurance reduces damage
Health=100 //health always maxes at 100, as in 100%
KO //If your knocked out or not


And this is how I prefer that same code, I find it just as readable and better because its shorter yet does the same things functionally speaking:
mob/proc/Attack() for(var/mob/A in get_step(src,dir)) if(!KO&&!A.KO&&!attack)
attack=1
var/Damage=(Str/A.End)*rand(1,15)
var/Evasion=(A.Spd/Spd)*50
if(!prob(Evasion))
step_away(A,src)
A.dir=turn(A.dir,180)
if(prob(Skill))
loc=get_step(A,turn(A.dir,pick(-90,90,180)))
step_towards(src,A)
A.Health-=Damage
if(A.Health<=0) A.KO()
else flick('Dodge.dmi',A)
spawn(20/Spd) attack=0
mob/var
Spd=1
Str=1
End=1
Health=100
KO
/*And yea there are no "You attacked successfully" or "You dodged" messages, because a landed
hit has a graphical representation of the opponent being knocked backwards, and a dodge has
a graphical representation of dodging. The text spam gets on my nerves is why*/


I explained why I prefer the second example, anyone care to explain why they prefer one over the other?

And yes I realize these are two different extremes of the same code with no mention of some method inbetween the two.

First example: 28 lines.
Second example: 20 lines.

Thats like a 30% reduction in game code length. If you have a massive project, to me thats a lifesaver, a difference between 10000 lines or 13000 lines. But I value the shortness (while keeping the same functions) over all else, so thats me. I also think its interesting to see the contrast between the two, and if anyone can show me a way to shorten it further please do so I can look at its awesome shortness. But only if the entire block of code is all in view without having to scroll horizontally. My habit is that if Im about to go out of horizontal view, its line break time, no matter what. Also in my DM preferences I have my tab spacing set to 1 <_< default is 4. So to me they look just like spaces. I do want to stress that the first and second code do the exact same thing and use the exact same arguments.
I agree with you. So long as you can catch any stray variable types, and don't lose any functionality, you might as well make it slimmer. The other day I went back over some old code I had done 4 months ago, and managed to cut it down from over 250 lines to 40, and then managed to cut that down to 26. That's nearly a 90% reduction! It's the difference between a 40MB game and a 4.4MB game!! (Well, kinda! =p)

~Ease~
And this is how I prefer that same code, I find it just as readable and better because its shorter yet does the same things functionally speaking:

Why is code better because it is shorter? If that's true then why don't you name all your variables with one character and compile your code in one line? The length of your code won't affect anything in your game.
Losing the src.stuff where it's redundant is all well and good. Likewise, compressing mob/proc/Attack() into one line is dandy. However your moving all those ifs and fors into one line isn't really doing much to reduce actual code length, only number of lines. At the same time you're sacrificing readability.

Now when your code is starting to get to the point of 8-10 indents, I agree it's time to start looking for alternatives. However you're not at that point, and putting mob/proc/Attack() into one line already saves you two tabs.

Also where readability is concerned, both versions are light on meaningful whitespace. The bunched-up code is harder to read. Remember the axiom: It's easier to write code than read it. If you ever need to go back to your own code someday you need to make it readable.

In addition, I'd change A to M as far as var names go, because A looks like it's meant to mean "attacker" when it's really just one of the mobs being attacked.

Lummox JR
While I tend to make the actual operations short, my code is often very long. I place whitespaces throughout, to indicated where relevant sections of code are grouped. I also tend to have self-documenting code, meaning the names of the variables and procs are descriptive enough that you can figure out what their used for. Of course, I should provide comments on how the actual algorithms work, because sometimes I go back and get confused.

For example, here's a fairly typical example of how I program:
proc/parse_escape_sequences(string)
var
length = length(string)

previous = 1
a = 1
for(a, a <= length, a ++)
if(text2ascii(string, a) == 92)
. += copytext(string, previous, a)

var/suppression
switch(text2ascii(string, a + 1))
if(32) continue // space
if(34) . += "\"" // "
if(60) . += "\<" // <
if(62) . += "\>" // >
if(91) . += "\[" // [
if(92) . += "\\" // backslash
if(110) . += "\n" // n
if(116) . += "\t" // t
if(46) // newline suppression
if(text2ascii(string, a + 2) == 46 && text2ascii(string, a + 3) == 46)
. += "\..."
suppression = 1

else CRASH("Unknown escape sequence (\"\\[copytext(string, a + 1, a + 2)]\") found.")
else CRASH("Unknown escape sequence (\"\\[copytext(string, a + 1, a + 2)]\") found.")

previous = a + (suppression ? 4 : 2)
a += suppression ? 3 : 1

. += copytext(string, previous)
In response to Ease
Ease wrote:
It's the difference between a 40MB game and a 4.4MB game!! (Well, kinda! =p)

No. It's not.

Readability is paramount. If you think that crammingeverythingtogetherwithoutanygoddamnedwhitespaceisago odidea then go ahead and do that but, quite frankly, keep that crap off the forums. It's not helpful.
In response to Garthor
Garthor wrote:
Readability is paramount. If you think that crammingeverythingtogetherwithoutanygoddamnedwhitespaceisago odidea then go ahead and do that but, quite frankly, keep that crap off the forums. It's not helpful.

Call me in-human, but I read that perfectly fine. I'm no super computer or someone who reads books and other things all the time, but thats pretty easy to decipher. There was no delay when I looked at it. I wasn't going "Hmm whats this word." I'd say this "readability" factor is only one to those that have issues reading (in a sense that it has to be nearly perfect for you to read). It's probably just because my handwriting is so horrible and sometimes crammed together that I can do this though. Even so, there's no readability factor to me. So I say, cut that code down. The quote that Lummox brought up really doesn't seem right. If you can write the code, then you can read it. Otherwise, you didn't write it correctly or you didn't know what you were doing while you did it. It may be harder for some of you, but seeing as its perfectly fine for me I would say, don't call him up on this "readability" factor. If he can read it then he's fine. Don't place your own coding issues with him.

Lastly, I'm unbiased on this topic. I love short code for, the oh-so-not-obvious-reason, of being short. But I'm also someone who likes organization and for that I like the original "grammatically" correct code as he called it. It adds organization and just looks nice, but that's just something I like about it. Partially OCD about things like that. So really, its just on your opinion. Neither one is any better than the other. Unless you have a problem reading code or you're OCD, then you should be fine with either. So you can be like me, and just use both. Cram it together, but space out parts so that each important zone is together, similar to what Popisfizzy did (white spotting) but also with the if's and fors 1 lined if possible (unless there's a lot of things but something simple like "for(var/mob/blah) if(blah.name == "Lummoxiscool") blah.verbs += /mob/lummoxonly/verb/Show_Us_How_To_Code_Properly" then I would 1 line it.

Sorry for ranting, mine's just one opinion and no one's probably actually going to read it all, but oh well, I have reached out!
In response to VcentG
Muybien,asíqueustedpuedeleeralgoenunalenguaqueustedhahablado porañosylosañosylosaños,sisequitaelwhitespace.Buenoparausted .¿Pero…quésiesunalenguaustednosabe?Yelesloqueestamosdiscutiend o,aquí.Gentedon'tsabelalenguabien,asíqueellanecesitaejemplos buenos,legibles.Enteramentedesemejantedeesto.

The code is not being written for you, it's being written for people who DON'T KNOW THE LANGUAGE. Making it harder for them to understand it because you don't have trouble understanding it (bonus: you wrote the damn thing yourself, of COURSE you understand it) is entirely goddamn stupid and - once again, because people here never seem to learn - entirely missing the point.
In response to Garthor
When you code, its being made for your game. Thus no one else needs to understand it aside from you. Hence why shortening it is entirely up to you.
In response to VcentG
First of all: we're discussing code being posted on the forum, because this thread was inspired by Dragonn repeatedly being told that unreadable code isn't needed.

Second: it doesn't matter if you "have no trouble", because we're not talking about you right now, we're talking about you in the future, trying to read through old code and figure out what it's doing. Cramming code together serves ZERO purpose except to make it harder to read and "LAWL COMPACT I M KEWL".

Take a dump all over your own code, if you must, but keep it off the forum.
In response to Garthor
I never said "get rid of all the white-space" - I'd never do that. I'm an indentation-obsessive. All my code is neatly spaced out and commented, but if I can see a way of doing something that can be done in a LOT less lines then I'll redo the code.

~Ease~
In response to VcentG
VcentG wrote:
Garthor wrote:
Readability is paramount. If you think that crammingeverythingtogetherwithoutanygoddamnedwhitespaceisago odidea then go ahead and do that but, quite frankly, keep that crap off the forums. It's not helpful.

Call me in-human, but I read that perfectly fine. I'm no super computer or someone who reads books and other things all the time, but thats pretty easy to decipher. There was no delay when I looked at it. I wasn't going "Hmm whats this word." I'd say this "readability" factor is only one to those that have issues reading (in a sense that it has to be nearly perfect for you to read). It's probably just because my handwriting is so horrible and sometimes crammed together that I can do this though. Even so, there's no readability factor to me. So I say, cut that code down. The quote that Lummox brought up really doesn't seem right. If you can write the code, then you can read it. Otherwise, you didn't write it correctly or you didn't know what you were doing while you did it. It may be harder for some of you, but seeing as its perfectly fine for me I would say, don't call him up on this "readability" factor. If he can read it then he's fine. Don't place your own coding issues with him.

The quote is quite correct in its point. Yes, you can read your own code that you just wrote, but if you return to that code a month later, will it still make sense? How about 6 months? I've returned to my code sometimes years later only to try to figure out what the heck I was thinking.

Trust me on this: The profound truth of that statement becomes clear with experience.

Lummox JR
In response to Lummox JR
Yeah, the code still looks the same. I have codes from over a year ago and I still pick 'em up. So I still side with what I said earlier, because for me its been the same. However, maybe it changes at the 5 year mark or the 10 year mark. So far for me it hasn't at the 3 years. (I feel old! I just realized I've been on byond for 4 years now. I know that's not a lot compared to some of you but I didn't know its been that long lol)
In response to VcentG
If I return to code I did 2 years ago yes, it sucks, but I can still read it. But I can read my compressed code better because thats -my- style, I can read my style better than anyone else's.

As said all this is merely preferences, I just want to know opinions of others here because I'm bored.

Code I did 6 months ago only has a few minor changes to my style, but is still very much readable to me.

And I didnt think to say what Vcent said, but that is also my opinion. The compression of a code's size or how many things are in 1 line dont affect the readability of it for me

The standard style of code is taking too much room vertically and uneccessarily ignoring room that is still left horizontally on the visible page, just seems like a waste.
In response to Garthor
Point taken, its to help them. I'm going to start using the generic coding style for examples but then include a bonus compressed version of it to show them that all the tabs arent -required- in the code, like I used to think when I started, and it confused me.
In response to Dragonn
I tend to use { ; } alot and compress mostly as much as I can.
I do that becvause I like it, and the fact that I use { ; }, is because I've a widescreen and I find it pretty unecessary to make it al readable. Garthor did make a point, for the people who need help and are pretty much new, it's better for them to make it more readable, but for yourself, and if you can, I'd say, shorten the **** out it.
In response to Popisfizzy
I havnt read any of the other comments but I'm with Popisfizzy on this one.

I personally always use spaces in my code and make sure im able to read it back without much comments needed.
Neither of the two ways of coding are better than the other I guess it's just what you prefer.

Besides, I think there is also a big difference between code that one person uses or code that a team is supposed to work on.
In response to Lummox JR
Bash.org summarises this nicely:

<@Logan> I spent a minute looking at my own code by accident.
<@Logan> I was thinking "What the hell is this guy doing?"

Eight years of programming in BYOND has given me a fairly nice syntax. I can compare the syntax of the very first code I wrote:

mob
eye
tester
name = "Spuzzum"
key = "Spuzzum"
Login()
..()
verb
teleport(x as num, y as num, z as num)
usr.loc = locate(x,y,z)
terminate_ant(mob/ant/M in view())
del M
reboot()
set category = "debug"
world << "\red Warning: Spuzzum is rebooting the world.\red"
world << "\red --5--\red"
sleep(10)
world << "\red --4--\red"
sleep(10)
world << "\red --3--\red"
sleep(10)
world << "\red --2--\red"
sleep(10)
world << "\red --1--\red"
sleep(10)
world << "\red Please be patient, as the world can take a short \
while to reload. If BYOND freezes, quit, then rejoin.\red"

world.Reboot()
readmail()
set category = "debug"
var/spuzzmail = file2text("spuzzmail.txt")
usr << "\n"
usr << "------------------------------------------------------"
usr << spuzzmail
usr << "------------------------------------------------------"
worldsay(T as text)
set category = "debug"
world << "Spuzzum: \"[T]\""
mobsay(M as mob in world,T as text)
set category = "debug"
M << "Spuzzum to [M]: \"[T]\""
Who()
var/mob/eye/M
usr << "Online at present: "
for(M in world)
usr << " - [M.name]"
usr << "\n"
return
create_queen()
var/mob/ant/royal/queen/O = new (src.loc)
O.ChangeColour("black")
O.owner = src


with some of the syntax of the more modern (unrelated) code that I write:

mob/char
var/list/status = list()

proc/Status(status_type)
if(status.Find(status_type))
var/associated = status[status_type]
if(associated) return associated
return 1
return 0

proc/AddStatus(status_type)
var/status/status_ref = GetStatus(status_type)
if(!status_ref) return 0
if(!status_ref.Precondition(src)) return 0

if(status_ref.frequency == INTERVAL_SEGMENT)
TASK_HANDLER.RegisterCharacterForSegments(src)
else if(status_ref.frequency == INTERVAL_TICK)
TASK_HANDLER.RegisterCharacterForTicks(src)

if(status.Find(status_type))
var/current = status[status_type]
status[status_type] = current+1
else
status += status_type

status_ref.Add(src)
return 1


proc/RemoveStatus(status_type)
var/status/status_ref = GetStatus(status_type)
if(!status_ref) return 0

if(status.Find(status_type))
var/current = status[status_type]
if(current > 1)
status[status_type] = current-1
else
status -= status_type

if(status_ref.frequency == INTERVAL_SEGMENT)
TASK_HANDLER.DeregisterCharacterForSegments(src)
else if(status_ref.frequency == INTERVAL_TICK)
TASK_HANDLER.DeregisterCharacterForTicks(src)

status_ref.Remove(src)

return 1

return 0


...and see an obvious improvement in both appearance and clarity (old-skool insistence on list.Find() notwithstanding). Seeing this particular snippet several months later, however, it does take me a few seconds to understand it; I used no comments in that code, and I should have.
I like kicking it old school

proc{

DenseView(var/Depth, var/Center){
//Input: The depth to search and a center focus
//Output: A list of tiles immediately accessible without obstructions

var/list/InitialView = view(Depth, Center);
var/list/Changes = list();

for(var/turf/Target in InitialView){
if(IsDense(Target.x, Target.y, Target.z) && !IsOpague(Target.x, Target.y, Target.z)){
Target.opacity = ON; //temporary
Changes += Target;
}

}

.=view(Depth, Center); //conduct a view again with the new opacities set.

for(var/turf/Target in Changes){
Target.opacity = OFF; //very important to turn off the opacities again.
}

}
}


a reimplementation of a widely used snippet
In response to Obs
i thought i was looking at C++ for a min with all the {'s and }'s o.o
Page: 1 2 3