Thread: D language?

  1. #31
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by Rashakil Fol View Post
    Of course, there are always some software engineering problems. But programming languages and programming language features can fix software engineering problems -- all languages do, and they do so in modest and less-than-modest fashions. Take strong typing, for example. That solves a software engineering problem. What about static typing? There's another. How about lexical scoping, or namespaces? Solves another one. Garbage collection? There's another one solved.* A serious module system (instead of #include barfage)? There goes another. The const keyword? There's another. Or better yet, pick a language where it would be redundant. Restrictions on naming that differentiate between values and types? There's more refinement to the namespacing problem. Isolation of side effects? Solves another one. I think that's coming to C# soon, in a primitive way. Type system-based descriptions of side effects? Ooooh. Statically typed software transactional memory? ~drool~.

    * Edit: the biggest one of them all -- since named functions and variables were invented. Hey, I forgot to list the invention of subroutines!
    Namespaces - what do they solve? I don't think you'll have so many functions that you run out of letter combinations for a function.
    Garbage collection - Yikes... never heard of freeing memory? When you allocate memory for an object, structure or buffer, why not free that memory when you don't use it anymore? It's as simple as that. Garbage collection is an "alibi" to do careless programming.
    Const keyword - the most useless thing on earth. If I want a value not to be changed, why not use macros? And who would be that stupid to accidentally modify a variable which is not supposed to be modified.

    Most of the stuff you mentioned doesn't give any real advantages. They just teach us bad habits like always giving the functions the same names in libraries, not freeing memory, making stupid mistakes etc.

    What's ruining the art of programming is that people are taught to do what would otherwise be mistakes and software has to hunt&kill them. Why not write good code? Nowadays most performance goes to runtime environments or CRT checking if you have made stupid mistakes. Why not spend performance for the reason that the application was designed for?

    When disassembling some programs programmed in high-level languages, I can clearly see that the code that the application actually was meant to do makes a small portion of the code that runs for every function. Visual Basic even adds "jo xxxxx" (if calculation overflow, then jump to exception handler, it triggers when doing unsigned INT_MAX+1, which results in 0) after almost every other assembly instruction. And MSVC++ compiled executables call a complex checking in the beginning and in the end of every function, not mentioning that it calls the checker many-many more times during the function depending on what it does.

    Anyone care to do MD5 benchmarking for example in C# and then compare it with C and Assembly? You'll be surprised.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  2. #32
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by Rashakil Fol View Post
    Of course, there are always some software engineering problems. But programming languages and programming language features can fix software engineering problems -- all languages do, and they do so in modest and less-than-modest fashions. Take strong typing, for example. That solves a software engineering problem. What about static typing? There's another. How about lexical scoping, or namespaces? Solves another one. Garbage collection? There's another one solved.* A serious module system (instead of #include barfage)? There goes another. The const keyword? There's another. Or better yet, pick a language where it would be redundant. Restrictions on naming that differentiate between values and types? There's more refinement to the namespacing problem. Isolation of side effects? Solves another one. I think that's coming to C# soon, in a primitive way. Type system-based descriptions of side effects? Ooooh. Statically typed software transactional memory?
    That are not the class of software engineering problems Im talking of. I would rather call them programming problems. And I disagree with maxorator: Im convinced they must be solved, too. But they help not much with the problems building todays complex software projects I mentioned in my former post. Garbage collection or namespaces does nothing to verify a design for example or to transform a design straight forward into something executable nor does it help to get changes from the executable back to the design/spec and so on.

  3. #33
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    I just haven't seen any actually useful features in new languages. Of course it's possible to create really useful features, but I haven't heard of such yet. But there are too many new languages coming without any improvements, there should only be another language if it really solves problems of programming, not problems of lazyness.

    C++ was one good step to resolve problems related to extremely complex applications, but the new programming languages use the same features, add unnecessary features and slow the thing down. I haven't seen ANY progress since C++.
    Last edited by maxorator; 08-13-2007 at 04:43 AM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  4. #34
    Disrupting the universe Mad_guy's Avatar
    Join Date
    Jun 2005
    Posts
    258
    Quote Originally Posted by maxorator View Post
    Garbage collection - Yikes... never heard of freeing memory? When you allocate memory for an object, structure or buffer, why not free that memory when you don't use it anymore? It's as simple as that. Garbage collection is an "alibi" to do careless programming.
    You have no idea what you are talking about. Garbage collection is there to alleviate the pains of programming; memory management is one of those things.

    You talk as if you program flawlessly (which, I can assure you of something: you don't,) and talk of other people as if they don't.
    If it's so simple, why are you not leading the revolution in software design? So far, your solution looks like nothing more than just "dealing with what we have now, because it's the best solution to the problem and always will be." This is one of the most asinine things I have heard in a very long time.

    Truly, if this is the way to reason about software, you will be famous for pointing it out for a very long time.

    Sadly, I can assure you you're wrong.

    Most of the stuff you mentioned doesn't give any real advantages. They just teach us bad habits like always giving the functions the same names in libraries, not freeing memory, making stupid mistakes etc.
    Now I'm quite certain you have absolutely no idea what you're talking about. Did you even read his post or, if you did, did you understand any of it (especially relating to types and transactional memory)? He listed plenty of good examples that help write software.

    Want a really, really good example? A very strong type system as seen in a language like Haskell or ML. This can help reduce the number of bugs in your programs to such an extent, you would be amazed.

    Case example: I am currently writing an IRC bot in haskell that has the advantage that you can write a plugin for it (in haskell,) and the plugin will be dynamically loaded into the system on startup. Generally, you could consider plugins a point of failure because they are prone to have errors (NULL pointer anyone?) You have to reason about them carefully since in an extensible system offering this functionality, you're asking bugs to creep in through user-provided plugins.

    On the contrary: the plugins system works so well that I've already moved almost every bot command into a plugin of it's own which has resulted in reduced complexity and boilerplate, at the expense of a little refactoring. What happens if a plugin is wrong or there's something incorrect about it? It doesn't load, because the compiler will catch the type errors at compile time and alert you about it. What happens when it does load? It works almost flawlessly upon the first activation. Every single expression has a very strict type, and unless all the types in the program fit together in a sound manner, they won't compile.

    This is not to say the plugins never have errors; indeed, the bot can fail for example if you try to take the head element from an empty list (and this isn't something you cannot reason about at compile-time, since it may very well depend on an external state.) However, the type system makes reasoning about them and how they should execute *a lot* easier, and it also ensures my plugins are at the very least, safe.

    I would also bet that if I wrote the equivilant bot in C, the amount of bugs would have been much higher than the haskell alternative.
    The silly thing is, I'd say ~95% of those bugs would have been caught at compile-time in haskell, because they would manifest at the type level.

    Conclusion: a strong type system reduces program bugs by an incredibly effective amount. This is a pretty big 'real advantage,' no matter what way you look at it.

    Here's another really good example: Software Transactional Memory. This solves the problem of synchronization and locking based solutions in multi-threaded programming. The solutions we use now such as mutexes and locks are archaic and while proven to work [sometimes], are still quite error prone. STM solves this problem very elegantly, and indeed, this is a very important topic, considering multi-core programming is not an option, but is more of a requirement these days if we wish to increase our performance and thoroughput.

    Conclusion: STM solves a lot of issues with multi-threaded programming (and additionally removes much complexity) and allows more composable, reliable concurrent software. This is a 'real advantage.'

    What's ruining the art of programming is that people are taught to do what would otherwise be mistakes and software has to hunt&kill them. Why not write good code?
    Because humans aren't flawless and we make errors. Stop speaking of yourself as omnipotent or something. You're far from the perfect programmer, I hate to inform you.

    Nowadays most performance goes to runtime environments or CRT checking if you have made stupid mistakes. Why not spend performance for the reason that the application was designed for?
    Why make your life harder and waste your time bug hunting, when a simple runtime or type system can automatically give you guarantees and make your life easier?

    I think you're under some [very] misguided assumption that to be a programmer, you should do everything yourself. Trusting any sort of abstraction just means you aren't a programmer, and you're ruining programming entirely. I think you should look at one of the greats of computing on this note:

    "Being abstract is something profoundly different from being vague... The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise." - E. Dijkstra


    When disassembling some programs programmed in high-level languages, I can clearly see that the code that the application actually was meant to do makes a small portion of the code that runs for every function. Visual Basic even adds "jo xxxxx" (if calculation overflow, then jump to exception handler, it triggers when doing unsigned INT_MAX+1, which results in 0) after almost every other assembly instruction. And MSVC++ compiled executables call a complex checking in the beginning and in the end of every function, not mentioning that it calls the checker many-many more times during the function depending on what it does.

    Anyone care to do MD5 benchmarking for example in C# and then compare it with C and Assembly? You'll be surprised.
    This has nothing to do with anything you've said above. It doesn't even prove a point. I am quite convinced you have no idea what you're talking about; if you were a programmer working for me, I can almost assure you you'd be out of a job pretty quickly. I'd want programmers who embrace new things, not ones who arrogantly disregard all that is not perfect as deemed by them. If you didn't read or understand anything else I said, at least ponder on that note for a little while.
    Last edited by Mad_guy; 08-13-2007 at 07:45 AM.
    operating systems: mac os 10.6, debian 5.0, windows 7
    editor: back to emacs because it's more awesomer!!
    version control: git

    website: http://0xff.ath.cx/~as/

  5. #35
    chococoder
    Join Date
    Nov 2004
    Posts
    515
    Given that F# already exists, someone seems to have forgotten E and using D is way outdated
    Of course J# also exists, and actually predates F#.

  6. #36
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by Mad_guy View Post
    You talk as if you program flawlessly (which, I can assure you of something: you don't,) and talk of other people as if they don't.
    If it's so simple, why are you not leading the revolution in software design? So far, your solution looks like nothing more than just "dealing with what we have now, because it's the best solution to the problem and always will be." This is one of the most asinine things I have heard in a very long time.
    Debuggers need to do the same job once what a run-time environment does every time you run the application.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  7. #37
    Disrupting the universe Mad_guy's Avatar
    Join Date
    Jun 2005
    Posts
    258
    Quote Originally Posted by maxorator View Post
    Debuggers need to do the same job once what a run-time environment does every time you run the application.
    The fact of the matter is, a runtime environment encapsulates a lot more than what a debugger does; they're completely different things. You have to be aware of a bug to put a debugger to any use (given this context.)
    If you, for example, have a program written in C that has a bug, say, it writes to an array one element out of bounds, it might not manifest itself in any meaningful way given a certain range of inputs while with others, it very well may. With a runtime doing your checking, you are guaranteed it will always catch the invalid memory access, regardless of the input, regardless if it's 'visible' as far as you're concerned, as long as it happens. It still gets caught. The runtime just made sure something very bad like arbitrary code execution didn't happen.

    You're doing nothing more than completely avoiding the point under the garb of 'efficiency.' These arguments do not work, and personally, I would rather have the runtime throw me an array out of bounds exception than simply have the bug go unnoticed and/or have it manifest in some arcane or possibly volatile and destructive way. I would also much rather be correct and have it take a little more time, than be flawed and have it go fast.
    Last edited by Mad_guy; 08-13-2007 at 08:50 AM.
    operating systems: mac os 10.6, debian 5.0, windows 7
    editor: back to emacs because it's more awesomer!!
    version control: git

    website: http://0xff.ath.cx/~as/

  8. #38
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Trying to write to the code section should trigger a general protection fault. Trying to write to an unallocated memory will certainly fail too. And data is usually in the data section, which is after the code section.

    The example you brought is a serious mistake. I usually double-check the allowed ranges when dealing with arrays.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  9. #39
    Disrupting the universe Mad_guy's Avatar
    Join Date
    Jun 2005
    Posts
    258
    Quote Originally Posted by maxorator View Post
    Trying to write to the code section should trigger a general protection fault. Trying to write to an unallocated memory will certainly fail too. And data is usually in the data section, which is after the code section.
    What you said does not apply to local variables that're allocated on the stack (which is where my example fits in.) In this case, writing to a variable outside of bounds is perfectly 'legal' and will it will cause undefined behavior (of which an access violation is certainly a possibility. Writing to an array outside it's bounds is a common programming error and vulnerability.)

    Example:

    Code:
    [austin@continuum ~]$ cat > test.c
    int main() {
      int test[5];
      test[7] = 1;
      return 0;
    }
    [austin@continuum ~]$ gcc-3.4 test.c
    [austin@continuum ~]$ ./a.out
    [austin@continuum ~]$ echo $?
    0
    [austin@continuum ~]$
    (Note, I'm using gcc-3.4 here because my gcc (4.2.1) on this system is currently broken (most likely a binutils incompatability I need to work out,) not because it just suits my case in point or anything.)

    This is what I'm talking about. I think you need to refresh yourself on how things like memory layout are typically done in a C-written program (and probably more about binary executable formats in general, too.)

    The example you brought is a serious mistake. I usually double-check the allowed ranges when dealing with arrays.
    Yes, that's good for you. But no matter what you say, the runtime can do a better job of making sure your memory writes are *inside* array bounds than you can when dealing with this sort of stuff manually, I can guarantee you (why? Because that's its job. It has far more intimate knowledge about how the memory is managed internally than you do, so don't fool yourself into thinking you could really do a better job manually than it does automatically. The people who designed these types of environments are not stupid, no matter what you'd like to think.)
    Last edited by Mad_guy; 08-13-2007 at 10:14 AM.
    operating systems: mac os 10.6, debian 5.0, windows 7
    editor: back to emacs because it's more awesomer!!
    version control: git

    website: http://0xff.ath.cx/~as/

  10. #40
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by Mad_guy View Post
    This is what I'm talking about. I think you need to refresh yourself on how things like memory layout are typically done in a C-written program (and probably more about binary executable formats in general, too.)
    I know what you're talking about. And as a reverse engineer I have quite a good idea how the memory layout works. Though I didn't assume you were talking about local variables, because it is not a good idea to allocate large arrays as local variables and with smaller arrays it's not likely to make a mistake like this.
    Quote Originally Posted by Mad_guy View Post
    Yes, that's good for you. But no matter what you say, the runtime can do a better job of making sure your memory writes are *inside* array bounds than you can when dealing with this sort of stuff manually, I can guarantee you (why? Because that's its job. It has far more intimate knowledge about how the memory is managed internally than you do, so don't fool yourself into thinking you could really do a better job manually than it does automatically. The people who designed these types of environments are not stupid, no matter what you'd like to think.)
    Of course they knew what they were doing when they designed the run-time environment. But if most of the bugs could be detected on compile-time, then why do we need the run-time environment to deal with the rest 5%? If a programmer learns from his mistakes then he will very soon learn to avoid these mistakes. There aren't very much different common mistakes.

    Critical bugs should be caught while testing the program. Using a run-time environment is like publishing a debug version of the program.
    Last edited by maxorator; 08-13-2007 at 10:37 AM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  11. #41
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Namespaces - what do they solve? I don't think you'll have so many functions that you run out of letter combinations for a function.
    They allow one to use names appropriate for the domain model, even when the name is already in use, without always having to resort to some (library) prefix, assuming appropriate use of using declarations and directives.

    They just teach us bad habits like always giving the functions the same names in libraries
    I do not see how naming appropriately is a bad habit. Convoluted naming, on the other hand (letter combinations?), is a bad habit.

    Const keyword - the most useless thing on earth. If I want a value not to be changed, why not use macros?
    It looks like you are overlooking the fact that const is not just used to declare constants, but also as a design mechanism to inform users of a function that an argument passed by reference will not be changed, or to enforce no changes to an argument passed by value. Macros do not respect scope and are not typesafe.

    And who would be that stupid to accidentally modify a variable which is not supposed to be modified.
    A future maintainer of the code, which may well include yourself coming back to maintain your own code.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #42
    Disrupting the universe Mad_guy's Avatar
    Join Date
    Jun 2005
    Posts
    258
    Quote Originally Posted by maxorator View Post
    Of course they knew what they were doing when they designed the run-time environment. But if most of the bugs could be detected on compile-time, then why do we need the run-time environment to deal with the rest 5%?
    See above:
    The fact of the matter is, a runtime environment encapsulates a lot more than what a debugger does...
    This includes things like thread management (in the case of green threads,) resource utilization, profiling and garbage collection.


    Look, my point isn't that you "catch all bugs," the point of my previous (long) post was that we catch a substantial amount with them with an addition like a strong type system. You said in Rashakil's post he didn't really outline anything that was 'useful,' when in fact, he did. He pointed out a few of REALLY useful things. And even this isn't my overall point, see below.


    Critical bugs should be caught while testing the program. Using a run-time environment is like publishing a debug version of the program.
    This comparison makes absolutely no sense, you're simply refusing to get the point of what I'm telling you: that these additions do make writing software easier and they do solve some problems with software development.

    Do they solve them all? No. There is no silver bullet.

    Do they help? Most certainly. That is my overall point, and you are simply stinting progress by saying things like this do not help and they're just a way to justify "careless" programming, and it's obvious you will never understand that until you have first hand experiance with it.

    All you're advocating that programmers "don't need help, they just need to suck less." This is the completely wrong approach to the whole situation, since there are more factors to it than your software "being written."
    Development time, safety, scalability, code quality, reusability, functionality, expressiveness. If we want to acheive these things, we have to make progress and move forward and adopt new ideas, rather than just be stubborn and 'hardcore' by using outdated, unsuited, unreliable and, to be honest, stupid development tools (note that I'm not pointing fingers here, I'm merely speaking in general.) No matter what way you paint it, a pig wearing lipstick is still a pig. You are doing nothing other than halting progress by saying these things, which, fyi, do make writing software easier "aren't needed." If there is a better textbook definition of "halting progress" than this, please, point it out to me.



    Software development is hard. It always will be hard, and there probably won't ever be a clean cut solution to the whole deal. But we can be smart and adopt new ideas and techniques to make the process easier and the quality better overall. That's called progress.

    Would you also advocate the use of wood to build skyscrapers and say that steel isn't needed, people just need to learn how to "build things better"?
    Didn't think so.
    Last edited by Mad_guy; 08-13-2007 at 11:39 AM.
    operating systems: mac os 10.6, debian 5.0, windows 7
    editor: back to emacs because it's more awesomer!!
    version control: git

    website: http://0xff.ath.cx/~as/

  13. #43
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    Quote Originally Posted by maxorator View Post
    Garbage collection is an "alibi" to do careless programming.
    Garbage collection lets you turn subroutines into functions.

    Quote Originally Posted by maxorator
    Most of the stuff you mentioned doesn't give any real advantages.
    Any nontrivial non-real-time problem can be solved in 1/5 the time by me using Haskell than by me or you using C.
    There are 10 types of people in this world, those who cringed when reading the beginning of this sentence and those who salivated to how superior they are for understanding something as simple as binary.

  14. #44
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by Rashakil Fol View Post
    Garbage collection lets you turn subroutines into functions.
    C doesn't have garbage collection and it has functions.

    what do you think the difference is between a subroutine and a function?

  15. #45
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    Quote Originally Posted by robwhit View Post
    C doesn't have garbage collection and it has functions.

    what do you think the difference is between a subroutine and a function?
    I'm not using C terminology. I mean you can write functions and use them as functions (in the mathematical sense) instead of using them like subroutines.
    There are 10 types of people in this world, those who cringed when reading the beginning of this sentence and those who salivated to how superior they are for understanding something as simple as binary.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What language did they make Java in?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 17
    Last Post: 07-03-2005, 04:18 PM
  2. Strange loop
    By D@rk_force in forum C++ Programming
    Replies: 22
    Last Post: 12-18-2004, 02:40 PM
  3. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  4. Language of choice after C++
    By gandalf_bar in forum A Brief History of Cprogramming.com
    Replies: 47
    Last Post: 06-15-2004, 01:20 AM
  5. Language Script..
    By vasanth in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 03-30-2003, 06:48 AM