Sign in to follow this  

jewelscript (self-plug, sorry!)

This topic is 4665 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, sorry about the shameless self-plug, but I couldn't resist! I'm currently working on a script language and hope to find some people interested in checking it out and telling me it is not entirely shit! *g* Seriously, *any* comment will be useful, because the project needs feedback in order to not go the way all the lonely basement developments go... ;) Cheers, jewe http://www.jewe.org

Share this post


Link to post
Share on other sites
Looking at the site, I think it adheres to the principles of Simply Better. It's like C or early C++ but a bit cleaner since the OP isn't trying to make it backwards compatible. A bit like Vault.

It's really great you have a little gui running and even made a game. All in all, it looks like a great achievement for a hobbby project so far.

Some notes...

I didn't see any mention of first class functions. These are pretty important for a lot of C++ programmers (as functors) and absolutely mandatory for functional programmers. Vault has them. Perhaps you should consider it. It might mean a rework of the syntax and some of the semantics you've already written though. On the other hand, it means you will be able to implement foreach, map, fold, reduce, and other higher order functions.

I see the & operator (reference) in some method calls. I'm wondering if you need those in there. I think you might like to remove references and make programmers pack up multiple return types in structs (or some other parameter packer). Then, on return of the function it returns the struct. Another way to do this is just pass by value (or const ref) and allow the return of multiple values. You see, there's contention between allowing argument mutation and disallowing it. I'm personally against it.[/political] [grin]
Consider:
function darken(float& red, float& green, float& blue){...}
float r =1.0, g=1.0, b=1.0;
darken(r, g, b);

vs.
function float,float,float darken(float red, green, blue) {...}
float r =1.0, g=1.0, b=1.0;
r, g, b = darken(r, g, b);

Removing the & operator means you will then be able to implement tail call optimisation fairly easily. And if you have TCO, you can then implement Continuations -which could be a powerful unique selling point.

Here's a paper on how to implement tail recursion when compiling Scheme in C.

I didn't see any info on module/packaging or linkage on the site so I won't comment. :)

good luck

Share this post


Link to post
Share on other sites
Hi flangazor,

It's really great you have a little gui running and even made a game. All in all, it looks like a great achievement for a hobbby project so far.

Thanks alot. :)

I didn't see any mention of first class functions. These are pretty important for a lot of C++ programmers (as functors) and absolutely mandatory for functional programmers. Vault has them. Perhaps you should consider it.

Yes, the funny thing is I planned to have them from the first day on, the virtual machine can handle functions like any other value or object, however, somehow it never made it's way into the compiler... I guess I thought they weren't so important. So here I stand corrected. ;)

I see the & operator (reference) in some method calls. I'm wondering if you need those in there. I think you might like to remove references and make programmers pack up multiple return types in structs (or some other parameter packer). Then, on return of the function it returns the struct.

Oh, you can do both. Either use references to modify function arguments, or simply return multiple values in an object:

class Color {
long r, g, b;
method Color(long ar, long ag, long ab) { r=ar; g=ag; b=ab; ]
}
function Color& Darken( long r, long g, long b ) {
... // do something
return new Color(r, g, b);
}

Another nice way is to use on-the-fly array for variable arguments and multiple return values:

function array& Darken( long r, long g, long b ) {
...
return { r, g, b }
}

The references pretty much behave like the ones known from C++. Unlike other script languages, JewelScript does not pass arguments or assign value by reference automatically. You have to explicitly specify a variable as type reference, otherwise the VM will assign / pass a COPY of the object. (Just like it is in C/C++).
The reason I decided to do it this way, is that I believe the developer should be in control. And, since it makes an important difference whether your complex object gets copied or just a reference is copied, I felt that the developer should see a representation of what happens in the source code.

CVeryComplexObject obj = myObj; // make a copy... slow
CVeryComplexObject& obj = myObj; // make a reference... fast, but dangerous


Removing the & operator means you will then be able to implement tail call optimisation fairly easily. And if you have TCO, you can then implement Continuations -which could be a powerful unique selling point.

Hm... I wouldn't want to remove them, because they're way to useful for obvious reasons. Passing references to the same object between functions is way faster than copying it. Plus, I think it is nice that you *can* pass values and objects into a function to have them manipulated. Even if you think it's not good programming practice, it might be sometimes the best solution.

Here's a paper on how to implement tail recursion when compiling Scheme in C.

Whoa... Thanks for the links, looks like I need to read more... I have no clue... ;)

I didn't see any info on module/packaging or linkage on the site so I won't comment. :)

Right, this whole area is still missing. Currently you can compile (and import) an arbitrary number of source files into one binary VM program. You can directly execute the program, or stream it into a file and load and run it later. However, you cannot link multiple binaries into one executable, which might be useful. (To make libraries or modules for 3rd parties that should not have access to the source code.)
However, I wonder how important this really is. I'd say it would be more of a
'nice to have' than a 'must have' or am I wrong?

Best,
jewe

Share this post


Link to post
Share on other sites
I think a lot of language designers underestimate how large projects will get in their languages. The only languages I know that were designed for really large projects from the beginning were Java and C#.


Quote:
class Color {

long r, g, b;

method Color(long ar, long ag, long ab) { r=ar; g=ag; b=ab; ]

}

function Color& Darken( long r, long g, long b ) {

... // do something

return new Color(r, g, b);

}
I think that's even worse. You've dynamically allocated memory in a lower stack frame for use in a higher stack frame without any sort of indication that Darken might do that. I'm sure you know how awful that is in a non-GC language.

Share this post


Link to post
Share on other sites
Quote:
Original post by flangazor

function Color& Darken( long r, long g, long b ) {

... // do something

return new Color(r, g, b);

}

I think that's even worse. You've dynamically allocated memory in a lower stack frame for use in a higher stack frame without any sort of indication that Darken might do that. I'm sure you know how awful that is in a non-GC language.


Well, technically JewelScript *IS* a non-GC language, for there is no such mechanism that looks for unused objects in memory and frees them. However, it uses reference counting to automatically destroy objects no longer in use.

To a C++ programmer the above code might look horrible. However, you can safely create and return objects in any GC'd / refcounted language, because the language takes the task of caring about releasing memory off the developer's shoulders - which is *one* of the reasons why script languages / Java are so popular, IMO.

I don't see any reason why not use this feature, if the language supports it. That would be like allocating objects with malloc() rather than using operator new in C++.

Cheers,
jewe

Share this post


Link to post
Share on other sites
Oh yeah I forgot it is refcounted. :)

Some of the paths in the XCode version of the project aren't relative. e.g. jcesym.h, jcesym.c, etc. Move the src folder to another directory (e.g. desktop) and open it in XCode. It will make the non relative paths red.

[Edited by - flangazor on April 1, 2005 5:59:14 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by flangazor
Oh yeah I forgot it is refcounted. :)

Some of the paths in the XCode version of the project aren't relative. e.g. jcesym.h, jcesym.c, etc. Move the src folder to another directory (e.g. desktop) and open it in XCode. It will make the non relative paths red.


Oh thanks for telling me that! I'll fix this ASAP! :)

Cheers,
jewe

Share this post


Link to post
Share on other sites
jewe_org, that looks really neat indeed! Good job there.

I'm actually wondering, HOW FAST is JewelScript? You should compare it with speed against any other(major) scripting engines, such as Lua, GameMonkey, Python, etc.

I'm currently looking into GameMonkey, and it comes with a benchmark tool. If you can rebuild the benchmark scripts in a few other languages(Scripts that do the exact same) you could speed compare those languages to your engine. In return, you can profile your script and then optimize the shit out of it.

I don't have alot of time to get the benchmarks running in other languages, otherwise I would have ran a few benchmarks for you.

Toolmaker

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
jewe_org, that looks really neat indeed! Good job there.

I'm actually wondering, HOW FAST is JewelScript? You should compare it with speed against any other(major) scripting engines, such as Lua, GameMonkey, Python, etc.

I'm currently looking into GameMonkey, and it comes with a benchmark tool. If you can rebuild the benchmark scripts in a few other languages(Scripts that do the exact same) you could speed compare those languages to your engine. In return, you can profile your script and then optimize the shit out of it.

I don't have alot of time to get the benchmarks running in other languages, otherwise I would have ran a few benchmarks for you.

Toolmaker


Hi Toolmaker,

well I did exactly that, I used the benchmark script from GameMonkey Script and ported Ackerman and Fibonacci to JewelScript in order to compare performance. This lead to a great frustration first, because it showed me that JewelScripts VM was much slower. So I completely revised the VM to fix the issues I had identified.

However, such benchmarks are not the perfect tool to measure performance, because they are quite "synthetic". What I mean is that benchmark scripts are often programs that you wouldn't use in a real life situation. Especially in game development, you would implement all the performance critical stuff in native code and use the script language as the "glue" between these native functions. You wouldn't implement a fibonacci sequence in script, for example.

Especially fibonacci and ackerman, which are highly recursive algorithms, will only (mostly) measure the performance of the function call overhead of the respective VM. JewelScript for example, since it is a register VM, computes fibonacci 2 times slower than GameMonkey Script, because it has to save register contents at each function begin and restore them at each function end, which of course creates some additional overhead. Another benchmark, however, a six times nested loop from 0 to 18 will run about 25% faster in JewelScript than in GameMonkey Script, again because it is a register VM and it doesn't have to access the stack all the time.

What I'm wanting to say is that such benchmarks can only give a coarse indication how the "real life" performance of the VM is. You should either run many different benchmark algorithms on both VM's and then use statistics to calculate the performance of both candidates, or which would be even better, create an application which uses both VM's in a "real life" situation, then see which one performs best.

And then, in design of a VM, sometimes you have to sacrifice performance for a cool feature that wouldn't be possible otherwise. I don't expect JewelScript to be faster than Lua or Python (I never tested that), which both have been optimized by experts who have gained a high level of know-how over the years. All I can say is that it is fast enough for the things I want to do with it, and I expect it to become faster and better as development on it continues over the months and years.

Cheers,
jewe

Share this post


Link to post
Share on other sites
Sign in to follow this