|
||||||||||||||||||
|
|
previous story
next story ![]() |
|
"Programming Languages for Games" Discussion Page: 1 2 »» |
|
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
| I suppose you could summarize his point something like this: * Take Haskell * Replace lazy evaluation with lenient evaluation * Add dependent types * Use a more verbose C-like syntax to avoid scaring C programmers Personally i agree on most of his points, except I'm not convinced about laziness being a bad thing (he cites performance, but I remain unconvinced -- see e.g. the computer language shootout for circumstantial evidence that Haskell is fairly fast). Also, I think one of the main strengths of Haskell is its elegant syntax so I'm not sure it's worth sacrificing just to make it easier on people who aren't used to it (I'd rather have these people spend a few days learning to read/write Haskell style syntax). The bottom line is that C/C++ is becoming way too costly to be used in the future. Both in terms of money (bugs cost money) but also in terms of performance. It's very, very hard to leverage multiple threads in C/C++, and it's only getting worse as we get more cores in our systems -- in contrast, concurrency in languages such as Haskell is almost as simple as single-threaded programming (due to it being purely functional, and having STM). | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | ||||
| The big problem with the performance of lazy evaluation isn't speed - it's storage. Expressions tend to grow and grow until you reach an empty list or something like it, and then collapse down again. Eager evaluation, by comparison, tends to keep expressions as small as possible at each stage by boiling the innermost expressions down before expanding the outermost ones. | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
"Space leaks", are fairly rare, and almost always come with a significant speed cost (i.e. you'll definately notice them). In any case it's, IMO, an implementation problem - the strictness analyzer of the compiler should spot cases like "sum [1..10000]" that and evaluate it strictly (i.e not keeping track of 1+2+3..etc. but rather evaluate each + immediatly) consuming O(1) space. Nonetheless, it *is* a problem, but I remain unconvinced that it's big enough to be a prohibitively expensive problem. Haskell, for instance, allows you to add strictness annotations (`seq`) so when the compiler can't do it for you, you can easily fix it yourself. At any rate, non-strict semantic (which is really all that the Haskell report demands, it's just that most implementatins choose to do that by using laziness) are so damn convenient so I really wouldn't want to lose it completely by going strict. Maybe Tim is right, lenient evalution may be the right compromise. | ||||
| ||||
![]() remigius
Member since: 5/4/2005 From: Oirsbeek, Limburg | ||||
Well, I think I need to look into Haskell to make an informed comment and I'll admit I'm rather biased toward C# anyway (see my sig ), but some code snippets are a bit far fetched... Take this one for example:
Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m)
{
Vertex[] Result = new Vertex[Indices.length];
for(int i=0; i<Indices.length; i++)
Result[i] = Transform(m,Vertices[Indices[i]]);
return Result;
};
What can go wrong with this according to mr. Sweeney? 1. Vertices may be null 2. Indices may be null 3. Indices may contain values greater than the Vertices array 4. m may be null 5. Result[i] can't fail, does the compiler realize this? 6. Indices.length may yield a null-reference exception 7. Vertices[Indices[i]] may be out of bounds My problem with this? Well, for starters points 3 and 7 are duplicates, just like points 2 and 6. A C# foreach statement would take care of point 5. This leaves us with 3 potential null-reference exceptions and the issue that an index may be greater than the size of the vertex array. The null-reference exceptions can be trivially caught using assert statements or with if statements, should more elaborate action be neccessary. It's also nice to note how the complete try/catch exception handling is ignored in this example. So the issue that an index in the Indices array may be greater than the size of the Vertices array is the only non-trivial problem with this code. You could just wrap the Indices array in some class which can perform the max index check and when implemented correctly, I doubt it would be much slower than the Haskell nat<n indicator. I can see that Haskell is potentially more expressive than C#, but then again, so is Prolog for certain classes of problems. As I said, I'm rather biased, but I can't help but wonder that languages like Haskell and Prolog hide away more complex issues 'under the hood', which makes it difficult to assess the efficiency of your code. I'm no Haskell expert by any means, but I'd imagine that the nat<n restraint is quite a performance hog when applied to larger arrays every frame. If someone could elaborate on these properties of Haskell, I'd be genuinly interested to hear more about them. As far as I can tell now, I'd say the abstraction of these kind of performance intensive operations in simple looking, (over-?) expressive statements is a dangerous property for realtime graphics programming and realtime programming in general. C# might not have this sort of feature built-in, but it isn't too hard to write this check yourself. This way the performance implications would be more obvious and you'd have more control over them (one-time evaluation per vertex/index buffer pair, for example). I guess it comes down to the loaded question "How far should language facilities go?", so I realize this may be an endless discussion, but I'd like to know what you guys think. Please don't burn me to the ground for disagreeing with mighty Tim ![]() Edited: and as a coupe de grace on this code snippet, issue number 4 can never happen, as the Matrix object in MDX is instantiated from a struct and as such can never be null, since it's a value type... Bit of a painfull mistake there, I'd say... Maybe nitpicking, but when someone's trying to make his point at the expense of C#, I'd think a bit more research might have been warranted. | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | ||||||||
Quote:I notice on the PPT that 6 and 7 are in a different colour to the rest, which makes me wonder if he doesn't already know that they're duplicates. Quote:No, point 5 is saying that i is guaranteed to be less than the size of the array, but that it's difficult for a compiler or other static analysis tool to discern that. How does a foreach help? Quote:Which requires additional explicit "check for this error condition" code on the part of the programmer. If the syntax for function signatures included an SQL-style "NULL | NOT NULL" suffix on each parameter (or MTTP, a Haskell Maybe type) then it would be harder to forget to do this. Quote:The nat<n thing isn't Haskell, it's his own pseudocode thing. That said, I think the point is not that it will be continually verified at runtime or anything like that. The point is to give the compiler or static analysis tools the information they need to ensure that the value could never be out of range, i.e. you can't assign from a generic "number" type to a "nat<n" type without going through "round" or "truncate" and "clampToRange" functions, because the types are different. Static typing, y'know? The massive advantage of functional languages like Haskell over something like C# is provability. You can prove, through methods like proof by induction, that a function is correct and will always be correct for any input. As far as I know that's not possible with procedural languages; the best we've got in procedural languages are things like loop invariants, and that leaves a lot of things to chance. (If I'm wrong about the provability of procedural languages, please let me know; I'm only a first-year CS student and my lecturers may have lied to make my life easier )Quote:It's worked well enough for Wings 3D, which while not written in Haskell, was written in another functional language (Erlang). Quote:Provided you remember to. And as the man said, 50% of the bugs in Unreal can be traced to forgetting to initialise variables, or forgetting to check that a pointer is not null before dereferencing it, or forgetting to check that an array index is out of bounds. None of these things are hard to do in and of themselves but if you find yourself having to remember to do it everywhere then it's only a matter of time before you start missing spots. Quote:Who said it was an MDX Matrix object? ![]() | ||||||||
| ||||||||
![]() ajas95
Member since: 12/4/2003 From: Seattle, WA | ||||
| This Tim Sweeny guy seems pretty full of it. When Naughty Dog wanted to start doing PS2 titles they decided that C++ couldn't cut it... but did they talk about all their language ideals and mitigations? No, they wrote a Scheme compiler and did 4 games at (mostly) 60 fps. So the question, Mr Sweeney, is "Can you do it at 60?" It seems like everyone else can. If Epic is ready for 20+ core PCs, then surely they'll run 60fps on a console w/ cutting edge gfx... even if they only have a measly 8 cores. | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: Exactly. Some modest extensions to the type system allows us to statically ensure that a whole slew of errors will never happen. Some of the things are already available in languages such as Haskell, but dependent types aren't (well, not entirely true, you can do lamda-calculus style defintions of type-level Peano's numbers using some fairly tricky type hacks, but nobody does that in practice :-)). There's a language called Epigram, closely related to Haskell in style and syntax, which is all about dependent types (a bit too much, IMO). Quote: Well, you certainly COULD prove things in a procedural languages. It's not impossible. But whereas it's often trivial to see that a function will never go wrong in Haskell, you can make no such guarantees without significant effort in languages with side effects. You are right though, no sane person would go trying to prove any significant piece of code written in a stateful language. I don't think most game developers will start proving their programs though. For me, the main point of using purely functional languages is that we really can't have side-effects in a world where concurrency is the best (or only) way to achieve performance (and that's the reality we will find ourselves in pretty soon). Pure functions are trivially parallelisable. Something like "foo x + bar y" cannot be parallellised in a language with effects because the first call (foo x) may do some side effect that affects the result of the second. In Haskell it is guaranteed to be side-effect free so the two calls can be computed in different threads. Also Haskell has STM, which means that you can do stateful memory transactions in different threads without ever having to worry about deadlocks etc. Moreover, STMs are (as far as I know) the only concurrency abstraction so far that is truly composable (hello code-reuse!). So it's not just productivity. Very soon it will be all about performance. It's possible (but very diffictult) to make use of 6-8 threads using C++, but will you really be able to make your game engine use 20+ cores using C++? Will you be able to structure your impure stateful code in 80 separate threads with somewhat equal burden on each one? I doubt it. We need better tools. | ||||
| ||||
![]() remigius
Member since: 5/4/2005 From: Oirsbeek, Limburg | ||||||||
Quote: Agreed, but you have to admit that those balloons he used make the C# code appear littered with potential bugs at first glance ![]() Quote: With the foreach loop you completely eliminate the indexing i variable, thus removing this whole point. If you scroll down the PDF to the Haskell/pseudocode snippet for this example, you'll see mr. Sweeney uses a for each loop there to eliminate this point too. Quote: Sorry about that misunderstanding, I assumed he was using Haskell here to make his point. I can see some merit on using a type with a limited "nat<n" range though and I can also see that it doesn't need to be as expensive in terms of computation as I originally assumed. However, you'd need to define a seperate static type for each size of vertex array, or am I missing something here? If I'm getting this right, it comes down to the choice between either defining a limited range type in a functional language like proposed by Tim, or just relying on a try/catch to check for this condition in a procedural language. I'd prefer the latter, as the vertex/index issue highlighted here is IMO a textbook example of an exception condition, which should be handled by try/catch functionality, causing little designtime and runtime overhead. Maybe I'm dead wrong on this, but for now I'll stick to my guns here ![]() Quote: I'd have to agree here to some extent, but it's a bit of a subjective point. I personally never cared too much for the provability of code, as most cases I have seen commonly relied on exotic case studies to make their point. Functional methods could be proven to work by proving the algorithms they employ (which may be defined in a context that is more suited for proofs) and verifying the correct implementation of these algortihms. You'd still have to guard against the input/output conditions, but these are typically the assumptions for your formal proofs. All in all, functional languages could very well be better suited for implementing 'proven functionality', but the pre/postcondition checks for example are bound to yield some overhead. Whether or not that's a efficiency hit you're willing to take depends on how performant your code needs to be and other subjective arguments. I doubt however that you'd want to take this hit on each method call in every frame in a realtime graphics applications. Quote: I'm not saying functional languages can't cut it, but I see a potential danger in the way they commonly abstract/hide expensive pieces of functionality in deceptively simple/cheap looking statements. It's been a while since I've done anything with Prolog, but as I recall it provided a very simple looking statement for a set inclusion test, as well as quite some 'solve' functionality with this characteristic. I don't know if Prolog makes a representative case for functional languages, but going from this I'd say the dangers of obscure performance pitfalls are very real. Especially when you want to employ such a language as a scripting interface, which may be used by folks outside the company that aren't as aware of the performance implications, like modders or enthousiast endusers (as with Neverwinter Nights for example). Quote: Again, I agree to some extent, but it's a bit of a dubious point to make. Having a language guard against this undoubtedly has some significant performance implications, though they're all rather exceptional cases of things that could go wrong. It's the choice again between performance-friendly try/catch blocks or guarding against this as a language facility. The try/catch blocks allows you more freedom for implementation, picking the things you wish to guard against with more accuracy and allowing for a tailored recovery if something should indeed go wrong. I can see some merit in having the language/platform prevent these exceptions, but there will always be cases that will give problems here. It's the question again how far language facilities should go to prevent exceptional error conditions. Quote: Reading that part of my reply again, I probably deserved that . It was a bit of a childish/smartass point to make, contributing little to nothing to the discussion. My apologies for that. | ||||||||
| ||||||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: No. He was talking about static guarantees. That means there's no performance hit whatsoever. It would be way cheaper to use static checking of indices rather than having to use runtime bounds-checking and exceptions. Everything he talks about are things that are verified at compile-time (which means that the run-time code can be much more efficient). And like he said. Even if this language runs several times slower than fully tuned C code, it's still a win. Higher productivity and reliability means you can put more of the system to good use. If you can employ all six threads in the Xbox360 100% of the time, then you're still going to be faster than your typical C++ style application which probably won't be anywhere near full utilization. | ||||
| ||||
![]() remigius
Member since: 5/4/2005 From: Oirsbeek, Limburg | ||||
Quote: This last point discussed Superpig's/Tim's point about these issues: Quote: I'd say checking against these issues cannot be done completely at compile-time. Some obvious cases may be intercepted by the compiler (as the C# compiler also already does) but most of these checks on function parameters would need to be done at runtime (null reference checking and reading index data from a file into a limited range type both would, for example), which will produce a runtime overhead. It may not be the dramatic overhead I first envisioned, but if it's a language facility to check against these things, it will be probably done each time this potential danger occurs in the code, which can amount to a significant overhead in a realtime application. Quote: I completely agree with you on this and I can see some parallels to the discussion on C++ and C#, where I'm on the other side of the fence. This is why I realize it's a rather subjective argument, but I wonder whether the things mentioned should be guarded against by the language itself, since they're really exceptional cases that can just be handled by the try/catch approach. To highlight the other extreme, typeless languages are also becoming more popular lately because these allow for higher productivety. The reliability of a functional language may be higher and proveable, but I doubt functional languages would do much to actually raise the productivity by definition. In some cases it might be entirely possible, but I think the 'functional language' class of languages is too big to make this statement for all functional languages in all implementations. The static guarantees you mentioned for example don't seem to increase developer productivity to me any more than a try/catch block. Also please note that I'm not trying to put down functional languages in favor of my procedural C#. I'm just arguing that the choice between functional/procedural is subjective and that procedural is up to par with functional. As I read mr Sweeney's PDF, I get the impression he finds several points lacking in a procedural languages like C# which are solved by functional languages. This is a point of view I don't share and I'm trying to prove wrong. | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | |||||
Quote:I disagree, though. If you use a "never null" type for your reference - a type that has the constraint that it can never be null - then you don't need to check at runtime. You won't be able to assign a "possibly null" expression to a "never null" type of variable; the type conversion would simply not be allowed. The assignment cannot take place. How does one code like this, you may ask? Haskell does it using pattern matching. A variable of the "maybe" type can only match two expressions: "Maybe A" or "Nothing," where 'A' is a parametrized type (i.e. "Maybe Int" or "Maybe Char"). So you effectively write two versions of the function, one to be used when the argument matches "Maybe A" and one to be used when the argument matches "Nothing." It's sort of akin to an if-not-null conditional expression except that it has this kinda implicit type conversion built in; because the argument is guaranteed to match the pattern, you can safely access subcomponents of the pattern (i.e. the 'A') without worrying about whether they're actually there. Quote:OK, so modify his example a little to have the function only transform the first N indices. ![]() Quote:I'd be careful about the use of the word "define," is all. Many types can be implicitly defined instead of having to be explicitly stated. It's almost like templated typedefs:
template<typename T, int size>;
class FixedArray
{
T internalArray[size];
public:
typedef DependentNaturalNumberTypeThatIsNoBiggerThan<size> Index;
T& operator ()(Index idx)
{
// no need to check for an out-of-bounds situation because idx is guaranteed to be in bounds
return internalArray[idx];
}
};
The user of that code doesn't need to define any types or anything - it could be something as simple as "myArray.Index i = 5; myArray(i) = 10;" etc. If you consider a type as being a collection of constraints on the possible values that type can hold - e.g. must be an integer in the range -127 to 128 - then it becomes very simple to construct types "on the fly" by simply looking at the constraints you need to satisfy. | |||||
| |||||
![]() remigius
Member since: 5/4/2005 From: Oirsbeek, Limburg | ||||
Quote: I was going to argue that this won't hold for passing in function parameters into external libraries as you can't be sure what someone else is passing in, but I can see I was suffering from a bit of tunnel vision here. I can imagine Haskell (and similar languages) will also place the MayBe restraints on function parameters (kinda like preconditions), eliminating my issue with them. I stand corrected ![]() Quote: It's up to Tim to provide an example that would have defied my counter argument But I can see what you mean.Quote: I'm a bit of a mess with C++ typedefs and templated classes, but wouldn't this still mean you have to define the DependentNaturalNumberTypeThatIsNoBiggerThan type somewhere? As I'm trying to break out of my newfound tunnel vision, I can imagine that a compiler can be made to recognize assignments that fall outside the lmited range of the type at hand, but this still won't solve the runtime check of reading in these numbers from an external source like a file, which should be a common operation on the proposed use of vertex/index buffers. You might be able to remove all these problems with a sufficiently expressive language, but for the vertex/indexbuffer example you'd still need a type with a range that is unique for the size of the vertexbuffer. This may be done incredibly efficiently and it would make the function certainly idiot proof, but I'm having some doubts if the language would really need to go 'that far' with its facilities. As I said, it's a subjective topic so I don't think we'll reach a conclusion soon. My original point was that procedural languages aren't as bad as they were made to look with that example and I stubbornly think I still have a bit of a point there. Other than that, this has been a most educative discussion and I think I'll go look into Haskell a bit to mount a better defense for C# in the future ![]() | ||||
| ||||
![]() Calefaction
Member since: 4/26/2004 From: Houston, TX | ||||
| Here is my problem with any of these discussions...and mind you, this probably comes from the fact that I am not a "college programmer". I learned to program myself and I turned it in to a workable skill myself. If there is anything I have learned it's "do what works". That's really the issue. Is Haskell or Prolog or any of these languages going to make my day to day life suddently magically easier? I highly doubt it. To me, it's all conjecture and theory. It's been proven that programmers develop cleaner, faster, better code when they are comfortable with the tools and the languages in use. A C# programmer who is more comfortable with that language is going to out-perform (in the loose, non-quantifiable sense) a programmer who is only marginally comfortable with Haskell or Prolog and attempting to use that language, no matter what fancy checks and balances the language offers. I appreciate the discussion, but it seems like the same language propaganda we have been hearing for years "Use this language, because we say it's better, and it has this whizbang feature". That's nice...but what does it really do for me? A good programmer is a good programmer, regardless of the language you stick in front of them. Trying to say one language, or one type of language (procedural or functional) is always going to do X, Y and Z the best is foolish and very subjective. People have been predicting the "Death of C++" for 10 years or so. Just like they have been predicting the death of C for 15+. Now people are predicting the "Death of precedural langauges"...and just like every other time, they will likely be wrong, no matter what Tim Sweeney wants you to believe (and his slides/presentation were pretty biased...he was really stretching in some of those examples to prove his point of how precedural languages are "Bad"). | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: A good race car driver is always going to be a good race car driver. However, he will be able to do much more if he's driving a driver-friendly car. Obviously someone who's a bad race car driver won't be magically better because they get to use a good car, but it certainly doesn't hurt. People get way to fussy about their languages. They're not religion! Just tools! Learn many of them, and use the ones you like best for a particular task. There are no silver bullets, but that doesn't mean that the language you use doesn't matter. It's just irresponsible (or stupid) to use an older, less powerful, language if better alternatives exist. Developing games is costly, we need to use better tools wherever we can find them. Most projects spend over 50% of the programming-time in correctness-related tasks (debugging, writing unit-tests, etc.), how come so many programmers (who are usually good at finding out what to optimize when it comes to code) are reluctant to use languages which emphasize correctness and reliability? It's obvious that this is where the big productivity savings could be achieved, yet so many refuse to even try some of the languages out there (and experience the huge difference for themselves). Some companies do meassure it though. Ericsson meassured a productivity boost of 9-25x when switching from C++ to Erlang (depending on the metric you use, IIRC the 9x was LOC/hour, whereas the 25x was features/hour). I certainly don't want to get into a language flame-war here. But saying that Tim is somehow "biased" against procedural languages is pretty far-fetched. What would be his motive for disliking procedural langauges? (I'll tell you: real-world experience writing one of the most widely used engines in C++, and a sound attitude towards languages - they're just tools, not religion). | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: Dependent types mean that the *type itself* can have a number in it. Int<4 is a type, and so is Int<5. You don't need to declare these anywhere (just like you can create a pointer-type from any type without having to declare a typedef for the pointertype, you just add a *). At certain cases you may need to convert from, say, Int to Int<1000, and Tim touches on this topic in his slides. He says that in 90% of the cases in the UnrealEngine 3.0 code that wouldn't be needed. This really is a Good Thing. You can express in the type of a function that you want a non-null pointer or a list of a certain size etc. so you don't have to do any checking to see that the caller didn't screw you. If you don't have this statically then *every* function should do sanity checking, but with this feature no function needs to do it. At some point some function will need to do the conversion to a bounded type (or non-null type etc.), but then the rest of the functions this data passes through to (which could be thousands, or millions for long lived data) get it for free, statically ensured. Performance is better, and reliability is a *LOT* better. And, as Tim says, and I'm sure your own experience agrees, almost all of the bugs in a system are due to: 1. Some state-invariant not holding ("oops, in this rare case here this member-variable is null" etc.) 2. Some parameter invariant not holding In my experience, (1) constitutes probably 50-70% of the errors in imperative programming, and guess what, it's completely solved in functional languages (state just isn't allowed in a pure function). Number (2) can be solved in most cases by a sufficiently expressive type system. So if we can eliminate something the causes for, say, 90% of the bugs in a system, then that really is a good thing. You can always say "well I'm a super-awesome programmer and won't be affected - I'll always remember to use try/catch etc.", but that's just arrogant (you may be affected less, but everyone makes misstakes). The same argument was used by people who thought that using C was a bad idea and insisted on sticking to assembler. Statically ensuring this is never ever a bad thing for anyone. | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | ||||
Quote:Well, sort of. The idea is that by supporting dependent types at the language level, a constraint like "no bigger than 5" can be applied to a type simply by adding it to the name, as Sweeny said in his talk ("nat<n"). You don't need to write a getter/setter function for the type or something like it (though I would imagine that you could if you wanted to), you just describe the constraints on the type. Then it comes down to the difference between "int" and "int{<5}" Quote:Yup, which is why you'd use unconstrained types for such reading. To pass the unconstrained types to a function that operates on constrained types, you'd have to "enforce" the constraint by providing behaviour to deal with values that are not within range (e.g. clampToRange or abs). That behaviour would /be/ your "type conversion" - just like how float->int conversions in C/C++ are performed by an implicit floor() call. | ||||
| ||||
![]() nuvem
Member since: 1/17/2004 From: Ottawa, Ontario | ||||
Quote:Of course, you would still have to ensure, on reading in the number from a file, that it fell within the bounded range; however, once you do it can be statically guaranteed that the value will be in range for any following function. | ||||
| ||||
![]() Calefaction
Member since: 4/26/2004 From: Houston, TX | ||||
Quote: But if you put a race car driver in a faster car that he isn't comfortable with, he is just as likely to go slower than if he was in his slower car that he is comfortable with. Not enough credance is given to level of comfort and knowledge. Yes, languages are just tools, but just like power tools in the non-programming world people are going to have preferences and things they are comfortable with. I may like Mikita power saws, you may like Black and Decker. If we both get the same job done in the same relative amount of time, then I really don't want to listen to your rhetoric about how good Black and Decker saws are...my Mikita is working just fine for me. You can't expect developers to want to up and change their comfort zone simply because you think this language or that language gives them this massive productivity boost. For all the hours I gain by not having to use try/catch, how many am I going to lose having to re-orient myself and make myself comfortable with this new language you pushed at me? This is why languages like C# and Java are popular. They keep developers inside their basic level of comfort while adding things that are needed too boost producivity. Most professional programmers are extremely familiar and comfortable with the "C-style programming model". Asking them to magically change because you or some professor at a school (or even Tim Sweeney) says so is not going to work out real well. For that matter, how hard is try/catch to use? Did it suddenly become difficult overnight and I missed it? I don't want every method/function in my code to explicitly be wrapped in training wheels to check for every possible error condition, static or otherwise. Part of being a programmer is know when to use a certain nut or bolt and when not to. When that starts getting abstracted away in these wonderful blackbox language features, it isn't helping the trully skilled developer. It's limiting them. You're right, languages aren't religions, they are tools. Given that advice, perhaps we should let people use the tools they are most comfortable with, rather then coming in and telling them their tools are inadequate and replacing them because you think it's more productive. | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: People aren't born with a certain language preference, it's just what you're used to. If I can demonstrate that X% of the bugs you make in your current language just won't happen due to advances in language theory, why would you not want to give it a try? Hell, any programmer worth his salary should be jumping up and down att the prospect of improving correctness by any amount. If they're too locked in their "comfort zone" to learn new things, they're not going to be able to hold a job for long. Things do change, and even if you're not going to be using, say, Haskell for your next project, you'll be a better programmer for trying it -- I know my C/C++ code only got better by trying "wacky" languages like Epigram or Scala. Quote: No, it's not difficult. In theory. In practice exceptions propagate to the top-level and crash the program all the time. Yes you can choose to ignore modern languages by saying "I can do everything I need in C++, I'm good enough to not need help from the compiler!", but you're only making your own life worse (and you're coming off as really arrogant). Exceptions can be used to spot and handle dynamic errors, but that doesn't mean it's not better (in every single case) to catch them statically at compile time. Not only does it reduce the number of silly little bugs, but it's also faster to perform checks at compile time rather than run-time. You can write just as good software in any language, but that doesn't mean that the choice of language is arbitrary. Some languages are better at certain things. Tim Sweeney discussed several areas which are of particular interest to games programmers, and which aren't well supported by the current de-facto "standard" language (C++). It's not a subjective matter of "taste" that C++ can't handle concurrency well, it's an objective fact. It just doesn't support the programming models needed (such as STM). Quote: That's a pretty silly statement. I'm sorry if that sounds harsh, but why would it be limiting to, say, get a more expressive type system? That type of reasoning has been used to resist every change for the better throughout history (such as assembler -> C), and it's been an utterly silly argument every time. It's not like language designers are trying to dumb things down, give them a little credit. They're researching more flexible, safe, and expressive ways to write code. To ignore all that hard work just to stay in your "comfort zone" is foolish. We're discussing languages and language features here. If you're not interested in that, then feel free to stop participating. I don't see why you would want to come in here and say "Hey! Let everyone use whatever language they want!". It's not like we're forcing anyone, we're just discussing the merits of various languages as it pertains to games programming. And there are certainly plenty of problem areas that could be catered to by the language. People are, of course, free to use whatever language they wish -- but we're also free to discuss the flaws of those languages (every language has them). | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | |||||||||||
Quote: ...until he becomes comfortable with the new car, at which point he will go faster than in the old car. Quote:Plenty of credence is given to level of comfort and knowledge - that's why Sweeny mentions the possibility of a C-like syntax for his hypothetical language, to allow people entrenched in C/C++ to transition more easily. However, even more credence is given to the concept that programmers are able to learn new things and adapt to change. (Especially when an increasing number of programmers have had formal educations that have exposed them to a variety of programming paradigms). Nobody's saying that something like what's been proposed would be adopted overnight, but to say that it shouldn't be pursued simply because people will be initially uncomfortable with it is short-sighted at best. Quote:Slippery use of the word "relative" there. In absolute terms, what we're talking about is a tool which will get the job done faster than what you're currently using for a significant portion of the time. Quote:Sure, but I can expect them to think about it after I show them some hard numbers and statistics, maybe get some of the guinea pigs to talk about how it affected their own projects. Quote:Well, let's see. You probably gain a few months development time that you would otherwise have had to spend fixing stupid bugs. If you're a good programmer, a programmer who can keep the conceptual aspects of his program seperate from the concrete code, then it might take a couple of weeks to switch. I don't think of myself as a "good" programmer (I have issues with attention to detail) but it only took me a couple of days to learn enough Erlang to write a small plugin for Wings3D, and that's having never experimented with functional languages before. Quote:No, but if the next incarnation of the Unreal engine comes with a standard and set of tools for this new language and a note from the developers saying "BTW guys, we really recommend you use this newlanguage API," then they are more likely to. Quote:So you want to just allow the errors to occur and pass away ignored? Quote:Yeah, maybe. Yet current projects have a few million "nuts and bolts" and the number is not decreasing. We're supposed to expect programmers to make that decision a few million times and expect them to never get anything wrong? I'm sure there's been at least one space shuttle incident that was blamed on a faulty rivet or something. Quote:If by "truly skilled developer" you mean "expert at low-level hackery" then you can keep him. I'll be over here with the system architects and the big picture guys. Quote:Firstly, stop pretending that C/C++ has not been shown to be inadequate. Perhaps it's sufficed for all the projects you've worked on, in which case more power to you, but there's a reason why some of us are looking at what Sweeny is proposing and going "sweet mother of bob, that would come in so handy." Secondly, nobody is forcing anyone to switch languages or change tools, so if you're too averse to change to even consider how the concepts being kicked around could benefit you, then feel free to go away and continue using your current approaches. If it turns out that the new tech is an immense improvement, it'll be your loss. | |||||||||||
| |||||||||||
![]() MichaelT
Member since: 1/5/2003 From: Stockholm, Stockholms Lan | ||||
| To the best of my knowledge no programming language have ever "died". So don't go thinking about imaginary nightmare scenarios, just because a programmer among others expressed an opinion. Personally I have had troubles dealing with multithreading in C++ but it's not exactly impossible either. I understand his points, but I'd much rather extend C++ to fix what needs fixing than inventing yet another language. | ||||
| ||||
![]() sebastiansylvan
Member since: 7/30/2004 From: Sweden | ||||
Quote: How are you going to extend C++ to fix its problems? I mean, without removing anything the problems are still going to be there for most of the reliability and concurrency problems. IMO it's better to just drop this 30+ year old legacy and start afresh. C++ is already so complex that there aren't any implementations which fully implement it (to my knowledge, at least) -- adding even more stuff to it, which would undoubtedly clash with some existing features, is probably too messy to be doable. | ||||
| ||||
![]() MichaelT
Member since: 1/5/2003 From: Stockholm, Stockholms Lan | ||||
Quote: Your quote is full of problems and no solutions, you basically said: -I Give up! Ask yourself: What is the cost of leaving C/C++ for another language? What new problems are there? How do I design this new language? How do I gain support for it? How can I get 3rd party tools to support it? Etc. Those are but an initial amount of endless questions. You basically said it yourself, C/C++ is 30+ years old. That is a lot of beta testing, solutions to problems, IP investment etc... Starting something new is not as simple as you might think. | ||||
| ||||
![]() superpig GDNet Technical Lead
Member since: 5/26/2001 From: Oxford, Oxfordshire | ||||
Quote: Those are all reasonable questions, but it's been done before - C++ faced the same questions when it first arrived on the scene, no? | ||||
| ||||
|
Page: 1 2 »» All times are ET (US) ![]() | previous story
next story ![]() |
|