Jump to content
  • Advertisement
Sign in to follow this  
Endar

Useful scripting language features?

This topic is 3681 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

I'm currently writing my own scripting language (for fun/learning/to be used), and when I was describing it to one of the guys at work, I realised that I was making it C-like because that's what I know. So, I'm looking for useful features that some other scripting languages have to add to my own to discover if they'll be useful for me as well. :D What ideas do you guys have?

Share this post


Link to post
Share on other sites
Advertisement
Anonymous lambdas, closures, garbage collection, tuples and expression syntax seem like basic features you should include to get an expressive language. Add one or two container types with all the required manipulation functions.

Then, move on to domain-specific features (those which make your scripting language superior to generic languages for the domain you wish to apply it to).

Share this post


Link to post
Share on other sites
In Lua, there's a cool thing that you can do: multiple assignments/returns, for example, if function f returns 4 numbers, you can do all these things:


one, two, three, four = f() -- each variable contains 1 number)
onelist = f() -- onelist is a table with numbers
one, two, three = f() -- one, two are regular variables, they each get two numbers, three becomes a table with 2 numbers



And if function g expects 4 numbers, you can do:


g(one, two, three, four)
g(table_with_four_numbers)
g(number_one, number_two, table_with_two_numbers)



I think it's a cool feature, and I haven't seen in it on many other scripting languages.

Share this post


Link to post
Share on other sites
Quote:
Original post by beun
I think it's a cool feature, and I haven't seen in it on many other scripting languages.


This is a typical usage of pattern matching (and tuples), with a few benefits. If I can remember correctly, it was first introduced by ML in the 1970's.

Share this post


Link to post
Share on other sites
You know, whenever I hear C-like syntax with anonymous lambdas, tuples, etc, all I can think of is ECMAScript.

Just saying.

Share this post


Link to post
Share on other sites
I forgot to specify that this is going to be a scripting language for a game (engine). I don't know if that will change the answers you've given ...

Garbage collection ... I'm not so sure, because I'm intending to have only primitive types, so I won't be needing dynamic memory.

Anonymous lambdas? That sounds hard... but useful. I'll definately be looking into that.

What do you mean by 'closures', 'expression syntax' and 'expressive language?'

Share this post


Link to post
Share on other sites
For a game scripting language, I want tons of concurrency features. Coroutine support. For inspiration watch this
">lecture by the author of Urbi, his language has a very elegant syntax for writing concurrent scripts.

I think having a special syntax for state machines would be nice (this is something that has been talked about on these forums before).

I also want to be able to change the code as the game is running, and see the results right away. There are different levels of how well this can be supported. Most dynamic languages allow you to easily reload behavior while running, but have difficulty when you try to redefine state. Then there are languages like Smalltalk where you can change almost anything while running.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endar
Garbage collection ... I'm not so sure, because I'm intending to have only primitive types, so I won't be needing dynamic memory.


You will need some form of garbage collection or another as soon as you starting using closures. In many situations, your containers (arrays, lists, hashes, whatever) will also involve some form of garbage collection. Although if your scripts run only in short-lived instances, you can always choose to apply the classic "free everything when the script ends" solution.

Quote:
What do you mean by 'closures', 'expression syntax' and 'expressive language?'


"closures": these are functions that can contain references to data. Suppose that you have an integer, and you wish to increment that integer whenever a certain event happens. Your design allows you to specify a function to be called when the event happens. You then wish to create a function which increments the integer every time it's called. The typical C solution would be:

int counter = 0;
void increment_counter() { ++counter; }
set_event_callback(&increment_counter);


However, this creates the problem of requiring a global counter. If you wanted to create counters on demand, this solution would not be enough. Using anonymous functions, a first approach would be to do this:

void create_counter(int *counter)
{
return new-function() { ++*counter; }
}
int c1, c2;
set_event_callback(create_counter(counter1));
set_event_callback(create_counter(counter2));


This, however, would require the function returned by create_corner to store a reference to counter (effectively storing the pointer it uses). This is called a closure.

"expression syntax": it basically means that everything in your language is an expression, making the language a lot simple than if you had an expression-and-statement dual grammar. For instance, in C languages, if() {} else {} is a statement and () ? () : (), which forces programmers to use a different construct depending on whether the branch is at statement scope or expression scope (and there's no expression-equivalent for a switch block). In an expression-based language, the same construct is used in both cases, making the language simpler and easier to use. Consider C:

void print_status(direction d, int time)
{
char *desc = 0;
switch (d)
{
case NORTH: desc = "North"; break;
case SOUTH: desc = "South"; break;
case EAST: desc = "East"; break;
case WEST: desc = "West"; break;
}

printf("Direction %s, time %d\n", desc time);
}


Note the variable assignment and redundant switch syntax. Compare with Objective Caml version:

let print_status d time = 
Printf.printf
("Direction %s, time %d")
(match d with
NORTH -> "North" | SOUTH -> "South" | EAST -> "East" | WEST -> "West")
(time)


Since everything is an expression, a "switch statement" (called a match-expression) can be used as a function argument for shorter code.

As for a language being expressive, it just means that it can be used to express ideas in a concise fashion.

Share this post


Link to post
Share on other sites
I am not certain that creating a scripting language is a minor undertaking since there are many more "advanced" expressive features that are within reach when c/c++ is removed from the equation and people might feel justified in asking for them. if this was a wish list then coroutines or continuations - but serializable so that the entire game state could be captured and saved to disk and then loaded and resumed again - maybe something like link.

Share this post


Link to post
Share on other sites
Quote:
Original post by niteice
You know, whenever I hear C-like syntax with anonymous lambdas, tuples, etc, all I can think of is ECMAScript.

Just saying.


Yeah, I think ECMAScript/javascript is actually a very underrated language, especially the more recent versions which have borrowed heavily from Python too.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!