I taught Python at Los Alamos National Laboratory for the second time two weeks ago, and finally found time last night to go through both sets of feedback forms. Given the current discussion on python-dev of ternary conditionals, namespaces, etc., I figured syntax issues would be most topical. Most of the students were in their 20's or 30's, with a handful in their 40's and 50's. When asked what they used on a daily basis, they split pretty evenly between Fortran and C++ (no C-but-not-C++ responses). They also divided pretty evenly between "numerical and/or visualization" and "systems programming". (At the lab, the latter means everything from making the web archive of past experimental results searchable, through to porting HDF-5 to massively-parallel machines and hacking the Linux kernel to make inter-process communication run faster.) 28 students had Ph.D.'s (all in math, physical science, or engineering); nine had M.Sc.'s (one in C.S.), and the three B.Sc.'s were all in C.S. So here goes... ------------------------------------------------------------------------- 0. "Hey, using indentation to show nesting is cool!" 'Nuff said --- thanks, Guido. ------------------------------------------------------------------------- 1. "What's with 'while 1: break' for normal loops?" This was the most common complaint about syntax --- neither Fortran nor C programmers found it natural to create an infinite loop, then jump out of it. (Several of the C++ programmers said that house style in their groups only allows 'break' for truly exceptional cases.) One student suggested the following loop-and-a-half notation: do: first-half while condition: second-half which has the nice property that both of the degenerate forms: do: first-half while condition # no trailing ':' and while condition: second-half are useful in their own right. Tim Peters tells me that this has been discussed many times before, and that the main obstacle is the introduction of a new keyword. He mentioned: while: first-half and while condition-1: second-half and while condition-2: third-half # [sic] and while final-condition # no trailing ':' as an interesting (but possibly confusing) generalization. ------------------------------------------------------------------------- 2. "Using range() in for loops is clumsy." My audience does a lot of 'for' loops over numerical bounds, and would prefer something slice-ish like: for i in 0:10:2 : body I think they could live with: for i in [0:10:2] : body I believe Brian Harvey mentions somewhere in "Computer Science Logo Style" (the best programming books for kids I've ever seen) that it was important to make basic counting loops very, very simple to write. It's a different audience (10-year-olds instead of Ph.D.'s with 30 years of Fortran behind them), but maybe worth examining. (While we're on the topic: is there an easy way to construct a slice like 3:10, pass it around as a variable, and later use it to index an arbitrary sequence?) ------------------------------------------------------------------------- 3. "Where is '+=' ?" and "Why can't I redefine assignment?" To my surprise, no-one asked why assignment wasn't an operator. However, a lot of people wanted in-place modification --- it's one of the innovations of C and derived languages that scientific programmers appreciate, since it saves them having to write 'pressure_gradient[(ix+1)*3+idx][iy-1-(idx%2)]' on both sides of an assignment, and then remember to update both occurrences when they notice the typo. (The '%' should be a '/'.) Several of the students who ticked the box "Familiar with object-oriented programming" asked why they could redefine addition, membership, etc., but not straight assignment. Guido explained the reasoning to me at IPC8, and pointed out that classes can always define a '.set(...)' method. However, I'm pretty sure that 'set()' will be a non-starter with this crowd (I can explain why if people care). ------------------------------------------------------------------------- 3.1 Min and Max On a related note, I also had requests for redefining "min" and "max" (e.g. to handle objects representing bounding volumes in 3D graphics). As a certain kind of mathematician will point out, these are really binary operators, just like "+", and it's only an historical accident that they aren't treated with the same respect (I'm quoting here). I mentioned this to Guido, and suggested the C* notation: a = x <? y # min b = x >? y # max He said (rightly) that '<?' and '>?' won't be familiar even to experienced programmers, but that user-definable 'min' and 'max' might be do-able. The only issue then is that if '+=' makes it into the language, something like 'min=' ought to as well... ------------------------------------------------------------------------- 3.2 Case Statement, and Remembering Matches in Conditionals Another related point came up in discussion of regular expressions. The code I showed them was: pat1 = re.compile(...) pat2 = re.compile(...) ...etc... while 1: line = ...get input... m = pat1.match(...) if m: code continue m = pat2.match(...) if m: code continue ...etc... Several students said that it wasn't at all clear that the various matches were intended to be mutually exclusive; one student became very frustrated trying to debug this code after accidentally deleting a 'continue'. If there's a cleaner way to structure this, I'd be grateful for an example. One student (a physicist who now does computer graphics) sent me: if x is: expr1, expr2: code using x (which is either val1 or val2) expr3: code using x (which is guaranteed to be val3) else: code using x (which is something else) which would make the above: while 1: line = ...get input... if m is: pat1.match(...): code using m pat2.match(...): code using m etc. (I'm not advocating, I'm just reporting...) ------------------------------------------------------------------------- 4. "Aren't tuples redundant?" I explained that the const-ness of tuples was needed so that they could be used as dictionary keys. The guy with Perl in his background immediately asked if that's reliable --- a tuple can contain a list, which can be mutated. You've all heard this one more times than I have... ------------------------------------------------------------------------- 5. "Why can't I put an 'except' after an 'if'?" This one surprised me. Several students wanted to be able to say: if (dict['fred'] > 0): code except KeyError: other-code or: for i in seq: i = i ** 2 except ArithmeticError: error-handling-code or even (from one guy with Perl in his background): dict['fred'] = dict['fred'] + 1 except KeyError: dict['fred'] = 1 They pointed out that 'try' does nothing except introduce a block, so why not just use the blocks that other keywords introduce? I'd be interested in knowing whether other people's students think like this... :-) ------------------------------------------------------------------------- 6. "There is no number six." That's really all that came up about Python syntax. None of the students were OO expects, so meta-classes and the like weren't raised. Generic programming did come up once, but the guy who asked hadn't clued in that typing is dynamic. The same guy also asked why he couldn't interleave anonymous and named function arguments, as in "def foo(a, b=3, c, d=5)" also came up, but everybody else who expressed an opinion said they'd find that confusing. Hope it's useful, Greg
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4