Forums

Understanding the limits of type inference

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

Understanding the limits of type inference

Postby gradha » Thu Sep 02, 2010 3:43 pm

Hello.

In the example at http://github.com/gradha/Cobralation/tr ... 2%20cobra/ there's the file shapes.cobra where it defines a shape's constructor as:
Code: Select all
   cue init(side as int, id as String)
      base.init(id)
      _mySide = side

It's my first time with a type inference language, so here it goes. Why does the code not compile if I remove the types for the parameters of the constructor? Since the code immediatelly calls the base constructor (which is defined as accepting String) and the _mySide variable is of type int, shouldn't Cobra detect this? Or does this only work for variables, and never for function prototypes?

I just want to know where's the limit of the type inference.
gradha
 
Posts: 23

Re: Understanding the limits of type inference

Postby hopscc » Fri Sep 03, 2010 5:40 am

If you remove the explicit typing on params they default to 'dynamic' which eventually become Object in the C# source code
I'd venture the failure messages for the compile refers to inability to convert 'Object' types to 'String' or int in passing the now dynamic params into the baseclass initializer.
(It would help immensely for 'compilation fails' type questions if you posted the error message.)

For it to work the types of the params on the methods need to match or be convertible ( i,e the baseclass needs to take a dynamic (unspecified arg Type as well and the type used is resolved at runtime)

This isnt type inference as such more typing compatibility across methods as you've explicitly specified the types on the initializers.

i.e This fails due difference in Types fro the baseclass initialiser and its call from the subclass
Code: Select all
class Shape is abstract
    var _myId as String

    cue init(s as String)
        base.init
        .id = s

    pro id as String
        get
            return _myId
        set
            _myId = value

    pro area as float is abstract
        get

    def toString as String is override
        return .id + " Area = " + String.format("{0:F2}", .area)


class Square inherits Shape
    var _mySide as int
   
    cue init(side, id )
        base.init(id)
        _mySide = side
   
    pro area as float is override
        """Given the side, return the area of the square."""
        get
            return _mySide * _mySide


    def main is shared
        pass   

with
Code: Select all
TypeInfer.cobra(24): error: The best overloaded method match for "Shape.Shape(string)" has some invalid arguments (C#)
TypeInfer.cobra(24): error: Argument "1": cannot convert from "object" to "string" (C#)
Compilation failed - 2 errors, 0 warnings


This succeeds (base initialiser and subclass call both same (unspecified,dynamic) type
Code: Select all
class Shape is abstract
    var _myId as String

    cue init(s)
        base.init
        .id = s

    pro id as String
        get
            return _myId
        set
            _myId = value

    pro area as float is abstract
        get

    def toString as String is override
        return .id + " Area = " + String.format("{0:F2}", .area)


class Square inherits Shape
    var _mySide as int
   
    cue init(side, id )
        base.init(id)
        _mySide = side
   
    pro area as float is override
        """Given the side, return the area of the square."""
        get
            return _mySide * _mySide


    def main is shared
        pass   



Type inference in itself is relatively simple - if you are creating a variable and its not already typed it'll take the type of its assignment expression (rvalue type) but you need to realise that the variable
still ends up staticly typed ( inferred not explicitly set)
Dynamic types confuse this some as a dynamic type sez that the variable type can be anything and change depending on whats assigned to it.
BUT as this gets converted to C# ( statically typed language currently) the implementation type for 'dynamic' is Object which means that you can make programs that compile fine wrt Cobra
but that the C# compiler balks at (mostly around implicit conversions from Object to some other type).

For classes I find this usually means that you either want to explicitly type all the params and vars (except where you definitely want a type morphing value - rare SFAICT) OR you leave all (most) of the values as dynamic and let them get the types from their construction/assignment types. Its arbitrary mixtures that cause problems especially up inheritance (method) chains.

I'd expect most of the issues with this are back end compiler specifics wrt what it allows with casting Object to
hopscc
 
Posts: 632
Location: New Plymouth, Taranaki, New Zealand

Re: Understanding the limits of type inference

Postby Charles » Fri Sep 03, 2010 10:02 am

-- Type inference happens for "var" declarations that are given an initialization expression such as "var _x = 0" and for local variables declared for the first time through assignment such as "x = 0".

-- When you omit the type of a "var" declaration and there is no initialization expression, Cobra infers "dynamic". Likewise for properties without types and parameters without types.

-- So when you write "cue init(side, id)" that is equivalent to "cue init(side as dynamic, id as dynamic)".

-- You are in fact, supposed to be able to pass a dynamically typed expression anywhere, resulting in a typecast at run-time that will either succeed or throw an exception. However, this is broken in the case of calling base.init.

-- However, it's unlikely that you actually want to type your parameters as "dynamic" when overriding cue.init. Especially for those parameters that are passed to "base", there is no apparent advantage.

-- Regarding style, since this is a tutorial that will be seen my others, I recommend having a blank line after "class Foo inherits Bar" lines, and also changing "_myFoo" declarations to simply be "_foo".

If you need me to expand or clarify anything, let me know.

HTH
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Understanding the limits of type inference

Postby gradha » Sun Sep 05, 2010 2:38 pm

Thanks for the clarifications. WRT the style, certainly maintaining the ugly camel case isn't desired.
gradha
 
Posts: 23

Re: Understanding the limits of type inference

Postby Charles » Sun Sep 05, 2010 10:08 pm

Camel case is fairly normal in Cobra such as types named "FooBar" and other things named "fooBar". See:

-- http://cobra-language.com/samples/

-- http://cobra-language.com/how-to/

Using "my" is not.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Understanding the limits of type inference

Postby gradha » Mon Sep 06, 2010 12:56 am

In that case I'll strive to avoid multi word names!
gradha
 
Posts: 23


Return to Discussion

Who is online

Users browsing this forum: No registered users and 59 guests