5 ms·
I agree that short python samples are as clear as a high level language can possibly be. Implementing algorithms, for instance, becomes incredibly easy in Pytho
by thedigitalengel 16y ago
I agree that short python samples are as clear as a high level language can possibly be. Implementing algorithms, for instance, becomes incredibly easy in Python. I face problems when Python programs get above a certain length.
I've done some Django programming in the past. A view gets a request object (pardon me if I'm wrong or if this has changed recently) and is supposed to then render the response (or something similar, I don't remember exactly). Now what is a request? If Django were in C, I would know what a request object really was, grep for it, and look up the header file. If request has a GHashTable named post_data, I don't think I need two guesses about what it exactly is. Same goes for C++ and C#.
Then you've inconsistencies. The same method may return a string object or an integer on different calls. And this happens in practice - I remember when I was (trying to) model a relational database in Django, I found a ManyToMany field returning (when invoking values ()) a list of dictionaries instead of a list of Model objects (which I was expecting).
Of course, if I was not dumb enough to not read the documentation I might not have stumbled; but the point is that Python allows this to happen. And since I don't have the benefits of a compiler, anything other than basic syntax errors (the ones I can catch by calling py.compile) explode at runtime.
The thing I've begun to notice that scripting languages tend to require you to hold the entire structure of the program in your head as you code. In C++ you know that unless you've gone out of your way to do some casting magic, a string get_foo () will always return a string. And you can always do get_foo ().c_str (). In python you're never sure.
- loup-vaillant 16y agoYou sound that you will like Haskell. It's type system can be really paranoid (it lets you express many invariants through it), yet remain very flexible. And If you can't fathom the segregation of (side) effects, there's still Ocaml.
- ldsa 16y agoOCaml is a dying, soon obsolete, language. Better use F# which has way better libraries and tools.
- zaphar 16y agoAs I understand it OCaml is in heavy use at a number of shops in the financial industry. I wouldn't say it was dying just yet. On the other hand F# is a new and as compared to OCaml untried and untested language.
- ldsa 16y agoNumber of financial companies using F# is about the same as for OCaml (but numbers are not evolving in the same manner). F# uses .NET which is way more tested than OCaml runtime. F# uses .NET libraries which are way more tested than OCaml libraries. F# core language is still a bit less tested, but considerable work is being done. In contrast, there is only fulltime person working on OCaml. OCaml community is dying, while .NET community is huge.
- zaphar 16y ago.Net being tested is not the same as F# being tested. The idea that the OCaml community is dying is purely subjective. OCaml, having been around longer than F#, may just be going through a perceived lull. Either way generalizing that F# will replace OCaml as the goto language in the ML family from a perceived decline in the OCaml community is probably not the right call.
- eru 16y agoWe also use Ocaml here (Citrix), and people agree that Ocaml seems to be going nowhere. Some projects have started switching to Haskell.
- loup-vaillant 16y agoDon't overlook the fact that F# is build on top of a proprietary, potentially patent-ridden platform. For many people, including me, that's a non starter.
- wyuenho 16y agoI'm surprised no one has mentioned Peter Norvig yet. http://norvig.com/21-days.html http://norvig.com/21-days.html From your comments, I kind of get that you want to be a real good programmer, and part of being a good programmer is to understand the different way you can wire bit and pieces together in the many different languages. I had a similar experience as you in that I went from C->C++->Java->Javascript->Scheme->SML->Python. I can definitely tell you that learning Scheme and SML first helped me tremendously in understanding dynamic languages in general. In more concrete terms, understand typing rules has helped me how to debug a program when I mess up in Python. For example, in SML, I can completely omit type annotations and the interpreter will infer the right type for me at parse-time, and that each function or statement must only return 1 type. In dynamic languages such as Python, you can still do what you can do in SML or Haskell, but the runtime system makes no guarantee that your program as it is written is type-safe when the interpreter parses all your source files. Type checking is done at execution, when the code path in question is exercised. However, if you THINK about how the types are infered in SML when you write in Python, you generally will not run into TypeErrors. The same goes for functions that return different types. To prevent tripping up with these functions, just apply what you've learned in Haskell or SML when you are debugging library functions that do this, and avoid writing functions that return different types.
- japherwocky 16y agowhat makes you think you can't grep for the request object/class?
- thedigitalengel 16y agoWhat I implied was that it was not immediately obvious what the class was. def foo (self, stream): What is stream here? void foo (std::ostream &out) { out << "bar" << endl; } Hope you get the point.
- japherwocky 16y agoSo, grep for what's calling your function, or use pdb.set_trace()
- duke_sam 16y agoYou seem to be complaining that when using a language new to you in combination with a large framework written in that language you would have been forced to read the (very good) documentation to figure out what was happening. The inconsistencies you mention are (in a well written code base) very rare. If you call a method get_name() odds are you are going to get back a string. If you seem to randomly get back an int or a dictionary or a datetime object it's a pretty good sign the code is foobar'd. Good Python programmers don't abuse the dynamic nature of the language. Methods should return predictable types (documentation is important), it might return different types depending on the input but this should be documented and obvious (say a parse date method that returns a datatime object if you pass it a string containing a date and time). The values() example you use is very clearly documented as returning a ValuesQuerySet that supplies dictionaries not models (http://docs.djangoproject.com/en/dev/ref/models/querysets/#values-fields http://docs.djangoproject.com/en/dev/ref/models/querysets/#v...). In a number of years using python, the standard library and 3rd party libraries I've never been left wondering "If I pass X to this method what the hell type am I going to get back". Just like in C/C++ I need to remember it returns a list or a string or a dictionary but that's usually where the mental overhead stops. Python is dynamic which means it's flexible. Flexibility is usually reached by sacrificing simplicity so Python encourages testing and good documentation. I would argue that these are both necessary features of any good code base, Python is just more upfront about this than a number of languages.
- thedigitalengel 16y agoI'm not really not complaining about anything - the shortcoming clearly lies within me and not in Django or Python. The purpose of this thread was merely to gauge what kind of paradigm shift people who were used to programming in C or C++ generally experience when they move to Python. Some people seem to find making the jump easier than others - I personally have found it difficult and have made little progress so far. Since I generally consider myself good with computers, I find this a little unnerving.
- arghnoname 16y agoThis is something I run into with perl/php/python/ruby/etc too. Perhaps I've just gotten used to outsourcing some of my brain to the compiler, but I really like to lean on it to get good results. Run-time blow-ups suck, and I've always preferred using a compiler to writing all these test cases to catch run-time type errors. I really like using a dynamic language for some tasks. I almost never use C, C++, or Java for any task I hope to start and complete within a day. Those jobs are small enough it's easy to keep track of what you are passing around. I spent 6 months writing all of my utilities in Python. I tried very hard to like it, but it just didn't tickle my fancy. I do like perl and ruby for a dynamic language. I think perhaps the issue is, if you are like me and you don't like using dynamic languages for large programs, the extra clarity of python isn't enough of a added bonus.
- LordLandon_ 16y ago> If Django were in C, I would know what a request object really was, grep for it, and look up the header file. If Django were in python, you wouldn't even have to grep >>> import django.http, inspect >>> print inspect.getsource(django.http.HttpRequest)
- vaughnkoch 16y agoOr even easier: ipython >>> from django.http import * >>> HttpRequest?? # prints out source code for HttpRequest
- kragen 16y agoI think you just need different techniques for Python than for C. You can write a dummy view that calls dir() on the request object (which will probably tell you how to get the POST data), asks it for its __class__, asks it or its __class__ for their __module__, asks for sys.modules[request.__module__].__file__, and so on. If you just want to know what's in the request object, rather than what its methods are, you can get its __dict__ and print that out, and then you get not just the type of its contents, but an actual example. When you have a REPL and an example of an object, you can call help() on the object and get generally pretty good documentation on And there's the inspect module, like LordLandon_ pointed out, but which I didn't know about. And when the going really gets tough, you can monkeypatch random libraries to change the way they work (e.g. to add logging) in order to debug the problem. All of the above applies to Python development in general, not just Django. Django in particular has several additional advantages: • it has an "interact" mode that pops you into a Python REPL so you can poke at all of this stuff interactively instead of having to save a source file and hop over to your browser; • it has really first-class documentation; • if you raise an exception in debug mode, the traceback includes dumps of all of the objects mentioned on all the levels of the traceback stack, along with a few lines of source code from the stack frame; In short, Python offers much more power to undertake the kind of analysis you were wanting to do than C or C++, but you have to do it dynamically, instead of statically.
- lars512 16y agoTo complement what other people are recommending here, I'd say that in cases like this I only sometimes read the documentation. Other times I put a line in my code: import pdb; pdb.set_trace() which makes it enter the debugger at that point, and I simply inspect the object that I'm really getting, looking at what it supports, the documentation on its methods, etc. Doing it this way is not always feasible, since sometimes there's a prohibitive amount of setup code that needs running before you can get a real object. For short code paths though, like Django apps, it works really well.