Useful scripting language features?

Started by
25 comments, last by Republicanist 15 years, 8 months ago
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?
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
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).
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 numbersone, 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.
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.
You know, whenever I hear C-like syntax with anonymous lambdas, tuples, etc, all I can think of is ECMAScript.

Just saying.
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?'
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
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.
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.
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.
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/&#106avascript is actually a very underrated language, especially the more recent versions which have borrowed heavily from Python too.

This topic is closed to new replies.

Advertisement