There is something I would like to share here again on the subject of procedure pointer. It's the sequel of the previous remark about the fact that the procedure pointer is a typed pointer and we can do almost nothing with it in the form of an "any ptr".

We need the full procedure signature to play the role of the type of the pointer. (That the signature becomes a type is by itself a non trivial concept!)

Note that the term signature seems not to be included in the manual's glossary, so this is what I'm talking about:---> sig=proc_type + proc_name + proc_arguments_list [ + proc_return_type ]

There is probably a better way to define the term of course, but I wanted to reiterate my concern about the 2 problems that occurs if someone wants to use the procedure with the help of only the address:

We have seen how to deal with proc_signature_as_type, with the help of TYPEOF if we keep a track of the PROCPTR (typed pointer, not an ANY PTR).But the proc_args_list is somehow complicated to store in a syntactic structure... (I didn't find a macro to do the job, but maybe someone here will ?)

My question here is about the second aspect. Isn't it possible to pass an argument list to a procedure (sub or function), in the form of a unique pointer (a buffer), so that we can unify the syntax required to use the procedure retrieved from its any ptr version?

It's a little technical but it would be very useful I think. Thanks anyway.

- - - - - -Last minute note:Should this article deal with instance member procedure pointers, or give a link to the topic?Last thing is pure curiosity, what about dim byref and procedure pointers?Those 2 issues have no emergency character for me, it's just a reminder.

coderJeff wrote:, 2 things I most often use function pointers:1) Call backs, for example, print logging, comparison function (for sorting using generic algorithm), enumerations (my own or like in WINAPI)2) Interface: a TYPE with several function pointer methods that are initialized when the CONSTRUCTOR is called. For example, a stream-like interface that might work with a file or memory, gets constructed with members pointing to different methods.

Your definition of INTERFACE make it concrete. I don't use c++ and I find vb.net interfaces very strange, probably because I don't understand what they are useful for.

I would add a 3) :library imported functions. They have there proper syntax in the context of dynamic libraries in fb, but it's the same familly.

hi fxm, in order to get deeper on the topic I read this wikipedia page below, https://en.m.wikipedia.org/wiki/First-class_functionMostly got nothing from it really usable (by me) but I noticed that they forgot Freebasic in their language comparison table!!I'm not able to fill the missing entry myself because I precisely would need it to understand the article :) If you or someone among the experts did the job, it would please me, but above all this is really a missing information that is only justified by the ignorance of the authors of the current version of the wikipedia page. This has to be avenged ;)

Sub sketch(fn As Any Ptr,colour As Ulong,axiscolour As Ulong=Rgb(150,150,150)) Using globals f=fn Dim As Double last=f(minx) For x As Double=minx To maxx Step (maxx-minx)/PLOT_GRADE Dim As Double x1=(xres)*(x-minx)/(maxx-minx) Dim As Double d=f(x) Dim As Double y1=(yres)*(d-maxy)/(miny-maxy) If Sgn(last)<> Sgn(d) Then Circle(x1,y1),2,0,,,,f If x=minx Then Pset(x1,y1),colour Else Line -(x1,y1),colour last=d Next x 'axis Dim As Long f1,f2 If Sgn(minx)<>Sgn(maxx) Then Line(((minx/(minx-maxx))*xres),0)-(((minx/(minx-maxx))*xres),yres),(axiscolour) 'y axis f1=1 If Sgn(minx)=0 Or Sgn(maxx)=0 Then f1=0 End If If Sgn(miny)<>Sgn(maxy) Then Line(0,(yres-(miny/(miny-maxy))*yres))-(xres,(yres-(miny/(miny-maxy))*yres)),(axiscolour) 'x axi f2=1 If Sgn(miny)=0 Or Sgn(maxy)=0 Then f2=0 End If

Sub getyrange(fn As Any Ptr,sx As Double,lx As Double,Byref by As Double,Byref sy As Double) Using globals f=fn #macro _window(topleftX,topleftY,bottomrightX,bottomrightY) minx=(topleftX) maxx=(bottomrightX) miny=(bottomrightY) maxy=(topleftY) #endmacro MinimumY=1e50:MaximumY=-1e50 For n As Double=MinimumX To lx Step(lx-MinimumX)/10000 Dim As Double v=f(n) If MinimumY>V Then MinimumY=v If MaximumY<V Then MaximumY=V Next _window(MinimumX,MaximumY,MaximumX,MinimumY) End Sub

Sub bisect(fn As Any Ptr,min As Double,max As Double,Byref O As Double) Using globals f=fn Dim As Double last,st=(max-min)/100000,v For n As Double=min To max Step st v=f(n) If Sgn(v)<>Sgn(last) Then Print(n);Tab(27);f(n) O=n+st:Exit Sub End If last=v NextEnd Sub

dodicat wrote:An artificial example.I have put any ptr where a function would do.

Hi dodi,

not so artificial. As far as I understand correctly this pagehttps://en.m.wikipedia.org/wiki/Map_(hi ... r_function)you show us here how to implement a "map". And an anonymous like. According to the Wikipedia this is advanced feature that one may find or not in the language. Here we have to conclude, it's feasible in fb thanks to the power of macros and procedure pointers (and to the artist that melts the both!).

Tourist Trap wrote:My question here is about the second aspect. Isn't it possible to pass an argument list to a procedure (sub or function), in the form of a unique pointer (a buffer), so that we can unify the syntax required to use the procedure retrieved from its any ptr version?

A twisted solution, using an OBJET PTR array, and the RTTI capability to retrieve the real type of object (among those derived from OBJECT) and thus the associated static procedure (but no procedure pointer usage):

Sub procedure(p() As Object Ptr, Byval I As Integer, Byref S As String, Byval D As Double) For N As Integer = Lbound(p) To Ubound(p) Print N & ":", If *p(N) Is t0 Then t0.s0(I) Elseif *p(N) Is t1 Then t1.s1(S, D) End If Next NEnd Sub

Sub procedure(Byval p As Object Ptr Ptr, Byval I As Integer, Byref S As String, Byval D As Double) For N As Integer = 0 To 1 Print N & ":", If *p[N] Is t0 Then t0.s0(I) Elseif *p[N] Is t1 Then t1.s1(S, D) End If Next NEnd Sub

dodicat wrote:I mean skipping the type declaration and inserting a function directly as a parameter.As perhaps in the thread example

I suppose that passing an any ptr to Threadcreate(), instead of a typed SUB pointer with the requested signature ('Sub (Byval As Any Ptr)'), disables the compiler signature test, but this lax behavior is not specified and can change as well in future compiler releases.

fxm wrote:Like any other pointer, a procedure pointer can be passed or returned by reference, and one can also create a reference to a procedure pointer.

Thanks. Overall, my questions are answered right now. There is still things to be clarified but I would have to test many things before - but already learnt good stuff today anyway :).

My 2 cents contribution to an attempt to get rid of the necessity to know by advance the procedure signature before using it when hidden in a pointer variable. Far from satisfying and very artificial , I think we will need the ability to treat a type as variable like the others some day. At least it's my temporary conclusion.

declare sub F0( as PROCARGDESC, as PROCARGUNIBUFFER)declare sub F1( as PROCARGDESC, as PROCARGUNIBUFFER)declare sub F2( as PROCARGDESC, as PROCARGUNIBUFFER)declare sub F3( as PROCARGDESC, as PROCARGUNIBUFFER)

' Classes of datatypes (derived from Object):' - Each class contains a datatyped pointer, initialized to the variable address at instance construction.' - 10 datatypes are taken into account in this examples, including:' - Integer,' - String,' - Sub(byVal as Integer),' - Sub(byRef as String, byVal as Double),' - Function(Byval As Integer) (byVal) as String' - Pointer to Integer,' - Pointer to String,' - Pointer to Sub(byVal as Integer),' - Pointer to Sub(byRef as String, byVal as Double),' - Pointer to Function(Byval As Integer) (byVal) as String' - 20 variables are tested, using the 10 datatypes.' - For each variable, an instance of matching class is created (a macro simplifies the creation syntax).' - The 20 instances are passed to a Sub by means of an array of Object pointers to instances.' - Using the Is (RTTI) keyword, the real datatype of each variable is recovered from its Object pointer.

Type cfvivs Extends Object '' Class for Function(Byval As Integer) (byVal) as String Declare Constructor(Byval p As Function(Byval I As Integer) As String) Dim As Function(Byval I As Integer) As String ppEnd TypeConstructor cfvivs(Byval p As Function(Byval I As Integer) As String) This.pp = pEnd Constructor

Hi fxm. It's quite a powerful implementation of type resolution at runtime, which is a great thing that is quite tricky for the beginner in fb current version. Unfortunately I can't play with it at the moment. I have a real life question that is related to callbacks in this example:

? r 'this shows nothing because we are not in the insynchronous case, which would require callback sleep 25loop until r<>0 or inkey()=chr(27)

? "you created or deleted a file in the folder"

sleep

To run this code , create a test directory and put the path of it in the code (in the 1st function).The problem here is that I fail to add the last arguments related to asynchronous call, with a callback. If someone knew how this has to be done it would be really interesting. Moreover this stuff is very useful if used asynchronously.