I may be naive but I am surprised by the complexity of the debate here. To my mind, what is required in essence is a text pre-processor ('macro definition language'), applied before run-time. Decorators appear to be heading in that direction, but I confess that I don't really understand them yet.
A pre-processor would also permit 'conditional compilation' in the manner of C, to cater for different host environments perhaps. In such cases you do not want to check the OS type or whatever every time that you run your program. So if you had a statement like '#IF OS == "Unix":, then the relevant code could be included in the main text (or not, as the case may be).
Coming from a C background, I find Static Typing to be useful, but I also have strong scripting experience and I appreciate that enforcement of ST can be a real burden for a programmer, and doesn't always deliver the promised benefits in terms of reduced development/testing effort. So I definitely favour the Optional flavour, but perhaps the pre-processor could issue Warnings rather than reject particular constructs, to permit a 'strong' implementation.
As for particular ST use cases, my inclination would be to cater for the specific rather than the generic. In other words, if min() is defined for an 'int' type then it should *not* accept a 'long'; rather, a new type would need to be delared - 'Natural' in this case perhaps? Intuitively, a similar argument applies to the min() sequence examples: as these (appear to have) different behaviours, they should be different types. If you really need a generic min() function, then write the type checker yourself, or persuade the Python developers to do so.
Finally, the syntax that I prefer is along the lines of C - i.e., declare the type first on the same line as the variable or function, such as 'Integer a=0'. If a text pre-processor is employed as I suggest, then it could easily (?) convert such syntactic sugar to decorators or whatever.
I'm not an expert in such matters, so I hope that these ideas are taken in the spirit of Guido's blog as a whole - i.e. "brainstorming" topics that could be used as stepping-stones to better/stronger proposals.
Apologies for commenting on my own post, but I feel that some clarification would be desirable.
If min() - for example - is currently defined to accept an 'int' type rather than a 'long', then it should obviously be modified to accept the latter. This is because these are essentially the same types, but simply of different sizes. Indeed, 'int' and 'long' are articifical to a large extent, included for historical or (perhaps) performance reasons, rather than being natural constructs that people normally use.
On the other hand, a min() function that compares strings is clearly a different beast - i.e. the characteristics differ from numbers in this case - and so should be considered as a separate implementation. Given a declaration of the form 'String s = min('a', 'b'), the compiler/pre-processor would employ the String version of min() rather than the "Numeric" one. This could be implemented as 'if ... elif' statements as described elsewhere, but there is no need for a generic type min() function as such - just a collection of particular types.
Finally, I note that min(a, b) applies to a sub-set of a sequence; it is a special case of min(a, b, c, ...).
I mean I know Python is trying to get away from C/Java, but come on...
Why not this?
def int foo(int a, list b): int something = 5
Your changing syntax anyway, might as well. And since you're messing with some of the core concepts of Python anyway, just drop the other shoe and do: __strict__ = True At the module, class, heck function level.
And interfaces could be handled perfectly well with class @decorators:
the big deal that i see here is that within cobra blocks you can use all of the language without having to introduce arcane constructs:
var _contacts as List<of Contact>
get contacts from var
def addContact(contact as Contact) require contact not in .contacts contact.name contact.customer is nil ensure contact.customer == this .contacts.count = old .contacts.count + 1 body contact.customer = this _contacts.add(contact)
while not all of the above can or should be readily implemented in python, maybe it’s possible to do something very similar this way:
@contract def f( x, y ): def require(): isinstance( x, int ) isinstance( y, float ) x > y ...
so there is only a single decorator and pre- and postconditions can use full-fledged python. testing could be integrated, too. of course, method definitions would suffer a slight bloat.
Flat View: This topic has 79 replies
on 6 pages