Viper, while I do agree in principle that learning a new language syntax style can be a daunting task no matter what the language, I completely disagree with the implication that any new style will be equally as difficult to learn. I think the ease of learning a new language is roughly proportional to the degree to which the new language is similar to languages one already knows.
The most natural language to most of us is of course our native spoken languages. For many of us that''s English. Programming Languages that read more like English tend to be easier to understand by looking at the syntax. I think this is why a lot of us programmers started out learning BASIC, HyperTalk, and other very high level languages. Once you''re familiar with BASIC, it can be a bit easier to go to C, because you''re familiar with the general syntax concepts, like WHILE, FOR, and IF.
I can''t think of any common traditional programming languages that lead easily to Scheme or Lisp. The natural progression factor just isn''t there. This lends itself to a naturally steep learning curve.
Furthermore, I feel Scheme/Lisp/whatever is just plain hard to read, regardless of skill level. Parentheses are not the cleanest-looking operators in the first place, which is why C coders generally opt to use lots of whitespace when dealing with lots of parentheses. To require parentheses around every single expression and statement is nuts to me, but opinions aside, you''ve got to admit it things could appear jumbled at times. Whether Perl is better or worse is a matter of opinion as well, but I don''t think anyone would argue that Perl is cleaner or easier for them to read than C, just because they''re more used to Perl than C.
Scripting Language Syntax Proposal
I just realized I'm assisting in the hijacking of my own thread. Sorry about that..
Um.. so about those types. Type migration, actually. I don't know that I like the idea of the scripter having to specify that it would be integer division, as in Perl. The whole point of having a Numeric type in the first place would be to abstract the concept of different numeric types (float, int) from the scripter. I think it should be handled 100% internally, if the combined Numeric type idea were to be carried out.
The more I think about it though, the more I like the idea of having two firm types -- string and number.
[edited by - irbrian on April 22, 2004 2:31:33 PM]
Um.. so about those types. Type migration, actually. I don't know that I like the idea of the scripter having to specify that it would be integer division, as in Perl. The whole point of having a Numeric type in the first place would be to abstract the concept of different numeric types (float, int) from the scripter. I think it should be handled 100% internally, if the combined Numeric type idea were to be carried out.
The more I think about it though, the more I like the idea of having two firm types -- string and number.
string Test = "Hello World."number Length = Test.length()print (Test + " is a string with " + Length + " characters." + endline)print (Length + " plus " + 5 + " equals " + (Length + 5) + ".")
You know, I think thats every bit as easy to understand as variant types.. maybe even more so, 'cause it seems like even the least experienced coder should understand perfectly what the variables are for and how they work. [edited by - irbrian on April 22, 2004 2:31:33 PM]
---------------------------Brian Lacy"I create. Therefore I am."
Not to obfuscate this thread anymore. The parentheis in Scheme are not what are hard to read. Have you ever really looked at a real Lisp/Scheme program? I do not mean some example of fibo numbers or a factorial calculator. The prefix notation and cryptic function names are difficult for a novioe to handle. Really, go look on the net at some of the larger Scheme programs. Common lisp is even worse.
I am an enthusiast of Scheme, I generally like the programming style. It is just looking at large programs I realize how hard it would be for a newbie scripter to come to grips with it.
I am an enthusiast of Scheme, I generally like the programming style. It is just looking at large programs I realize how hard it would be for a newbie scripter to come to grips with it.
quote:
Original post by irbrian
The more I think about it though, the more I like the idea of having two firm types -- string and number.
So do you allow conversion (i.e. "casting") between the two types:
string sTest = "40000"number nLength = sTest.length() // nLength now holds 5string sLength = nLength // sLength now holds "5"number nTest = sTest // nTest now holds 40000
Or do I have to explicitly cast to avoid a syntax error (which is not very script-friendly)?
Regards,
Jeff
[ CodeDread ]
Hi folks sorry for the diversions.
I have been following the thread and implementing some of the ideas that you have been discussing.
I have done a re-write of my older VM and made alot of progress in correcting the deficiencies in the other design.
I spent a while trying to decide what type of data structure would best be used and what is the best design approach to modeling the types of the interpreter. This is considerably important because the underlying design of the type system needs to be fairly efficient and thought out. I have tried various approaches and learned from my mistakes. I decided to go the way of typed pointers to objects. The virtual functions are not too terribly slow but it doesn''t perform as well as Python (but close). I think in time it could be correct to get at least 20-30% more improvement out of it. It isn''t my main concern right now as long as it is close enough to Python and other languages.
Internally in my tagged object class it contains pointers to the internal data types in the interpreter. It has positive and negative ramifications. The negative side is that it requires more memory (not much really, but I doubt anyone will write a script with millions of objects in the language which would take about 30-40 megs of memory), and that all operation are dynamic and require testing and switching to modify data at run-time. The positive side is it is not to slow, it does not need to allocate memory constantly (even though I have worked out a garbage collection scheme which I have not yet implemented in the new interpreter), it is entirly dynamic and will change types in expression (which could be good or bad depending on how you look at it), and the system can be both statically and dynamically typed. It could be possible to switch it on and off at compile time or at run-time. With judicious #defines a lot of stuff could be set at compile time from paranoid to extremely liberal.
I took the advice that all variables need to declared before use.
This is done with the var operator. Types can be specified. The syntax is var v : int or var v : type("name"). In the interpreter it won''t matter much but I have always had plans to work a backend to it to translate to C++ or other native code languages. I decided that static translation and compiling to a DLL is more useful to me than a JIT and would probably be much easier to debug and get working right now.
It is still a stack based design but it implements stack frames. It will eventually be tail recursive.
I will give you an example sytanx of what the language is functionally going to be like, but not fully implemented yet:
Object foo [: inherits(...)] [( library("somelib.dll")]
{
var a : type("sometype")
func foo() { print("construct") }
func ~foo() { print("destruct") }
// implements OP_ADD on the object
operator + ( a : type("foo") ) { ... }
// etc...
};
var foo : type("foo");
func fib( a : int ) : 1
{
if( a == 0) { return(0); }
if( a == 1) { return(1); }
return( fib(a-1) + fib(a-2) );
}
print(" HI WORLD :-) ");
// this is fine code and declerations can be freely mixed
func stuff( a : int ) : 0 // number of returned objects
locals: local1 : int
{
local i : int;
i = a;
local j : int;
j = i+i;
/// etc, locals can be declared anywhere like in C++, they are /// variables on the stack frame. var variables are in the global ///namespace
}
var d : double;
d = to_double("1234") + 1.0 + 2;
// etc etc ...
Mostly that is all implemented but objects which I will be working on in the next few days.
If people are interested in examining the prototype stuff I can make a download on my web page. It is still prototype stuff so don''t get your hopes high about it being exceptionally easy to read or making sense :-)
But my main goal has been to reduce the backend to C++ eventually and turn modules into compiled C++ code and linked through DLL libraries (hence the library tag in the code example). It will also be possible to just declare a namespace of C functions as well with something like:
namespace my_name_space (library("whatever.dll")
{
cfunc func1( a : type) : type;
// etc..
}
import("my_name_space.mod") ...
The basic built in types are
bool
int
double
string
char ( or possibly alias this with ints)
object
The basic data structures are
list
array
table (2-d array)
map ( dictionary, etc)
It isn''t quite as nice as modern scripting languages and it might almost qualify as something similar to Visual Basic without the nice editor or GUI (yet). I will give it to other people if they find it useful but I can''t make any promises that it will fulfill anyone else''s needs but my own.
I have been following the thread and implementing some of the ideas that you have been discussing.
I have done a re-write of my older VM and made alot of progress in correcting the deficiencies in the other design.
I spent a while trying to decide what type of data structure would best be used and what is the best design approach to modeling the types of the interpreter. This is considerably important because the underlying design of the type system needs to be fairly efficient and thought out. I have tried various approaches and learned from my mistakes. I decided to go the way of typed pointers to objects. The virtual functions are not too terribly slow but it doesn''t perform as well as Python (but close). I think in time it could be correct to get at least 20-30% more improvement out of it. It isn''t my main concern right now as long as it is close enough to Python and other languages.
Internally in my tagged object class it contains pointers to the internal data types in the interpreter. It has positive and negative ramifications. The negative side is that it requires more memory (not much really, but I doubt anyone will write a script with millions of objects in the language which would take about 30-40 megs of memory), and that all operation are dynamic and require testing and switching to modify data at run-time. The positive side is it is not to slow, it does not need to allocate memory constantly (even though I have worked out a garbage collection scheme which I have not yet implemented in the new interpreter), it is entirly dynamic and will change types in expression (which could be good or bad depending on how you look at it), and the system can be both statically and dynamically typed. It could be possible to switch it on and off at compile time or at run-time. With judicious #defines a lot of stuff could be set at compile time from paranoid to extremely liberal.
I took the advice that all variables need to declared before use.
This is done with the var operator. Types can be specified. The syntax is var v : int or var v : type("name"). In the interpreter it won''t matter much but I have always had plans to work a backend to it to translate to C++ or other native code languages. I decided that static translation and compiling to a DLL is more useful to me than a JIT and would probably be much easier to debug and get working right now.
It is still a stack based design but it implements stack frames. It will eventually be tail recursive.
I will give you an example sytanx of what the language is functionally going to be like, but not fully implemented yet:
Object foo [: inherits(...)] [( library("somelib.dll")]
{
var a : type("sometype")
func foo() { print("construct") }
func ~foo() { print("destruct") }
// implements OP_ADD on the object
operator + ( a : type("foo") ) { ... }
// etc...
};
var foo : type("foo");
func fib( a : int ) : 1
{
if( a == 0) { return(0); }
if( a == 1) { return(1); }
return( fib(a-1) + fib(a-2) );
}
print(" HI WORLD :-) ");
// this is fine code and declerations can be freely mixed
func stuff( a : int ) : 0 // number of returned objects
locals: local1 : int
{
local i : int;
i = a;
local j : int;
j = i+i;
/// etc, locals can be declared anywhere like in C++, they are /// variables on the stack frame. var variables are in the global ///namespace
}
var d : double;
d = to_double("1234") + 1.0 + 2;
// etc etc ...
Mostly that is all implemented but objects which I will be working on in the next few days.
If people are interested in examining the prototype stuff I can make a download on my web page. It is still prototype stuff so don''t get your hopes high about it being exceptionally easy to read or making sense :-)
But my main goal has been to reduce the backend to C++ eventually and turn modules into compiled C++ code and linked through DLL libraries (hence the library tag in the code example). It will also be possible to just declare a namespace of C functions as well with something like:
namespace my_name_space (library("whatever.dll")
{
cfunc func1( a : type) : type;
// etc..
}
import("my_name_space.mod") ...
The basic built in types are
bool
int
double
string
char ( or possibly alias this with ints)
object
The basic data structures are
list
array
table (2-d array)
map ( dictionary, etc)
It isn''t quite as nice as modern scripting languages and it might almost qualify as something similar to Visual Basic without the nice editor or GUI (yet). I will give it to other people if they find it useful but I can''t make any promises that it will fulfill anyone else''s needs but my own.
quote:Seems like that might work, actually. The behavior seems pretty obvious in this case. When it becomes less obvious is if you''re trying to convert a string with characters to a number:
Original post by rypyr
So do you allow conversion (i.e. "casting") between the two types:
... Or do I have to explicitly cast to avoid a syntax error (which is not very script-friendly)?
string sTest = "floor13.section5.desk6"number nTest = sTest
What behavior would be expected here? Will nTest be 3.56 (parses out all valid characters ''1'', ''3'', the first ''.'', ''5'', and ''6'')? Should it be 13 (looks for valid chars, parses until the next invalid char ''s'')? Or should it just be 0 (or else null) because the string is an invalid number?Oh, and of course I forgot to mention the third necessary type in my previous post -- a boolean type would still be necessary. If dynamic type conversion is allowed, IMO booleans should be converted on the basis of whether the corresponding value has any value other than 0 (for a number) or "" (for a string). These values would correspond to false, and any other value would correspond to true. Going the other way, True might convert to a number value of 1 or a string value of "true".
---------------------------Brian Lacy"I create. Therefore I am."
quote:
Original post by irbrian
Oh, and of course I forgot to mention the third necessary type in my previous post -- a boolean type would still be necessary.
Why is boolean is not necessary if you have "number"? C doesn''t have a boolean type for cripe sakes!
If you''re going to add Boolean, I would suggest differentiating between integers and real then. They''re problem domains are different.
That matches with my 4 basic types in my config file syntax: Boolean, Integer, Real, String.
Then there are Composite types...
[ CodeDread ]
quote:Whether the engine handles booleans internally as integers or as something completely different, I think a boolean type should still be included in the language, even if its "syntactic sugar." It seems like it makes sense if there are any kind of types at all. In a way, this language is about having elegant syntax as well as (hopefully) being functionally elegant.
Original post by rypyr
Why is boolean is not necessary if you have "number"? C doesn''t have a boolean type for cripe sakes!
quote:I''m not sure I understand why it matters. Could you elaborate?
If you''re going to add Boolean, I would suggest differentiating between integers and real then. They''re problem domains are different.
---------------------------Brian Lacy"I create. Therefore I am."
quote:On the other hand, it might make sense to do something like this:
Original post by rypyr
So do you allow conversion (i.e. "casting") between the two types:
... Or do I have to explicitly cast to avoid a syntax error (which is not very script-friendly)?
Original post by irbrian
Seems like that might work, actually
string sTest = "40000"number nTest = sTest.getNumber() // standard conversion methodnTest /= 1.17sTest = nTest.DecimalFormat("0.00") // Instead of getString(), // format with 2 . placesstring Output = "$" + sTestprint (Output) // Outputs $34188.03
I'm not sure which I like better. [edited by - irbrian on April 24, 2004 12:46:29 AM]
---------------------------Brian Lacy"I create. Therefore I am."
quote:
Original post by rypyr
Why is boolean is not necessary if you have "number"? C doesn''t have a boolean type for cripe sakes!
[ CodeDread ]
Becuase he''s not building a C compiler...?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement