A C-like scripting language?

Started by
56 comments, last by Rebooted 15 years, 11 months ago
Quote:Original post by Decrius
Sorry to say, but:

let delay = randomfloatrange (-20) (-15) in
iter (fun (t, fx, hz) -> global_FX(t, fx, hz, delay))

Looks very unclear with the spaces and random-looking brackets. Why does it need brackets around numbers, and what does -20 and -15 mean? It looks more like a language that tries to make source code as small as possible, which they over-do so the readability is decreasing.

It isn't clear because you don't know ML! -20 and -15 are just the parameters to the randomfloatrange function. Your code uses them too.

The "iter" function takes 2 parameters: the first is a function and the second is a list. The iter function then applies the function passed as the first parameter to every element in the list.

The first parameter is:
(fun (t, fx, hz) -> global_FX(t, fx, hz, delay))

This is an inline function definition (also called a lambda form). It says that the function, when given a tuple, will just call the "global_FX" function with those parameters and the delay.

The list is the second parameter. It is a list of tuples where each element is one of the filenames.

When this code runs, the iter function will take each line in the list, feed it to the lambda function which will feed it to the global_FX function. Also notice that the delay parameter was the same each time, so we extracted it out.

Splitting it up this way has a few advantages. The first is the amount of code decreases, because you don't have to explicitly call the global_FX function so many times.

The second, more important benefit, is that code redundancy decreases. This makes code cleaner and more robust. If you had to, for example, add a parameter to the global_FX function, the C version would be much more of a pain to fix.

Also, by separating the data from the function call, the code is more general. If, later on, you wanted to read these strings in from a file, you could simply read them into a list and pass it to the iter function instead.

Quote:Original post by Decrius
As for the array, C has them concentrated by subject, and has rows. While that example has just a block of data which is much harder to read over and looks messy.

Not at all. This example has *more* structure since each element in the list is actually a tuple containing three strings. Why does it look messy?


Quote:Original post by Decrius
And more code isn't bad. It gives readabilty and is easier to scan with your eyes, since things are more stretched out. Imagine a language where every word would do like 5 operations...you'd have a 10 line code which does a dozen of things but you can't grasp it since it's very compact written...*shivers*

That isn't what is going on with the ML version. To me, it is easier to read because it separates the data from the functionality. Or, if you prefer, it separates the parameters from the function call. This is something that isn't done much in C-style languages, so it looks confusing, but is actually simpler.

That said, you can certainly choose any language you like, but learning new things is always good :)
Advertisement
"Thanks, that looks good too. How well can it be bind to C/C++?"

here is a example ..

// .h file
class SiInterface
{
public:
//=== constructor ===//
SiInterface();
//=== destructor ===//
virtual ~SiInterface();
//! sleep the given number of milliseconds
void SiSleep( int iMsSleep );
//! logon operator onto keyboard
int SiLogonOperator( int iKbdNum, int iEmpNum );

static void RegisterWithSquirrel( void );
};
DECLARE_INSTANCE_TYPE(SiInterface); // declare type for squirrel

// .cpp file
SiInterface g_oSi; // one and only instance of squirrel interface

void SiInterface::RegisterWithSquirrel( void )
{
// bind class SiInterface
SqPlus::SQClassDef<SiInterface> ( _T("SiInterface") ).
func(&SiInterface::SiSleep, _T("SiSleep") ).
func(&SiInterface::SiLogonOperator, _T("SiLogonOperator") );

g_poSi = &g_oSi;
// pass pointer to C++ pointer to SiInterface
SquirrelObject root = SquirrelVM::GetRootTable();
SqPlus::BindVariable(root, g_poSi, "Si");
}


// .nut file
Si.SiLogonOperator( 1,1 );
Si.SiSleep(1000);
Si.SiLogonOperator( 2,2);
Quote:Original post by rip-off
The most important thing to remember though is that scripting is supposed to make development time faster and easier. If it isn't doing that for you then I would drop it.

If Angelscript looks right for you - go for it.

I haven't used Angelscript but I imagine the benefits are probably safety and developer time. You have no idea how big a difference cutting out the compile and link stages can make to developer time. Small changes can be a simple matter - quit the program, change the script and run again. Or you could make it better. Your game could auto-detect when someone changes a script it uses and re-load the script.

After I made the majority of my game logic scripted, I could go days (or weeks) without compiling my application. All the changes I wanted to make were totally controlled by scripts.

Safety means that your scripts shouldn't be able to crash the game. The game should be able to detect any logic errors in the scripts and cleanly shutdown, notify the user or otherwise sanely handle the error. None of this bad pointer crap that C is known for.


I'm unsure if it does make development quicker, looks more like a limited version C, but I will look into it.

@Simian Man
Thanks for explaining, makes sense now. It's just that I really like how C is written, other languages always give me the feeling of huge over-head...somehow. And I also don't always fully grasp why people make so many languages, one-for-all language would be better then all those small languages IMHO.

@drac_gd
Thanks for the example, looks easy aswell. I will look into both AS as Squirrel ;).

[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
And I also don't always fully grasp why people make so many languages, one-for-all language would be better then all those small languages IMHO.


The quality of a programming language is defined by what this language prevents you from doing. A language which would let you do anything you want would be, by its very design, a bad language.
Quote:Original post by Decrius
Thanks for explaining, makes sense now. It's just that I really like how C is written, other languages always give me the feeling of huge over-head...somehow.

It's a baseless feeling, fed by years of bullshit about how C is "fast" and everything else is "slow". There are common tasks at which other languages are orders of magnitude faster than common C implementations, despite those languages themselves being implemented in C! Why? Because those languages establish higher-order abstractions, at which level the operations in question are simpler and thus quicker.

Quote:And I also don't always fully grasp why people make so many languages, one-for-all language would be better then all those small languages IMHO.

There is no one language that is well-suited (much less ideally suited) to all problem domains.

From reading this thread, you are a little too caught up in your own opinions, which is unfortunate given your lack of extensive education and/or experience. Why should someone who only knows C - and can't know it well, since he doesn't know its shortcomings - make statements about general language design? You don't even know what a tuple is!

Accepting your own ignorance, or the limitations of your knowledge, is a prerequisite to learning.
What? No Python love here? Something is seriously wrong with this thread. [wink]

I quite like Python. It's syntax is similar enough to C's to be easily picked up by programmers instantly, but it still is easy enough for designers to use. It's main drawback, IMO, is that it's a pain to interface with C++. I guess with C it's not so bad, due to the cTypes module, but with C++ you'll spend more time building the interface than writing the scripts. Oh well, it's a very nice language.
Quote:Original post by Oluseyi
It's a baseless feeling, fed by years of bullshit about how C is "fast" and everything else is "slow".


Proof me wrong then, I like to see facts, not opinions.

Quote:Original post by Oluseyi
Accepting your own ignorance, or the limitations of your knowledge, is a prerequisite to learning.


<rant>

Oh really?

I've respected every opinion here on this forum when I first came here. I kept swapping libraries and luckily never was trapped to keep swapping languages too. Everybody has it's own opinion, and I respect that, but here everyone tries to enforce their opinion onto everyone.

That is really sad, I see some users being attacked with so many different opinions, they have no idea what to do. Now I program in C, half the users loves me, half the users hate me. Then I use this, same. Then I use that, the same responses.

If people wouldn't think they are elite and know-it-all (and thus enforce their opinions) this place would be much better, and people would actually learn a language instead of swapping every now and then.

Ofcourse, you should learn multiple languages. But C/C++ should certainly be one of the languages you should master, and if people would actually let me use it instead of complaining, this forum would be a much nicer place (it's very nice already, but I just happen to see a lot of endless, pointless discussions about language choice).

Actually, I just wanted you guys's opinions on the scripting language close related to C syntax. I wasn't asking for anything that looks better in your eyes, since it looks worse in my eyes. Ofcourse, I could take the time and learn it, but for scripting languages I find that being pretty pointless in the end and very time consuming.

</rant>

Quote:Original post by ToohrVyk
The quality of a programming language is defined by what this language prevents you from doing. A language which would let you do anything you want would be, by its very design, a bad language.


May I ask you why quality is connected to what a language is not?

I think a multi-purpose language gives longer code, since it should support many different purposes, while a one-purpose language 'assumes' things, and can therefore leave out many clarifications. It would give longer code, and harder to maintain, but aslong as the programmer knows what he does I don't see why it could lead to bad design. Or do you mean something else with bad design?

Thanks.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Perhaps you can have a look at gamemonkey which is a "lua implementation"-like with a C-like syntax.
Quote:Original post by kratolp
Perhaps you can have a look at gamemonkey which is a "lua implementation"-like with a C-like syntax.


Thank you, looks very nice too. I will take it into consideration ;)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
Proof me wrong then, I like to see facts, not opinions.


Some time back, I had to write a web page analysis system, and I used C. Needless to say, I spent an entire month getting all the string manipulation to work correctly while eliminating any overhead I could identify. Then, I ran the stuff, and although it seemed to run pretty fast in the beginning, after a day of running it simply ground to a halt. I didn't have time to optimize it, so I killed the process and used the partial results.

What I learned later was that someone else on the same team had to do some work that was quite similar to mine. But instead of using C, they used an in-house scripting language that compiled to java bytecode with bindings to the same C library I was using. They had finished coding all the algorithms in a single week (because they didn't have to care about memory management or buffer overflows, they had access to sane string manipulation operators, and the scripting language had functional programming support) instead of a full month like I did. The ability to write "a + b" instead of "measure, allocate, strcpy, strcat, deallocate, return" does give you that kind of productivity gain. And believe me, when you're dealing with web pages, you don't want to be using fixed-size buffers.

Then, they ran it. The program ran overall in a slow fashion, and ground to a halt after one day. They profiled it, found that there was a bottleneck in one of the hash tables, and solved that bottleneck by clearing the hash table every 10000 pages. The program still ran slowly, but it remained at a constant speed and delivered the full results after another day of computations. By looking at the profiling results some time after that, I noticed that I had the same bottleneck, which (they told me, once I had left the team) indeed solved the speed problem of my program.

The point of this comparison is that a hand-written C program took a month to complete and was too slow to provide full results, whereas a similar program written in a scripting language delivered the full results in two weeks. The entire time I spent writing C string manipulation code accounted for a performance increase in 1% of the execution time, while 99% of the execution time was (unpredictably) concentrated in the hash table processing. Moreover, a single statement was all it took to obtain a drastic increase in performance, where all that overhead removal code had failed.

In short: obtaining performance increase in C isn't free, you have to spend time and effort to make it happen. Had that time been spend working on algorithmic bottlenecks instead of memory allocation handling, your program would have been faster in many cases.

Quote:
Quote:Original post by ToohrVyk
The quality of a programming language is defined by what this language prevents you from doing. A language which would let you do anything you want would be, by its very design, a bad language.


May I ask you why quality is connected to what a language is not?


There are two main schools of thought on what makes a programming language great. The first school of though, the older of the two, believes that programmers are close approximations of perfect beings with infinite knowledge, infinite brain power, and the ability to concentrate on an infinite amount of different concepts at the same time, and that great results will be achieved by giving them maximum freedom. This is generally summarized as "the programmer knows what he is doing". This school of thought thus proposes that a perfect language would be expressive enough to let the programmer do whatever he wishes to achieve the end result.

This leads to languages such as C, C++, PHP or LISP: broad enough to let you do whatever you wish, even if it involves shooting yourself in the foot as soon as you forget even the tiniest detail.

The amount of foot-shooting led to the appearance of a second school. This school of though believes that, although truly exceptional programmers exist, the vast majority of programmers are in fact frail and fragile creatures with limited knowledge and limited concentration skills. Thus, a system with infinite freedom would lead to two consequences: first, since there are several equally difficult ways of achieving any result, programmers tend to choose different ways and thus have trouble understanding each other's code, and second, since programmers are prone to making mistakes, freedom is more of a downside than an advantage. This school of thought thus believes that a language should shoehorn the programmer into a simple mindset by restricting his choice of actions to only a subset of what technology would allow him to, in a way that makes most foot-shooting activities unthinkable.

This leads to languages such as early Java, XSL, Haskell or OCaml: these force you into a specific way of developing, and prevent many of the classic mistakes that come from the languages with more freedom of action.

I used to belong to the first category of people. I saw myself as an infinitely competent programmer, able to notice all the bugs that appeared when I happened to make them. And then, I got a job. My job involved developing a PHP content management system, and I had to report my project's statut (with a prototype demo) every week. While I do consider myself a good developer, the number of errors that can happen with PHP is staggering—sure, the absence of types means your language is more expressive than about every single other language except Java and C# (and even then, object can only get you so far), but this usually means that you can express original and unusual errors in that language. Also, the vast freedom allowed had to be restrained: the contract specified that code had to be readable, so any clever manipulations involving PHP oddities were out of the question. Shortly after that, I came to appreciate the calm safety of restrictive languages.

OCaml is my personal favorite in this respect. See, most mistakes in code come from trying to do X, but achieving Y instead. This, in turn, derives from the fact that the code for doing Y is very similar to the code for doing X. In a language such as OCaml, the structure of code is such that the code for doing Y is, most of the time, extremely different from the code for doing X. The only exception here would be constants, where it's easy to use a constant instead of another or commit off-by-one errors, but the standard library of the language (and, generally, the philosophy of the language) tends to prevent such things.

The core reason for this is algebraic types. Consider for a short moment the C type system:

type = basic-types | structures            | type [N]           | type *           | type (*)(type)


Out of these, only the basic types, structures and pointers are used frequently in average C code. Function pointers do appear sometimes, but they are usually kept extremely simple. In short, it's very difficult to have many different types in C. Now, consider the OCaml type system:

type = basic-types | structures           | type * type            | type -> type           | type type


First, unlike C, types tend to be much deeper in OCaml. It's certainly not unusual to have a (string list, int option) Hashtbl.t list lying around (if you're wondering, that would be the data structure for supporting "undo" in a virtua lfile system). You have more combinators, especially those which involve more than one type. In the end, this means that an average program in OCaml will involve an order of magnitude more types than a C program. Thus, a subtle mistake in code will result in a type mismatch with a much higher probability than in C code.

This topic is closed to new replies.

Advertisement