Quote:Quote:Quote:Original post by Joakim_ar Here's my language ideas, close to the ones of GameMonkey, but tweaked to something I like better. |
I like the syntax for member variables, no need for the "self" or "this" keyword. |
Well, C++ manages to use member variables without, for the most part, needing to use "this". It uses "this" when you have to refer to the object itself, whilst ".x" doesn't appear to suggest an intuitive way to refer to that.
If you were refering to Python, note that "self" isn't a keyword, it's just a parameter. |
I was refering to when you have an ambiguity, a local variable with the same name as a member variable. In C++ you can use the 'this' pointer to bypass the default 'local variables are first' rule. As I remember other languages use the 'self' keyword (I've used it in REALBasic for one). As you probably know, I dislike keywords and having just a dot in front of a variable name seemed like a good idea. I think I was taking Joakim_ar a little differently, perhaps he accesses all member variables this way.
Quote:Quote:Quote:Assignments (= += -= *= /= ^= &= |=) to variables can not be made inside expressions |
I agree. I think that only optimised and fast languages really need this - and even then it is arguable. Why should testing for someting, an expression have a side effect? |
Why shouldn't it? |
Why should it? It's a condition not an execution, it goes against logic itself. Even if you have function calls in a conditional, they themselves shouldn't have any side effects. Code such as this:
int errorValue;if (errorValue = doSomethingThatCouldFail()){ cout << "Something failed, Error value:" << errorValue << endl;}
Is horrid and outdated. It may be the nicest and fastest way to do things in C / C++, but shouldn't be used in other languages that have better constructs. It is these things that make learning and using C / C++ such a nightmare, you are expected to know that an integer can count as a boolean, and that assignments can happen in conditionals.
If you read the conditional in english it says "if errorValue equals the result of doSomethingThatCouldFail() then execute the next line" which goes against what it actually does.
Quote:Quote:What do you think about expression computation? Should the expression "boolean_method() && another_method()" return false if boolean_method() returns false, or should the whole expression be calculated (similar with or)? |
Apply the principle of least astonishment. It's likely that most of your users will be familiar with short-circuiting behaviour for "and" and "or". Unless you have a good reason for the language to behave contrary to how people would expect, don't. |
When you say that most of my users will be familiar with the short-circuiting behaviour, are you sure? This is a scripting language after all, not a tool for C programmers. In fact I hope most users of this language won't need to know how to program in C, to be able to use it. I even hope that people who use my language don't need to know how to program to find it useful.
So when I apply the principle of least astonishment, I think where the users of this language are coming from. Someone at least experienced in logic will understand the concept of a conditional and probably find the short-circuiting behaviour unusual, but this would only be if they used the concept of methods returning booleans. I personally even found this concept unusual. If I was to only allow const methods in an expression the short-circuiting argument would be moot. The more important idea here is whether to allow conditionals to have side effects.
I think conditionals shouldn't have side effects, and I know that I don't use them when I want to code well. I think they are a cause of bugs, but more importantly the code is harder to read.
Perhaps one of the overall themes here is whether the language should force good habits by limiting the things that can be done, or should the good habits be left to the user. I would say that if a feature could lead to bad habits, and can safely be removed then it should.
Quote:Quote:Original post by umbrae So I was thinking about how the bytecode will work and I'm having a few thoughts. Since I only have one return type, would it be bad to have one register type thing, that always contain the return value? push 3 push 9 call <add method> // the parameters used get popped off the stack // $r now contains the return value |
Why bother? Unless there's a good reason not to store the return value on the stack, why make extra work for yourself? |
Simplicity and beauty. I crave perfection and hate code that just works. I think I have a bit of a problem, everything that I want to code myself has to be perfect (not including assignments, (deadly) group work and plain work), otherwise I rewrite it. The problem with this obsession is that a lot of things don't get finished (or sometimes even started). The other thing is that once I have solved a problem, there is no point programming it - it is solved, and so some projects are left.
I estimate that I have written about 25,000 lines of code on this language project alone - and at the moment I am going to start again (new syntax etc). That's not saying the code that has been written is useless, often I will sit there with the old code on one side of the screen, and the new code on the other and just copy large sections of it.
I did the
personality test and found I was
INTP which sounds like it suits me well.
Quote:Quote:If the object is at the start, the vm needs to know the number of parameters the method takes - so I think that's out of there. |
But don't you think it should know the number of parameters the method takes? In fact, don't think you think it will? Unless you're planning to have variable length argument lists. |
The compiler will, for sure. But the virtual machine just runs the code that it sees. The methods themselves pop off the parameters, and pop on the return value, the vm itself just executes. Some part of it will know how many parameters, but that part shouldn't have to deal with the grindstone, the executing core.
That is, unless the way parameters are passed around is changed. If the virtual machine automatically, upon a method call, popped the parameters off and set them up as local variables - which would actually be quite cool. Is this a good idea?
Quote:Quote:Does anyone know how C++ does it? I had a bit of a look, but it was very nasty code (powerpc code is very nasty, possibly more nasty than x86 but not sure) |
No temporary register needed.
push 2 push 4 push a call method call method
When possible, C++ will do what I did there. But note that asking 'what C++ does' is meaningless, because C++ compilers are free to do anything. |
Thanks for the code, I hadn't though of doing it that way. But wouldn't coding it backwards like that use a lot more stack than normal? And also that would mean that code like this
a.method1(method2()).method3(method4())
would be executed in this order:
method4()method2()method1()method3()
When you would think it would execute in this order:
method2()method1()method4()method3()
To me that would cause a bit of confusion when trying to debug things.
Quote:Quote:I'm thinking about having two stacks, one for variables and one for parameters, what do people think? The variable stack is expanded as it is needed. |
That seems unnecessary. Once called, a function never recieves any more parameters, so you could just put the parameters at the bottom of the variable stack. |
Again, for simplicity. But you are right, just I was going to reference variables by their offset along the stack, and creating another variable would mean that all the parameter offsets would shift down one. This would make compiling one bit more tricky, and if anyone wanted to read the code - it would be harder to understand.
Unless you referenced variables from an offset that counts up towards the top of the stack, from the first parameter. but then there needs to be a way to change this stack pointer from method to method.