Dang, no wonder I've been struggling with it. Well it would be cool if I can figure it out. If I can get that and register allocation working, I'd be goldenbwat wrote:Figuring that stuff takes a lot longer than a couple of days! The dragon book has over 100 pages on parsing (chap 4) and from the looks of it, LR parsing and parser table generation is about half of that chapter. I've got volumes I and II of Parsing Theory by Sippu and Soisalon-Soininen, and together they're over 600 pages and of those about 200 cover LR parsing and table generation (the first volume covers the basics needed to understand parsing in general and that's another 200 pages). It's a big subject and you shouldn't be surprised if it takes time to get it. If you do make the effort then you'll have a skill that you'll find yourself using in all manner of different types of programs.Joshw wrote:I've really just struggled for a day or two on figuring out how to compute the parse table, and handling shift/reduce conflicts, etc.
Self hosting OS/Compiler from scratch
-
- Member
- Posts: 46
- Joined: Wed Mar 05, 2008 4:41 pm
- Location: San Francisco, California, USA
- Contact:
Re: Self hosting OS/Compiler from scratch
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Re: Self hosting OS/Compiler from scratch
A hobby osdever has basically two options. Either he can write yet another clone of Unix, and then port gcc/binutils to his new OS, or else, at some point along the road, he has to write a tool set for his brand spanking new OS.Brendan wrote:If you're able to run the native compiler on Linux, then you should start by splitting your "tools + OS" project into 2 separate projects and then forget about the OS until after the "tools" project is finished (and possibly forget about the OS completely, given that there'd be at least 5 well established "work alike" OS projects you can join and/or fork instead).
Last edited by mathematician on Mon Jan 20, 2014 4:22 pm, edited 1 time in total.
The continuous image of a connected set is connected.
Re: Self hosting OS/Compiler from scratch
Hi,
I mostly use kwrite (no screen space wasted on distractions and fast startup times). My build utility starts via. a keyboard macro whenever I press F12 (and typically completes within 10 ms). I don't need (or want) a huge bloated IDE.
The first version is crap; because there are zero comments explaining what it's supposed to do, it doesn't use enough temporary variables (which is why you had to spread a single "return" statement across 3 entire lines), all the complexity (and all the bugs, optimisation opportunities, etc) are hidden from people that need to see it, and it's far too easy for anyone to make the assumption that it's working on plain floating point values rather than vectors.
Note: One of the first things I'd do to clean up this mess is to replace your "max(dot(normal, l->dir), 0.0)" with "abs(dot(normal, l->dir))", but (given that I do know it's not normal math) I'd have to assume you failed to overload "abs()" and my change will break the code for no "obvious to me at the time" reason.
The second version is crap; because it also has zero comments explaining what it's supposed to do, it has a compile time error (bracketing mismatch), and the "temporary variable deficiency" was allowed to reach critical levels by a desperate man clutching at straws and resorting to the most obviously biased example I've seen for at least 3 weeks.
Note: For a readable example, see the example on wikipedia.
Cheers,
Brendan
Maybe you're using over-complicated languages that require over-complicated tools?Owen wrote:Maybe you're using crappy tools?Brendan wrote:There's nothing irrational about it. The time it'd take someone to figure out that '*' has been overloaded and to find the code for the overloaded '*' is greater than the time it'd take for someone to figure out that "vector_mul()" differs from the standard '*' operator and to find the code for it (in a file hopefully called "vector.c").Owen wrote:Of course, I also understand that you're irrationally scared that a "a * b" in the face of operator overloading might cause b to be printed to a, but are not at all scared that "vector_mul(a, b)" will do the same (and think that vector math code should be horrible to write or read as a result), so there's that...
For a small project (e.g. where all code fits on the same screen) the difference is negligible. For a large project (e.g. where no member of the team is able to remember every single little detail at any point in time) the sum of all the little "Um, I can't remember what this actually is" moments adds up to a massive disaster for code maintenance.
I mostly use kwrite (no screen space wasted on distractions and fast startup times). My build utility starts via. a keyboard macro whenever I press F12 (and typically completes within 10 ms). I don't need (or want) a huge bloated IDE.
You hover over the asterisk by accident while you're trying to concentrate on something important, and some stupid context sensitive menu thing gets stuffed into your face? Next time you've got a few hours to spare you might want to hunt through the IDE's manual and see if you can change that to "right click" instead of "hover".Owen wrote:I hover over the asterisk in "a * b" and hit the "Go to definition key".
As someone that likes readable code, they're both crap.Owen wrote:Of course, as somebody who understands the mathematics, the codeis a lot less obtuse thanCode: Select all
auto reflection = -reflect(l->dir, normal); return l->ambient + l->diffuse * max(dot(normal, l->dir), 0.0) + l->specular * pow(max(dot(reflection, -transformedPosition), 0.0), m->shininess;
Code: Select all
auto reflection = -vec3float_reflect(l->dir, normal); return vec3float_add(l->ambient, vec3float_add(vec3float_mul(l->diffuse, vec3float_max(vec3float_dot(normal, l->dir), vec3float_spread(0.0))), vec3float_mul(l->specular, vec3float_pow_float(vec3float_max(vec3float_dot(reflection, vec3float_sub(vec3float_spread(0), transformedPosition)), vec3float_spread(0.0)), m->shininess)));
The first version is crap; because there are zero comments explaining what it's supposed to do, it doesn't use enough temporary variables (which is why you had to spread a single "return" statement across 3 entire lines), all the complexity (and all the bugs, optimisation opportunities, etc) are hidden from people that need to see it, and it's far too easy for anyone to make the assumption that it's working on plain floating point values rather than vectors.
Note: One of the first things I'd do to clean up this mess is to replace your "max(dot(normal, l->dir), 0.0)" with "abs(dot(normal, l->dir))", but (given that I do know it's not normal math) I'd have to assume you failed to overload "abs()" and my change will break the code for no "obvious to me at the time" reason.
The second version is crap; because it also has zero comments explaining what it's supposed to do, it has a compile time error (bracketing mismatch), and the "temporary variable deficiency" was allowed to reach critical levels by a desperate man clutching at straws and resorting to the most obviously biased example I've seen for at least 3 weeks.
Note: For a readable example, see the example on wikipedia.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Self hosting OS/Compiler from scratch
Not really. The conflict that you can't port a lot of software if you don't support POSIX is very real. But what a compiler requires from the OS is simple enough that POSIX compatibility is really not necessary for that. You can just port it over using your native APIs.mathematician wrote:A hobby osdever has basically two options. Either he can write yet another clone of Unix, and then port gcc/binutils to his new OS, or else, at some point along the road, he has to write a tool set for his brand spanking new OS.
Now I remember why discussing with you is so unproductive. You disagree with the most obvious and most fundamental software engineering principles, and the worst thing about it is that you seem to be serious.Brendan wrote:The opposite actually. Only needing to worry about one case (your own specific case) is an order of magnitude easier than worrying about many potential cases (templates).Kevin wrote:If you copy instead of share, or if you don't have type safety, you increase the complexity and make it a lot harder to verify correctness.
Worrying about an implementation for one specific case may be easier than worrying about an implementation for many similar cases (it may just as well be the same effort, though, because when I ask for a list, I usually want a plain stupid linked list and performance doesn't matter, so the implementation is exactly the same in all cases - starting to talk about fancy hash table thingies doesn't prove that you thought harder, but that you missed the point).
In any case, worrying about n implementations of n specific cases is magnitudes harder than maintaining a single implementation for n users. Everybody who knows a bit about software engineering will tell you this, and if you did actually write real-world code instead of just theorising about your software world revolution, your own experience would say the same. (In fact I think you're clever enough to come to the same conclusion even without trying it out, but that would still require that you're even willing to accept that thought.)
Re: Self hosting OS/Compiler from scratch
Hi,
Let me tell you something. Your OS looks amazing. It's not the first OS to look amazing and won't be the last. People at Apple aren't going to be thinking "Wow, that's an ingenious new way to do file systems". Microsoft aren't going to wish their IPC was as elegant as yours. Andrew Tanenbaum won't be using your OS to teach new students how to do distributed systems properly. It won't inspire research papers or create new interest in micro-kernels. The Xorg/Wayland team won't be so impressed that they'll radically redesign the Linux graphics stack. The HPC people aren't going to launch an investigation into why Linux doesn't scale as well as your OS. If it "succeeds", nobody outside these forums will notice because there's nothing even slightly interesting or unique about it. It's just other people's code ported on top of an uninspired yawn. I've seen it all before; and I can tell you now it will not succeed. What will probably happen is that you'll persevere for about 3 more years, but as time passes your motivation will fade, until inevitably your dull little OS will sink into obscurity.
The ironic thing is that there's only one way to prevent this decline. If you want your OS to matter one day, you're going to have to find new and interesting ways to do things that other people probably wouldn't even consider. Your only hope is to invest a lot of time, money and effort into finding and researching innovative new ideas, and question everything that you've grown to consider "standard practice". Your only hope is to become more like me.
Now try to imagine what happens if you manage to do anything interesting enough for other people to bother with. Where do you think you're going to get application developers from if you can't just port the same tired old GNU stuff that almost every other alternative OS uses? Your application developers aren't going to be the 5 people on earth that actually have managed to understand all of C++11 (or the 5000 people that only think they've managed to do this). It's not going to be professional/experienced programmers at all. It's going to be amateurs and university students that are interested in "tinkering" but have no real experience and little or no training (and aren't cursed by prior misconceptions at all, and don't notice that it's all very different). They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
So...
Cheers,
Brendan
..assuming the native APIs provide "similar enough behaviour". For some examples, my OS will never have anything like STDIN, STDOUT, STDERR; will never let anyone open a file as 'read/write'; won't allow any application to read "plain text"; and won't allow something allocated on one thread's stack to be accessed by any other thread. This is just the tip of the iceberg. Porting a compiler to an OS that's actually different (rather than just "same with superficial implementation differences") is likely to be extremely problematic.Kevin wrote:Not really. The conflict that you can't port a lot of software if you don't support POSIX is very real. But what a compiler requires from the OS is simple enough that POSIX compatibility is really not necessary for that. You can just port it over using your native APIs.mathematician wrote:A hobby osdever has basically two options. Either he can write yet another clone of Unix, and then port gcc/binutils to his new OS, or else, at some point along the road, he has to write a tool set for his brand spanking new OS.
I don't just seem to be serious - I am serious. Complexity is the single largest problem facing programmers. Making languages more complex is not going to help.Kevin wrote:Now I remember why discussing with you is so unproductive. You disagree with the most obvious and most fundamental software engineering principles, and the worst thing about it is that you seem to be serious.Brendan wrote:The opposite actually. Only needing to worry about one case (your own specific case) is an order of magnitude easier than worrying about many potential cases (templates).Kevin wrote:If you copy instead of share, or if you don't have type safety, you increase the complexity and make it a lot harder to verify correctness.
Um, do you understand that a singly linked list is extremely easy to implement (e.g. literally easier than trying to remember what header file to #include)?Kevin wrote:Worrying about an implementation for one specific case may be easier than worrying about an implementation for many similar cases (it may just as well be the same effort, though, because when I ask for a list, I usually want a plain stupid linked list and performance doesn't matter, so the implementation is exactly the same in all cases - starting to talk about fancy hash table thingies doesn't prove that you thought harder, but that you missed the point).
Why would you need to maintain any implementation for any other users? Are these other programmers so incompetent that they can't write their own? Maybe it's because they've been spoonfed libraries to do trivial things for far too long?Kevin wrote:In any case, worrying about n implementations of n specific cases is magnitudes harder than maintaining a single implementation for n users.
Sigh. The truth? I find your attitude personally offensive. I usually do, but I usually say nothing. I've spent (and will continue to spend) a massive amount of time, money and effort trying to find, invent and research new and unique ideas that may (or may not) make things cleaner and easier for end users and the IT industry as a whole (of which, programmers like you and I are irrelevant). My goal is not to create another "hobbyist" OS - I've already done that several times. My goal is not to create a drop-in replacement for Linux or Windows either (that's a doomed strategy that doesn't interest me). My goal is to innovate, and I don't care if it takes me 20 years before I reach the "kernel that boots and does something" stage (again). Because I do this research (instead of just recycling the same old stuff everyone else has done for the last 40 years and having code to show for my efforts) you think that's a great excuse to put me down and dismiss my work?Kevin wrote:Everybody who knows a bit about software engineering will tell you this, and if you did actually write real-world code instead of just theorising about your software world revolution...
Let me tell you something. Your OS looks amazing. It's not the first OS to look amazing and won't be the last. People at Apple aren't going to be thinking "Wow, that's an ingenious new way to do file systems". Microsoft aren't going to wish their IPC was as elegant as yours. Andrew Tanenbaum won't be using your OS to teach new students how to do distributed systems properly. It won't inspire research papers or create new interest in micro-kernels. The Xorg/Wayland team won't be so impressed that they'll radically redesign the Linux graphics stack. The HPC people aren't going to launch an investigation into why Linux doesn't scale as well as your OS. If it "succeeds", nobody outside these forums will notice because there's nothing even slightly interesting or unique about it. It's just other people's code ported on top of an uninspired yawn. I've seen it all before; and I can tell you now it will not succeed. What will probably happen is that you'll persevere for about 3 more years, but as time passes your motivation will fade, until inevitably your dull little OS will sink into obscurity.
The ironic thing is that there's only one way to prevent this decline. If you want your OS to matter one day, you're going to have to find new and interesting ways to do things that other people probably wouldn't even consider. Your only hope is to invest a lot of time, money and effort into finding and researching innovative new ideas, and question everything that you've grown to consider "standard practice". Your only hope is to become more like me.
Now try to imagine what happens if you manage to do anything interesting enough for other people to bother with. Where do you think you're going to get application developers from if you can't just port the same tired old GNU stuff that almost every other alternative OS uses? Your application developers aren't going to be the 5 people on earth that actually have managed to understand all of C++11 (or the 5000 people that only think they've managed to do this). It's not going to be professional/experienced programmers at all. It's going to be amateurs and university students that are interested in "tinkering" but have no real experience and little or no training (and aren't cursed by prior misconceptions at all, and don't notice that it's all very different). They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
So...
Everyone that knows a bit about software engineering is.... less important than a school-kid that's spent 2 days diddling with something like GameMaker.Kevin wrote:In any case, worrying about n implementations of n specific cases is magnitudes harder than maintaining a single implementation for n users. Everybody who knows a bit about software engineering will tell you this, and...
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Self hosting OS/Compiler from scratch
My IDE takes around a second to start up. The only screen space which isn't editor or toolbar is the project navigator, which is a generally useful thing.Brendan wrote:Hi,
Maybe you're using over-complicated languages that require over-complicated tools?Owen wrote:Maybe you're using crappy tools?Brendan wrote:There's nothing irrational about it. The time it'd take someone to figure out that '*' has been overloaded and to find the code for the overloaded '*' is greater than the time it'd take for someone to figure out that "vector_mul()" differs from the standard '*' operator and to find the code for it (in a file hopefully called "vector.c").
For a small project (e.g. where all code fits on the same screen) the difference is negligible. For a large project (e.g. where no member of the team is able to remember every single little detail at any point in time) the sum of all the little "Um, I can't remember what this actually is" moments adds up to a massive disaster for code maintenance.
I mostly use kwrite (no screen space wasted on distractions and fast startup times). My build utility starts via. a keyboard macro whenever I press F12 (and typically completes within 10 ms). I don't need (or want) a huge bloated IDE.
My compiles might take longer (but then again I use tools which let me think about the problem, not the minutiae of the hoops I'm going to make the processor jump through)
KEY.Brendan wrote:You hover over the asterisk by accident while you're trying to concentrate on something important, and some stupid context sensitive menu thing gets stuffed into your face? Next time you've got a few hours to spare you might want to hunt through the IDE's manual and see if you can change that to "right click" instead of "hover".Owen wrote:I hover over the asterisk in "a * b" and hit the "Go to definition key".
I hover over the asterisk and hit F2.
As someone that likes readable code, they're both crap.Brendan wrote:Code: Select all
auto reflection = -vec3float_reflect(l->dir, normal); return vec3float_add(l->ambient, vec3float_add(vec3float_mul(l->diffuse, vec3float_max(vec3float_dot(normal, l->dir), vec3float_spread(0.0))), vec3float_mul(l->specular, vec3float_pow_float(vec3float_max(vec3float_dot(reflection, vec3float_sub(vec3float_spread(0), transformedPosition)), vec3float_spread(0.0)), m->shininess)));
The first version is crap; because there are zero comments explaining what it's supposed to do, it doesn't use enough temporary variables (which is why you had to spread a single "return" statement across 3 entire lines), all the complexity (and all the bugs, optimisation opportunities, etc) are hidden from people that need to see it, and it's far too easy for anyone to make the assumption that it's working on plain floating point values rather than vectors.[/quote]
Its' a blinn-phong shader! Its' probably in a function "blinnPhong", maybe in the file "blinnPhong.whatever"
Do you get anything from those extra temporaries? I don't. I can see the maths that's happening straight away.
abs(dot(normal, l->dir)) would break the code for the obvious to me reason that abs(x) != max(x, 0.0). The latter is a a clamp to >= 0, not a sign removal.Brendan wrote:Note: One of the first things I'd do to clean up this mess is to replace your "max(dot(normal, l->dir), 0.0)" with "abs(dot(normal, l->dir))", but (given that I do know it's not normal math) I'd have to assume you failed to overload "abs()" and my change will break the code for no "obvious to me at the time" reason.
You're right, to an extent: If I was forced to work within such a crippled, inexpressive environment, I would use more temporaries.Brendan wrote:The second version is crap; because it also has zero comments explaining what it's supposed to do, it has a compile time error (bracketing mismatch), and the "temporary variable deficiency" was allowed to reach critical levels by a desperate man clutching at straws and resorting to the most obviously biased example I've seen for at least 3 weeks.
That doesn't excuse the crippled environment for anything. Its' made my code hard to read, not me.
If you're working on a project where someone is doing Blinn-Phong and you don't understand Blinn-Phong... you haven't gone and done the prerequisite reading first.Brendan wrote:Note: For a readable example, see the example on wikipedia.
-----
You seem to be hung up on the complexity of C++.Brendan wrote:Now try to imagine what happens if you manage to do anything interesting enough for other people to bother with. Where do you think you're going to get application developers from if you can't just port the same tired old GNU stuff that almost every other alternative OS uses? Your application developers aren't going to be the 5 people on earth that actually have managed to understand all of C++11 (or the 5000 people that only think they've managed to do this). It's not going to be professional/experienced programmers at all. It's going to be amateurs and university students that are interested in "tinkering" but have no real experience and little or no training (and aren't cursed by prior misconceptions at all, and don't notice that it's all very different). They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
Let it go.
Pick another language.
High level doesn't mean complex.
I mean, as an implementation detail, it probably does.
But as a user? I can't think of anything less.
Now, as for the people who are going to go and pick up a new OS and a new language and play with it?
Hobbyists, yes. But overwhelmingly those who learn how to program learn how to do so to do something, and they aren't going to be able to do that effectively with 1970s era tools like raw unprotected pointers.
Give them a garbage collector. Give them pre-made collections. Give them a bunch of libraries.
And watch them fly.
Give them simpler. Not simpler to implement. Simpler to use.
Re: Self hosting OS/Compiler from scratch
Hi,
For what I'm aiming for eventually (where executables are compiled when they're first executed) fast build times are just as important for different reasons.
However; for this discussion, simpler languages do mean easier to write tools. Given the choice between implementing (e.g.) a Pascal compiler and implementing (e.g.) a C++ compiler, I'm sure most people would decide a Pascal compiler is easier to implement.
Cheers,
Brendan
Sounds better than Eclipse at least.Owen wrote:My IDE takes around a second to start up. The only screen space which isn't editor or toolbar is the project navigator, which is a generally useful thing.Brendan wrote:Maybe you're using over-complicated languages that require over-complicated tools?Owen wrote:Maybe you're using crappy tools?
I mostly use kwrite (no screen space wasted on distractions and fast startup times). My build utility starts via. a keyboard macro whenever I press F12 (and typically completes within 10 ms). I don't need (or want) a huge bloated IDE.
If something takes more than about 3 minutes I end up going for coffee or watching TV or something, getting back 5 minutes after it's finished and by then it takes a further few minutes to figure out what I was doing. I also build frequently (like every 20 minutes or so on average, but sometimes 5 times in 10 minutes) to catch simple errors sooner. Getting the "compile then test, then continue" time down to less than 30 seconds saves a massive amount of time; which is part of the reason I put a lot of work into my little build utility (which is also part of the reason I can build everything so fast - the other part of fast build times is avoiding "slow to compile" languages).Owen wrote:My compiles might take longer (but then again I use tools which let me think about the problem, not the minutiae of the hoops I'm going to make the processor jump through)
For what I'm aiming for eventually (where executables are compiled when they're first executed) fast build times are just as important for different reasons.
The only reason I knew what it was is that you said in your post - I couldn't have know if I were looking at the code you posted alone.Owen wrote:Its' a blinn-phong shader! Its' probably in a function "blinnPhong", maybe in the file "blinnPhong.whatever"Brendan wrote:As someone that likes readable code, they're both crap.Owen wrote:Code: Select all
auto reflection = -vec3float_reflect(l->dir, normal); return vec3float_add(l->ambient, vec3float_add(vec3float_mul(l->diffuse, vec3float_max(vec3float_dot(normal, l->dir), vec3float_spread(0.0))), vec3float_mul(l->specular, vec3float_pow_float(vec3float_max(vec3float_dot(reflection, vec3float_sub(vec3float_spread(0), transformedPosition)), vec3float_spread(0.0)), m->shininess)));
The first version is crap; because there are zero comments explaining what it's supposed to do, it doesn't use enough temporary variables (which is why you had to spread a single "return" statement across 3 entire lines), all the complexity (and all the bugs, optimisation opportunities, etc) are hidden from people that need to see it, and it's far too easy for anyone to make the assumption that it's working on plain floating point values rather than vectors.
Yes - you get easier to read code, because the name of a temporary variable is a much bigger clue about what's going on than an unnamed sub-expression nested inside another expression.Owen wrote:Do you get anything from those extra temporaries? I don't. I can see the maths that's happening straight away.
Heh - you're right.Owen wrote:abs(dot(normal, l->dir)) would break the code for the obvious to me reason that abs(x) != max(x, 0.0). The latter is a a clamp to >= 0, not a sign removal.
I still think the operator overloading is a trap for people that aren't as familiar with the codebase as the person who wrote the code (which tends to include the person that wrote the code after they've been working on some other project for a few months).Owen wrote:You're right, to an extent: If I was forced to work within such a crippled, inexpressive environment, I would use more temporaries.Brendan wrote:The second version is crap; because it also has zero comments explaining what it's supposed to do, it has a compile time error (bracketing mismatch), and the "temporary variable deficiency" was allowed to reach critical levels by a desperate man clutching at straws and resorting to the most obviously biased example I've seen for at least 3 weeks.
That doesn't excuse the crippled environment for anything. Its' made my code hard to read, not me.
If a team of 5 programmers are working on writing a game; 1 is working on some sort of quest scripting system, 1 is working on sound and networking, 1 is doing AI, one is doing sound and a 2D menu system, and 1 is doing 3D graphics; then every single developer is going to know about Blinn-Phong when a bug is discovered and the person that was handling 3D graphics is on holidays?Owen wrote:If you're working on a project where someone is doing Blinn-Phong and you don't understand Blinn-Phong... you haven't gone and done the prerequisite reading first.Brendan wrote:Note: For a readable example, see the example on wikipedia.
I'm not hung up on C++. Any language that is pointlessly overcomplicated and harder to learn, use, debug, read or compile is bad; and I'm sure I've complained about plenty of other languages in the past. The only reason I haven't complained about C# (which is where this discussion started) is that C# is much cleaner/easier than C++ in just about every possible way.Owen wrote:You seem to be hung up on the complexity of C++.Brendan wrote:Now try to imagine what happens if you manage to do anything interesting enough for other people to bother with. Where do you think you're going to get application developers from if you can't just port the same tired old GNU stuff that almost every other alternative OS uses? Your application developers aren't going to be the 5 people on earth that actually have managed to understand all of C++11 (or the 5000 people that only think they've managed to do this). It's not going to be professional/experienced programmers at all. It's going to be amateurs and university students that are interested in "tinkering" but have no real experience and little or no training (and aren't cursed by prior misconceptions at all, and don't notice that it's all very different). They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
Let it go.
Pick another language.
High level doesn't mean complex, and complex doesn't mean high level. For example, I consider Java to be higher level than C++ and also less complex.Owen wrote:High level doesn't mean complex.
Not sure what you mean here. As a user of the compiler (e.g. a programmer) learning the language is your first hurdle, and the more complex it is the harder it is to learn and the more experience you need before you learn to avoid pitfalls. As a user of applications or the user of an OS it makes no difference (except for number of bugs, but there's many factors involved in that).Owen wrote:I mean, as an implementation detail, it probably does.
But as a user? I can't think of anything less.
You're right, and I do know that eventually (for what I'm doing) I will need a higher level "high level language". That's not my immediate concern though (I need OS and native tools first).Owen wrote:Now, as for the people who are going to go and pick up a new OS and a new language and play with it?
Hobbyists, yes. But overwhelmingly those who learn how to program learn how to do so to do something, and they aren't going to be able to do that effectively with 1970s era tools like raw unprotected pointers.
Give them a garbage collector. Give them pre-made collections. Give them a bunch of libraries.
And watch them fly.
Give them simpler. Not simpler to implement. Simpler to use.
However; for this discussion, simpler languages do mean easier to write tools. Given the choice between implementing (e.g.) a Pascal compiler and implementing (e.g.) a C++ compiler, I'm sure most people would decide a Pascal compiler is easier to implement.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Self hosting OS/Compiler from scratch
I agree with the fact that the debug cycle time, should be minimized. And that it should preferably be kept in the domain of seconds. However with proper code separation, and intelligent tools, you should only be compiling your changes (and linking the executable), whenever a change was made. If this takes more than a few seconds, then you're doing it wrong.Brendan wrote: If something takes more than about 3 minutes I end up going for coffee or watching TV or something, getting back 5 minutes after it's finished and by then it takes a further few minutes to figure out what I was doing. I also build frequently (like every 20 minutes or so on average, but sometimes 5 times in 10 minutes) to catch simple errors sooner. Getting the "compile then test, then continue" time down to less than 30 seconds saves a massive amount of time; which is part of the reason I put a lot of work into my little build utility (which is also part of the reason I can build everything so fast - the other part of fast build times is avoiding "slow to compile" languages).
For what I'm aiming for eventually (where executables are compiled when they're first executed) fast build times are just as important for different reasons.
I do agree with the fact that C++ is waaaay harder to compile than C, indeed if template meta programming is utilized, however if only changes are to be recompiled at each iteration, then this should not be a major issue. I don't mind a full recompilation taking a few minutes if only the debug cycle time is within seconds.
As for 10ms compilation. I honestly have no problem 'waiting' for a few seconds, as I'll likely be thinking meanwhile, but maybe that's just because I'm not a "10ms debug cycle time" kinda guy.
Operator overloading *can* be a trap, that is if it's used non-intuitively. I honestly believe that it allows for cleaner code, indeed in terms of linear algebra, because it allows you to express what you do in math, that is it allows you to use the multiplication symbol, when you use it in math.Brendan wrote: I still think the operator overloading is a trap for people that aren't as familiar with the codebase as the person who wrote the code (which tends to include the person that wrote the code after they've been working on some other project for a few months).
And being able using the multiplication operator, when you expect to be able to use it, e.g. for multiplying matrices, allows you to not know the codebase at all, but rely on the common understanding of the underlaying mathematical construct, or as we like to refer to it; The interface. - That is your now coding against the mathematically accepted interface, rather than some implementation specific one, which may or may not throw implementation specific details, parameters and such at you.
To quote a rather intelligent fella on this forum;
I truly agree with this statement! - And that's why would should hide all the complexity of implementations behind interfaces. Operator overloading can help us provide a intuitive interface. Templates can help us provide a generic and common interface for specialized implementations. - Both of these are complex to implement, but easy to use. And that's the main point here, the burden is on the implementer, and not on the user.Brendan wrote: Complexity is the single largest problem facing programmers.
If I want to use a list, then all I want is to be able to store my data (the interface), how the data is stored is up to the implementation, which I expect to do the right thing, i.e. split my data into hot and cold sections, ect.
If I want to multiply vectors, then I'll just use the multiplication operator (the interface), and it's up to the implementation to do it, in the optimal way given the available hardware, ect.
I actually agree with you on this, C++ is an overcomplicated language, and it is hard to learn, use, debug, ect., and honestly one of the main reasons why C++ is overly complicated is because of it's backwards compatibility with C, and the fact that C++ is a multi-paradigm language.Brendan wrote: I'm not hung up on C++. Any language that is pointlessly overcomplicated and harder to learn, use, debug, read or compile is bad; and I'm sure I've complained about plenty of other languages in the past. The only reason I haven't complained about C# (which is where this discussion started) is that C# is much cleaner/easier than C++ in just about every possible way.
I do however believe that the recent standards of C++, namely 11 and 14, has helped out quite a bit on this front, and the ISO committee is clearly aware of the issue. Also C++17 is going to be a large step forward.
That being said, there are thing which are a lot simpler to handle in C++ than in C, say; exception handling (even though I know that you do not agree on this), resource handling (mostly due to RAII), generic code & reusability (due to template), ect.
I do not want to get into a discussion about this, because I know we'll never come to an agreement, about which is better.
However I'd like to point out, that while I do something think you're a bit stubborn at times, then I do think, that you've really hit the nail on the head with you answer to Kevin, in terms of breaking through with ones OS, and I'd like to applause you on the fact that you're trying out new stuff, if your goal is to change the world of OSes. However I'm convinced not everyone is trying to break through with their OS, mine is really just past time programming.
// Skeen
// Developing a yet unnamed microkernel in C++14.
// Developing a yet unnamed microkernel in C++14.
Re: Self hosting OS/Compiler from scratch
You'll have ways to input data to a program, and you'll have ways to get the output of it. If you didn't, your OS would be useless. The more different your API is from what is commonly expected, the more effort will be needed to port software to your OS and to map concepts used by the compiler to a meaningful user interface. But I'm sure that it's entirely possible, without unreasonable effort.Brendan wrote:..assuming the native APIs provide "similar enough behaviour". For some examples, my OS will never have anything like STDIN, STDOUT, STDERR; will never let anyone open a file as 'read/write'; won't allow any application to read "plain text"; and won't allow something allocated on one thread's stack to be accessed by any other thread. This is just the tip of the iceberg. Porting a compiler to an OS that's actually different (rather than just "same with superficial implementation differences") is likely to be extremely problematic.Kevin wrote:Not really. The conflict that you can't port a lot of software if you don't support POSIX is very real. But what a compiler requires from the OS is simple enough that POSIX compatibility is really not necessary for that. You can just port it over using your native APIs.
Yes, complexity is a large, perhaps the single largest problem. No, you don't solve it by moving the complexity from the compiler and the standard library to the programmer of each individual application.I don't just seem to be serious - I am serious. Complexity is the single largest problem facing programmers. Making languages more complex is not going to help.
This "no code sharing, no modularity" thing was already tried out, like 50 years ago. It was not better, modularisation and code reuse made things easier, not harder.
Do you understand that it's extremely easy to have a brain fart and make a mistake while implementing the thirty-seventh copy of the like three lines to remove an element from the list? Perhaps you don't make stupid mistakes, but most of us do.Um, do you understand that a singly linked list is extremely easy to implement (e.g. literally easier than trying to remember what header file to #include)?
And you even wanted to make it easy for those who just want to "tinker" with some code instead of really knowing what they're doing, right? Do you think they would get the list right on the first attempt?
Being "spoonfed libraries to do trivial things" (and less trivial things) is essentially avoiding complexity. You ought to support it.Why would you need to maintain any implementation for any other users? Are these other programmers so incompetent that they can't write their own? Maybe it's because they've been spoonfed libraries to do trivial things for far too long?Kevin wrote:In any case, worrying about n implementations of n specific cases is magnitudes harder than maintaining a single implementation for n users.
And you have my sincere respect for doing that and for thinking "out of the box". However, I find your attitude sad and even offensive to our profession that you keep ignoring the experience that we do have. You're wasting a significant part of the time you invest by ignoring the lessons history has taught. Arguing against reuse of algorithms is only one example for this. It is simply foolish and won't make your OS any cleaner and easier for end users.Sigh. The truth? I find your attitude personally offensive. I usually do, but I usually say nothing. I've spent (and will continue to spend) a massive amount of time, money and effort trying to find, invent and research new and unique ideas that may (or may not) make things cleaner and easier for end users and the IT industry as a whole (of which, programmers like you and I are irrelevant).
This is going to sidetrack the discussing, but okay, why not...Let me tell you something. Your OS looks amazing. [...] I've seen it all before; and I can tell you now it will not succeed. What will probably happen is that you'll persevere for about 3 more years, but as time passes your motivation will fade, until inevitably your dull little OS will sink into obscurity.
So my OS looks amazing. Oh really? I didn't think you would know my personal OS, as I've never really published it. But anyway, as a German I love brutal honesty, so let's be honest: No, the result of my OS development attempt isn't amazing, it's a pile of shit. But a very instructive pile of shit, it taught me a lot of things and it is still useful to show other people examples of how you can implement some things, and of how you shouldn't do other things. And at the end of the day, it's the pile of shit that got me my job.
In this light, it already has succeeded, no matter if anyone else knows it.
Okay. Let's take C then and make it a bit easier and less error-prone by adding a few features like generics (perhaps also remove some features), and they'll be happy. In fact, generics are the one feature that I miss most in C, we might not need to add much more. But trying to emulate it with preprocessor magic is ugly and error-prone.They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
It's funny how you value extremely low-level and extremely high-level languages, but totally reject something in the middle grounds.Everyone that knows a bit about software engineering is.... less important than a school-kid that's spent 2 days diddling with something like GameMaker.
Re: Self hosting OS/Compiler from scratch
If an OS written from scratch is more innovative, clearly have potential and is not treated like a "hobby OS", I think it would be really fun to start writing applications on it. It is just an advantage if there are no ported applications from the past. Everything is new. Why we have to miss all the fun people have decades ago when everything was new?
What I mean is that a rich set of applications would be available very soon. There are a lot of people working on "open source" for free and I think a notable amount of them would happily move to a new potential OS if such a thing existed. More importantly, all new programmers are likely to select the "interesting new one" instead of an old-school sinking ship.
Now that we have the resource of writing the applications, we need to have a solid base for all this. That is where the OS, development tools and good specifications of how to write software show up.
What I mean is that a rich set of applications would be available very soon. There are a lot of people working on "open source" for free and I think a notable amount of them would happily move to a new potential OS if such a thing existed. More importantly, all new programmers are likely to select the "interesting new one" instead of an old-school sinking ship.
Now that we have the resource of writing the applications, we need to have a solid base for all this. That is where the OS, development tools and good specifications of how to write software show up.
Re: Self hosting OS/Compiler from scratch
Hi,
To retain the benefits of my "everything asynchronous" OS design you'd have to restructure the executable to make it a lot more like a system of cooperating "event handling state machines" (and a lot less like serial/imperative code); potentially including splitting it into multiple processes. If you don't retain the benefits of my design (e.g. by doing a massive amount of work that hides the asynchronous nature under an "legacy emulation layer" that makes everything behave in a synchronous manner), I will do everything I possibly can to ensure your process will never be allowed to execute.
My objections to templates have nothing to do with code sharing or modularity and everything to do with complexity - the ability for a programmer to easily understand and customise the code their own software uses. For an example, let's say you happen to use std::list in an application. You profile your application and find that std::list is a performance bottleneck, so you "hover over it and press F2" (or whatever) to open the std::list code in your IDE, then spend a few minutes to understand that code, and then tune it to perform better for your application's specific usage. This is so easy that anyone could do it (even a school kid that has only been programming for 3 weeks) because templates are awesome, right?
Wrong. More likely is that someone who has spent many thousands of $ and several years at university just to prepare themselves for the over-complicated language happens to open the std::list code in their IDE, vomits, then implements their own list handling for their special case because it's a whole lot easier.
If I have a piece of code that I can see, and you have a piece of code that's 300 times more complex that you can't see, who has more complexity?
Just because you want to pretend it doesn't exist doesn't mean it's not there.
I'm also not ignoring lessons history has taught. I'm using lessons history has taught to avoid known problems that you've failed to recognise, learnt to accept, and now have difficulty acknowledging.
Also note, as I've said previously, the things that confuse beginners are also the things cause experienced programmers' bugs. You only really need to look at security advisories for any large project to see this.
C++ is definitely a low level language (pointers, no GC, etc). C++ is also definitely a high level language (attempting to replace memory management with object creation and destruction, standard container abstractions, etc). This doesn't make it a "middle level language", it just makes it schizophrenic.
Cheers,
Brendan
What you call "possible, without unreasonable effort" is what I call "extremely problematic".Kevin wrote:You'll have ways to input data to a program, and you'll have ways to get the output of it. If you didn't, your OS would be useless. The more different your API is from what is commonly expected, the more effort will be needed to port software to your OS and to map concepts used by the compiler to a meaningful user interface. But I'm sure that it's entirely possible, without unreasonable effort.Brendan wrote:..assuming the native APIs provide "similar enough behaviour". For some examples, my OS will never have anything like STDIN, STDOUT, STDERR; will never let anyone open a file as 'read/write'; won't allow any application to read "plain text"; and won't allow something allocated on one thread's stack to be accessed by any other thread. This is just the tip of the iceberg. Porting a compiler to an OS that's actually different (rather than just "same with superficial implementation differences") is likely to be extremely problematic.Kevin wrote:Not really. The conflict that you can't port a lot of software if you don't support POSIX is very real. But what a compiler requires from the OS is simple enough that POSIX compatibility is really not necessary for that. You can just port it over using your native APIs.
To retain the benefits of my "everything asynchronous" OS design you'd have to restructure the executable to make it a lot more like a system of cooperating "event handling state machines" (and a lot less like serial/imperative code); potentially including splitting it into multiple processes. If you don't retain the benefits of my design (e.g. by doing a massive amount of work that hides the asynchronous nature under an "legacy emulation layer" that makes everything behave in a synchronous manner), I will do everything I possibly can to ensure your process will never be allowed to execute.
You solve it by removing complexity. Attempting to hide the complexity in a standard library does not remove the complexity, it just means that programmers have to deal with a complex standard library.Kevin wrote:Yes, complexity is a large, perhaps the single largest problem. No, you don't solve it by moving the complexity from the compiler and the standard library to the programmer of each individual application.I don't just seem to be serious - I am serious. Complexity is the single largest problem facing programmers. Making languages more complex is not going to help.
You can do code sharing in many ways. Some are simple (e.g. cut & paste) and some are complex (e.g. templates). Similarly, you can do modularity in many ways (e.g. open source static libraries, closed/proprietary shared libraries, "services", etc), and some are simple and some are not.Kevin wrote:This "no code sharing, no modularity" thing was already tried out, like 50 years ago. It was not better, modularisation and code reuse made things easier, not harder.
My objections to templates have nothing to do with code sharing or modularity and everything to do with complexity - the ability for a programmer to easily understand and customise the code their own software uses. For an example, let's say you happen to use std::list in an application. You profile your application and find that std::list is a performance bottleneck, so you "hover over it and press F2" (or whatever) to open the std::list code in your IDE, then spend a few minutes to understand that code, and then tune it to perform better for your application's specific usage. This is so easy that anyone could do it (even a school kid that has only been programming for 3 weeks) because templates are awesome, right?
Wrong. More likely is that someone who has spent many thousands of $ and several years at university just to prepare themselves for the over-complicated language happens to open the std::list code in their IDE, vomits, then implements their own list handling for their special case because it's a whole lot easier.
Do you understand that it's extremely easy to have a brain fart and focus on trivial things (e.g. easily fixed mistakes) while ignore the larger picture (thousands of lines of convoluted "factory factory" crap that requires a degree in astrophysics to get away from quickly enough)?Kevin wrote:Do you understand that it's extremely easy to have a brain fart and make a mistake while implementing the thirty-seventh copy of the like three lines to remove an element from the list? Perhaps you don't make stupid mistakes, but most of us do.Um, do you understand that a singly linked list is extremely easy to implement (e.g. literally easier than trying to remember what header file to #include)?
It's unlikely they'll get it right on their very first attempt, likely they'll get it right on their second or third attempt, and very likely they'll learn and gain experience that makes them far more competent than some worthless programmer that has only ever glued together code written for them by other people (who never truly understands what their code is actually doing or why the performance of their software sucks so badly).Kevin wrote:And you even wanted to make it easy for those who just want to "tinker" with some code instead of really knowing what they're doing, right? Do you think they would get the list right on the first attempt?
If I have one orange sitting on my desk, and you have 300 oranges hidden in locked chest, who has more oranges?Kevin wrote:Being "spoonfed libraries to do trivial things" (and less trivial things) is essentially avoiding complexity. You ought to support it.Why would you need to maintain any implementation for any other users? Are these other programmers so incompetent that they can't write their own? Maybe it's because they've been spoonfed libraries to do trivial things for far too long?Kevin wrote:In any case, worrying about n implementations of n specific cases is magnitudes harder than maintaining a single implementation for n users.
If I have a piece of code that I can see, and you have a piece of code that's 300 times more complex that you can't see, who has more complexity?
Just because you want to pretend it doesn't exist doesn't mean it's not there.
I'm not arguing against the reuse of algorithms. I'm arguing for the reuse of algorithms in an open and easily understood, modified and customised form. I'm only arguing against the reuse of algorithms in an overly complicated pain in the neck form that's hidden behind your back in a massive library of puke.Kevin wrote:And you have my sincere respect for doing that and for thinking "out of the box". However, I find your attitude sad and even offensive to our profession that you keep ignoring the experience that we do have. You're wasting a significant part of the time you invest by ignoring the lessons history has taught. Arguing against reuse of algorithms is only one example for this. It is simply foolish and won't make your OS any cleaner and easier for end users.Sigh. The truth? I find your attitude personally offensive. I usually do, but I usually say nothing. I've spent (and will continue to spend) a massive amount of time, money and effort trying to find, invent and research new and unique ideas that may (or may not) make things cleaner and easier for end users and the IT industry as a whole (of which, programmers like you and I are irrelevant).
I'm also not ignoring lessons history has taught. I'm using lessons history has taught to avoid known problems that you've failed to recognise, learnt to accept, and now have difficulty acknowledging.
Your forum signature has a link to the tyndur wiki pages, and the web browser I'm using translates German into English fairly well.Kevin wrote:This is going to sidetrack the discussing, but okay, why not...Let me tell you something. Your OS looks amazing. [...] I've seen it all before; and I can tell you now it will not succeed. What will probably happen is that you'll persevere for about 3 more years, but as time passes your motivation will fade, until inevitably your dull little OS will sink into obscurity.
So my OS looks amazing. Oh really? I didn't think you would know my personal OS, as I've never really published it. But anyway, as a German I love brutal honesty, so let's be honest: No, the result of my OS development attempt isn't amazing, it's a pile of shit. But a very instructive pile of shit, it taught me a lot of things and it is still useful to show other people examples of how you can implement some things, and of how you shouldn't do other things. And at the end of the day, it's the pile of shit that got me my job.
In this light, it already has succeeded, no matter if anyone else knows it.
For beginners, most of the pitfalls of C are much more fundamental than that. They're things like confusion about the differences between arrays and pointers, why "x = a * b / c;" is giving them wrong results, accidentally relying on either undefined or implementation defined behaviour, bugs involving misunderstanding operator precedence or promotion rules or order of evaluation, function pointer syntax, all types of "out of bounds" problems, etc. If you think asking these people to write templates will prevent their confusion then you're badly mistaken.Kevin wrote:Okay. Let's take C then and make it a bit easier and less error-prone by adding a few features like generics (perhaps also remove some features), and they'll be happy. In fact, generics are the one feature that I miss most in C, we might not need to add much more. But trying to emulate it with preprocessor magic is ugly and error-prone.They're people who can learn a language that's about as complex as C quickly enough to satisfy their curiosity and keep them interested; but they're also people who will decide to forget it if it looks complicated rather than fun.
Also note, as I've said previously, the things that confuse beginners are also the things cause experienced programmers' bugs. You only really need to look at security advisories for any large project to see this.
I'm not sure where you got this from.Kevin wrote:It's funny how you value extremely low-level and extremely high-level languages, but totally reject something in the middle grounds.Everyone that knows a bit about software engineering is.... less important than a school-kid that's spent 2 days diddling with something like GameMaker.
C++ is definitely a low level language (pointers, no GC, etc). C++ is also definitely a high level language (attempting to replace memory management with object creation and destruction, standard container abstractions, etc). This doesn't make it a "middle level language", it just makes it schizophrenic.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Self hosting OS/Compiler from scratch
Hi,
4 weeks later a release is made. When you get the bug report from frustrated users in 6 weeks time (which mostly all just say "code doesn't work right" with no useful details) and then spend 4 entire days trying to find a problem before you eventually discover the matrix multiplication bug; then you can pat yourself on the back and say "that wasn't complex at all!"..
My idea of simple is that you can look at a tiny piece of code in isolation and know exactly what it does with no chance of being surprised/misled; and therefore you can look at group of tiny pieces (a line of code?) and know exactly what it does with no chance of being surprised/misled; and therefore you can look at a group of groups (a function?) and know exactly what it does with no chance of being surprised/misled; and so on, all the way up to understanding every single piece of an extremely large program with no chance of being surprised/misled.
If you can't look at a tiny piece of code in isolation (e.g. like "a * b") and know exactly what it does with no chance of being surprised/misled; then you can't be sure you understand anything correctly at all.
For example, for C, you can't assume that someone hasn't done this somewhere:
..and therefore you can't assume that a tiny piece of code like "a * b" isn't actually doing something like "foo + bar".
That's not simple. That's confusion that increases the chance of introducing bugs. It's complex.
Cheers,
Brendan
For what I'm planning to do (where executables are "portable" and compiled to native code the first time they're executed); there's only 2 cases - either everything has to be compiled (e.g. user hasn't used the executable since the "portable" version was installed), or nothing needs to be compiled (e.g. user has used the executable before so there's already a native executable).skeen wrote:I agree with the fact that the debug cycle time, should be minimized. And that it should preferably be kept in the domain of seconds. However with proper code separation, and intelligent tools, you should only be compiling your changes (and linking the executable), whenever a change was made. If this takes more than a few seconds, then you're doing it wrong.Brendan wrote:If something takes more than about 3 minutes I end up going for coffee or watching TV or something, getting back 5 minutes after it's finished and by then it takes a further few minutes to figure out what I was doing. I also build frequently (like every 20 minutes or so on average, but sometimes 5 times in 10 minutes) to catch simple errors sooner. Getting the "compile then test, then continue" time down to less than 30 seconds saves a massive amount of time; which is part of the reason I put a lot of work into my little build utility (which is also part of the reason I can build everything so fast - the other part of fast build times is avoiding "slow to compile" languages).
For what I'm aiming for eventually (where executables are compiled when they're first executed) fast build times are just as important for different reasons.
So you see a line of code that says "a = c * b;" and you decide it'd be a little nicer in alphabetical order and change it to "a = b * c;". It's just multiplication, so obviously this is fine. You commit it to whatever versioning system (commit note is "Minor code clean ups") and forget about it.skeen wrote:Operator overloading *can* be a trap, that is if it's used non-intuitively. I honestly believe that it allows for cleaner code, indeed in terms of linear algebra, because it allows you to express what you do in math, that is it allows you to use the multiplication symbol, when you use it in math.Brendan wrote:I still think the operator overloading is a trap for people that aren't as familiar with the codebase as the person who wrote the code (which tends to include the person that wrote the code after they've been working on some other project for a few months).
And being able using the multiplication operator, when you expect to be able to use it, e.g. for multiplying matrices, allows you to not know the codebase at all, but rely on the common understanding of the underlaying mathematical construct, or as we like to refer to it; The interface. - That is your now coding against the mathematically accepted interface, rather than some implementation specific one, which may or may not throw implementation specific details, parameters and such at you.
4 weeks later a release is made. When you get the bug report from frustrated users in 6 weeks time (which mostly all just say "code doesn't work right" with no useful details) and then spend 4 entire days trying to find a problem before you eventually discover the matrix multiplication bug; then you can pat yourself on the back and say "that wasn't complex at all!"..
What you're saying is that templates are good as long as you only use existing templates and nobody ever writes them, maintains them, improves them or debugs them.skeen wrote:I truly agree with this statement! - And that's why would should hide all the complexity of implementations behind interfaces. Operator overloading can help us provide a intuitive interface. Templates can help us provide a generic and common interface for specialized implementations. - Both of these are complex to implement, but easy to use. And that's the main point here, the burden is on the implementer, and not on the user.
Ah, I see. Before using "std::list" you send an email to the person that wrote it and let them know which pieces of your data are hot and which pieces are cold; and they optimise the generic implementation for your specific case (and "de-optimise" it for other people's specific cases). That way, you don't have to look at or understand the template, or deal with the complexity of templates, because you're still only using existing templates. Nice!skeen wrote:If I want to use a list, then all I want is to be able to store my data (the interface), how the data is stored is up to the implementation, which I expect to do the right thing, i.e. split my data into hot and cold sections, ect.
Yes.skeen wrote:I actually agree with you on this, C++ is an overcomplicated language, and it is hard to learn, use, debug, ect., and honestly one of the main reasons why C++ is overly complicated is because of it's backwards compatibility with C, and the fact that C++ is a multi-paradigm language.Brendan wrote:I'm not hung up on C++. Any language that is pointlessly overcomplicated and harder to learn, use, debug, read or compile is bad; and I'm sure I've complained about plenty of other languages in the past. The only reason I haven't complained about C# (which is where this discussion started) is that C# is much cleaner/easier than C++ in just about every possible way.
Seems to me that they're only adding more stuff and not removing anything. I don't pay much attention to C++ though.skeen wrote:I do however believe that the recent standards of C++, namely 11 and 14, has helped out quite a bit on this front, and the ISO committee is clearly aware of the issue. Also C++17 is going to be a large step forward.
I think (in general) people don't fully understand what I mean by "simple" (or its opposite, "complex").skeen wrote:That being said, there are thing which are a lot simpler to handle in C++ than in C, say; exception handling (even though I know that you do not agree on this), resource handling (mostly due to RAII), generic code & reusability (due to template), ect.
My idea of simple is that you can look at a tiny piece of code in isolation and know exactly what it does with no chance of being surprised/misled; and therefore you can look at group of tiny pieces (a line of code?) and know exactly what it does with no chance of being surprised/misled; and therefore you can look at a group of groups (a function?) and know exactly what it does with no chance of being surprised/misled; and so on, all the way up to understanding every single piece of an extremely large program with no chance of being surprised/misled.
If you can't look at a tiny piece of code in isolation (e.g. like "a * b") and know exactly what it does with no chance of being surprised/misled; then you can't be sure you understand anything correctly at all.
For example, for C, you can't assume that someone hasn't done this somewhere:
Code: Select all
#define a foo +
int bar;
int *b = &bar;
That's not simple. That's confusion that increases the chance of introducing bugs. It's complex.
There are at least 3 other people that I know of (most of whom do have more serious projects and are likely to have read what I wrote) that needed to understand my motivations and the importance of not "recycling the status quo". I probably should apologise to Kevin (sorry Kevin) for directing those comments to him alone, given that I was using it as a sly way of getting the message to a larger group.skeen wrote:However I'd like to point out, that while I do something think you're a bit stubborn at times, then I do think, that you've really hit the nail on the head with you answer to Kevin, in terms of breaking through with ones OS, and I'd like to applause you on the fact that you're trying out new stuff, if your goal is to change the world of OSes. However I'm convinced not everyone is trying to break through with their OS, mine is really just past time programming.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Self hosting OS/Compiler from scratch
How long would you accept the startup/compilation time to be, and how large of a the runtime impact is acceptable? - Because in terms of supporting 'slow-compiled' languages in this approach, one has either 1. compile everything up-front and accept the delay (which obviously needs to be considerably small), or 2. do lazy compilation whenever something is needed (when a function is called), or when it's likely to be needed soon (i.e. by lambda closure of functions dependencies).Brendan wrote:For what I'm planning to do (where executables are "portable" and compiled to native code the first time they're executed); there's only 2 cases - either everything has to be compiled (e.g. user hasn't used the executable since the "portable" version was installed), or nothing needs to be compiled (e.g. user has used the executable before so there's already a native executable).skeen wrote:I agree with the fact that the debug cycle time, should be minimized. And that it should preferably be kept in the domain of seconds. However with proper code separation, and intelligent tools, you should only be compiling your changes (and linking the executable), whenever a change was made. If this takes more than a few seconds, then you're doing it wrong.Brendan wrote:If something takes more than about 3 minutes I end up going for coffee or watching TV or something, getting back 5 minutes after it's finished and by then it takes a further few minutes to figure out what I was doing. I also build frequently (like every 20 minutes or so on average, but sometimes 5 times in 10 minutes) to catch simple errors sooner. Getting the "compile then test, then continue" time down to less than 30 seconds saves a massive amount of time; which is part of the reason I put a lot of work into my little build utility (which is also part of the reason I can build everything so fast - the other part of fast build times is avoiding "slow to compile" languages).
For what I'm aiming for eventually (where executables are compiled when they're first executed) fast build times are just as important for different reasons.
First of all, I don't see why changing the order of the arguments should break the code. Multiplication has the commutative property, so should it's implementation, and hence changing the order of the arguments, shouldn't have any effect at all on the output.Brendan wrote:So you see a line of code that says "a = c * b;" and you decide it'd be a little nicer in alphabetical order and change it to "a = b * c;". It's just multiplication, so obviously this is fine. You commit it to whatever versioning system (commit note is "Minor code clean ups") and forget about it.skeen wrote:Operator overloading *can* be a trap, that is if it's used non-intuitively. I honestly believe that it allows for cleaner code, indeed in terms of linear algebra, because it allows you to express what you do in math, that is it allows you to use the multiplication symbol, when you use it in math.Brendan wrote:I still think the operator overloading is a trap for people that aren't as familiar with the codebase as the person who wrote the code (which tends to include the person that wrote the code after they've been working on some other project for a few months).
And being able using the multiplication operator, when you expect to be able to use it, e.g. for multiplying matrices, allows you to not know the codebase at all, but rely on the common understanding of the underlaying mathematical construct, or as we like to refer to it; The interface. - That is your now coding against the mathematically accepted interface, rather than some implementation specific one, which may or may not throw implementation specific details, parameters and such at you.
4 weeks later a release is made. When you get the bug report from frustrated users in 6 weeks time (which mostly all just say "code doesn't work right" with no useful details) and then spend 4 entire days trying to find a problem before you eventually discover the matrix multiplication bug; then you can pat yourself on the back and say "that wasn't complex at all!"..
But assuming that your implementation of the multiplication operator does not do what it should, then I don't see how this is different from; "a = matrix_mul(c,b)" ==> "a = matrix_mul(b,c)", if the implementation of this function doesn't have the commutative property either, then you have the exact same issue.
The only difference, is that exchanges the multiplication operator with a call to "Vec::operator_mul(Vec const&)", which does exactly what your "matrix_mul" would do. Whether one prefers the multiplication operator or a function is, i guess, nothing more than personal preference.
My point is that, when you're using existing templates, then you don't have to maintain, improve or debug them, and that's good!Brendan wrote:What you're saying is that templates are good as long as you only use existing templates and nobody ever writes them, maintains them, improves them or debugs them.skeen wrote:I truly agree with this statement! - And that's why would should hide all the complexity of implementations behind interfaces. Operator overloading can help us provide a intuitive interface. Templates can help us provide a generic and common interface for specialized implementations. - Both of these are complex to implement, but easy to use. And that's the main point here, the burden is on the implementer, and not on the user.
However I do think you're exaggerating, on how advanced it is to write templates; for containers it's mostly replacing your payload data type with T. For template meta-programming, then yes, things may seem somewhat advances, but this is mainly because you leave OOP and procedural programming behind, and venture into the world of functional programming (which is truly a challenge if you never been there before).
Also I'm a firm believer in that one shouldn't write generic code, but that one should refactor code duplication into generic code.
You do not send an email to the person, who wrote the list, instead you hint the implementation with information, i.e. hint which pieces of the data are cold/hot. One of the things I'm working with currently, is using the profiler's output to generate a header file, which is used to hint my generic libraries of optimization possibilities, in each given usage context.Brendan wrote:Ah, I see. Before using "std::list" you send an email to the person that wrote it and let them know which pieces of your data are hot and which pieces are cold; and they optimise the generic implementation for your specific case (and "de-optimise" it for other people's specific cases). That way, you don't have to look at or understand the template, or deal with the complexity of templates, because you're still only using existing templates. Nice!skeen wrote:If I want to use a list, then all I want is to be able to store my data (the interface), how the data is stored is up to the implementation, which I expect to do the right thing, i.e. split my data into hot and cold sections, ect.
C++11 provides a powerful way to do this, namely user defined literals, which are pretty much strings, that can be parsed at compile time, and used to create objects. The literals can for instance profiler information.
It is true, that they are 'mainly' adding stuff, mostly because removing stuff breaks code. However as of C++11 they have started deprecating features, also the committee is becoming more willing to break compatibility with C, as there are already quite some semantic differences between compiling a C programing with a C and a C++ compiler, and as C is indeed not a subset of C++.Brendan wrote:Yes.skeen wrote:I actually agree with you on this, C++ is an overcomplicated language, and it is hard to learn, use, debug, ect., and honestly one of the main reasons why C++ is overly complicated is because of it's backwards compatibility with C, and the fact that C++ is a multi-paradigm language.Brendan wrote:I'm not hung up on C++. Any language that is pointlessly overcomplicated and harder to learn, use, debug, read or compile is bad; and I'm sure I've complained about plenty of other languages in the past. The only reason I haven't complained about C# (which is where this discussion started) is that C# is much cleaner/easier than C++ in just about every possible way.
Seems to me that they're only adding more stuff and not removing anything. I don't pay much attention to C++ though.skeen wrote:I do however believe that the recent standards of C++, namely 11 and 14, has helped out quite a bit on this front, and the ISO committee is clearly aware of the issue. Also C++17 is going to be a large step forward.
I truly agree that one should be able to understand the code by inspecting a few lines at a time. Nobody has the ability to comprehend the entire complexity of large software projects, and hence we need to hide complexity to the best of our knowledge. However I do not think that "a * b", is any worse than "matrix_mul(a, b)", and as for your example, one could also use a macro, to replace "matrix_mul" with something that does addition.Brendan wrote:I think (in general) people don't fully understand what I mean by "simple" (or its opposite, "complex").skeen wrote:That being said, there are thing which are a lot simpler to handle in C++ than in C, say; exception handling (even though I know that you do not agree on this), resource handling (mostly due to RAII), generic code & reusability (due to template), ect.
My idea of simple is that you can look at a tiny piece of code in isolation and know exactly what it does with no chance of being surprised/misled; and therefore you can look at group of tiny pieces (a line of code?) and know exactly what it does with no chance of being surprised/misled; and therefore you can look at a group of groups (a function?) and know exactly what it does with no chance of being surprised/misled; and so on, all the way up to understanding every single piece of an extremely large program with no chance of being surprised/misled.
If you can't look at a tiny piece of code in isolation (e.g. like "a * b") and know exactly what it does with no chance of being surprised/misled; then you can't be sure you understand anything correctly at all.
For example, for C, you can't assume that someone hasn't done this somewhere:..and therefore you can't assume that a tiny piece of code like "a * b" isn't actually doing something like "foo + bar".Code: Select all
#define a foo + int bar; int *b = &bar;
That's not simple. That's confusion that increases the chance of introducing bugs. It's complex.
// Skeen
// Developing a yet unnamed microkernel in C++14.
// Developing a yet unnamed microkernel in C++14.
-
- Member
- Posts: 46
- Joined: Wed Mar 05, 2008 4:41 pm
- Location: San Francisco, California, USA
- Contact:
Re: Self hosting OS/Compiler from scratch
So I can't say I've thoroughly read through all 43 replies, but I think I read through the helpful ones. Thanks guys.
Re: Self hosting OS/Compiler from scratch
C++ is indeed a bit schizophrenic in this regard, however it is also the only widespread language that really gives you the ability to deal with hardware, pointers, ect, while also providing high level abstractions (and typically at a zero or low cost).Brendan wrote: C++ is definitely a low level language (pointers, no GC, etc). C++ is also definitely a high level language (attempting to replace memory management with object creation and destruction, standard container abstractions, etc). This doesn't make it a "middle level language", it just makes it schizophrenic.
As for Garbage Collection, as of C++11, the language has gotten a garbage collection abi. The idea is to allow for better garbage collection support, while there are already garbage collectors for C++93, these have some issues when dealing with pointer arithmetic. The new abi deals with this, via hinting, that is whenever you do something nasty (i.e. xor a pointer with another), then you'll have to hint the garbage collector, that the pointer is still active, until you hint this is not the case anymore, such that the garbage collector will not deallocate the object, just because there isn't a reference to it on the stack (or by lambda closure of heap allocated structures).
Also one has to accept the fact that C++ is really 'two languages', i.e. a low level and a high level one, and can be used as either. The new standard revisions are aiming to improve greatly on the high level part, such that the language gets to be more accessible to novice programmers alike.
// Skeen
// Developing a yet unnamed microkernel in C++14.
// Developing a yet unnamed microkernel in C++14.