ID:1723173
 
A lot of times you'll see people write code that is more efficient because it executes fewer commands. Maybe something like this:
procName()
mob.someVar = mob.proc1() * mob.proc3()
return mob.proc2()

Looking at that code, maybe you can guess that proc1() and proc3() return numerical values, and whatever proc2() returns is god knows what. Only the initial programmer would know. But for the sake of maintaining code over generations of edits, such shorthand notation isn't always better. You'll come back to it some 2+ months later and think, "What the shell was going on here? What do these functions even mean?" and even if you've left comments like what the procs return, you still need to figure out why you're doing what you're doing and what its overall impact is.

This is why I think that fundamentally, a little bit of step-by-step goes a long way (in the "long-run", so to speak).

rewriting that original code from before
procName()
q1 = mob.proc1() // Naturally you need comments
q2 = mob.proc3()
mob.someVar = q1 + q2
return mob.proc2() // Can't think of a good example for this atm.

This is really just a limited example I came up with right before class, but stew on this a bit. I personally believe that it's easier to follow, especially if you're working with other programmers on your game. Sure, it's less efficient, but it lets you know what you're doing with what you're doing.
Strangely enough, the examples you have presented here are somewhat irrelevant to the point you are trying to make.

In most cases, if you are dealing with a complex procedure with multiple loops, then your second example will always be more efficient than the first. Being more modular and readable is actually just an added side effect in this case. Think about what is going on here. If you added a loop to the first example, you would be calling mob.proc1() and mob.proc3() over and over again. If you added a loop to the second example, those procs would only be called once, because you are storing the return values for reuse later on. While this doesn't really apply to a proc that simple, it's still a valid point to make.

What I'm trying to say is that the second example is more efficient, more readable, and more modular than the first when you scale the procedures up to a more realistic complexity, so there is really no point at all to ever worry about the first example.
In response to Multiverse7
Multiverse7 wrote:
If you added a loop to the second example, those procs would only be called once

Only if proc1() and proc3() would return the same value every time during the loop...
In response to Magicsofa
It really depends on the intended purpose of the procedures and the return values they produce. I have found it to be sufficiently common for loops to make use of values that are determined outside of the loop, such that it makes sense to use the same style for regularly changing variables, just for consistency. It's also important to keep in mind that in the case of nested loops, variables can be constant relative to an inner loop, but changing relative to an outer loop. It's best to try to expect the unpredictable when you are programming something, because it might have to change later on.
If you name your procs and vars correctly, the first example is better because it takes less time to read.
procName()
q1 = mob.proc1() // Naturally you need comments
q2 = mob.proc3()
mob.someVar = q1 + q2
return mob.proc2() // Can't think of a good example for this atm.


This is .. quite .. difficult to read compared to your first example and does addition not multiplying like the first example..

procName()
mob.someVar = mob.proc1() * mob.proc3()
return mob.proc2()


This is easy to read.

  q1 = mob.proc1() // Naturally you need comments
q2 = mob.proc3()
mob.someVar = q1 + q2


This is utterly confusing not only does it do the same thing (except it's not multiplying like the first snip) it's a waste of time and space. It's not beneficial to anyone to change from a one liner to this .. thing ..
In response to A.T.H.K
The problem is that this is a really bad example, and you seem to be taking it literally, which is not how it was intended (I hope).

If this were real code, then I would certainly prefer the one-liner.
In response to Multiverse7
Multiverse7 wrote:
The problem is that this is a really bad example,

Agreed

and you seem to be taking it literally, which is not how it was intended (I hope).

I was taking it literally in a real world setting, yes.

If this were real code, then I would certainly prefer the one-liner.

Seems not everyone would.

I guess I'm just used to strict programming standards where comments & human readability comes first..

In the end you want to write your code so any person can read it and say ok, this does this and that and returns this then does that.

Thus making it as easy as possible for them to understand and make changes if necessary.
Efficiency only goes so far, I'd rather have code look good and function properly than to try and optimize it as much as I possibly could. But in the end there's always room for improvement.
Laser50 wrote:
Efficiency only goes so far, I'd rather have code look good and function properly than to try and optimize it as much as I possibly could. But in the end there's always room for improvement.
Note that in some places, speed trumps everything else, including maintainability, readability, modularity, stability, OOP, etc.
And sometimes there is no room for improvement.

Also, the point at which quality vs speed becomes a zero-sum game (must sacrifice one to improve the other) is different for every language.

The prime example is procedure call overhead.
Having tail-call optimization raises the bar by allowing recursion as a viable low-level problem-solving technique, making code much more elegant in certain places.
And having an inline directive makes heavy use of helper procs viable in tight spots, making performance-critical code far more readable, maintainable, and compact.

Posted this because I've seen some ...misguided individuals assert that such features are "not suited" for DM/BYOND quite a few times on these forums.
Lugia319 wrote:
You'll come back to it some 2+ months later and think, "What the shell was going on here? What do these functions even mean?"

Only if you gave your methods useless names. Spending time naming your methods properly should rule out the need for any comments on what they do.

A lot of people write useless comments that could have been avoided.
GatewayRa wrote:
You see, that's exactly what he did with the examples he posted. proc1, proc2, someVar, all of each given no implication what the code is doing with his recommended example being less than ideal.

Shall I use the traditional proc/var names from programming websites? I guarantee at least half of the PHP references (and probably some of the DM guide) use
proc/foo()
world << "bar"

proc/Text2World()
var/foo = "foo"
var/bar = "bar"
var/foobar = foo + bar
world << foo
world << bar
world << foobar


Even properly named procedures still need comments along the code, especially when working with a group. Because what's obvious to you might not be obvious to me or to my sister or to my cat.

The long and short of it is, it's not a crime to have 2 more commands in your loop that iterates 100 times because 200 commands is NOTHING compared to the 1 GHz processors+ everyone is running these days. It's okay to not abuse short-circuiting to reduce CPU time. It's more important for code to be readable and easily modified than it is for it to run .00002 seconds faster.
In response to Lugia319
If you can't understand what this is:

var/circumference = pi() * radius ** 2

You shouldn't be programming. I don't have to foolishly comment everything if I name things properly.

var/circumference = pi() * radius ** 2 // Get the circumference.

Don't be asinine.
In response to Zecronious
Zecronious wrote:
If you can't understand what this is:

> var/circumference = pi() * radius ** 2
>

You shouldn't be programming. I don't have to foolishly comment everything if I name things properly.

> var/circumference = pi() * radius ** 2 // Get the circumference.
>

Don't be asinine.

Circumference is probably something that would better be put as an instance variable of the circle object than something you get through function because you should only be computing it once.

#JustSaiyan

In response to Lugia319
I thought you said it doesn't matter, it's just an example? Don't be hypocritical.
In response to Zecronious
Zecronious wrote:
I thought you said it doesn't matter, it's just an example? Don't be hypocritical.

I thought you said it does matter? Don't be hypocritical.
In response to Lugia319
No that was GatewayRa.
GatewayRa wrote:
You have not defined proc1 or proc3 in your code, there is 0 inference about your codes functionality, and the fact you're arguing the second example conveys that better is baffling.

Presumably the comments stated would cover that for you, but I guess we lowly C++ programmers can't handle you pro DM programmers. In every C++ program I've ever read or written we have

////////////////////////////
// Banners like this that //
// tell you what the code //
// does for every method //
// as well as what the //
// parameters needed are //
////////////////////////////

But my b. DM doesn't need pre/post conditions because the function name tells you everything. What it returns and what's needed as input. 2legit2quit.
In response to Lugia319
You're a C++ programmer?

GatewayRa wrote:
That's the most obnoxious thing you've ever side alongside your recommendation to use less efficient and less compact code over a single statement.

I pride myself on being obnoxious. Nay, I go out of my way to be even more obnoxious, as it provides me with more amusement (and the forums with more drama). And it is better to use less efficient and less compact code over single statements for the sake of readability.

// But just for you

threadbare
for(var/I = 0 ; I <= 23 ; I++)
j++
Nazis
for(j, ; j > 12 ; j++)
if(I < 10) goto Nazis
if(j > I) goto threadbare
world << I
world << j
Page: 1 2