ByRef and Function overloading - what is driving the xojo linker.

Hello everybody,

I’m a little bit frustrated with Xojo. My recent problem is the following:
I’m overloading functions to simplify stuff eg:

fun(int, int)
fun(myType, int)
...

This works well and Xojo can differentiate between those functions - So the linker takes the arguments in the account.

Now, I have a function, which is changing objects, as well as intrinsic data types. So I really would like to write something like

fun(ByRef int, ByRef int)
fun(myType, ByRef int)

Now, in my case I’m using either string or int (which shall become a pointer/reference) and I get the message, that there is more than one item with this name…
So: Is the Linker in Xojo only distinguish between objects, intrinsic data-types and pointers(References)? - But this wouldn’t make any sense, because objects and my pointers/References are both pointers/references…
Or is Xojo trying to convert mit Pointer(Int) to some String?

Here is a more real defined code:

//function definitions:
assign (ByRef new_val As Integer, cur_record As RecordSet, cur_field_name as String) integer (...)
...
assign (new_val As String, cur_record As RecordSet, cur_field_name as String) integer (...)
...

//function calls
if assign(tmp_log_entry.id, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id
if assign(tmp_log_entry.name, cur_record, sql.name.name) <> 0 then return -1 // string value in tmp_log_entry.name

Thannks
Hans Jochen

Edit:
I observed the following, strange behaviour:
This works, when running my code with:

Dim tmp_int As Integer = 0
if assign(tmp_integer, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id

It must be

Now, when I create a seperate class, only for the integer pointers:

assign_int (ByRef new_val As Integer, cur_record As RecordSet, cur_field_name as String) integer (...) ,
and call it with my original class-entries I get an error:“you cant pass an expression as a parameter that is defined as byref”.

So…I did not want to pass an expression, and I’m not clear, what Xojo is doing here.
My class ist more like an public structure, an tmp_log_entry.id is a simple Int.
Where are my thoughts wrong?

I’m not in front of computer right now, but IMO this should work. This doesn’t seem to make sense:

if assign(tmp_log_entry.id, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id

The first parameter is ByRef, and I’m not sure that a ByRef argument can be a property of an object.

For test purposes try to compile something like that:

Dim xxx As Integer if assign(xxx, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id
If the compiler does not complain anymore, then you would at least know that the overloading works.

[quote=289959:@Eli Ott]I’m not in front of computer right now, but IMO this should work. This doesn’t seem to make sense:

if assign(tmp_log_entry.id, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id

The first parameter is ByRef, and I’m not sure that a ByRef argument can be a property of an object.

For test purposes try to compile something like that:

Dim xxx As Integer if assign(xxx, cur_record, sql.id.name) <> 0 then return -1 // int value in tmp_log_entry.id
If the compiler does not complain anymore, then you would at least know that the overloading works.[/quote]

Yeah right guess, thanks :slight_smile:
So, it is impossible to pass a reference in Xojo? How does Xojo handle pointers all in all?

An address of an object is passed to a method. This is my value I can use. Now I’m accessing a property of my passed-object - and all in all, this should be a memory address - right? And Xojo doesn’t allow to use this memory-address for other purposes?

the problem here is an EXPRESSION cannot be passed by ref

assign(tmp_log_entry.id

may be a call to method which cannot be passed by ref
or it may be a simple property
or it may be a computed property

[quote=289961:@Norman Palardy]the problem here is an EXPRESSION cannot be passed by ref

assign(tmp_log_entry.id

may be a call to method which cannot be passed by ref
or it may be a simple property
or it may be a computed property[/quote]

Ok, thank you too. Does this mean, that I can’t pass variables in an OO way?
It’s a litte bit confusing, that Xojo is not aware of the difference between () and not-() - So, everything can be done by variables/functions in a confusing mixture. But accessing parameters of a class and passing them to some functions… Is this not a fundamental need in modern programming?

Isn’t the word “assign” an internal keyword?

What does ByRef has to do with OOP?

Xojo does not enforce the use of parentheses on a function call where the function takes no arguments or on a sub-procedure call.

Assigns is a reserved word.

Oh, hm… to stick to cars and tires: I would say that a OOP way to change tires is maybe something like this
change_tires(my_car). Since I don’t want to pass my whole car around all the time: change (my_car.tires) or change_tires(my_car.tires) would be preferable.
But Xojo only allows me to pass the whole car as a reference, or parts of the car as a copy! So I can’t have a mechanic, specialized for tires on my car - I must send him a complete copy of my tire and dublicate it for myself and asign it back to my car - this very unncessary - if I don’t have overseen some fancy feature in Xojo.

So Xojo only allows something like:

tires = my_car.tires
change_tires(tires, new_tires)
my_car.tires = tires

And so disallows a implementation of

change(mycar.oldtires, newtires)

I think that is not an implementation of the required abstraction and polymorphism, required for OOP…
But maybe I’ve overseen some features

I do not see your problem here. Just remove the ByRef on the parameter. ByRef is needed only on scalar arguments to change the value in the calling routine.

Yeah, but this is my problem: I want the first parameter to be changed without seperating it from its class - And since it is a scalar it has to be reffered. This is the problem Norman Palardy mentioned, Xojo (or xojo’s linker) does not distinguish between methods and parameters of objects (Maybe there are no non-intrinsic-parameters in xojo at all - they are simple pseudo-parameters, accessed via some hidden oeprators(?)) Otherwise it would be very neat to tell Xojo, that something is a parameter and can really be seen as one… I mean, I can pass pointers to functions around, and pointers to (predefined) memory-blocks - but Xojo can’t do it only for one abstraction-level.

That is not possible. And makes no sense. And is not OOP. Just hand it over the object. What is the problem with that? The correct OOP way would be to send a message to the other object, not to manipulate one of its properties (encapsulation).

Oh, sorry, for the missunderstanding:
I’ve created an object as an replacement for a structure with dynamic sizes(which isn’t possible in xojo due to pointers) - lets say these are may properties. And this ‘structure’ shall be edited for the purpose of encapsulation by the ‘original’ object which is holding the structure. The tasks which shall be done on the structure are all the same but for different data-types (calling some databse-routines and converting). Since the structure must be most flexible it would be preferable not to redo the whole process of definition and calling - data processing and so on.
And now I have this routine, which is receiving the ‘structure’ and I want to work with it’s members, depending on their type. And I don’t want a long and single routine which works on all possible types or define the type, where I have to work on…
But this polymorphism is simply not possible (or only over some long way, which does not look nice), since Xojo obviously assumes that a object’s property can also be a object’s method.

But maybe you’re right: I must think about it, if may way of replacing missing pointers for structures in xojo is good enough, or if I must use something more dynamic-less or something with much more writing (shiver :))

Anyway, thanks foryour input :slight_smile:

In Xojo structures are only exists for declares into dynamic libraries. Use classes for all other data structures. It seems you try to “translate” something from another programming language – don’t do it (C++: struct vs. class. Swift: struct vs. class. Xojo: class).

[quote=290004:@Hans Jochen Steffen]
tires = my_car.tires
change_tires(tires, new_tires)
my_car.tires = tires
[/code]
And so disallows a implementation of

change(mycar.oldtires, newtires)

I think that is not an implementation of the required abstraction and polymorphism, required for OOP…
But maybe I’ve overseen some features[/quote]

You cant tell if mycar.oldtires is

  • a bare integer
  • a method
  • a computed property (which is also effectively a method)

A method result cant be passed byref since the only thing that method returns is a temporary value & that cannot be byref
A value type, like an integer, can be

And thats the issue here
That just IS the way the language is designed - only VALUE TYPES can be passed byref and an expression, like mycar.oldtires, is not a value type - its an expression

Now - COULD the compiler figure out that mycar.oldtires is a value type ?
I suppose thats a good question for Joe - it seems theoretically possible but thats not how it works today.

Hans Jochen,
You’re not wrong with your expectation. It’s just that the Xojo compiler has a design error.

Claiming that x.y is an expression is just plain wrong if you read any compiler book. It’s a qualified symbol first. It’s just as much an expression as “v” (from “dim v as Integer”) is. Instead, it’s a symbol, and it has a type. If it’s assignable, then it’s an L-Value. If it can have (or deliver) a value, it can be USED in an expression.

But since we’re talking about Byref Parms, the compiler’s question (view) is: Is that argument an L-Value? And if you pass a simple variable to it, such as “v”, then yes, it’s assignable, i.e. it’s an L-Value, and therefore valid. This is the same as when evaluating a assignment: The left side of the “=” has to be an L-Value, the right an expression. That’s why “v = v” is valid, because v is both an L-Value AND an expression.

But saying just because x.y IS an expression, it can’t be allowed as a Byref parm is nonsense, as that would also mean that “v” must be disallowed as it’s also an expression.

Another example, which shows the illogical behavior of the compiler even more is this:

Class MyClass Property v as Integer Sub foo (ByRef x as Integer) Sub test () foo (v) // works foo (self.v) // does not work End Sub End Class

The above two lines of calling foo are technically the same. Both pass the property v to foo’s ByRef parameter. Yet, the first compiles, the second doesn’t. This makes no sense, other than the realization that there’s a bug in the compiler about detecting what is actually passed to the ByRef parameter.

Lastly, any other programming language that has the concept of structures (objects, records) and byref parms doesn’t have this illogical behavior. They all allow any kind of L-Values to be passed to byref parms just fine. It’s only Xojo that gets this wrong.

I could write much more about, but I just wanted to assure Hans Jochen that he’s not wrong. The compiler is wrong, and we’ll have to work around its quirks.

The work-around would be to use a temporary variable, like this:

dim tmp as Integer = myObject.property foo (tmp) myObject.property = tmp

That’s what other compilers may do internally when handling non-L-Values such as setter/getter properties, BTW. But not Xojo.

I can confirm I’ve already incurred into this problem and used the same workaround suggested by Thomas.
I agree, this is definitely a bug in the parser.

I’d expect that IF you did report it that it would be marked as Not A Bug

If it’s not a bug, it must be a hidden feature then :wink:

EXPRESSIONS cannot be passed byref
Never have been able to
And anything using a DOT operator is an expression

The compiler doesn’t, as far as I know, look at what the expression resolves to (a value or reference type)
Joe would have to comment on whether it’s plausible or feasible to extend things to permit such a construct

But at the moment it is what I said at the outset - EXPRESSIONS cannot be passed byref

Personally i think that this behavior can’t be classified as a bug.
Yes, it seems strange that Byref cannot be used on object’s properties but this, for me, can be explained.
Object instances in Xojo can’t be referenced by pointers i.e. you can’t have pointers to objects and, consequently, you can’t access object’s properties using pointers.

An object’s instance contained in a variable is an opaque pointer to an object: you must create the object instance using the New operator.
You can pass and object ByRef to a Xojo method but not to a function contained in an external dll.
When you pass an object ByRef to a method you are permitting to the called method to create a new instance of the object discarding the passed object so, in this case, the result of the New operator assigned to the passed parameter create a new object discarding the original object: the object seen in the method and outside the method itself is the same.
This does not happens if you pass the object not using ByRef: in this case the result of the New operator assigned to the passed parameter create a new object instance without discarding the original object that remains the same outside the method: the object seen in the method is another object totally unrelated to the object seen outside the method itself.

I don’t know why Xojo it is implemented this way but with this behaviour you can for example, as in other languages, dinamically move objects in memory without problems because you can’t grab the object pointer.
Object implementation is a private affair to Xojo and totally unknown to the outside world.