I can open up a text editor and start writing C, or Java, or Perl, or PHP - all without that much thought on whitespace, indentation etc. I can later run indent -kr, or perltidy, or astyle and so forth and make the code I banged out look nice and tidy. Sometimes I feel like doing the nice indentation myself while coding, sometimes I do not and let the scripts do it. With Python "there is one way to do it" and you have to think about indentation while coding. It is annoying. It is like Java and exceptions, forcing me to put try/catch loops everywhere and messing up my scope - even for a little prototype program which will be run once and will never need to catch an exception. It is treating me like I am an idiot and forcing me to work in a regimented manner.
When I first learned Python, at one point I decided to put a do/while loop in my program. I was not able to discover how this was done in documentation. I go on IRC #python and am told Python has no do-while loops (which I later confirmed is true). I was told, and I am assuming the source knows more than me, that this is due to the indentation system. One screwy thing done as a result of another screwy thing.
There are a lot of nice things about Python. The code is clean and understandable. It sometimes allows you to do in 2-3 lines what might take 10 lines in another language. And so on. But some programmers feel certain aspects of it are drawbacks, and these things are not easily dismissable. If they were, they would not be brought up again and again.
while(some_condition):
do_stuff do_stuff
while(some_condition):
do_stuff
The advantage of do/while in this situation is avoiding the duplicate code. while True:
codeHere()
if shouldStop():
break do_stuff
while(some_condition):
do_stuff[1] E.g.:
int main() {
}
vs. int main()
{
}
This is an apt analogy because most companies will have some sort of code style guide that you have to follow, which doesn't make "coding at company X where bracket placement is enforced" much different from "coding in Python where whitespace is enforced."I've yet to come across someone that had a severe hatred of Python due to the significant whitespace that was a programmer I respected. The last person that I knew (who had a visceral hatred of Python whitespace) wrote Perl code like this:
sub func1 { shift->func2(shift)->func3(@_) }
or sub func1 { grep { $_[0]->func2($_) } $_[0]->func3() }
Note: These are literally code samples with the function names changed.I don't know any Perl programmers that would condone this sort of code. It's a maintenance nightmare, especially since these were not one-off instances. Seems to me that the people that have a hatred of Python's handling of whitespace don't like being 'constrained' by their language, and are probably happier with Ruby or Perl.
I wrote some code with lots of nameless functions as input parameters (think JavaScript style or Ruby blocks), which of course was an ugly pain to port to Python with no multi-line lambdas.
List comprehensions is another example -- a kludge coming from that the lack of multi instruction lambdas stop real map functions. (The fun part is that this necessity is touted as something good, instead of admitting that it is unnecessary complexity to learn.)
If you're trying to fight the language's style, then you will obviously run into friction. I'm sure there are plenty of people coming from C/C++/Java that think that dynamically-typed languages are unusable because type can't be enforced at 'compile time.' Defining an anonymous function vs. a one-time use local function is mostly a matter of style/preference[1].
| which of course was an ugly pain to port to Python with
| no multi-line lambdas
There are two things you are describing here:1) It was a pain to name all of these anonymous blocks.
2) The idea of naming the blocks is annoying / aesthetically displeasing to you.
#1 is just part of porting something between different languages. You would equally run into issues porting JS and/or Ruby code to Haskell, even with support to lambdas. #2 is just personal opinion / preference, even if it's one that shared by many.
| (The fun part is that this necessity is touted as
| something good, instead of admitting that it is
| unnecessary complexity to learn.
I could use the same argument to rail against statically-typed languages. "A type system is just unnecessary complexity to learn."[1] I welcome examples of where anonymous functions are unable to be replaced by local functions passed by reference.
Uh... different paradigms. The scripting languages, which we are talking about here, are generally very similar.
>> I welcome examples of where anonymous functions are unable to be replaced by local functions passed by reference.
Where did I write "unable" -- did I disprove some Turing machine theorem and forget about it? :-)
In this specific case it was a declarative data structure with some data next to code. It was well suited to have a dozen or two short functions next to the data structures.
You could rethink the whole thing and do something different in Python to keep it readable. But among the normal languages (in the same paradigm), Python is the odd man out, just because of the lack of multi line lambdas.
(I also gave the example of bad influences on map, etc.)
| >>Ruby code to Haskell
|
| Uh... different paradigms. The scripting
| languages, which we are talking about here,
| are generally very similar.
Different languages are different, no matter how
many similarities that they have. You are going
to run into issues porting between languages.
Expecting anything else is setting yourself up for
disappointment.C++ and ObjC are both 'C-based', so there should be zero issues porting code between them, right? French and Spanish are both Latin-based, so they are practically the same language, right?
| >> I welcome examples of where anonymous
| >> functions are unable to be replaced by
| >> local functions passed by reference.
|
| Where did I write "unable" -- did I disprove
| some Turing machine theorem and forget about it?
| :-)
Poorly worded on my part. | In this specific case it was a declarative
| data structure with some data next to code. It
| was well suited to have a dozen or two short
| functions next to the data structures.
|
| You could rethink the whole thing and do
| something different in Python to keep it
| readable. But among the normal languages (in
| the same paradigm), Python is the odd man out,
| just because of the lack of multi line lambdas.
1. The inclusion of multi-line lambdas in a
language is what makes it 'normal'? This just
seems more like a personal opinion than anything
objective. I could easily say that Ruby is the
odd-man out and Perl/Python are the 'normal'
languages, because of this: a = 0
if a
puts "Evaluates to True"
end
Or Perl is the odd-man-out and Ruby/Python are the
'normal' languages because they have a GIL.2. If keeping the data structure and functions together was the best use-case, then maybe Python wasn't the tool for the job. Just like I wouldn't talk about how crappy Ruby is because it doesn't have SciPy/NumPy.
All the scripting languages are very, very similar (see data structures, etc).
In short, you don't argue against my point.
My point was that Python stops multi-line lambdas for some weird purity argument re white spaces (I haven't found any other motivation).
This hurts quite a few use cases (for a 2nd -- copy paste and automatic indentation of code is at least more complex, and so on) and makes it necessary to learn weird syntax (list comprehensions), which incidentally is touted as the next coming of Christ...
And the inability to admit a wart on Python is quite typical -- didn't Guido tell you guys to stop trolling recently, because you were getting bad reputation..?
>> Or Perl is the odd-man-out and Ruby/Python are the 'normal' languages because they have a GIL.
These three are all similar -- avoid threading. :-(
Not that it is relevant for my original point, either.
Perl gets a bad rep on threading because it's threads don't map to what many people consider the strong points of threads, which is light weight processes. Perl fails spectacularly in that regard, but if you want multi-process programming with a standard, well understood set of primitives for IPC, it's really quite nice. That is, the 'threads' module isn't all that great by itself, but when paired with 'threads::shared', it's really quite nice (as long as you are pre-spawning workers or don't require quick thread spawning).
For example, I love how locks are scope based, which makes the following possible:
my $local_var = do { lock($lock_var) }
as well as: {
lock($sync_var);
$sync_var = "start!";
cond_broadcast($sync_var);
}> I wrote some code with lots of nameless functions as input parameters (think JavaScript style or Ruby blocks), which of course was an ugly pain to port to Python with no multi-line lambdas.
As nnq points out elsewhere in this thread, this doesn't have anything to do with significant whitespace. Python only allows you to have a single expression in the body of a lambda, and from what I've read the reason it stays this way is to discourage using a lambda as an argument to map, fold, filter & friends. The usual suggestion from Python programmers is to just use a locally defined, named function, which to be honest is often what I do anyway in languages like ML, because it's clearer.
And anyway, just because it was hard to port some code from language A to language B due to something different about B doesn't really seem like a valid knock against B.
If you REALLY can give good references that show this is wrong, I'm very interested (like, I would guess, most Ruby users).
(It would also be interesting with a link to a PEP or something with, as you claim, arguments that map etc should be discouraged -- and that is why no multi line lambdas exists. For instance, how would the syntax look like??)
You made specific claims (regarding map recommendations in Python and that white space has nothing to do with one instruction lambdas). I asked for references. I assume you have none?
Note that with significant white space a usable syntax for multi-instruction lambdas seems... non-trivial. It seems to me as an unusually stupid fan boy position. But a few well argued references, which you lack, would change my mind. I'm no troll.
Edit: I might also note that your reference nng is a low-Karma account that argues that a cometing open source language to his love child is dead -- typical language war troll. Is that your only reference?
Please relax... no tool is perfect for all situations. It is always a trade off.
Also, welcome to HN (or are the prepared troll accounts with a few hundreds of Karma running out? :-) ).
You asked about multi-line lambdas in python and I gave you a valid Python syntax for multi-line anonymous functions. Here is PEP 202, which simply says list comprehensions are more concise than for loops and map/filter etc.
http://www.python.org/dev/peps/pep-0202/
RE: accounts - I delete all of my accounts on social websites once a year.
| (or are the prepared troll accounts with
| a few hundreds of Karma running out? :-) )
Keepin' it classy.I might also note that I got two non sequitur answers in a row, so a joke like that is imho not an extreme reaction. Hardly as sarcastic as you was over a joke, at least...
Edit: I might also note that this article (76 votes) is 5 places below another roughly equally old article (8 hours) with 13 votes. So it is probably flagged to Hell. I do feel classy, compared to some others.
For most things as an hiring manager I'm OK with people working with their favourite language on whatever project I assign them to (as long as it isn't too esoteric; OCaml is OK, but Haskell is probably pushing it a bit too far, for instance), except when they have to work on an existing code base, in which case I wouldn't want to hire someone hating it; they'd be miserable and the resulting code would be awful.
There are many valid technical reasons to rather choose C than Python, Java than Perl, or PHP than Go, Erlang rather than C++ ...
But Perl vs Python vs Ruby? Hardly any difference, extremely similar dynamic languages. It's only a matter of personal taste at this point.
I think it's quite reasonable to be suspicious of a interviewee who is against Python solely because it enforces sensible code indentation.
Though saying "I don't like python's code indentation" is not the same as "I'm against python". Well, at least I see no relation between the two.
There are a numbers of things to dislike about Python; however, after you used the language for a while, you realize significant white space isn't one of them. It is like saying lisp's parentheses are ugly: sure, you might not like them, but they are a huge reason the language (and, really, the way of thinking about code) is so powerful.
(Non)Problem solved.
Not to mention you should indent your code exactly the same way (in a consistent format, either tabs or spaces) with how you'd indented Python code.
print(reduce((lambda x, y:
x + y), xrange(10)))
print(reduce((lambda x, y: x + \
y), xrange(10)))
HINT: It runs.I'm using Python from time to time, but I wouldn't spontaneously use it for my personal projects, I prefer Perl for that.
The only languages I really wouldn't want to work with is Java.
doesn't
care
how
much
whitespace appears between words, only that there's more than none. Python definitely cares how much.
Don't get me wrong -- I like Python and I use it a lot, but its reliance on syntactically significant whitespace isn't in the plus column.
English has well-defined whitespace rules, as does nearly every programming language. Every programming language style guide I've ever read has talked about indentation, so you have to indent according to rules no matter which language you use.
Have you ever thought to yourself, "wow, there's no way I'll be able to finish this task on time because I have to indent according to Python's rules"? I'm guessing no.
True, but it's because changing the whitespace doesn't break the prose. But in Python it certainly breaks the code.
> so you have to indent according to rules no matter which language you use.
Sort of. I've written any number of programs in languages that use braces as delimiters, but very lazily, then used a beautifier to fix things up at a keystroke.
I agree with your point that the source must eventually follow accepted formatting, but it's not true that I necessarily need to pay attention to that (as I do in Python).
Some of the better beautifiers even enforce optional style choices, like turning this:
function_name(variables)
{
Into this: function_name(variables) {
Automatically.The latter style has pretty much taken over since I started programming 40 years ago, to the degree that I've come to like it.
I emphasize I like Python and I find its advantages far outweigh the whitespace issue on my personal radar.
> Have you ever thought to yourself, "wow, there's no way I'll be able to finish this task on time because I have to indent according to Python's rules"? I'm guessing no.
You're right, but only because my editor automatically manages Python indentations in most cases, so I don't think about it any more.
The one caveat are Python source files that, from time to time and for various reasons, get infested with tabs. Then things get complicated as I try to get rid of the tabs without destroying the program's logic. IMHO tabs should be outlawed.