what would YOU expect to happen here ?

  1. 2 weeks ago

    Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air
    Class Class1
       sub foo()
          msgbox currentmethodname
       end sub
    end class
    
    Class CustomClass1
      inherits Class1
       sub foo()
          msgbox currentmethodname
       end sub
    end class
    
    Window Window1
      Sub bar(c as Class1)
          msgbox currentmethodname
      end sub
    
      Sub bar(c as CustomClass1)
          msgbox currentmethodname
      end sub
    
      Function factory() as Class1
             return new CustomClass1
      End Function
    
      Event Open
            
            dim c as Class1
    
            c= factory()
    
            c.foo
    
            // have to do the check in this order because a CustomClass1 is also a Class1
           // but a Class1 instance is JUST a Class1 instance
            if c isa CustomClass1 then
               msgbox "c isa CustomClass1"
            elseif c isa Class1 then
               msgbox "c isa Class1"
            end if
    
            bar(c) // <<<<<<< this one might surprise you as to which one gets called !
      end event
    
    End Window
    

    Which BAR method do you expect will be called ?

  2. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    The one for Class1 as the compiler picks it based on the variable type!

  3. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    I was kind of hoping there'd be others who chimed in as thats VERY different from which Foo gets called :)
    Its downright surprising, not really intuitive, and IMHO a "weird" behaviour

  4. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    Same as with properties which gets picked on variable type and not on actual class type. (as properties can't be overwritten)

  5. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    you dont find it weird that despite the local holding an instance of CustomClass1 that the wrong method is called ?

  6. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    Well, I simply know that the compiler doesn't include the isa check there.

    You get the right behavior if bar is a method on the class.

  7. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @ChristianSchmitz You get the right behavior if bar is a method on the class.

    which is what I expect it should also do when its not

  8. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    Fill a feature request?

  9. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    already done
    was just hoping others might respond with what they though _should_ happen

  10. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    Well, I don't expect a C++ compiler to do this much better.

  11. Andrew L

    Mar 19 San Francisco, CA, USA
    Edited 2 weeks ago

    Window1.Bar(Class1) is called. This isn't surprising to me. The hidden "self" parameter is the only parameter whose runtime type is taken into account in method overriding. For Window1.Bar() "self" is the Window object, all other parameters are typed according to their static type.

  12. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @ChristianSchmitz Well, I don't expect a C++ compiler to do this much better.

    Xojo isnt C++ :P

  13. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @Andrew L Window1.Bar(Class1) is called. This isn't surprising to me. The hidden "self" parameter is the only parameter whose runtime type is taken into account in method overriding. For Window1.Bar() "self" is the Window object, all other parameters are typed according to their static type.

    Trust me there is no hidden self and its not really relevant
    Its handled differently and thats an internal implementation detail

    The runtime type of the local IS well known
    You can view it in the debugger and Isa will also do the right thing in the code that follows (see my code posted above)

    Its ONLY the call of Bar that gets it wrong and that is because instead of determining which version to call at runtime its done at compile time
    And THAT is the oddity (one that bites me from time to time as I am always surprised by this and then have to remind my self to do something different to work around this weirdness)

  14. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    Here is C++ version which works in Xcode:

    #include <iostream>
    
    class Class1 {
    public:
    	virtual void foo()
    	{
    		std::cout << __FUNCTION__ << " in Class1\n";
    	}
    };
    
    class CustomClass1 : public Class1 {
    public:
    	virtual void foo()
    	{
    		std::cout << __FUNCTION__ << " in CustomClass1\n";
    	}
    };
    
    
    class Window {
    public:
    	virtual void bar(Class1 *c)
    	{
    		std::cout << __FUNCTION__ << " with Class1 \n";
    	}
    	virtual void bar(CustomClass1 *c)
    	{
    		std::cout << __FUNCTION__ << " with CustomClass1 \n";
    	}
    	virtual Class1* factory()
    	{
    		return new CustomClass1();
    	}
    	
    	void test()
    	{
    		Class1 *c = factory();
    		c->foo();
    		bar(c);
    	}
    };
    
    
    
    int main(int argc, const char * argv[]) {
    	// insert code here...
    	std::cout << "Hello, World!\n";
    	
    	Window w;
    	w.test();
    	
    	return 0;
    }

    output is:

    Hello, World!
    foo in CustomClass1
    bar with Class1
    Program ended with exit code: 0

    So C++ also just calls function based on variable declaration.

  15. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @Norman P Xojo isnt C++ :P

    of course IF xojo IS now consistent with C++ then when can we have postincrement (++) and postdecrement (--) ? :P

    principle of least surprise _should_ be followed here regardless of what C++ does

  16. Andrew L

    Mar 19 San Francisco, CA, USA

    @Norman P Its ONLY the call of Bar that gets it wrong and that is because instead of determining which version to call at runtime its done at compile time

    That's what I'm saying. The virtual method Window1.Bar is being dynamically dispatched based on the runtime type of Self/Window1, not the c parameter. But it's not wrong, it's single dispatch polymorphism.

  17. Michael H

    Mar 19 Pre-Release Testers, Xojo Pro Europe (Hamburg, Germany)

    Changing this behavior required matching method calls against signatures at runtime which would incur a performance penalty, no? This isn’t an issue when calling the method of a class.

  18. Christian S

    Mar 19 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    I think it is fine and you as developer should use methods and overwrite them or do isa check yourself.

  19. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @Andrew L That's what I'm saying. The virtual method Window1.Bar is being dynamically dispatched based on the runtime type of Self/Window1, not the c parameter. But it's not wrong, it's single dispatch polymorphism.

    actually its decided at compile time and which to dispatch to is NOT determined at runtime in any way

    @ChristianSchmitz I think it is fine and you as developer should use methods and overwrite them or do isa check yourself.

    which leads to fragile code as everytime you add a new subclass IF you have code that is stylistically like this then you have to make sure you add a new "select case" or "ISA" check for every new one you add

    and THAT is why I see this as a problem

    can it be designed around ?
    many times yes
    but not always

    and therein lies the problem
    for instance

    Module Module1 
      Class Class1
         sub foo()
            msgbox currentmethodname
         end sub
      end class
    
      Class CustomClass1
        inherits Class1
         sub foo()
            msgbox currentmethodname
         end sub
      end class
    
      Sub bar(extends c as class1)
                    msgbox currentmethodname
       End sub
    
      Sub bar(extends c as CustomClass1)
                    msgbox currentmethodname
       End sub
    
    End Module
    
    Window Window1
      Event Open
            
            dim c as Class1
    
            c= new CustomSubclass
    
            c.foo
    
            // have to do the check in this order because a CustomClass1 is also a Class1
           // but a Class1 instance is JUST a Class1 instance
            if c isa CustomClass1 then
               msgbox "c isa CustomClass1"
            elseif c isa Class1 then
               msgbox "c isa Class1"
            end if
    
            c.bar // <<<<<<< this one might surprise you as to which one gets called !
      end event
    
    End Window

    again we have much the same issue
    and IF you extend a built in class you dont have always have the same options to deal with this like you might if it was your own code

  20. Norman P

    Mar 19 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    @Michael Hszlig;mann Changing this behavior required matching method calls against signatures at runtime which would incur a performance penalty, no? This isn’t an issue when calling the method of a class.

    if it has that big a penlty then we probably need to worry about how virtual methods in classes are handled as thats a similar dynamic dispatch mechanism

  21. Newer ›

or Sign Up to reply!