How to create an array of function pointers?

BlitzMax Forums/BlitzMax Programming/How to create an array of function pointers?

Pineapple(Posted 2015) [#1]
How do I allocate an array of function pointers? One would expect the syntax to look like this, but it doesn't work.

' works for ints (compiler likes this)
local intarray%[]
intarray = new int[10]

' doesn't work for function pointers (compiler shits on this)
local funcarray%(arg0%,arg1%)[]
funcarray = new int(arg0%,arg1%)[10]



Brucey(Posted 2015) [#2]
This works,
SuperStrict

Framework brl.standardio

Local arr:Int(a:Int)[10]

arr[0] = x

arr[0](5)


Function x:Int(i:Int)
	Print "Hello " + i
End Function



Brucey(Posted 2015) [#3]
I couldn't work out how to use it with "New", however you can do this:
Local arr:Int(a:Int)[0]

arr = arr[..10]



LT(Posted 2015) [#4]
Brucey, I think he means that funcarray should store 10 functions afterwards. arr = arr[..10] just ends up with Null values.


Brucey(Posted 2015) [#5]
It will store 10 functions, once you populate the array...
SuperStrict

Framework brl.standardio

Local arr:Int(a:Int)[0]

arr = arr[..10]

For Local i:int = 0 Until arr.Length
    arr[0] = x
Next

For Local i:Int = 0 Until arr.Length
    arr[0](i * i)
Next

Function x:Int(i:Int)
	Print "Hello " + i
End Function



LT(Posted 2015) [#6]
I know, but I think he's expecting it to be populated when you use New typename[n]. It seems more natural to me that way, too.. /shrug


Brucey(Posted 2015) [#7]
Yes, I know, but I couldn't get that syntax to work - unless you've had more luck? ;-)

So, I posted some alternative syntax which does exactly the same thing.


LT(Posted 2015) [#8]
Something for ng? Pretty please? :)

EDIT: I suppose having Nulls, by default, is less overhead.


Derron(Posted 2015) [#9]
[...]I think he means that [...]

I think pineapple would enjoy it to be recognized as "she".


@problem
I am not able to imagine that the suggested "new functionDefinition()" would work at all. I would have come up with something Brucey already did: manually resizing an array and filling it with pointers (or a single pointer to make them "not null").


To create another alternative:
local fArray:Byte Ptr[]
local fPointer:Byte Ptr
local fInstance:int(arg:int)
function f:int(arg:int); print arg; end function
fPointer = Byte Ptr(f)

fArray = new Byte Ptr[10]

For local i:int = 0 to fArray.length
	fArray[i] = fPointer
Next

fInstance = fArray[0]
fInstance(10)


... but I prefer the one Brucey already proposed.


bye
Ron


LT(Posted 2015) [#10]
I think pineapple would enjoy it to be recognized as "she".
Ah, well, apologies to the op...clearly did not draw that conclusion from "pineapple."


Yasha(Posted 2015) [#11]
arr = arr[..10] just ends up with Null values.


What are you expecting it to be populated with by default? It can't choose a function for you...

Incidentally, remember you can also create arrays like this:

Local arr:Int(a:Int)[] = [..
    func1, ..
    func2, ..
    func3, ..
    func4 ..    'etc
]


Auto-arrays are much nicer than manually populating or sizing anything.


LT(Posted 2015) [#12]
I was talking about types. Yes, I know the op was talking about functions.


Yasha(Posted 2015) [#13]
Oh yeah, for object types it would be possible.

I think it would violate the Principle of Least Surprise though, and it optimizes for the uncommon case. Even though it could be done, some reasons not to:

- it doesn't provide much benefit over an empty array (no performance benefit compared to a manual loop with New immediately afterwards, and only saves you three lines)
- there's a good chance it would be wasteful, since many arrays are created to be populated with existing items (those that aren't are usually auto-arrays, as above)
- the default values of some builtin object types (String, Array) compare equal to Null under current language rules
- most importantly, it suddenly makes array creation nondeterministic, maybe even interfering with your program's operation, since New can contain arbitrary code with side-effects

(you'd also have to change the rules to allow Object to be instantiated when creating an array of Object elements, but this isn't really a big deal; can be faked as-is with reflection anyway)

Null isn't a great language feature, but if it exists, you may as well embrace it.


LT(Posted 2015) [#14]
Yeah, probably not worth it.


Pineapple(Posted 2015) [#15]
Thanks for the suggestions. Wouldn't using slices to set the size of the array be slower than just creating a new array, though? I thought maybe I could create a new int array and then cast it to a function pointer array, but it turns out the obvious syntax for casting to a function array doesn't work either.


LT(Posted 2015) [#16]
Setting the array size to 10 initially is perhaps a touch faster, as long as you know the size ahead of time.


Pineapple(Posted 2015) [#17]
The problem is that I don't know it ahead of time.


Yasha(Posted 2015) [#18]
You know the number in the type part of the variable declaration doesn't need to be a constant, right?

Local arr:Int(a:Int)[ a().b(c.d) ]  'creates an array of very unpredictable size


Using New ...[] with arrays could be considered more readable, but it's totally optional. The above creates an object in the same way. The variable is null if the square brackets are empty, and a reference to a dynamically-created array of the given size otherwise.


Pineapple(Posted 2015) [#19]
I was trying to assign the array to a field of a class from inside a method. I realize now that I could probably just create the array that way and then assign the field to the array. The lack of decent syntax remains a bummer, though.