fscarpa58

Dear all

when programming in FORTRAN I was used to pass the name of a function to another sub or function. With VB.NET I have some problem.

Suppose I have several functions, named F1,F2, F3,.., and that I have to perform some common task on these functions (for instance numerical integration).

Well, I wish to manage things in such a way to have a library function or subroutine (to do integration) and to call it passing various parameters 'and' a function name ( e.g. F3 ) to perform the integration of F3 .

In other words I wish something similar to this fragment of code to work (declarations and initialization omitted):

module main

integ1= integration(a,b,step,F1)

integ2= integration(a,b,step,F2)

end module

module functions

function F1(x)

....

end function

function F2(x)

......

end function

end module

module library

function integration(x1,x2,stepx,F)

......

and function

end module

however I do not succed to accomplish this, so I need help from you.

thank in advance

Federico



Re: Visual Basic Language passing a function's name to another function (or sub)

Spidermans_DarkSide

Hi,

You can also pass ByRef ( by reference instead of ByVal )

ByVal = ByValue.

 

Like this.>>

This is doing

 2*2 in F1,

 3*3 in F2 and

 4^5 in F3

giving 4*9*1024 = 36,864

CDEC is Convert To DECimal as Math.Pow uses DOUBLE datatype.


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim sum As Decimal
        sum = CDec(F1(2) * F2(3) * F3(4, 5))

        MsgBox("The sum result is= " & sum.ToString)
    End Sub

    Function F1(ByVal num As Decimal)
        num = num * 2
        Return num
    End Function

    Function F2(ByVal num As Decimal)
        num = num * 3
        Return num
    End Function

    Function F3(ByVal num1 As Double, ByVal num2 As Double)
        Dim result As Decimal
        result = Math.Pow(num1, num2)
        Return result
    End Function

 

Regards,

S_DS

 






Re: Visual Basic Language passing a function's name to another function (or sub)

MS Johan Stenberg

I believe that you are looking for Delegates.

Check out http://msdn.microsoft.com/library/default.asp url=/library/en-us/vblr7/html/vastmDelegate.asp for an example on how to use 'em...

Best regards,
Johan Stenberg






Re: Visual Basic Language passing a function's name to another function (or sub)

Spidermans_DarkSide

 

Hi,

Is a moderator deleting replies here

 

Regards,

S_DS

 






Re: Visual Basic Language passing a function's name to another function (or sub)

Spidermans_DarkSide

Hi,

Are some MSFT's deleting other MSFT posts too

Strange things are happening right now.

I did have a reply in this thread as well there was a reply by a MSFT.

Regards,

S_DS






Re: Visual Basic Language passing a function's name to another function (or sub)

Dick Donny

Hi federico

You need to pass a delegate to the function ... something along these lines

private delegate sub func(of T)(byval x as T)

integ1 = integration(a,b,step, new func(of integer)(addressof F1))

integ2 = integration(a,b,step, new func(of integer)(addressof F2))

sub integration( .....

'' dowork

f1.invoke(x)

If any of that is not clear, let me know

Richard





Re: Visual Basic Language passing a function's name to another function (or sub)

Brendan Grant

Rather than passing the name of a method, you might consider using .NET delegates to enable you to create a reference/pointer to a method that in turn can be passed around and then called like an ordinary method.




Re: Visual Basic Language passing a function's name to another function (or sub)

Frank Carr

The CallByName function should do what you want. Here's an example:

    Debug.Print(testmain(10, 5, "test1"))

    Public Function testmain(ByVal x As Integer, ByVal y As Integer, ByVal functionname As String) As Integer
        Return CallByName(Me, functionname, CallType.Method, x, y)
    End Function

    Public Function test1(ByVal x As Integer, ByVal y As Integer) As Integer
        Return x + y
    End Function

    Public Function test2(ByVal x As Integer, ByVal y As Integer) As Integer
        Return x - y
    End Function

    Public Function test3(ByVal x As Integer, ByVal y As Integer) As Integer
        Return x * y
    End Function

Of course, there are other techniques, such as overloading or delegates, that are preferred in cases like you described. You may want to investigate them to see if they will accomplish what you want to do in a better way.






Re: Visual Basic Language passing a function's name to another function (or sub)

DMan1

Private Sub Test(ByVal S As String)

Dim X As Integer = 1

Dim y As Integer = 2

Dim z As Integer = 3

Dim ANSWER As Double = Integration(F1(X), F2(Y), 10, F3(Z))

End Sub

Private Function F1(ByVal x As Integer) As Single

'...

End Function

Private Function F2(ByVal y As Integer) As Single

'...

End Function

Private Function F3(ByVal z As Integer) As Double

'...

End Function

Private Function Integration(ByVal x1 As Single, ByVal x2 As Single, ByVal StepX As Integer, ByVal F As Double) As Double

'...

End Function






Re: Visual Basic Language passing a function's name to another function (or sub)

Geert Verhoeven

Hi,

I think that what you need are delegates. Here is an example: http://www.codeproject.com/vb/net/Delegate.asp

Greetz,

Geert

Geert Verhoeven
Consultant @ Ausy Belgium

My Personal Blog






Re: Visual Basic Language passing a function's name to another function (or sub)

MS Johan Stenberg

You probably want to use a delegate.

Best regards,
Johan Stenberg






Re: Visual Basic Language passing a function's name to another function (or sub)

Jared Parsons MSFT

What you're looking for is a delegate. It allows you to pass the function (not it's name though) and you can invoke the function from the called function. Example, you need to do an operation on an element of type C1 which returns an integer, you would define a delegate like so

Public Delegate Function D1(ByVal c As C1) As Integer

And a function to utilize the delegate

Public Sub Target(ByVal f as D1) 
 ...
 f(MyC1Value)
End Sub

To create in instance of D1, use the AddressOf operator






Re: Visual Basic Language passing a function's name to another function (or sub)

fscarpa58

I have to thank you very much for your valuable suggestions.

I have implemented both the delegate and the CallByName techniques.

They works well but the first results to be about 50 time faster than the second one. Furthermore, the CallByName method needs, in general, one more argument to be passed since it needs to know the class that contains the functions (I think). As a consequence, if the functions are in a module I was not able to implement the technique (help needed).

I also found an additional technique. If each function is encapsulated in a class (as the lone method, say .value) we can pass the class to the library function (sub) as an object (after instantiation) and reference the function as objectname.value(x).

It is very elegant (seen from the calling fragment) but also slow like the callbyname technique. Can somebody tell me why or suggest modification to go faster

thankyou again

Federico





Re: Visual Basic Language passing a function's name to another function (or sub)

Dick Donny

Hi Federico

CallByName is a hangover from earlier versions of VB and should not be used.

Delegates are the preferred solution (and quicker) because the compiler may be able to resolve pointers at compile time as opposed to runtime.  As a bonus, you get type safety and design type assistance from visual studio. 

Not having to do resolution at runtime leads to more performant code.

With regard to the last comment about using a class, if I understand this correctly you have a parameter of type object and you are calling the lone method on that class.  That will be slower because once again the runtime is having to resolve function pointers at runtime.  There are ways to speed this up by having your classes implement an interface and using generics to resolve types at compile time, but this will probably lead to a larger executable size and is considerably more work than needed (depends if you want to go the true OOP route or are happy to bring some of that functional goodness to your code)

Stick with the delegates .... they are ideal for your situation.

Richard





Re: Visual Basic Language passing a function's name to another function (or sub)

fscarpa58

I Dick, All

>>>There are ways to speed this up by having your classes implement an interface and using generics to resolve types at compile time<<<<

I am very interested to this concept.

I implemented things as follows and I note a couple of things

1) the speed difference is terrific;  0.03 s for the delegate meth. vs.  5.0 s for the class meth.

2) if under /My Project /  Compile / Late binding; call could fail at runtime/    I change the option from   none to  warning

 then  in the fragment      F.value(x) * dx  I get the warning message: operands of type Object  used for operator "+" ; etc.

As you said, the runtime conversion from object to double is the cause of poor performance.

However, I have not understand your suggestion to fix it.

 Federico

 

Imports system.math

Public Class F1 'encapsulated function

Function value(ByVal x As Double) As Double
     Return x ^ 3
End Function

End Class

Public Class F2

Function value(ByVal x As Double) As Double
     Return Sin(x)
End Function

End Class

Delegate Function funcDlg(ByVal x As Double) As Double

Module TEST

Function G1(ByVal x As Double) As Double
    Return x ^ 3
End Function
 
Function G2(ByVal x As Double) As Double
    Return Sin(x)
End Function

 

Sub main()

Dim u1, u2 As Double
 
u1 = integral1(0, 1, 0.00002, AddressOf G1)
u2 = integral1(0, PI, 0.00002, AddressOf G2)
 
u1 = integral2(0, 1, 0.00002, New F1)
u2 = integral2(0, PI, 0.00002, New F2)

End Sub

End Module

 

Module library

Function integral1(ByVal a As Double, ByVal b As Double, ByVal dx As Double, ByVal F As funcDlg) As Double

Dim x, sum As Double

For x = a To b Step dx
     sum = sum + F.Invoke(x) * dx
Next

Return sum

End Function

Function integral2(ByVal a As Double, ByVal b As Double, ByVal dx As Double, ByVal F As Object) As Double

Dim x, sum As Double

For x = a To b Step dx
     sum = sum + F.value(x) * dx
Next

Return sum

End Function

End Module