Skip to main content
GameDev.net gamedev.net
🔒 Locked

Opinion on syntax for func ptr in AngelScript

Started by WitchLord Jan 4, 2010 at 10:12 AM 21 replies 6.6k views
Original Post
WitchLord
WitchLord
Hi guys, I'm trying to decide what syntax I should use for function pointers in AngelScript. I would very much like some feedback from the community on this: So far I've come up with two alternatives, but feel free to suggest others. Alternative 1: C function pointer style:

// A function pointer variable
void (@funcPtr)() = null;

// A function that takes and returns a function pointer
void (@)() retFuncPtr(void (@f)()) { return @f; }

// Typedef
typedef void (@functype)();



Alternative 2: C++ template style:

// A function pointer variable
function<void f()> @funcPtr = null;

// A function that takes and returns a function pointer
function<void f()> @retFuncPtr(function<void f()> @f) { return @f; }

// Typedef
typedef function<void f()> functype;



Alternative 3: Inspired by C# delegates:

// Typedef - required in order to use the function pointer
typedef void functype();

// A function pointer variable
functype @funcPtr = null;

// A function that takes and returns a function pointer
functype @retFuncPtr(functype @f) { return @f; }

Which alternative do you prefer? It would be great if you state the reasons for your opinion too, but it is not necessary. Thanks, Andreas [edit]Added alternative 3 based on xivVerge's suggestion about delegates[/edit] [Edited by - WitchLord on January 4, 2010 12:58:00 PM]
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
xivVerge
xivVerge
I like the second alternative because i like templates :)
But since you are free on the syntax why not use something like delegates (e.g. used in C#) to save the @.

delegate int OperatorDelegate(int, int);int Add(int x, int y){  return x+y;}int Sub(int x, int y){  return x-y;}int retFunc(OperatorDelegate f, int x, int y){  return f(x, y); }void main(){  OperatorDelegate f = Add;  retFunc(f, 1, 2);}


Tim
e3d_ALiVE
e3d_ALiVE
i'm all for delegate method


[Edited by - e3d_ALiVE on January 4, 2010 12:49:27 PM]
Crazy dude smoking D3D11, AngelScript, PhysX, 3D Sound, Network, DB, FBX, and some other weird things, doing that on Visual Studio 2010 + Visual Assist X on Overclocked CPU
quarnster
quarnster
I think the delegate way is the cleanest.
WitchLord
WitchLord
Thanks for the suggestion. The delegate syntax is nice and I'll give this some more thought.

However, I'd like to tell you already that I'm not implementing delegates (as defined by C#) at this moment, just simple function pointers.

I will also maintain the @ for the sake of consistency. However, just as the @ can be omitted for object handle assignments, it will also be optional for function pointer assignments.

In a future version of AngelScript I'd like to add the option to remove the @ from the syntax all together. However, that would make all reference types behave as handles (just as in Java), thus raising other issues that I do not want to deal with at the moment.

[edit]I added alternative 3 to the original post. Not exactly like the delegates, but inspired by them.[/edit]
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
Friggle
Friggle
The delegate version looks nice, that's true.
However, a good portion of its simplistic look is due to the mandatory typedef if I get the idea correctly.

If the typedef would be used throughout the C++ like example #2 then this one would look similarly simple but my feeling is that the syntax for the C++ typedef is somewhat clearer than with #3.
However, this might be just because I'm not quite familiar with C#...

Cheers,
Thomas
xivVerge
xivVerge
Alternative 3 looks very nice and clean and has the advantage that you don't need to copy the function declaration every time you use a function pointer.

Tim
WitchLord
WitchLord
Yes. I think I will require the 'typedef' to declare the signature of the function pointer, rather than making this optional.

This will also make the parser a lot simpler, which is always a good thing.

The only question that remains is the syntax for the 'typedef', or perhaps I should call it something else, maybe 'funcdef'. Alternative 3 is definitely the cleanest, but is it the easiest to understand?
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
Friggle
Friggle
For the discussion on the best syntax of the typedef, could it be helpful to consider an example that defines a callback function type that takes parameters and returns a value?
WitchLord
WitchLord
I'm afraid I didn't understand your question. Could you elaborate on what you meant? What kind of example are you looking for?

However, maybe it is not such an important issue after all. After all, in embedded scripts, the script writer would usually not have to define its own function signature for function pointers. The application would define the signature of the function pointers it expects to use, like key event handlers, etc.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
Friggle
Friggle
The examples above use pointers to functions that are void (i.e. don't return a value) and also don't take any parameters, right?
Additionally, my perception is that example 2 and example 3 would look almost identical in case example 2 would make actual use of the typedef which is given in its last line. The only difference between #2 and #3 would then the syntax for the corresponding typedef.

My thought was, that discussing an example of a typedef that defines a function that takes parameters and returns something could be more useful to get an idea of which typedef syntax is clearer.

I don't think that my words above give a better explanation for my previous post, do they? I rather think that I'm getting something wrong here in principle, in this case just ignore it, I will see the light sooner or later ;-)

Cheers,
Thomas
Halifax2
Halifax2
I prefer alternative #2, it is cleaner than alternative #1 and has the necessary verbosity that alternative #3 lacks in my honest opinion.

Although people may say that you should comment your code, or the like, I believe that alternative #3 is very vague, especially if the definition comes from another file. At least with alternative #2 I can read it word for word and understand it right away. In my eyes alternative #1 is just as good as alternative #2, but alternative #1 is a little "rougher" on the eyes.

So those are my reasons for going with alternative #2.
Denzel Morris (@drdizzy) :: Software Engineer :: SkyTech Enterprises, Inc.
"When men are most sure and arrogant they are commonly most mistaken, giving views to passion without that proper deliberation which alone can secure them from the grossest absurdities." - David Hume
WitchLord
WitchLord
Friggle:

The typedefs for the different alternatives but with parameters might look something like this:

// Alternative 1typedef bool (@functype)(int, string ∈);// Alternative 2typedef function<bool function(int, string ∈)> functype;// Alternative 3typedef bool functype(int, string ∈);



Halifax2:

I agree that the typedef in alternative 2 may be a bit more understandable than the one in alternative 3. For that reason I think maybe typedef is not the right word for this, I need something more explicit, maybe like this:

function bool CALLBACK(int, string ∈);


The typedef can still be used to declare aliases if desired.

I really don't think it is vantageous to repeat the function signature rather than using a single type identifier. Especially if the function signature has a lot of parameters, then it will pollute the code a lot, which confuses the inexperienced programmer.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
Halifax2
Halifax2
Very true WitchLord. By the way, I like that final syntax you posted there at the end of your post. You're right about the type definition issue.
Denzel Morris (@drdizzy) :: Software Engineer :: SkyTech Enterprises, Inc.
"When men are most sure and arrogant they are commonly most mistaken, giving views to passion without that proper deliberation which alone can secure them from the grossest absurdities." - David Hume
Bismuth
Bismuth
Does a function pointer really have to be defined with a return type and all function parameters? Why not simply use an universal pointer that can point to any function, having the runtime autodetect the function parameters and return type whenever the pointer changes? When the pointer gets called, have the runtime check that the passed parameters and return type match. If they don't or the pointer is null, the runtime raises an exception.

Just a thought.
SiS-Shadowman
SiS-Shadowman
That sounds like using a void pointer plus some runtime checking. What would be the benefit of that? I mean, in the end you expected a pointer to match a certain signature, otherwise you can't call it anyway.
WitchLord
WitchLord
Quote:
Original post by Bismuth
Does a function pointer really have to be defined with a return type and all function parameters? Why not simply use an universal pointer that can point to any function, having the runtime autodetect the function parameters and return type whenever the pointer changes? When the pointer gets called, have the runtime check that the passed parameters and return type match. If they don't or the pointer is null, the runtime raises an exception.

Just a thought.


If AngelScript was a dynamically typed language, then that is what I would have done. However, AngelScript is statically typed, and should do all the type checks at compile time. If I can catch a programmer error at compile time instead of at run time I want to do that.

Still, there will be a generic function pointer that can store all function signatures. However, it cannot be used to call the function it points to. In order to call the function the pointer must first be dynamically cast to the correct function signature.

Regards,
Andreas
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - <a href="http://www.angelcode.com/tower" rel
Wavesonics
Wavesonics
Boy I remember learning function pointers in C++ the first time, it was frustrating syntax to learn starting out.

#3 has the most elegant syntax, but the typedef could be a stumbling block for some.

What if you could reference a compiler defined type for the function signature?
int foo( bool b );// foo_funcType is a compiler generated type for pointers to functions with foo's signaturefoo_funcType@ fooPtr = null;


If I'm not mistaken, the compiler first parses all the function signatures, b4 actually compiling the functions right? So you'd always have the signatures by the time you needed to create a func pointer type out of them.

What do you think? It seems like a nice higher level sort of thing for a scripting language, no?
jal_
jal_
I'm all for #3. It's just cleaner.
Bismuth
Bismuth
Quote:
Original post by WitchLord
If AngelScript was a dynamically typed language, then that is what I would have done. However, AngelScript is statically typed, and should do all the type checks at compile time. If I can catch a programmer error at compile time instead of at run time I want to do that.
Hmm, yes that makes sense.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.