Wiki

Ticket #361 (new defect)

Opened 10 years ago

Last modified 10 years ago

Getters should always specify return types

Reported by: kobi7 Owned by:
Priority: major Milestone:
Component: Cobra Compiler Version: 0.9.6
Keywords: getter Cc:

Description

currently cobra accepts code such as this:

get hasSubCmds
	return _sub.count > 0

however it seems to get confused about the type, in the call site.
I suggest making it mandatory to supply a return value, (which the user may simply forget sometimes).

get hasSubCmds as bool
	return _sub.count > 0

Change History

Changed 10 years ago by kobi7

  • keywords getter added
  • version changed from 0.8.0 to 0.9.6

Changed 10 years ago by kobi7

I said the compiler seems to get confused. I'd like to clarify.
I think the compiler was regarding the getter return value as "dynamic?" or "Object?"
(which generated the bug or confusing behaviour of #359)
though according to getType and typeOf at the call site, the code was bool

Changed 10 years ago by kobi7

How to reproduce
in external library:

class GetterTest
	get hassome
		return false

in current console project:

use external
class Program

	def main
		g as GetterTest = GetterTest()
		x = g.hassome # false
		trace x
		if x
			print 'x = true'
		else
			print 'x = false'

the output is:

    trace : x=false
          - at Program.cobra:7
          - in Program.main

x = true

Press any key to continue...

Changed 10 years ago by hopscc

Interesting
Presents difference between Dynamic Type and Object Type and library loss of information..

Description/title is wrong tho'
Getters used in libraries should always specify return types

This only happens if the getting class/property is in an externalibrary, if its in the same compilation stream as the caller it returns the expected values
because the compiler knows the return type is a (nilable) Dynamic so makes a better choice as to code gen vis-vis dynamic and Object types.

The problem isnt the getter - thats declared implicitly to return Dynamic? (which is same as Object? (eventually). i.e. anything at all including nil, actual type determined at runtime)

(if you dont declare a return type for properties in cobra it defaults to Dynamic?)

Unfortunately theres (currently) some info loss in Dynamic types going into libraries - when compiled they become Dynamic? which cobra codegens to Object? which is what they are stored as; when pulled out of a library they are seen only as Object? (not Dynamic? and codegen treats them slightly differently)

The issue is in this line

if x

You are thinking thats a boolean test ( for x being true/false)
which is true (hehehe)
if x is declared as boolean (or even recognised as Dynamic?) but its not for (erstwhile) Dynamic items read from libs , here they are Object? so that test as written becomes a non nil test.

if x <> nil

not

if x == true

Try this

	def main
		g as GetterTest = GetterTest()
		x = g.hassome # false
		ct_trace x
		trace x, x.getType
		if x 
			print 'x = true'
		else
			print 'x = false'
			
		if x == true
			print 'x = true'
		else
			print 'x = false'
		
			
		x1 = g.hassomeB # false
		ct_trace x1
		trace x1, x1.getType
		if x1
			print 'x = true'
		else
			print 'x = false'
			

(and add a properly typed (to bool) getter (hassomeB) to Getter.)

The last line of the compile time trace shows the difference in types...

short answer solution
1) explicitly type getters in libraries OR
2) if you have dynamically types getters dont shortcut the conditionals for testing their values from libraries

Long answer:
Charles this is probably (if not a defect) a definite gotcha...
The cobra library loses the info that a return type is Dynamic? (in cobra) vs an Object?

For cobra generated libs we could add an a type attribute that cobra can read when consuming the libraries to reassert the original Dynamic Type (so all would be cool for cobra generated libs - this may be sufficient since other generators dont know about cobra Dynamic? at all)

Alternatively promote any library types that are Object? to Dynamic? when the libraries are read - that'd be correct for all libraries from any generator but may
cause some slowdowns ( use of the dynamic native wrapper calls) for some uses...

Changed 10 years ago by Charles

Right, there is an issue with library boundaries and non-standard Cobra types such as dynamic and nullable references (ex: String?). I've known about this for awhile, but other bugs have been a higher priority so far.

The solution, as you pointed out hops, is to put the info in an attribute.

There is no problem with properties having "dynamic" as the default return value. That's a feature.

Changed 10 years ago by nerdzero

Implementing ticket 319 could also address this, right?

Changed 10 years ago by kobi7

  • summary changed from getters should always supply a return value to Getters should always specify return types

changed title as per hopscc's suggestion

Changed 10 years ago by hopscc

(nerdzero)
Probably needs a bit of research to see if cobras dynamic can map onto and off of Net4 C# dynamic in a satisfactory manner - good reminder I'd forgotten about that addition in .Net4...

Note: See TracTickets for help on using tickets.