|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
On January 21 2013 14:16 AmericanUmlaut wrote:I read this when you posted it, and it's been bothering me ever since. I very, very strongly disagree with several of the points that are made in the Kotaku article. Two that stand out to me especially: 1. The author makes a big deal about how much better public properties are than private properties combined with getters and setters. This is, at best, a very situational decision to make. There are certainly advantages in using public properties, and I don't disagree with the advantages that he points out (readability and avoiding unnecessary code clutter), but they also make some problems. Adding a trigger that fires whenever a certain value changes is trivial when you already have setters for all of your class properties, but changing a class to use a setter instead of a public property can be nearly impossible - try searching your source code for all the instances of ".name =", then verifying that every variable does in fact refer to an instance of the correct class. My other problem with public properties is language-specific. In C, which is the language in discussion in the article, strong typing gives you a fair bit of validation baked into the language, since the compiler won't let you set an int to a string. In languages like PHP or Javascript that are not strongly typed, though, using setters allows you to add validation that is otherwise impossible, which is a really easy way to prevent some trivial programmer errors. 2. This one I really hate: The article's author poo-poos comments. Good code should be self-documenting, he says, and then uses an example of a horrible comment to explain why we shouldn't use comments at all. The fact of the matter is, there are an immense number of things that programmers write every single day that are simply not human parsable without at least a bit of thinking, and saying any code that requires a comment is probably badly written is utterly ridiculous. There is a huge difference between the example of bad commenting in the example, which looks like something a freshman who was just told to comment her code would write, and the sort of helpful comments that make code more readable and reduce the time it takes another programmer to understand it. Seriously, this one completely infuriates me. Writing good comments is, in my mind, as important and sometimes as difficult to do well, as writing good code. Writing code that does its job is fairly easy - a large part of a programmer's job in writing code is not to communicate to the computer, but to communicate to a human reader, and good comments are immensely helpful in that task. Yeah, the author definitely has a lot of misguided generalizations. His point about using public variables instead of getters/setters for things that don't require extra logic is valid, but for a lot of languages that don't actually have built-in properties this can heavily limit how you can change code down the line (this is the reason people are often taught to *always* make getters/setters, even though a lot of the people teaching this also don't realize that ). Strong/weak-typing doesn't really play too much into it, the major thing is that myObj.myVar = x; is different from myObj.myVar(x); and requires code changes outside of your class (and often in 3rd party code that you don't control) in order to refactor.
As for comments, I basically agree with you. Saying that code can always stand on its own just means you haven't had to work on anything reasonably complex. The important thing to remember is that comments can also make code *less* readable, which is something many people neglect to consider. The communication point is an interesting one, Carmack actually dwelled on this a bit in his 2012 QuakeCon keynote:
At QuakeCon 2012 John Carmack said: In reality in computer science, just about the only thing that’s really science is when you’re talking about algorithms. And optimization is an engineering. But those don’t actually occupy that much of the total time spent programming. You know, we have a few programmers that spend a lot of time on optimizing and some of the selecting of algorithms on there, but 90% of the programmers are doing programming work to make things happen. And when I start to look at what’s really happening in all of these, there really is no science and engineering and objectivity to most of these tasks. You know, one of the programmers actually says that he does a lot of monkey programming—you know beating on things and making stuff happen. And I, you know we like to think that we can be smart engineers about this, that there are objective ways to make good software, but as I’ve been looking at this more and more, it’s been striking to me how much that really isn’t the case.
Aside from these that we can measure, that we can measure and reproduce, which is the essence of science to be able to measure something, reproduce it, make an estimation and test that, and we get that on optimization and algorithms there, but everything else that we do, really has nothing to do with that. It’s about social interactions between the programmers or even between yourself spread over time. (more full transcription here)
|
On January 21 2013 14:16 AmericanUmlaut wrote:I read this when you posted it, and it's been bothering me ever since. I very, very strongly disagree with several of the points that are made in the Kotaku article. Two that stand out to me especially: 1. The author makes a big deal about how much better public properties are than private properties combined with getters and setters. This is, at best, a very situational decision to make. There are certainly advantages in using public properties, and I don't disagree with the advantages that he points out (readability and avoiding unnecessary code clutter), but they also make some problems. Adding a trigger that fires whenever a certain value changes is trivial when you already have setters for all of your class properties, but changing a class to use a setter instead of a public property can be nearly impossible - try searching your source code for all the instances of ".name =", then verifying that every variable does in fact refer to an instance of the correct class. My other problem with public properties is language-specific. In C, which is the language in discussion in the article, strong typing gives you a fair bit of validation baked into the language, since the compiler won't let you set an int to a string. In languages like PHP or Javascript that are not strongly typed, though, using setters allows you to add validation that is otherwise impossible, which is a really easy way to prevent some trivial programmer errors. 2. This one I really hate: The article's author poo-poos comments. Good code should be self-documenting, he says, and then uses an example of a horrible comment to explain why we shouldn't use comments at all. The fact of the matter is, there are an immense number of things that programmers write every single day that are simply not human parsable without at least a bit of thinking, and saying any code that requires a comment is probably badly written is utterly ridiculous. There is a huge difference between the example of bad commenting in the example, which looks like something a freshman who was just told to comment her code would write, and the sort of helpful comments that make code more readable and reduce the time it takes another programmer to understand it. Seriously, this one completely infuriates me. Writing good comments is, in my mind, as important and sometimes as difficult to do well, as writing good code. Writing code that does its job is fairly easy - a large part of a programmer's job in writing code is not to communicate to the computer, but to communicate to a human reader, and good comments are immensely helpful in that task. As for 1) considering he was talking about strongly-typed languages and specifically C/C++ his comment is I would say a matter of opinion and I somewhat agree with it actually. In those languages good IDE allows you to find all references reasonably easily without even using search. But that is neither here nor there. In my opinion what swings it towards him being right for C/C++ is the fact that those languages have no nice support for properties and in that case the positives outweigh the risk. Basically coding conventions depend on the language in question, not really a surprise 
As for 2) I agree with you. But Doom3 code is actually commented reasonably well, so maybe he meant to not use useless comments, but then he wrote it extremely unclearly.
|
On January 21 2013 15:01 tec27 wrote:Show nested quote +On January 21 2013 14:16 AmericanUmlaut wrote:I read this when you posted it, and it's been bothering me ever since. I very, very strongly disagree with several of the points that are made in the Kotaku article. Two that stand out to me especially: 1. The author makes a big deal about how much better public properties are than private properties combined with getters and setters. This is, at best, a very situational decision to make. There are certainly advantages in using public properties, and I don't disagree with the advantages that he points out (readability and avoiding unnecessary code clutter), but they also make some problems. Adding a trigger that fires whenever a certain value changes is trivial when you already have setters for all of your class properties, but changing a class to use a setter instead of a public property can be nearly impossible - try searching your source code for all the instances of ".name =", then verifying that every variable does in fact refer to an instance of the correct class. My other problem with public properties is language-specific. In C, which is the language in discussion in the article, strong typing gives you a fair bit of validation baked into the language, since the compiler won't let you set an int to a string. In languages like PHP or Javascript that are not strongly typed, though, using setters allows you to add validation that is otherwise impossible, which is a really easy way to prevent some trivial programmer errors. 2. This one I really hate: The article's author poo-poos comments. Good code should be self-documenting, he says, and then uses an example of a horrible comment to explain why we shouldn't use comments at all. The fact of the matter is, there are an immense number of things that programmers write every single day that are simply not human parsable without at least a bit of thinking, and saying any code that requires a comment is probably badly written is utterly ridiculous. There is a huge difference between the example of bad commenting in the example, which looks like something a freshman who was just told to comment her code would write, and the sort of helpful comments that make code more readable and reduce the time it takes another programmer to understand it. Seriously, this one completely infuriates me. Writing good comments is, in my mind, as important and sometimes as difficult to do well, as writing good code. Writing code that does its job is fairly easy - a large part of a programmer's job in writing code is not to communicate to the computer, but to communicate to a human reader, and good comments are immensely helpful in that task. Yeah, the author definitely has a lot of misguided generalizations. His point about using public variables instead of getters/setters for things that don't require extra logic is valid, but for a lot of languages that don't actually have built-in properties this can heavily limit how you can change code down the line (this is the reason people are often taught to *always* make getters/setters, even though a lot of the people teaching this also don't realize that  ). Strong/weak-typing doesn't really play too much into it, the major thing is that myObj.myVar = x; is different from myObj.myVar(x); and requires code changes outside of your class (and often in 3rd party code that you don't control) in order to refactor. As for comments, I basically agree with you. Saying that code can always stand on its own just means you haven't had to work on anything reasonably complex. The important thing to remember is that comments can also make code *less* readable, which is something many people neglect to consider. The communication point is an interesting one, Carmack actually dwelled on this a bit in his 2012 QuakeCon keynote: Show nested quote +At QuakeCon 2012 John Carmack said: In reality in computer science, just about the only thing that’s really science is when you’re talking about algorithms. And optimization is an engineering. But those don’t actually occupy that much of the total time spent programming. You know, we have a few programmers that spend a lot of time on optimizing and some of the selecting of algorithms on there, but 90% of the programmers are doing programming work to make things happen. And when I start to look at what’s really happening in all of these, there really is no science and engineering and objectivity to most of these tasks. You know, one of the programmers actually says that he does a lot of monkey programming—you know beating on things and making stuff happen. And I, you know we like to think that we can be smart engineers about this, that there are objective ways to make good software, but as I’ve been looking at this more and more, it’s been striking to me how much that really isn’t the case.
Aside from these that we can measure, that we can measure and reproduce, which is the essence of science to be able to measure something, reproduce it, make an estimation and test that, and we get that on optimization and algorithms there, but everything else that we do, really has nothing to do with that. It’s about social interactions between the programmers or even between yourself spread over time. (more full transcription here) Funny how we used the same thing (lack of property support) to reach completely opposite conclusions . So to clarify I think using getters and setters AS DEFAULT in C/C++ is not a good idea. Because the lack of support means they are "cluttery" and annoying. But you should use them in cases when it makes sense, basically when there is possibility that the change would mean too much work. Like points of communication with external world, or even if it makes sense inside the project in some rare circumstances.
|
Hihi,
I'm doing another assignment. It's a simple website that uses an sql database.
Using a repeater I list all students on a particular course (eg history).
I want to stick a button inside the repeater, allowing you to remove a given student from his (single) course.
(this is not part of the assignment, the marking guide just wants us to be able to remove a student using only his courseID (rather than using his studentID and his courseID, however that would work - i guess in a single-table database?)
I tried copying http://stackoverflow.com/questions/8225877/repeater-internal-textbox-in-oncommand-event amongst other things and eventually got it to run (by adding "private" to the start of the function rather than just calling it "void .." , lol).
So amazingly it runs but the buttons still remove EVERY student from a course rather than just the one student next to the button in the repeater...
Here's a ss to give a clearer picture of what i'm trying to do.. + Show Spoiler +
Here's the code I have (though its working just the same as it was before I changed it to look like this, copying the above link)
+ Show Spoiler +
<asp:Repeater id="StudentOnCourseRepeater" runat="server" OnItemCommand="R1_ItemCommand"> <ItemTemplate> <p> First Name: <%# Eval("StudentFirstName") %> <br /> StudentSurname: <%# Eval("StudentSurname") %> <br /> StudentCourse: <%# Eval("CourseID") %> <br /> StudentCourseName: <%# Eval("CourseName") %><br /> <asp:Button ID="btnRem" runat="server" Text="Remove from course" CommandName="cmd" CommandArgument='<%#Eval("CourseID") %>' ></asp:Button> </p> </ItemTemplate>
</asp:Repeater>
.
protected void R1_ItemCommand(Object Sender, RepeaterCommandEventArgs e) { if(e.CommandName=="cmd") { DataTable dt = new DataTable();
SqlConnection dbconn = new SqlConnection(connectionString); dbconn.Open();
SqlCommand sqlCom = new SqlCommand("UPDATE Students SET Students.CourseID='27'", dbconn);
sqlCom.ExecuteNonQuery();
dbconn.Close(); } }
(note i set the studen'ts courseID to 27 here instead of simply deleting it. 27 can be a blank entry or say "no course" or whatever) All code for both pages: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="studentsOnCourse.aspx.cs" Inherits="EnrolmentSystemWeb.studentsOnCourse" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> Student ID: <asp:TextBox ID="txtStudentID" runat="server"></asp:TextBox> Course ID: <asp:TextBox ID="txtCourseID" runat="server"></asp:TextBox> <br /> <asp:Button ID="btnGet" runat="server" Text="Get from CourseID" onclick="btnGet_Click" /> <br /><br /> <asp:Repeater id="CourseInfoRepeater" runat="server"> <ItemTemplate> <p> Course ID: <%# Eval("CourseID") %> <br /> Course Name: <%# Eval("CourseName") %> <br /> </p> </ItemTemplate> </asp:Repeater> <asp:Repeater id="StudentOnCourseRepeater" runat="server" OnItemCommand="R1_ItemCommand"> <ItemTemplate> <p> First Name: <%# Eval("StudentFirstName") %> <br /> StudentSurname: <%# Eval("StudentSurname") %> <br /> StudentCourse: <%# Eval("CourseID") %> <br /> StudentCourseName: <%# Eval("CourseName") %><br /> <asp:Button ID="btnRem" runat="server" Text="Remove from course" CommandName="cmd" CommandArgument='<%#Eval("CourseID") %>' ></asp:Button> </p> </ItemTemplate>
</asp:Repeater> <br /><br /> <a href="Default.aspx">Main Menu</a> <br /><br /> </div> </form> </body> </html>
----------------------------------------------------------------------------------------------
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Data;
namespace EnrolmentSystemWeb { public partial class studentsOnCourse : System.Web.UI.Page { private string connectionString = "user id=TestUser;password=password;server=PERCY-PC\\SQLEXPRESS;Trusted_Connection=yes;database=EnrolmentSystem";
protected void Page_Load(object sender, EventArgs e) {
DataTable dt = new DataTable();
SqlConnection dbconn = new SqlConnection(connectionString);
dbconn.Open();
SqlDataAdapter sqlAdapt = new SqlDataAdapter("SELECT * FROM Courses", dbconn);
sqlAdapt.Fill(dt);
dbconn.Close();
CourseInfoRepeater.DataSource = dt; CourseInfoRepeater.DataBind(); }
protected void R1_ItemCommand(Object Sender, RepeaterCommandEventArgs e) { if(e.CommandName=="cmd") { DataTable dt = new DataTable();
SqlConnection dbconn = new SqlConnection(connectionString); dbconn.Open();
SqlCommand sqlCom = new SqlCommand("UPDATE Students SET Students.CourseID='27'", dbconn);
sqlCom.ExecuteNonQuery();
dbconn.Close(); } }
/* protected void btnRem_Click(object sender, EventArgs e) { DataTable dt = new DataTable();
SqlConnection dbconn = new SqlConnection(connectionString); dbconn.Open();
SqlCommand sqlCom = new SqlCommand("UPDATE Students SET Students.CourseID='27'", dbconn);
sqlCom.ExecuteNonQuery();
dbconn.Close();
}*/
protected void btnGet_Click(object sender, EventArgs e) { DataTable dt = new DataTable(); int CourseID = Convert.ToInt32(txtCourseID.Text); SqlConnection dbconn = new SqlConnection(connectionString); dbconn.Open();
// SqlDataAdapter sqlAdapt = new SqlDataAdapter("SELECT * FROM Courses INNER JOIN Students ON Courses.CourseID=Students.CourseID WHERE CourseID=" + CourseID, dbconn);
SqlDataAdapter sqlAdapt = new SqlDataAdapter("SELECT * FROM Students INNER JOIN Courses ON Students.CourseID=Courses.CourseID WHERE Courses.CourseID=" + CourseID, dbconn);
sqlAdapt.Fill(dt);
dbconn.Close();
StudentOnCourseRepeater.DataSource = dt; StudentOnCourseRepeater.DataBind(); } } }
I guess it wont run for you thought since you dont have the sql database made. Its 2 tables, one with StudentID StudentFirstName Surname CourseID, and another with CourseID CourseName TutorName .
I'm gonna keep looking for a better guide/example, coz I think I'm kinda close - though its not working one bit, it does run at least looking like that. I'm surprised it works to the extent that it does, but anyway :p
Edit okay i have this and it looks like its working :o + Show Spoiler +
protected void R1_ItemCommand(Object Sender, RepeaterCommandEventArgs e) { if(e.CommandName=="cmd") { DataTable dt = new DataTable();
SqlConnection dbconn = new SqlConnection(connectionString); dbconn.Open();
int test = int.Parse(string.Format("{0}", e.CommandArgument));
SqlCommand sqlCom = new SqlCommand("UPDATE Students SET Students.CourseID='20' WHERE StudentID="+test, dbconn);
sqlCom.ExecuteNonQuery();
dbconn.Close(); } }
|
I have a problem I think you guys will find pretty simple. I have to present my PHP project tomorrow, and now 2:00 I have got some serious problems. Can anyone help me out? PM please.
|
You don't have any kind of where clause in your "delete" command. When you say
UPDATE Students SET Students.CourseID='27' It means update ALL records in "Students" and change the CourseID to 27.
You need to limit that using a where clause (e.g. WHERE StudentID = 5). You should be able to get that value out of one of the arguments that came in. If you change your Eval on CourseID to StudentID (or w/e it is you call it) then you can use e.CommandArgument to get that ID of the record you want to "delete."
Alternatively I think you can use e.Item.FindControl() to get the ID. Actually in your case that probably wouldn't work since you don't have a control housing the ID (e.g. a label with the ID bound).
Just dig around in the RepeaterCommandEventArgs.Item and you should eventually find what you're looking for. Some docs: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeateritemeventhandler(v=vs.110).aspx
It's been a few years since I've done ASP.NET mind you.
|
sorry, i added an edit to the bottom of my post - i managed to solve that :D
thanks for the link though.
the onlyy thing left to do is make it so the webpage refreshes after the change is made with the button. which looks a lot more difficult than its worth atm (only got tomorrow to do all the "writeup" stuff which is 50% of the mark). ill probably just use "Server.Transfer(Page.Request.RawUrl);" which i can stick at the end of the protected void R1_ItemCommand function and it does the job pretty much. otherwise it looks like i have to take a look at javascript or something to make the page refresh and i just dont have time (ie its not worth any marks)
the good news is that by the end of tomorrow i will be pretty much sort of uptodate with everything, and determined this time to not stop but keep up the momentum!!!
|
With regard to comments and the Doom 3 reviewer guy, I guess he hasn't done much Windows kernel and low level hackery using undocumented structures and whatnot. Although to be fair, most people don't/shouldn't 
I disagree with some of what he says with regards to some style. Actually I used to use his current style of {} but switched a couple of years ago to the one he dislikes because I find it easier to read with more vertical spacing. Large clumps of text in a small area are harder for my eyes to parse out I guess. I agree with the ugliness of C++ constructs, I prefer using C style as much as possible.
|
On January 19 2013 20:47 Frigo wrote:Show nested quote +On January 12 2013 12:29 phar wrote:On January 12 2013 02:21 Frigo wrote:On January 11 2013 16:36 phar wrote: Either one is a godsend when you end up having to code something quick over a spotty remote connection. Or you know, you could just code it on localhost and upload it. Not if you're not allowed to code locally. Ah yes, bypassing version control, testing, continuous integration, and all the advantages of modern software engineering. What a grand idea! What does not being able to have local copies of code have to do with any of the things you listed?
|
On January 23 2013 10:35 FFGenerations wrote: sorry, i added an edit to the bottom of my post - i managed to solve that :D
thanks for the link though.
the onlyy thing left to do is make it so the webpage refreshes after the change is made with the button. which looks a lot more difficult than its worth atm (only got tomorrow to do all the "writeup" stuff which is 50% of the mark). ill probably just use "Server.Transfer(Page.Request.RawUrl);" which i can stick at the end of the protected void R1_ItemCommand function and it does the job pretty much. otherwise it looks like i have to take a look at javascript or something to make the page refresh and i just dont have time (ie its not worth any marks)
the good news is that by the end of tomorrow i will be pretty much sort of uptodate with everything, and determined this time to not stop but keep up the momentum!!! Why should it be difficult? Button clicks force a postback and you can just refresh it on page load where IsPostback. I'm not entirely sure why you'd need to refresh it, though, since it should be doing a fresh grab from your server each time the page is loaded. I guess there might be some built in caching.
|
Hyrule19083 Posts
On January 23 2013 11:57 phar wrote:Show nested quote +On January 19 2013 20:47 Frigo wrote:On January 12 2013 12:29 phar wrote:On January 12 2013 02:21 Frigo wrote:On January 11 2013 16:36 phar wrote: Either one is a godsend when you end up having to code something quick over a spotty remote connection. Or you know, you could just code it on localhost and upload it. Not if you're not allowed to code locally. Ah yes, bypassing version control, testing, continuous integration, and all the advantages of modern software engineering. What a grand idea! What does not being able to have local copies of code have to do with any of the things you listed? They don't. And committing untested changes to a vcs is a bad idea. Everyone codes locally. Unless what he means is he's only allowed to code on a specific machine, in which case a VPN or something.
|
On January 23 2013 14:11 Craton wrote:Show nested quote +On January 23 2013 10:35 FFGenerations wrote: sorry, i added an edit to the bottom of my post - i managed to solve that :D
thanks for the link though.
the onlyy thing left to do is make it so the webpage refreshes after the change is made with the button. which looks a lot more difficult than its worth atm (only got tomorrow to do all the "writeup" stuff which is 50% of the mark). ill probably just use "Server.Transfer(Page.Request.RawUrl);" which i can stick at the end of the protected void R1_ItemCommand function and it does the job pretty much. otherwise it looks like i have to take a look at javascript or something to make the page refresh and i just dont have time (ie its not worth any marks)
the good news is that by the end of tomorrow i will be pretty much sort of uptodate with everything, and determined this time to not stop but keep up the momentum!!! Why should it be difficult? Button clicks force a postback and you can just refresh it on page load where IsPostback. I'm not entirely sure why you'd need to refresh it, though, since it should be doing a fresh grab from your server each time the page is loaded. I guess there might be some built in caching.
in my picture here + Show Spoiler +http://i.imgur.com/pzV4AWA.jpg when you click one of the delete buttons, the delete works but the page is not automatically updated ie it remains exactly the same until you manually reload the page or you enter something in the courseID input box and hit enter
(ignore this for now, it seems to be working anyway at least with what im doing atm)
edit: wow im a massive idiot. i missed a class the other week and just checked the college website. everything i was trying to figure out earlier is written up here with step by step code to make it work exactly. TT
edit2: i have no idea what postback is. instead i just ran the pageOnLoad function everytime anything changed , which was code to display the results of a repeater which displays student/course details anyway. it didnt work at first which is why i was looking for another way but it turns out i was being dumb like it was not public or something similar to that.
just submitted the assignment (50% was design docs & essay) . cant BELIEVE i didnt realise there was so much shit on the college website i could have just copypasted instead of googling like a madmad and thinking i was being a genius about it all. but still managed to stick in 1 instance of a stored procedure at the last minute (though the college example didnt use a variable!) and at one point i killed my sqlmanager relationship by changing a data type and not realising it had to be an int to autoincrement (agh panic attack!).
after thursday (more like this coming monday) i'll start my own project/thing at last (ie find a great tutorial and go through from the very beginning onwards). probably C# (?)
yay
|
Regarding the Doom3 source code, I find it strange how they decided to go with operator overloading rather than having either member functions or global functions to handle vector math.
Vector2 v1 = {3.0f, 1.0f}; Vector2 v2 = {1.0f, 0.0f}; Vector2 v3 = {2.0f, 0.0f};
Vector2 v4 = v1 + v2 + v3;
//As opposed to: //vec2Add(Vector2* destination, const Vector2* src1, const Vector2* src2); Vector2 v4; vec2Add(&v4, &v1, &v2); vec2Add(&v4, &v4, &v3);
//Or: //Vector2::add(const Vector2* src1, const Vector2* src2); Vector2 v4; v4.add(&v1, &v2); v4.add(&v4, &v3);
Depending on the compiler, the operator overloading results in an additional temporary variable being created, since the return value optimization is smart, but not omniscient. Just a minor quirk that I had, hehe.
|
It makes sense to use a language construct specifically designed to express arithmetic operations, with all their advantages like operator precedence, and to code in a clean, legible, safe manner, instead of cluttering the namespace with dubious helper functions that may or may not interference negatively with inheritance, and may or may not confuse other programmers.
For example, I read "vec2Add" as "vector to add", which makes no sense. The signature of the function is no help either in deciphering its purpose. Does it add two vectors and place the result into a newly made destination? Or does it add both vectors to an existing destination? Or is it outright lying about the parameters and return a Vector2 value, with the sum of all three vectors?
Similarly, what is the purpose of that member function? Does it place the sum of vectors into the current instance? Does it instead add the sum to the instance? Or is it just a normal method that returns the sum?
Why are they accepting pointers instead of references? Are they doing something with the pointers or the values of the pointers? Are they adding them to a collection or otherwise using them as integers?
From the example, you also seem confused about what are they doing exactly, since you add v4 as well to the result, which the original did not do.
The meaning of operators + and += are bound by convention. Their usage is bound by the rules of the language, and are completely unambiguous. They are clean, legible and safe. You know exactly what are they doing, and can make an educated guess about how they are doing it, and you can derive predictions about the performance.
If only Java had arithmetic operator overloading...
|
You can excuse my haste in creating the example; in both scenarios, the add function is a void function that doesn't return a copy (in fact, I felt that was obvious considering I did not indeed assign the result of "vec2Add" to an lvalue). That's the entire purpose of avoiding operator overloading. I find that all of your complaints are easily rendered irrelevant with the existence of comments, which would obviously exist in such a case.
/*Adds src1 and src2 and fills destination with the result*/ void vec2Add(Vector2* destination, const Vector2* src1, const Vector2* src2);
/*Adds src1 and src2 and fills this vector with the result*/ void Vector2::add(const Vector2* src1, const Vector2* src2);
This would likely be a "fixed" version of the function. I don't believe your comment that it looks like "Vector to add" is exactly the fault of the function's name, considering you would then extend that to a "Matrix22" class looking like a matrix with 22 entries -_-
Also, I'm confused as to why you're complaining about the use of pointers over references. Would you instead want to see the use of const Vector2&? It literally makes no difference. The pointer itself cannot be reassigned, and it should actually be entirely obvious what the function is doing. It's adding two vectors in R2 and assigning the result to the destination. The function signature is incredibly helpful, considering one of the parameter's name is "destination".
I don't think the "readability" of the + and += operators offer a strong argument against the use of helper functions or member functions concerning vector operations (or matrix operations, or really any kind of math) because these are calculations that are being performed thousands of times per second, if not more. Do you really want to suffer the drawback of creating tons of temporary objects just to make it look prettier? What about more complicated objects, when you're suddenly tossing around the stack like a ragdoll due to the sheer size of every object?
|
Yeah that's pretty strange. The math libraries I've seen shy away from higher level constructs in order to keep simplicity, portability and optimization all tight. The math library I've made for my own game projects definitely wouldn't be using the + operator like that due to the annoying and unnecessary copies being returned. Even if RVO is utilized you still have one copy per + operation being created.
Either there's some tricky optimization going on that I'm unaware of, or they just didn't really care about the extra copies for that particular code segment. In all honesty allocating some stack memory and copying some floats isn't much of a big deal if the code isn't run very often.
|
I exaggerated the drawbacks of using operator overloading just a bit (well, maybe more, hehe), although it's mainly because I see "vectors" and immediately think "this is going to be used a ton for physics, transformations, etc.", although in reality, it's perfectly acceptable to use a simple + if you refrain from using that particular operator when doing heavy lifting. I'm not saying operator overloading is bad (I think it's a wonderful tool when used properly), although forgoing luxury for performance via a C-style function is often a good idea.
The advantage of using helper functions and whatnot over operators would be uniformity across multiple operations. Having a "vector2Add" function while at the same time having a "vector2Norm" function makes sense. Having a "vector2Norm" function without a corresponding "vector2Add" can be confusing - if anything, having both the helper function and the operator would be preferred (RVO would allow a single + or += to be used in a statement without creating any temporary variables, if I'm not mistaken). It's possible I'm stepping on id's toes a bit, since they might actually have such function alternatives to the operators anyway.
|
There's nothing "tricky" about it. Operator usage like that is completely trivial for compilers to optimize completely. Have you actually looked at assembly output in release mode that code like that generates? Especially with trivial operations like vector add, a function like
vec2 operator+(const vec2 &a, const vec2&b) { return vec2(a.x+b.x,a.y+b.y); }
used like this
vec2 a(2,4),b(3,5); a = a+b;
will never yield more than two instructions (the minimal amount, plus the movs back to memory if a is really needed somewhere else long term) on any compiler that has an optimizer.
Your discussion is a prime case of premature optimization. You don't know what you're talking about and make the code less readable and more verbose because of false optimization assumptions. Not to mention that your optimizations might introduce corner cases for compilers (e.g. more aliasing) which have the potential to completely disable some optimizations, thus making the code actually slower in the final product.
|
Anyone here familiar with ssis? I have a relatively simple package that does a data import from file to db, then runs a few stored procedures. If either the data flow portion or the subsequent SQL tasks fail, I want the entire package including the import to rollback. My solution was to put all the tasks into a sequence container with TransactionOption set to 'Required'. This worked fine but now when I am pointing the db to a remote server this property seems to be causing the package to hang and ultimately fail. I am guessing this has to do with the server's MSDTC settings.
Eventually I will be moving these packages to the same server I am trying to connect them to remotely, which will hopefully solve this problem. But I was hoping for alternative solutions. Besides putting everything into a sequence container, is there another way of making sure everything rolls back on fail?
|
Oh, of course it will be optimized away if you're only doing a single addition. Try adding four vectors on one line and see what happens. Using gcc, an additional (redundant) temporary object is constructed somewhere in the middle. This isn't premature optimization at all.
|
|
|
|