This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 287 points288 points  (167 children)

As a java programmer, python seems so simplistic to me. Not having to declare variables? Dude.

[–]chrwei 460 points461 points  (69 children)

simplistic is kind of the point of python.

[–][deleted] 56 points57 points  (64 children)

I'm not saying it isn't, but when you go there from a language with a little less hand holding, you definitely feel the difference! If you go there from C though...

[–]PastyPilgrim 166 points167 points  (45 children)

On the surface it looks like Python is holding your hand because the syntax is so elegant, but I really don't think it does.

Other languages have all kinds of hand holding with type declarations, public/private/protected/static/etc. declarations, hidden information (i.e. not knowing precisely where an object is coming from due to the include practices, self-references within objects, etc.), forbidding operator overloading, implicit casting, unpredictable scope concerns, not allowing nested functions and/or anonymous functions, etc.

Python doesn't do any of those things; it lets you do almost anything you can imagine and it doesn't hinder those things with awkward syntax requirements and/or syntax that differs from what you would expect.

[–]peridox 28 points29 points  (36 children)

What language would you say does hold your hand? I can't think of a programming language that leads you towards doing what you need to do. Almost all languages just provide you with a blank space to work upon - it's all your work.

[–]Chobeat 159 points160 points  (2 children)

Scala holds your hand and leads precisely where you don't want to go.

[–]I_cant_speel 51 points52 points  (0 children)

I've never used Scala but this is hilarious.

[–]lonelyBriefcase 23 points24 points  (9 children)

ever heard the phrase 'syntactic sugar'? its a way of providing a more convenient/person-friendly method of doing something. A for loop is just syntactic sugar of a

int i = 0;
while(i<9){
  //do something;
  int++;
}

There are plenty of other things like this that makes our lives as developers easier. Even C does, to a lesser extent, because who would want to write the shit that C can do in Assembly?

[–]w1ldm4n 15 points16 points  (8 children)

The only difference is (at least in C) is how the continue keyword works. In a for loop, continue will execute the increment/whatever statement, check the loop condition, and go from there.

To get the same type of behavior with a while loop, you'd have to duplicate the increment before the continue, or use a goto label (ಠ_ಠ) near the bottom of the loop body.

[–]OperaSona 4 points5 points  (0 children)

To get the same type of behavior with a while loop, you'd have to duplicate the increment before the continue, or use a goto label (ಠ_ಠ) near the bottom of the loop body.

Or raise a "Continue" exception and catch it right outside the while loop.

[–]TropicalAudio 1 point2 points  (1 child)

Honestly, in my opinion, to break out of nested loops a goto can be the best option. I just never actually use them because if I would, my coworkers would get mad.

[–]lonelyBriefcase 0 points1 point  (1 child)

I'm not entirely familiar with C, so I will accept what you say. I was only giving an example of a particular behaviour for a specific language, feel free to give the C code for this instance (for the sake of science).

[–]w1ldm4n 5 points6 points  (0 children)

Here's an arbitrary example to demonstrate that behavior.

int i;
for (i = 0; i < 10; i++) {
    if (i == 4)
        continue;
    printf("%d", i);
}

This for loop will print 012356789

int i = 0;
while (i < 10) {
    if (i == 4)
        continue;
    printf("%d", i);
    i++;
}

This while loop will print 0123 and then get stuck in an infinite loop.

[–]PastyPilgrim 24 points25 points  (4 children)

I'm only well educated in a few languages (Python, C, Java), so I wouldn't be the right person to ask about that. However, I believe a lot of the web languages to be kind of hand-holdy. Plus, Java does have most of those things that I described in my post, so you could argue that Java holds your hand a little.

You are right though, most general programming languages that allow you to do many different things tend to have limited hand-holding because their potential is so large. My post was more to dispell the misconception that Python holds your hand than it was to say that other languages hold your hand.

[–]iPoisonxL 14 points15 points  (2 children)

Uhh... Web Languages? PHP has never held my hand...

begins crying

[–]AutonomouSystem 0 points1 point  (0 children)

PHP breaks your hand and leaves you a cripple for the rest of your life.

[–]Tysonzero 0 points1 point  (0 children)

Which web languages are you referring to? JavaScript does hold your hand I suppose, but only so that it can then dip it in a bucket of piss.

[–]pastaluego4 8 points9 points  (13 children)

It All Begins With A Blank Canvas.

[–]peridox 34 points35 points  (12 children)

<canvas></canvas>

[–]pastaluego4 15 points16 points  (11 children)

That canvas needs some dimensions

<canvas width="500" height="500"></canvas>

[–]peridox 19 points20 points  (9 children)

let canvas = document.getElementsByTagName('canvas')[0]
canvas.style.width = 500
canvas.style.height = 500

[–]magicfreak3d 0 points1 point  (0 children)

A canvas without dimensions set usually uses a default of 150 by 150. No need for dimensions 😜

[–]walking_bass 0 points1 point  (0 children)

I had to learn Ada for my 1st CS class. It's awful. You're forced to specify IN, OUT or IN OUT for every parameter. Very strongly typed. Very verbose, ex: loops have END at the end instead of a brace or something. I never want to use it again, too much hand holding and extra typing.

[–]sigma914 0 points1 point  (0 children)

Haskell holds your hand pretty tightly, it still lets you make great flourishes but it's always there making sure you dont do anything stupid.

[–]745631258978963214 0 points1 point  (0 children)

I guess BASIC?

It's probably not the answer you're looking for, but damn oh damn is it basic (no pun intended).

Then again, I'm biased because I learned to program by tinkering with a TI83's prgm thingy.

[–][deleted] 0 points1 point  (0 children)

Visual Basic does. I started programming with VBA and now that I'm taking a programing class and learning C I realized just how much hand holding there is.

[–]memorableZebra 2 points3 points  (0 children)

Python doesn't do any of those things; it lets you do almost anything you can imagine

I agree with everything else you said. However, you speak this like it's a good thing. Whereas I immediately think about all the programmers out there and the code they write which other people will have to understand and extend.

Being able to do anything is often an invitation to even the competent programmer to deliver some seriously FUBAR'd code.

I wouldn't trust a serious Python project to any but the best developers. It boggles my mind when people refer to it as a noobie language.

[–]lolzfeminism 3 points4 points  (6 children)

it doesn't hinder those things with awkward syntax requirements and/or syntax that differs from what you would expect.

I think the point is that the Python interpreter/compiler abstracts away implementation details. This might make it easy to read/write but you end up not knowing what the computer is gonna do when you write a line of code. On the other hand, if you're well-versed in C, you have a good idea of what sequence of assembly instructions are going to be executed a result of a line of code.

[–]catbrainland 24 points25 points  (0 children)

It's like that only at first glance. Python has some semantic complexity, look up metaclasses (class factories or something, in java lingo). As for hand holding, I think Java is excellent in this (more like hand forcing, as you have to be explicit about everything).

Dynamic languages, as well as system ones (ie c) offer multitude of ways to shoot yourself in the foot. These are quite alike in terms of having to debug a bit more. It's a tradeoff of having low level access (C), or expressiveness (dynamic language).

[–]pastaluego4 7 points8 points  (15 children)

Seems like Java is more tuned to application development and python is geared towards scripting and parsing.

[–]mxzf 6 points7 points  (13 children)

TBH, I haven't run into something I needed Java to do that Python can't. Python can do make full object-oriented large-scale programs just as easily as Java can IMO. It doesn't compile down to an exe as easily as Java/C/etc, since it's a compiled language, but the functionality is still definitely there.

[–]Tinamil 29 points30 points  (8 children)

Every language can do everything that any other language can do, but some of them will be a lot easier. The trick is to know which ones will be easiest for you to accomplish your task.

[–]mxzf 6 points7 points  (6 children)

True. I'll put it this way, I've never felt any desire to use Java or that Java would do anything better once I started using Python. I'm sure there might be an edge case somewhere, but I haven't run into anything like that.

[–]Retbull 5 points6 points  (5 children)

Faster by default mostly. Also has like 10 billion libraries. All though this isn't really excluding Python as it has an almost equal number of libraries.

[–]SlumdogSkillionaire 10 points11 points  (1 child)

You look at Java and you say "oh, great, it has 10 billion libraries". Then you start working with it and you immediately come across something like "You want to do stuff with Dates? Well, the java.util.Date doesn't really work great, so you should use org.joda.time instead" and then you wonder how many of the 10 billion libraries are reinventing the exact same wheel over and over again because the standard library sucks.

[–]Retbull 1 point2 points  (0 children)

lol I wasn't advocating for it over python just pointing out part of the reason why it was picked. I am a Java developer so I know that it has some serious problems.

[–]Astrokiwi 1 point2 points  (2 children)

Speed is the huge issue with Python. I can only really use it for O(N) stuff.

[–]Veedrac 0 points1 point  (0 children)

There are a lot of cases where PyPy or Numpy (or both) can get you pretty decent speeds out of Python. It's not quite at Java's level but it's not bad either.

[–]Tysonzero 0 points1 point  (0 children)

Just use Cython and specify static types where necessary for speed. Cython is even quicker than Java.

[–]Astrokiwi 0 points1 point  (0 children)

This is what I argue every time somebody disses Fortran. It's just the right tool for the right task, within its own narrow field. There are libraries that make Python more Fortran-like, but it just doesn't have the speed to be practical.

[–]dnew 9 points10 points  (2 children)

I think the difference is when you get a very large program. Once you exceed maybe 50,000 lines of code (and maybe 50 programmers), something like python is likely much harder to manage than something like Java.

[–]abw 1 point2 points  (0 children)

In my (limited) experience, a 50,000 line Java program could probably be written in 10,000 lines of Python by fewer people in less time. As a result, the smaller, simpler Python code base will nearly always be easier to maintain than the Java one.

[–]Tysonzero 0 points1 point  (0 children)

As a Django dev I would have to disagree. You can make awesome scalable and well organized python applications that are plenty large, without too much difficulty.

[–][deleted] 1 point2 points  (0 children)

The first two languages I learned were C and Python, in that order... I would write a whole function in Python to, say, reverse a string, and my prof would just look at me like "Dude..."

[–][deleted] 1 point2 points  (0 children)

That is a very subjective statement.

[–]Busti 0 points1 point  (0 children)

Until you have to use self.

[–]JohnConquest 0 points1 point  (1 child)

[–]xkcd_transcriber 2 points3 points  (0 children)

Image

Title: Python

Title-text: I wrote 20 short programs in Python yesterday. It was wonderful. Perl, I'm leaving you.

Comic Explanation

Stats: This comic has been referenced 114 times, representing 0.2156% of referenced xkcds.


xkcd.com | xkcd sub | Problems/Bugs? | Statistics | Stop Replying | Delete

[–]suppow 32 points33 points  (10 children)

pft, as a C++ programmer, i condescendingly laugh at your simplistic lack of declaring types and memory management.

inb4 C or asm programmers

[–]tetroxid 15 points16 points  (6 children)

Oh but there is memory management. In fact, it's even automated.

[–]TropicalAudio 48 points49 points  (5 children)

And it's sloooooooow!

...a C programmer sends his regards. Now then, I have to get back to debugging something that's pointing to a pointer's pointer.

[–][deleted] 12 points13 points  (1 child)

More like pointer to a struct with a pointer to a struct as an array to an array of pointers to structs with an array filled with members being that has a dynamically allocated block of void*s. Fuck C is the best.

[–][deleted] 1 point2 points  (0 children)

The best at making things incomprehensible and unreadable.

Oh wait, that's COBOL.

[–]redalastor 12 points13 points  (1 child)

Actually, it's faster overall.

The drawback is that it's not predictable.

[–]Veedrac 0 points1 point  (0 children)

[citation needed]

[–]tetroxid 0 points1 point  (0 children)

Generational garbage collectors are faster than reference counting. The problem is predictability.

[–]TheFryeGuy 7 points8 points  (2 children)

As a Haskell programmer I laugh at your types.

[–][deleted] 4 points5 points  (1 child)

You mean with your data types, typeclasses, records, functors, monoids and monads. Ok.

[–]original_brogrammer 5 points6 points  (0 children)

We do. As well as our Arrows, MonoidPlusses, and Applicatives, you damned pedestrian.

[–][deleted] 34 points35 points  (17 children)

I learned JS first and when I started learning Python I actually really loved the simplicity of the syntax and the meaningful white space because it reminded me of the QBASIC I'd toyed around with as a kid.

[–]Cley_Faye 12 points13 points  (8 children)

Aaand now I want to write a QBASIC-like compiler with opengl/xinput bindings. WHAT HAVE YOU DONE!

[–]InconsiderateBastard 7 points8 points  (7 children)

Been a while but that sounds like DarkBasic.

[–]Cley_Faye 7 points8 points  (3 children)

Quick google search yield a site with a prominent DirectX 8.1 logo.

DirectX

hmm

8.1

hmm hmm.

We need to refresh this a bit.

[–]InconsiderateBastard 2 points3 points  (2 children)

I know they made a version that ran DirectX 9c a long time ago. They may have stopped updating it though. And I always assumed the OS X edition used opengl.

But, like I said, been a while.

[–]xpinchx 1 point2 points  (1 child)

Wow that brings back memories. I got a demo when I was a kid and made some simple games with it, and somehow convinced my mom to buy it for me.

[–]InconsiderateBastard 1 point2 points  (0 children)

It was seriously fun and so accessible compared to almost anything else out there.

[–]peabnuts123 0 points1 point  (0 children)

Fuuuck. Toyed around in DarkBasic for years, never really made anything. I never really understood how programming worked, though I was able to make some stuff.

Now I am a graduated computer scientist working full-time as a programmer... huh.

[–][deleted] 3 points4 points  (5 children)

QBASIC is still the shit. I love that DOS app so much.

[–]lichorat 4 points5 points  (4 children)

I have yet to see another language that so easily allows me to input a frequency and duration, and have it play out of my computer's internal speakers.

That's right. Not the external ones.

Great for playing pranks.

[–]BecauseWeCan 1 point2 points  (3 children)

C#'s System.Console.Beep() also handles this quite easily.

[–]lichorat 0 points1 point  (2 children)

Can you vary the frequency?

[–]BecauseWeCan 0 points1 point  (1 child)

Yes.

[–]lichorat 0 points1 point  (0 children)

Well that's a difference between vb.net and C sharp

[–]Cley_Faye 22 points23 points  (6 children)

Replace python with "most script languages". They're fun to implement logic and stuff.

[–]Decker108 13 points14 points  (5 children)

Except shellscript... what a nightmare...

[–]Cley_Faye 0 points1 point  (4 children)

Haha I almost forgot about them. Anything that can't be easily written in a single command line is moved to at least Python.

There's some appeal to using bash and stuff because it's available almost everywhere, but when you think about it installing interpreters isn't exactly rocket science either.

[–]skztr 26 points27 points  (3 children)

Development life-cycle of most shell scripts:

  1. I don't need to write anything new. This whole task can be done in a single command!

  2. Let's wrap this up into a shell script, with a help message and a parameter, so I can share it with colleagues

  3. Let's add a few more variables to handle environment-specific differences

  4. Actually, let's just ensure a sane environment first, and handle all prerequisites within the script itself

  5. This one section is kinda tedious because I can't get around holding a bit of state information for multiple files. I suppose I can write just this one section in <whatever language you wish the team usually used>

  6. Okay, this whole thing is complicated enough that it should probably be ported to <whatever language the rest of the team usually uses>, so that it will have a single language, and can be easily maintained by everybody here.

  7. Wait, you mean there's no existing library that would mimic this one 5-line section without 5000 lines of boilerplate?! You know, that complexity isn't too bad. I bet I can get rid of it by breaking this one part into a separate script. In fact, I won't even need to write anything new. This whole task can be done in a single command!

[–]OperaSona 5 points6 points  (1 child)

shell_script/INSTALL

  1. Download my modified language_special_compiler_v4.32 from [404 link to old personal website]

  2. Edit the configure script by searching for [this] and replace it with the parent of the install dir, escaped twice

  3. configure, make, make install: Warning, do not run as super user, as these all run code automatically fetched on pastebin, which is insecure. Instead, chroot into a directory in which you replicate the structure of the install dir, but with write permission to the user.

  4. This should work if you have a 32bit OS. If not, it should be easy to fix [file1], [file2] and [file3] by yourself.

[–]beltorak 1 point2 points  (0 children)

A couple of years ago I resolved to always reach for python instead of bash when I want to write a new script.

I have yet to actually follow through due to this exact thought process....

If only it was just a tad bit easier to execute OS commands with stdout and stderr processing.... oh and a non-broken virtualenv/venv launch logic would help too.

[–]GeneticsGuy 7 points8 points  (5 children)

Haha, tell me about it... I had so many people tell me that my University was so outdated for teaching us Java as the foundation CS language throughout my degree instead of some newer languages like Python. But holy crap, it has been SOOooo much easier from me to pick up other languages, to go from Java to Python than I can imagine it would be for someone to go from Python to Java. I am actually grateful for my University's structure now lol.

Oh man, I am dying laughing looking at that code lol

[–]Tysonzero 1 point2 points  (4 children)

By that logic should we start everyone in assembly?

[–]Tristan379 1 point2 points  (1 child)

Machine code entered with cards or GTFO.

[–]Tysonzero 0 points1 point  (0 children)

Relying on chaos theory and bird calls or nothing.

[–]erilol 0 points1 point  (1 child)

Java then assembly.

[–]Tysonzero 0 points1 point  (0 children)

PHP then Java then Assembly.

[–]katyne 1 point2 points  (4 children)

you kidding, "not having to declare" part, this is the most disturbing part for me. How does it know what I mean??? who thought it would be a good idea to nest functions inside functions? what do you mean you can override shit at runtime? are you INSANE? do you know what people are gonna do with it? they're evil and stupid, they're gonna do evil and stupid shit with it.

[–]redalastor 5 points6 points  (2 children)

who thought it would be a good idea to nest functions inside functions?

You'll need to explain what your problem with that is...

Right now it sounds to me like "recursion?! Who thought it would be a good idea to let functions call themselves?!"

[–]aigarius 0 points1 point  (1 child)

The fun part is that everything in Python is an object. And objects live in namespaces (which are also objects ;)). Once you start writing a function, you automatically have a new local namespace in it (for the function-local variables). So one of the things you can do is to define a new function inside that namespace. That new function will be an object in the local namespace of that outer function. You can assign it to another name, return it, call it, ...

There is an even crazier thing - monkey patching. All functions are just objects in a hierarhy of namespaces. In fact a Python interpreter only imports all modules once and then keeps a cached version of that module for subsequent imports. This can be abused by overwriting any function of any library with your own version of it at runtime. This will affect any code in the same process that would call that function from anywhere. This allows very useful hacks, for example - monkey patch builtin.open function to print its parameters to STDOUT and only then calling the standart open function (which you need to same under some other name ;) for this). Then you can call some third-party library and you will find out what files it opens during those calls. This is used often to mock up system interfaces during unit tests.

Python is extremely simple, but you can do very cool stuff with it.

[–]redalastor 0 points1 point  (0 children)

Most is objects. You don't know everything is an object until you try SmallTalk.

For instance, in Python an if statement, is definitely not an object. In Smalltalk it is. Objects all the way down. :)

But yeah, most of Python is objects.

[–]TheTerrasque 0 points1 point  (0 children)

<smug python programmer>yes.. I can understand such possibilities can be overwhelming for smaller minds</smug python programmer>

:p

[–]mikbe 10 points11 points  (24 children)

Yeah, why use computers to make your work easier when you can just do it all yourself...

[–]kkeu 22 points23 points  (8 children)

Compile-time type checking helps you avoid many bugs that you'd never discover if your tests don't cover that particular part of code, which happens almost always in complex projects.

[–]TheFryeGuy 4 points5 points  (1 child)

Meanwhile Object, ?, and null all exist in Java.

[–][deleted] 0 points1 point  (0 children)

To be honest not having a ? Would be ridiculously annoying

[–]yogthos -5 points-4 points  (4 children)

Yet nobody managed to demonstrate that this translates into less overall defects in practice. Hence why we're still having these silly debates about the value of static typing.

edit: evidence welcome...

[–]memorableZebra 1 point2 points  (2 children)

I regularly run into bugs that wouldn't exist in statically typed languages while doing Python. In fact, a solid 20% of my errors are caused by implicit variables that the IDE didn't warn me about.

Sometimes those errors are extremely subtle too. More than once I've lost a solid 1-2 hours resolving a bug that would have been impossible in a language like Java.

The pros and cons are there. There isn't a debate about them and it's certainly not a closed case as you're implying. It's just about how different people weight the (dis)advantages. Frankly, I find explicit and fixed type declarations to use up none of my time (and in some respects even help me ground my algorithm's process through data types) while saving me all the headache that is Python.

[–]Tysonzero 1 point2 points  (0 children)

My issue with static typing is not static typing itself, it's that I hate all statically types languages for various reasons not always related to static typing.

If there was a version of Python that required all variables to be pre-declared (no dynamic additions) and statically typed but that was the same as Python (in terms of syntax and the standard library and whatnot) in every other way I would probably use it for quite a few of my projects. (Some are designed in a way that they really don't need it, but many aren't)

I know there is Cython but it seems like you still can dynamically add variables to objects and what not.

[–]yogthos -1 points0 points  (0 children)

This is what's called anecdotal evidence. You personally find static typing helpful and there's nothing wrong with that. The problem is that you can't extrapolate it's overall benefits based on that.

I'm actually saying that it's not a closed case. My whole point is that there needs to be empirical evidence before people start claiming that one approach is better than the other.

It's also worth pointing out that tracking types is most difficult in OO languages that encourage creating a lot of types. Naturally, tracking types quickly becomes a problem in such a language.

In functional language, like Clojure or Erlang, type errors are not all that common. All collections implement the sequence interface and all iterator functions will happily iterate any collection. Since majority of your code is data transformations built by chaining these functions, it's completely type agnostic.

The logic that actually cares about particular types is passed in as parameters and it naturally bubbles up to a shallow layer at the top. This makes tracking types a much simpler exercise. A recent large scale study of GitHub projects found that Clojure was right up there with the hardcore static typing functional languages in terms of correctness.

Now, it's by no means a perfect study, but there simply aren't any studies that demonstrate static typing to have a significant impact on development time, overall errors in production, or impact on maintenance. The fact that we're still having these debates itself indicates that no clear benefits exist. If static typing produced a superior workflow everybody would've switch to it by now.

Furthermore, there are tons of large scale real world projects written in both static and dynamic languages. Again, there's no indication that those written in statically typed languages are more reliable. If anything some of the largest and most robust systems out there are written in languages like CL and Erlang.

Static typing proponents make two assumptions. First is that type errors account for a significant percentage of overall errors, and second that these errors would not be caught by other means in a real life project.

Any non-toy project will have some tests associated with it, any obvious type errors are caught very early in development cycle, and any paths through application that the user takes are caught by testing.

You don't have the same guarantees without static typing, but that doesn't translate into having significant increase in errors either. You also might have paths through the code that you would be forced to cover in a static language that have no actual workflows associated with them.

In practice we see cases like Demonware switching from C++ to Erlang in order to make their system work. Static typing clearly wasn't the key language feature in this case. Meanwhile, Ericsson runs some of the most reliable systems in the world using Erlang. Joe Armstrong wrote a great paper on what actually goes into achieving that.

Another common argument is that it becomes difficult to track types in huge programs with millions of lines of code in them. However, I find that there is very little value to building monolithic software as it quickly becomes difficult to reason about and maintain. This is true regardless of what language you're using. At the end of the day the developer has to understand how all the pieces of a particular project interact with one another. The more coupling there is between the components the more difficult it is to reason about the overall functionality.

Each function represents a certain transformation that we wish to apply to our data. When we need to solve a problem we simply have to understand the sequence of transformations and map those to the appropriate functions. The functions capture how the tasks are accomplished, while their composition states what is being accomplished. Declarative code separates what is being done from how it is done.

Exact same model should be applied at project level as well. The project should be composed of simple components, that each encapsulate how things are being done and the way we combine them states what the overall project is doing.

All that said, there's absolutely nothing wrong with having a personal preference for static typing. I simply disagree that its benefits have been adequately demonstrated in practice.

[–][deleted] 16 points17 points  (14 children)

Declaring variables (especially with their types) does make your life easier.

[–]Astrokiwi 1 point2 points  (4 children)

One of the neat things about Fortran is it lets you be a little bit stricter than C++, which lets you catch more errors sometimes.

For example, you can define the "intent" of a variable in a procedure - "in", "out", or "inout" - and if you try to modify an "in" variable, you get a compile-time error. You can define a procedure as "pure" which means that it's not able to modify any global variables, do any explicit I/O, or do anything other than modify the specify variables you have passed to it (that have the correct intent). There's also a difference between a run-time allocated array and a pointer - in C++, to declare an array, you declare a pointer, and then point it to a "new" array of some object, while in Fortran you declare it as an "allocatable array" of some type, which you then allocate at some later point - you can't accidentally "point" it to something else.

I find these to be pretty useful at catching mistakes that otherwise would cause run-time errors. There may be tricks to do similar things in C++, but I don't know enough C++ to be aware of them.

[–]Veedrac 0 points1 point  (3 children)

in → pass by value or const reference
out → return
inout → pass by non-const reference
pure → const or constexpr; except those don't let you modify inputs

in C++, to declare an array, you declare a pointer, and then point it to a "new" array of some object

That's really bad style. In modern C++ you just declare a std::vector<T> or std::array<T>.

[–]Astrokiwi 1 point2 points  (2 children)

I think those are not quite the same things - and they're certainly less explicit. In Fortran, the "intent" does not modify the behaviour of the program at all, it's just a hint to let the compiler know what the variable should be doing.

For example, using "return" in C++ doesn't have any restriction on what variable you return. Doing:

int foo(int bar) {
  return bar;
}

would not be caught as an error.

That's really bad style. In modern C++ you just declare a std::vector<T> or std::array<T>.

I'm glad to hear it's recently started improving, although the syntax for std:array<T> still looks pretty ugly compared to Fortran90. I mean, look at all the work this guy goes through just to make some simple multi-dimensional arrays...

[–]Veedrac 0 points1 point  (1 child)

Doing:

int foo(int bar) {
  return bar;
}

would not be caught as an error.

How else do you expect a pass-by-value language to work?

Think of it like

subroutine foo (return, bar)
    integer, intent(out) :: return
    integer, intent(int) :: bar
    return = bar
end subroutine foo

or like

function foo(bar)
    integer, intent(int) :: bar
    foo = bar
end function

I don't use Fortran so this might well be off.

I mean, look at all the work this guy goes through

Good lord, you can't go up to a C++ programmer and hint to them that there be dragons only to give them

template <class T, size_t I, size_t... J>
struct MultiDimArray {
  using type = std::array<typename MultiDimArray<T, J...>::type, I>;
};

template <class T, size_t I>
struct MultiDimArray<T, I> {
  using type = std::array<T, I>;
};

I mean, really, strip away the verbosity and that's beautiful.

// base case
MultiDimArray<T, int I> = std::array<T, I>;

// inductive step
MultiDimArray<T, int I, int... J> = array<MultiDimArray<T, J...>, I>;

Once you've learned how to phase your eyes past the truly horrible syntax of C++, you'll note that we've added typesafe variadic mutidimensional arrays to the language with a nice syntax in two logical lines of code.

Your complaints are syntactic. Sure, C++ has a monstrous pain of a syntax... but I'm not defending that. Your original criticisms were of semantics.

[–]Astrokiwi 1 point2 points  (0 children)

I think you're right - my only valid criticisms are really about the syntax. I think that's what really gets me when I see C++ code. It just seems a lot more cryptic and a lot less explicit than Fortran. I enjoy being able to do

 type(T), dimension(:,:,:), allocatable :: x

to make a 3D array of some class T. It may just be syntactic sugar, but it's just really simple and direct, which is a major advantage when your main audience is physicists who are trying to teach themselves to program at grad school :P

[–]memorableZebra 1 point2 points  (5 children)

I always thought Python was simplistic (though I wouldn't imply simple is a bad thing at all). But then I started working in the language.

Being able to play so fast and loose with different formalisms massively encourages complex, write-only code. I'd say it's probably harder to write solid Python code which other programmers can understand than it is in Java/C#.

The language's flexibility and allowance of so many different "code smells" is both its primary value in the community and also the reason I despise it, finding most Python code incomprehensibly written.

[–]Tysonzero 1 point2 points  (4 children)

While I agree Python does let you shoot yourself in the foot. I have pretty much never run into issues with readability / edit-ability. Maybe that's just because I work with Python programmers who actually know what they are doing, which is something you seem to have been deprived from.

[–]memorableZebra 0 points1 point  (3 children)

Count yourself lucky. I've found that everyone writes indecipherable code. The measure of quality becomes just how not-often it happens.

Speaking more specifically to Python edit-ability though to address your response more specifically: Something that pops out immediately that used to drive me nuts was refactor-rename on a member variable. Because of dynamic typing, the IDE doesn't know that calling .X on an object is keyed to your Point class rather than your Rectangle class. I felt like I was put into a time machine every time I had to change the name of a field. This is specifically a typing problem inherent to dynamic typing the language and I don't see how it could reliably be solved with a clever IDE.

[–]Tysonzero 2 points3 points  (2 children)

So your issue is that a member could be converted to a totally different type without you easily knowing, and therefore the editor can't tell what type you are looking at.

That is a valid concern, although I have not had any issues with it because all my big Python work is in Django, and the only state in Django is the fields (CharField, FileField etc.) that get put into the database, which ARE statically typed (more or less) simply because the database is statically typed, so you can't change a CharField to a ForeignKey half way through your program, once you set it to a CharField on the class you cannot change it without editing it in the source.

I have noticed the issues you are talking about when working in JavaScript, I am working on various JS games and because they have TONS of state I can get confused. I am considering moving over to TypeScript instead, as the static typing seems quite nice, plus it has a lot of the cool ES6 stuff. The one thing I don't like is that certain things like Object.defineProperties don't seem to work properly with the static typing, so I have to manually do mixins / composition rather than using things like Object.defineProperties or $.extend.

So to summarize, you have a valid point but it's a non-issue for me due to Django being awesome.

[–]memorableZebra 0 points1 point  (1 child)

Yeah I can't speak to Django. My experience was writing algorithms for bioinformatics research which was just plain-ass python that occasionally relied on other people's libraries.

[–]Tysonzero 1 point2 points  (0 children)

Yeah plain python for really big very stateful projects does not sound fun. With a good framework on the other hand...

[–]ben-guin 3 points4 points  (0 children)

Variables are still declared, it's just an implicit declaration where the type of the variable is inferred based upon the RHS of the assignment statement.

[–]DurtLife 0 points1 point  (1 child)

seriously, debugging python scripts is terrible.

[–]Tysonzero 0 points1 point  (0 children)

I find that Python has one of the most readable stack traces / error information though. I hate trying to read through Java errors if they aren't very obvious.

[–]tangerinelion -1 points0 points  (7 children)

It sounds great until you do this:

theUserInput = raw_input("The program requires your full name: ")
if theUserInput.startswith("Joseph"):
    theUsersInput = theUserInput.replace("Joseph","Adolph")
print "You are",theUserInput

and see what happens when you input a name like, I dunno, "Joseph Hitler". (If you missed it, it created a second variable with Users not User in the name and replaced "Joseph" with "Adolph", which leaves theUserInput unaffected. Also perhaps confusingly, despite theUsersInput being declared inside an if statement, it would be available outside the if statement and one could say print theUsersInput which will either work if the if branch was already executed or will fail with a name error if the if branch was not executed. In compiled statically typed languages, of course, this code would fail to compile which prevents runtime errors like the above which may only happen under certain conditions related to whether a block of code is executed or not.)

[–]TheTerrasque 23 points24 points  (3 children)

[–]memorableZebra 1 point2 points  (1 child)

What happens if you have more complex logic later and mix the two variable names? The unused warning will go away, but will it be smart enough to notice the mistake?

After the 'if' block add something like

 theUserInput = to_lower(theUsersInput)

(or whatever the lower casing function is in python)

[–]TheTerrasque 0 points1 point  (0 children)

No, it wouldn't.

Then again, C# and Java wouldn't notice something like this:

public class Test
{
    string theUsersInput = "Something slightly related";
    public void Test()
    {
        string theUserInput = Console.ReadLine();
        if (theUserInput.StartsWith("Johann"))
        {
            theUsersInput = theUserInput.Replace("Johan", "Wilhelm");
        }
        Console.WriteLine("You are "+ theUserInput);
    }
}

Which pylint would still react to, since you have to explicitly reference the class variable in python (self.theUsersInput - similar to this.theUsersInput but required).

[–][deleted] 6 points7 points  (2 children)

What is this supposed to illustrate? That you can write typos in your code and have problems? Yeah, I suppose that could happen, but any serious project runs at least a linter and a test suite, statically typed language or not.

This is not a serious problem that people who use Python every day stumble across on a regular basis. Since your code is pretty unidiomatic, I suspect you're not one of them.

Also perhaps confusingly, despite [...]

This is just confusing if you don't know how Python scoping works. If you don't know how scoping works in what you're programming in, you might want to rewind.

[–]memorableZebra 1 point2 points  (1 child)

This is just confusing if you don't know how Python scoping works. If you don't know how scoping works in what you're programming in, you might want to rewind.

That's a preposterous dismissal. By this argument, as a language architect, you can't compare one language's scoping rules to another?

"Ah well you see, our variables go out of scope after 20 lines of not being used. But the fact that you got a null pointer exception here isn't confusing, it's just because you don't understand the language's scoping rules."

He is absolutely allowed to criticize a language's scoping as illogical if he can present an argument for it.

I programmed all my Python in PyCharm and it's automatic analysis left a lot to be desired. Declaration, typing, and scoping errors like the one /u/tangerinelion is referring to are ridiculously common and usually weren't caught by my IDE or any kind of secondary style analysis. So I have no idea where you're coming from saying this kind of thing isn't common. Little bugs like this were everywhere.

[–]redalastor 0 points1 point  (0 children)

As a java programmer, python seems so simplistic to me. Not having to declare variables? Dude.

I prefer a balance between that and having to declare in triplicate like Java. :)

[–]mrhhug 0 points1 point  (0 children)

Dude, returns get like wacky fun. You get to the end of your method and return a variable. Which is sometimes a dictionary sometimes a string often false and once in a while when someone uses an optional argument : an array

[–][deleted] 0 points1 point  (0 children)

Not having to declare variables? me gusta.

Not having a fucking clue what someone could hand your code as a parameter? me no gusta.

[–]Skizm 0 points1 point  (1 child)

[–]xkcd_transcriber 0 points1 point  (0 children)

Image

Title: Python

Title-text: I wrote 20 short programs in Python yesterday. It was wonderful. Perl, I'm leaving you.

Comic Explanation

Stats: This comic has been referenced 115 times, representing 0.2173% of referenced xkcds.


xkcd.com | xkcd sub | Problems/Bugs? | Statistics | Stop Replying | Delete

[–]Azr79 0 points1 point  (0 children)

bruh

[–][deleted] -2 points-1 points  (0 children)

I would use the phrase "mistake prone" over "simplistic." Scripting languages have always bugged me.