Why Can't Delegates have string parameters? Lamda like capabilities?

I am confused… When one uses addhandler for an event one is essentially assigning a delegate for method to that event handler, and that method can have method parameters of any type including strings and objects…

But it seems not to be so for a method explicitly defined as a Delegate in the IDE…

That does not make sense to me…maybe it’s its Xojo trying to be overprotective because this use was not originally envisioned?

In this case I am not using delegates to call external/OS but just as function pointer objects for Xojo methods that can be passed as a parameter to another Xojo method.

I have a delegate created in a module defined as:

Public Function DBToDataTypesDelegate(Source as SourceDB, DBType as DBColumnType, FieldName as String) as DataTypes
Where the parameters are (enum, Enum, String) as Enum

Elsewhere were I try to do: (SpecialCaseMethod does have the right signature)

Dim theDelegate as New DBtoDatatypesDelegate(AddressOf SpecialCaseMethod)

I get a compile error on the Delegate definition saying:

[quote]External functions cannot use ordinary strings as parameters. Use CString, PString, WString, or CFStringRef instead.
[/quote]

But this is NOT for an external function and event delegates are not limited like this…

In this case the string will always fit in a PString, so I chnaged teh delegate to use a SPtring…

BUT that added to teh overhead of converting a string to a PString and then back from a PString to a String… which is not great but it does work and I can pass the function as method parameter.

Is this because of something I am missing, a bug (the docs don’t say delegates are limited to external methods) or shortsighted design combined with less than complete documentation?

In other words, a bug report or feature request?

  • karen

I guess it’s because a delegate needs to know the exact size of variables to reserve for the delegate methods you could assign to it. String in that context is a flexible block of bytes and not handled by reference, in which case its size would be the pointer to it.
C and P and W and all those special strings in contrast are handled internally as a ptr to the memory they reside. So the compiler gets happy with the size information for them.

Which makes me wonder: If String and MemoryBlock are interchangeable and a MemoryBlock can be represented by the ptr to it: – would a MB work instead?

[quote=467284:@Ulrich Bogun]I guess it’s because a delegate needs to know the exact size of variables to reserve for the delegate methods you could assign to it.
[/quote]

Then why when can one use string parameters for methods with Addhandler?

[quote]
Which makes me wonder: If String and MemoryBlock are interchangeable and a MemoryBlock can be represented by the ptr to it: – would a MB work instead?[/quote]

Why bother when a PString and Cstring will auto convert to and from string anyway? AT least it’s clear the method takes a string of some sort!

It would be really nice if delegates for Xojo methods could have the same capabilities as AddHandler interns of method parameters

[quote=467284:@Ulrich Bogun]I guess it’s because a delegate needs to know the exact size of variables to reserve for the delegate methods you could assign to it.
[/quote]

But remember as string are immutable, so they should be able to be passed as pointers (or handles) under the hood.

As this is likely how Delegates with string parameters work with AddHander for events, it should be able to be made more general… That combined with being able to create and implement delegates in the IDE like we can do with interfaces, would made function passing to methods easy to implement…

I keep seeing people keep asking for Lamda functions…

If I understand what they are (never used a language that had them), while this is not quite that, this would seem to be type safe way to be able to add that sort of functionality to the language in a relatively easy to use, and straight forward Xojo philosophically consistent way…

And we seem to be 80+% of the way there! (Make they do what Addhandler can and add more IDE support and we are there!!!

  • karen

As stated in Delegate documentation a delegate can have a string as a parameter (see the last example).
Maybe are you using a Declare for defining the function delegate as reported in External Functions Cannot Use String Data Types as Parameters ?

[quote=467420:@Maurizio Rossi]As stated in Delegate documentation a delegate can have a string as a parameter (see the last example).
Maybe are you using a Declare for defining the function delegate as reported in External Functions Cannot Use String Data Types as Parameters ?[/quote]

But I am not using declares or an external function… For some reason the compiler THINKS I am. I suspect that is because it thinks a delegate not created using AddHandler must be an external function… but that is just not the case.

What i think happened is that delegates were initially conceived of only in terms of external functions and when they extended them for use with events, instead of considering the general case, they only created a hack that only worked with Addhandler.

Perhaps teh delegate constructor can be made smart enough to tell that the address passed is for a Xojo method … If not maybe the constructor could take an option boolean parameter (IsXojoMethod) that default to false to maintain backwards compatibility. (If they still worry about that)

-karen

Can you replicate the case in a small sample? Maybe a bug needing a report.

Yes I can reproduce easily…

<https://xojo.com/issue/58628>

In my usage I have never defined a new delegate. The way I understand it, a delegate is the address of a handler, so I set the value to an address.

Updating your example project to this resolves the error:

dim DM as TestDelegate = AddressOf TestMethod dim sTestTest as String = DM.Invoke("Test") break

Edit: Update
Reading through the docs http://documentation.xojo.com/api/language/delegate.html the example with the constructor suggests that it’s specifically for external/system functions. With that in mind, yeah, it’s understandable that you wouldn’t be able to use the Xojo framework String externally.

Xojo strings are not a simple linear array of bytes where chars are stored but something very similar to an object where, as an example, also the encoding is stored.
So It’s normal that a Xojo string must be converted to a CString or a WString i.e. to a pointer to a simple linear array of bytes when passed to functions external to Xojo framework.

Can one really Dim a As New XYZ-Delegate? I don’t think so…
In your test project, I’ve added a Property: Private Property DM as TestDelegate
And in the .Open Event:

DM = AddressOf TestMethod Dim sTest As String = DM.Invoke("aa") break
That works just fine and as expected.

Edit: Ah, @Tim Parnell was faster with that same idea :slight_smile:

[quote=467437:@Tim Parnell]
Reading through the docs http://documentation.xojo.com/api/language/delegate.html the example with the constructor suggests that it’s specifically for external/system functions. [/quote]
The documentation.xojo.com/api/language/delegate.html reports:

[quote]There are two ways to create values that can be stored in delegates:

Usually, AddressOf (and WeakAddressOf) are used, taking an existing method and returning a function pointer in form of a delegate.

The other way is to specify a function pointer address of type Ptr, passing it to a delegate constructor.[/quote]

My bad.

I had not done much with delegates until now except for Addhandler so I just assumed they were objects despite being described as function pointers…and indeed they actually behave like pointers!

Now to fix my code.

-Karen