News for hackers. Stuff that matters.
Re:Why Python is Slow: Looking Under the Hood by Spittie on Friday May 09, 2014 @01:44PM (#7722212)
I'd love to see optional typing in Python, I wonder if there is any official reasons about why it never got introduced.

I very rarely change the type of a variable, so it would be essentially free speed and free speeds for me.

I actually wonder, do people use dynamic typing so often? I mean, it's nice to do "variable = int(variable)" when I know that I'm getting an integer in a string, but that's probably the only use case can I can think off that doesn't just reuse variables for something else.

Re:Why Python is Slow: Looking Under the Hood by nairteashop on Friday May 09, 2014 @02:01PM (#7722335)
> I'd love to see optional typing in Python, I wonder if there is any official reasons about why it never got introduced.

Here are a few from Guido himself (not really anti static-typing, but just walking you through pros/cons as he sees them). Great reads:

http://www.artima.com/weblogs/viewpost.jsp?thread=85551

http://www.artima.com/weblogs/viewpost.jsp?thread=86641

http://www.artima.com/weblogs/viewpost.jsp?thread=87182

Re:Why Python is Slow: Looking Under the Hood by njharman on Friday May 09, 2014 @04:37PM (#7723141)
I consider http://cython.org/ to be the "optional typing" implementation of Python.
Re:Why Python is Slow: Looking Under the Hood by collyw on Friday May 09, 2014 @01:54PM (#7722277)
I started programming in Java, and moved to Perl and now Python. At first it seemed a bit weird, dynamic typing, but now I embrace it and enjoy the flexibility it offers. I see that many people prefer static typing and I am not sure why.

Can someone give me a concrete example of when static typing would be beneficial? (The majority of my work revolves around databases, so I guess I rely on that as a kind of type checking to a degree).

Re:Why Python is Slow: Looking Under the Hood by yogsototh on Friday May 09, 2014 @02:28PM (#7722510)
Static typing à la C,C++,Java,js,etc... is from my experience inferior to dynamic typing.

On the other hand, the Haskell typing is superior in many ways to dynamic typing. Because you lose very few power of expression but you gain a lot of time in your workflow (and also security).

Concrete example (I'll use js):

    function showField(data) {
       console.log(data.field1.filed2);
    }
you relaunch your application, you click on three to four elements, then you enter your name and a password. You click on the button, and "BAM, filed2 doesn't exists". Correct the typo or add a test and replay the game of executing your new code.

Static typing:

    showField : ConcreteData -> IO ()
    showField data = putStrLn $ filed2 (field1 data)
Try to compile, get the error: showField : filed2 doesn't exists, may be you mean "field2".

correct your code. Now you're done.

Here is another example:

Dynamic typing:

    function showField(data) {
      if (data.field) { console.log("OK"); } 
      else { console.log("Not OK")}
    }
    
    ...
    
    showField(myData);
Try it using all manipulations to reach the test case, then: ERROR, couldn't find field for null. :-| replace by if (data && data.field).

In static typing:

    showField data = if (field data) 
                        then putStrLn "OK"
                        else putStrLn "Not OK"
compile: could not match String with (Maybe String) at ... now:

    showField data 
      | field data == Nothing = putStrLn "Not OK"
      | otherwise = putStrLn "OK"
You fixed it, but you didn't had to lose your time searching the error.

The BIG bonus is that you detect the error before you discover it at runtime. Imagine you didn't detected the error during your test (even with unit tests). This is why it is so easy to push this kind of error in production in a dynamic typed language.

And I only scratched the surface.

I program mostly in JS now, and I love even more when I am doing Haskell.

Re:Why Python is Slow: Looking Under the Hood by yiransheng on Friday May 09, 2014 @05:44PM (#7723423)
Very well put, I am learning haskell at the moment, and beginning to appreciate the power of its type system in a way never which I never felt in Java, C etc.

When you chain a series of functions/actions together, only to supply data for computation last, type signatures almost always ensures the correctness of the entire computation. This is true even the computation occurs at a high abstraction level. It's almost like magic, when dealing with the more difficult concepts (well for beginners) like monads. There has been a number of times when I wrote something but cannot make sure it does what I want, yet it compiles and a few tests reveals it indeed works like a charm.

Whereas in dynamic languages, it'd be a nightmare to dig into the dirty details at runtime. I always have this problem in R, a series of supposedly elegantly linked operations fail for mistakes like forgetting to convert character values into factor type. To debug such errors, I always have to explicitly carry out middle steps and store intermediary results, until finally locating the problem.

Another note, even in javaScript, sometimes there at patterns encourage the use of implicit types or interfaces(typeclass in haskell). The canonical example is jQuery, most of the times you can safely do:

    $(something).method1().method2(param).method3()...
This is because any jQuery object inherits methods from $.fn, and most of these methods returns either the same jQuery object, or another jQuery object. In a sense, jQuery itself is a typeclass, anything looks like $(something) is a instance type.
Re:Why Python is Slow: Looking Under the Hood by lispm on Saturday May 10, 2014 @03:50AM (#7724793)
To find undefined slots or undefined functions, you don't need a type system. A competent compiler is sufficient.
Re:Why Python is Slow: Looking Under the Hood by yogsototh on Saturday May 10, 2014 @08:48AM (#7725204)
The type system enforce some kind of usage.

    myObject[ someFunction() ] = 1;
No compiler in the world would be able to detect if myObject.field should exists or not.

In a (good) type system oriented language, you have to declare that myObject is a Map, and therefore when you want to access "field" you know this access could be "Nothing". The type system alert you if you don't handle the "Nothing" value.

Re:Why Python is Slow: Looking Under the Hood by nly on Friday May 09, 2014 @03:29PM (#7722821)
Static typing makes it a lot easier to reason locally about code.

I can't understand what a function is doing in isolation when the types are unknown. A function takes a variable foo and returns foo[bar], what did it return? Is that even valid code? What does that even mean if foo is a string and bar is a database handle? Ok, this is a lookup of some kind... is it an index or a hash table? I have no way of knowing without reading the comments (which may or may not exist). The only other way to figure out what the function is used for is to trace the data all the way back to its creation... literally find every call site and slog my way up the call stack.

In a dynamic language you can't even tell if all your code will execute until you run it and test all the code paths, let alone attempting to convince yourself that it's correct. I don't understand why people want that cognitive burden when the compiler can tell you straight away that you've typed something nonsensical.

I've just never seen a code sample that made me want to throw away static typing. Not even one.

Re:Why Python is Slow: Looking Under the Hood by lispm on Saturday May 10, 2014 @03:58AM (#7724804)
If you use a language with type inference, you won't see what it returns either. Because it is not in the code. You would need an IDE which finds it out.

Sometimes it computes a type and you have no idea what the type is about.

Also dynamic typing does not mean you don't know what a function receives or returns. Many dynamically typed languages are object oriented and use classes.

For example in Lisp I would write:

    (defmethod collide ((s1 ship) (s2 submarine))
      ...
      (the collision-event (make-collision-event ...)))
Then I know that the arguments are objects of class ship and submarine and it returns an collision-event.

It's not statically typed, but the code is nicely readable and testable.

Re:Why Python is Slow: Looking Under the Hood by benjiweber on Saturday May 10, 2014 @05:24AM (#7724916)
With inferred types you still know that callers must be passing something for which the operations performed are valid.

Many languages allow you to specify types even when they may be inferred to add clarity/preconditions. This is useful for modelling the domain as well as local reasoning. Perhaps the current implementation is valid for all integers, but in the domain context it only makes sense for the range 0-100.

Re:Why Python is Slow: Looking Under the Hood by nly on Saturday May 10, 2014 @07:33AM (#7725091)
If the compiler can infer the type locally then so can I. At least for reasonably well structured code.
Re:Why Python is Slow: Looking Under the Hood by cousin_it on Saturday May 10, 2014 @08:39AM (#7725186)
I thought type inference in Haskell or ML was a global algorithm.
Re:Why Python is Slow: Looking Under the Hood by Aaronontheweb on Friday May 09, 2014 @03:10PM (#7722745)
Static typing lends itself to static analysis and other defensive programming practices that are easy to enforce at compile-time (such as design by contract.) A lot of bugs and design errors die long before erroneous code hits source control as a result - definitely not all of them, but many of them.

The best compromise between static typing and dynamic typing, IMHO, is what C# (and later generations of C++) do: implicit typing via the VAR keyword.

You can't implicitly type the members of an object or the arguments of a function, but you can implicitly type variables in local scope. This is how C# is able to support anonymous types and functions so easily - implicit typing abstracts away the gangly looking static objects that are produced by LINQ queries and the like.

Implicit typing makes it very easy to refactor large blocks of statically typed code without compromising the benefits of static typing. So you get some of the flexibility of dynamic typing with the predictability of static typing.

Realistically - you don't utterly redefine the type of objects at runtime very often in production code even with dynamic languages, so you don't lose much with implicit typing.

Re:Why Python is Slow: Looking Under the Hood by MichaelGG on Friday May 09, 2014 @04:41PM (#7723152)
>You can't implicitly type the members of an object or the arguments of a function

That was due more to architectural issues in the C# compiler than any principled reason. C#'s type inference is extremely weak and incomplete and is a poor example of "getting it right".

Re:Why Python is Slow: Looking Under the Hood by Aaronontheweb on Friday May 09, 2014 @05:26PM (#7723333)
I'm failing to imagine a scenario where implicitly typing either of these would benefit me as the developer - having those elements remain statically typed seems like "the right thing to do" given their role in defining public code contracts. Could you help me understand why this is a bad thing?
Re:Why Python is Slow: Looking Under the Hood by MichaelGG on Friday May 09, 2014 @07:43PM (#7723881)
They are always statically typed; no one is talking about dynamic typing. Inferred types are just as static as any others.

Example: Dictionary<string, Func<string, int, Dictionary<string, string>>> somedic = new Dictionary<string, Func<string, int, Dictionary<string, string>>> { ... }

Is almost entirely better served by

  let somedic = dict [ ... ]
Your point about defining a public interface is separate. If you have a specific API that you cannot break, then feel free to type it out all you want. If you feel a piece of code is confusing or unclear without an annotation, go ahead and add it.

For the majority of code, having to specify the types is an exercise in verbosity, nothing more. Unless you're only writing public libraries with no internal implementation, I don't see how there's not a scenario.

Re:Why Python is Slow: Looking Under the Hood by Aaronontheweb on Saturday May 10, 2014 @02:36PM (#7726428)
I agree that doing that type of inference would be convenient - I deal with a lot of nested generics like that on daily basis.

But this is just syntactic sugar, and the var keyword already takes care of the left-hand operand in this equation. Generic functions also do a reasonably good job of type inference under this set of circumstances, although I've found that generic delegates and lambdas not so much.

Re:Why Python is Slow: Looking Under the Hood by Aaronontheweb on Friday May 09, 2014 @06:29PM (#7723593)
whoops, meant to say "gangly looking HIDDEN objects" instead of "static" objects
Re:Why Python is Slow: Looking Under the Hood by antocv on Friday May 09, 2014 @02:10PM (#7722394)
Static typing provides more information for the programmer and for the runtime.

More information makes the code somewhat readable and understandable 10 years after when it was written. Dynamic typing often becomes a much more messy affair.

Static typing is beneficial when you want to catch a certain type of errors before your code enters production, it makes you write less error prone code.

Re:Why Python is Slow: Looking Under the Hood by lispm on Saturday May 10, 2014 @04:02AM (#7724812)
Not my experience. Dynamically typed OO language carry enough information around.
Re:Why Python is Slow: Looking Under the Hood by oldmanjay on Saturday May 10, 2014 @07:53AM (#7725117)
the point is that in statically typed languages, the type information is used at compile time, and the computer can reason about certain types of errors for you prior to execution. in dynamic languages, the type information may well be there, but you need to exercise the code at runtime (via tests or whatever, but still runtime) to make use of it.
Re:Why Python is Slow: Looking Under the Hood by lispm on Saturday May 10, 2014 @09:04AM (#7725252)
True, but code is running. If it's not used, then the error won't be relevant anyway. I'm not talking about rocket, aircraft, power plant software. But even there, I never heard that any of those really critical domains use Haskell (or similar) in their control systems.
Re:Why Python is Slow: Looking Under the Hood by zmmmmm on Friday May 09, 2014 @10:02PM (#7724203)
Your only experience with static typing is with Java which has one of the lowest "value for effort" type systems around. Java's type system is mostly bookkeeping and doesn't help you functionally really at all while taking a lot of effort to deal with at the programmer end. By contrast there are much more powerful type systems where the typing takes much less effort AND delivers you actual functional benefits. Crucially Java's generics are not preserved through to runtime, so there is no actually difference between List<Integer> and List<String> to the JVM, only the compiler. If there was a difference all sorts of powerful things could be done with the types at runtime, but as it is it's mostly just the compiler complaining about whether you dotted i's and crossed t's.

I program a lot in Groovy these days, and it now has optional static typing with a limited amount of type inference. What I observe is that I voluntarily prefer to type my variables much of the time because it really does save time and takes only a fraction more effort than leaving them untyped. I find Python quite hard to decipher much of the time because it's nearly impossible to know what type a variable passed into a function is unless you trace back to the caller.

Re:Why Python is Slow: Looking Under the Hood by vorg on Saturday May 10, 2014 @01:43AM (#7724632)
> I program a lot in Groovy these days, and it now has optional static typing with a limited amount of type inference

Groovy has enabled types on variables and functions (and fields and methods) since Groovy 1.0 but that makes the code run slower.

Re:Why Python is Slow: Looking Under the Hood by zmmmmm on Saturday May 10, 2014 @02:31AM (#7724692)
That is not what I am referring to. 2.0 introduced true static typing that compiles to code that not only enforces complete type correctness at compile time (unlike the old option) but executes at near Java speed.
Re:Why Python is Slow: Looking Under the Hood by maxlybbert on Friday May 09, 2014 @02:26PM (#7722496)
In Javascript (which is also dynamically typed) I've had a few times where adding 1 and 0, say, yielded "10" because either the 1 or the 0 originally came from a string. OK, I can live with that, but I find the fact that you can use that string in numeric comparisons potentially confusing.

The general argument is that if you write enough unit tests, you can guarantee that your code doesn't make those kinds of mistakes. The statically-typed response is "why should you have to write unit tests when the compiler can make that guarantee for you?"

Re:Why Python is Slow: Looking Under the Hood by ajanuary on Friday May 09, 2014 @02:38PM (#7722561)
Adding strings to integers is usually referred to as weak typing, which is a seperate and orthogonal concept to dynamic typing. The runtime of a dynamic language could look at the two types of the values, decide they're different and throw a type error. Similarly, a static type checker could look at the types of the values and decide it knows how to do an implicit cast from one to the other.
Re:Why Python is Slow: Looking Under the Hood by maxlybbert on Friday May 09, 2014 @07:12PM (#7723770)
That's a valid point. But, being dynamically typed, you don't find out about the type error until runtime. It's possible, although unlikely, that a Python web application can run for months before hitting a particular code branch where a string and an int are added together, and an exception is thrown. (In Python, it's also possible to get syntax errors long after you start your program).

It's possible that the compiler would have had enough information to determine this, if the compiler were to check types. Again, the proposed solution is to simply write enough tests to exercise all code paths.

For what it's worth, I enjoy working in Perl. But I realize when I do that some things are deferred until runtime. I also enjoy working in C and C++, partly because I can push some things to compile time (type checks, sure, but also arithmetic ( http://en.cppreference.com/w/cpp/numeric/ratio/ratio ), unit checking ( http://www.boost.org/doc/libs/1_55_0/doc/html/boost_units.ht... ), a decent amount of reflection ( http://en.cppreference.com/w/cpp/header/type_traits ), some assertions (static_assert), etc.). I don't necessarily push it all to compile time, but C++ allows me to.

Re:Why Python is Slow: Looking Under the Hood by rectangletangle on Friday May 09, 2014 @03:00PM (#7722697)
Python is a strong dynamically typed language. Unlike JavaScript, which is a weak dynamically typed language. In Python `'1' + 0` throws a `TypeError`. While JavaScript attempts to figure out what you meant.
Re:Why Python is Slow: Looking Under the Hood by Chattered on Friday May 09, 2014 @06:41PM (#7723634)
Which would be fine if I only ever used "+" with literals. But normally, I write things like

x + y

where x and y are values I got from who knows where. Javascript shouldn't pretend to figure out what I mean by this, because in many cases, I'm talking gibberish, and all I have is a bug.

I'd rather not talk about this stuff in terms of "types." It's about assertions, and Python makes them early and throws the exceptions early. It's a defensive practice that you can emulate in any language, and your assertions can be much richer than anything that is typically thought of as a type.

Re:Why Python is Slow: Looking Under the Hood by rectangletangle on Friday May 09, 2014 @11:13PM (#7724352)
I'm definitely a fan of Python's strategy. It's much better at detecting bugs early and often. That, and there's a distinction in Python between identity and equality, with the `is` and `==` operators respectively.
Re:Why Python is Slow: Looking Under the Hood by thaumasiotes on Saturday May 10, 2014 @08:41AM (#7725192)
Frankly, I think Perl has the best approach to this specific problem. We all want to do some string concatenation. We all want to render some non-string values as strings sometimes. So:

    1 + 0 = 1
    1 . 0 = 10
Just stop using + to concatenate strings.
Re:Why Python is Slow: Looking Under the Hood by redler on Friday May 09, 2014 @09:36PM (#7724166)
> In Javascript (which is also dynamically typed) I've had a few times where adding 1 and 0, say, yielded "10" because either the 1 or the 0 originally came from a string. OK, I can live with that, but I find the fact that you can use that string in numeric comparisons potentially confusing.

There are two problems demonstrated by your example; the other is the overloading of the + operator as a design decision in JavaScript. Easier, but worse.

Re:Why Python is Slow: Looking Under the Hood by collyw on Saturday May 10, 2014 @03:50PM (#7726654)
That's a JS probelem. The majority of dynamic languages would handle this "properly".
Re:Why Python is Slow: Looking Under the Hood by tetha on Friday May 09, 2014 @02:12PM (#7722410)
We are currently refactoring a bunch of stuff at work, and by now we can largely manage dependencies between various subsystems with the type system - without the type checking being too intrusive. Basically this means: If I have the current application and I add a new subsystem because I need it, and I don't have all the requirements of this system in place already, I get an error at compile time telling me to fix this. This makes it very hard to do certain classes of mistakes.

The interesting thing is that a sufficiently powerful type system with strong type inference eventually converges with dynamic typing in ease of use, but it offers the option to do rather complex reasoning about the code at compile time, again, preventing certain classes of errors.

Beyond the classes of errors being prevented, I feel like a mature, strongly typed architecture offers a certain amount of guidance in implementing new solutions. If you start implementing certain interfaces in our more mature codebases, you get a number of situations you need to handle - since the interface forces you to implement certain methods. You can't forget these situations, again, preventing mistakes or recreating the same bugs.

Note that both situations assume a certain level of maturity in a solution. Initially, a type system can be somewhat annoying while you work out the kinks, I'm perfectly fine to admit this. This requirement also implies what I feel - in small, hacky scripts, static type systems tend to be annoying to some degree. But in large, complex systems, I don't want to miss them.

Re:Why Python is Slow: Looking Under the Hood by im3w1l on Friday May 09, 2014 @05:23PM (#7723321)
I recently made a class implementing an interface from a library in python. That interface had a "canonical" implementation, in that most instances of that interface were of that class. When I tried to call some functions from that library with my own class, they tried to call methods from the "canonical class", which were neither present in the interface nor my implementation.

Result: program crashed when trying to call not present method. Had to clear up a few of these before it would work. If the type system hadn't been so forgiving the library implementers would have realized how their abstractions were leaking, and it would have been a lot easier for me to implement the interface correctly.

Re:Why Python is Slow: Looking Under the Hood by gizmo686 on Friday May 09, 2014 @04:18PM (#7723051)
There is no reason you can not have something like "variable = int(variable)" in a strongly typed system. In fact, Haskell lets you do (essentially) this by shadowing variables. This particular example wouldn't work, because Haskell would view it as a recursive definition, but there is no reason you couldn't design a language so that the asignee side looks at the pre-shadow variable.
Re:Why Python is Slow: Looking Under the Hood by skriticos2 on Friday May 09, 2014 @03:30PM (#7722824)
In my experience the dynamic typing is very useful when you start to do collections and nested data structures. You easily create a mixed type nested directory tree with only a few lines of code without all that boilerplate.
Re:Why Python is Slow: Looking Under the Hood by spion on Friday May 09, 2014 @03:44PM (#7722886)
And because you can create them so easily, soon you end up with hundreds of them and you have no idea which one contains what :)
Re:Why Python is Slow: Looking Under the Hood by Dewie on Friday May 09, 2014 @06:55PM (#7723697)
> You easily create a mixed type nested directory tree with only a few lines of code without all that boilerplate.

A similar thing can be achieved in Haskell, with the Typeable typeclass. The Scrap Your Boilerplate also fixes problems like this.

There has to be some use for dynamic typing when even Haskell (ghc) adds support for it, I guess.