RapydScript icon indicating copy to clipboard operation
RapydScript copied to clipboard

Cannot perform binary '>=' operation ...

Open valq7711 opened this issue 8 years ago • 6 comments

Hi Alex! These rows

obj = { a: 'some'}
obj.a = 34
obj.a >= 0

or even

obj = { a: 'some'}
obj.other = 34
obj.other >= 0

cause compilation error Cannot perform binary '>=' operation ...

valq7711 avatar Mar 03 '17 17:03 valq7711

If the hash values are all of the same type at declaration (and in your case they are, because there is only 1), the compiler assumes that the hash will only contain values of that type in its lifetime. That assumption fails in your case. TypeScript solves this problem by letting user define an interface, a more durable yet much more verbose solution. A workaround in your case would be to add another data type to your object at declaration:

obj = { a: 'some', _: false }

or add nothing to the hash at all and set obj.a later:

obj = {}
obj.a = 'some'

I could disable this feature if it's unpopular, but I personally kind of like the approach of locking down the hash type.

In the end, I wanted to replace this system altogether with a more powerful one I built as a sub-project: https://github.com/atsepkov/Interstate. The problem is that Interstate isn't finished, and I had to work on other things instead, so I set it aside. However, even in its current state Interstate should be a lot more powerful. It already does a good job tracking all possible types for each variable (that it has seen in variable's lifetime), but I want to enhance it to narrow down current possible states. Interstate also currently does not handle properties, but I don't think it would be hard to add them.

atsepkov avatar Mar 03 '17 23:03 atsepkov

The other failure mode with Interstate is that it should be refactored to use promises instead of the current linear timeline approach. I did not realize this when I started writing it, but use of promises would allow it to resolve variables at a later date, even if their declaration is not yet available to reference. A proper promise chain combined with partial variable resolution would allow interstate to blow the doors off even what TypeScript can do, because TypeScript is not smart enough to detect violations through multiple function declarations (see my presentation on it: http://slides.com/atsepkov/intelligent-compilers#/, of particular interest is the slide titled "TypeScript isn't Perfect").

atsepkov avatar Mar 03 '17 23:03 atsepkov

Thanks for the reply! it's something like silent declaration ... but I think the explicit is better than the implicit, especially considering that it is neither Python nor JS feature. What about a hash with dozens pairs? have to read/check them all to understand what is that hash like?

valq7711 avatar Mar 06 '17 23:03 valq7711

I could disable this feature if it's unpopular, but I personally kind of like the approach of locking down the hash type.

I think this kind of type checking could use a command line switch to activate or deactivate them. I haven't been bitten by this behaviour yet but I'm glad reading about it prior.

amigrave avatar Mar 08 '17 14:03 amigrave

The main problem of silent declarations is: you see the hash of ten pairs - nine strings values and only one number value (for ex. - width : 10 ) - is that the trick or bug (should be - width: '10px')? What did author want to say? You can't answer this question without inspecting code to understand how/where that hash is used!

valq7711 avatar Mar 08 '17 18:03 valq7711

Good point, although that's what comments are for. The other use case I started considering after is use of hash as a set of configuration parameters, which this doesn't address well. In that case you would want each specific key to always be a specific type, probably what it was first defined as:

config = {
    username: 'bob',             # String
    active: true,                # Boolean
    created: Date.now()          # Date
}

This is where I'm hoping Interstate to pick up the slack, once I finish it. Perhaps the best way to handle this is to introduce new syntax to let the user "lock" type. That's effectively what interface in TypeScript does, I just don't like the excess verbosity.

atsepkov avatar Mar 08 '17 21:03 atsepkov