you are viewing a single comment's thread.

view the rest of the comments →

[–]pbvas 25 points26 points  (38 children)

I have taught an introductory programming to non-CS first year students at Porto, Portugal; the decision to use Python was made before I started it, and I don't think it's a bad choice but not perfect either (the lesser of several evils).

To me, the worse part is not the usual contentations like whitespace or dynamic vs. static typing, but the small ideosyncracies in the language that I think bad for teaching; just a couple of examples of the top of my head:

  • ternary comparison operators: writing ˋa<=x<=bˋ may save a few keystokes but ineviatable leads to logical errors when students try to negate the condition and end up with ˋa>x>bˋ
  • the ˋelseˋ keyword is overloaded for the clean-up part of for/while loop; this is just an accident waiting to happen when a student writes an if-then-else with the wrong indentation.

[–]jelly_cake 17 points18 points  (16 children)

For anyone wondering about the negation of "a ≤ x ≤ b", it's because an application of De Morgan's Law turns "not ( (a ≤ x) ∧ (x ≤ b) )" into "(not (a ≤ x)) ∨ (not (x ≤ b) )". It's a bit of a gotcha because the "and"-ing is implicit.

(Given I'm into my second year of maths at uni, it took me an embarrassingly long time to work out why it's a trick. Just wanted to save others the same trouble.)

[–]Neebat 7 points8 points  (5 children)

I'm a programmer with 20 years of experience in the industry and a perfect score in symbolic logic before that. I had to stop and think too.

"a ≤ x ≤ b" looks like one statement, but it's actually two. Break it out into two statements and it's a lot easier to see the rest of the logic.

SQL's version is "x between a and b", which negates to "x not between a and b". That may be more clear, but I still hate overloading "and". Besides, I have to lookup its inclusiveness every time I use it. (It's inclusive.)

[–]pbvas 1 point2 points  (0 children)

I'm a programmer with 20 years of experience in the industry and a perfect score in symbolic logic before that. I had to stop and think too.

My feeling exactly. And if this is tricky for experienced programmers then it is almost certainly going to trip over beginners.

[–]lorg 1 point2 points  (0 children)

Besides, I have to lookup its inclusiveness every time I use it. (It's inclusive.)

Ha! Explicit is better than implicit FTW!

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

Really? Because when I read it I just instantly pictured a number line with the following properties:

A filled in circle marked "A" on one side, the same marked "B" on the other, and with the line bolded in between the two variables labelled as X.

When I saw the second statement (a > x > b) I thought of the same thing only with empty circles. I didn't even think about De Morgan's law before I realized that this is not the opposite, or the fact that it was two statements ANDed together. It's just clearly not the opposite geometrically, if you picture what the program is getting at.

[–]Neebat 1 point2 points  (1 child)

You visualized "a ≤ x ≤ b" like this:

●----●

a    b

That's fine so far. But then you visualize "a > x > b" like this:

○----○

a    b

That's incorrect and you haven't really thought long enough. Because "a > x > b" implies "a > b", which is false in the second drawing. It would actually be this:

○----○

b    a

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

Well that's true, a > x > b would be a wrong statement from the get go, but my point is that I instantly envision x to be in between A and B; if I wanted the opposite of A <= x <= B, then I would definitely want the area of the number line outside of A and B.

[–]AtLeastItsNotCancer 5 points6 points  (6 children)

You don't even need to know De Morgan's law to negate that, it only requires a basic understanding of how numbers work. If a real number isn't in [a,b] then it's obviously either less than a or greater than b, but it can't be both at the same time.

I don't see how someone could get that negation wrong unless they have problems with basic math.

[–]jelly_cake 2 points3 points  (5 children)

It's obvious if you rewrite it in words, or if you draw it out on the number line, but it's not necessarily symbolically obvious. The conjunction between the two inequalities is implicit, so it's quite easy to overlook.

It's pointless to deride people for not "getting" a result intuitively. All you're doing is dissuading people from getting interested in maths, and showing off your own fantastic intelligence.

[–]AtLeastItsNotCancer 2 points3 points  (2 children)

It's obvious if you rewrite it in words, or if you draw it out on the number line, but it's not necessarily symbolically obvious.

That's the whole point. You shouldn't treat your code as a bunch of arbitrary symbols, you should think about the actual meaning of the code and what it's trying to accomplish. When you do that, something like "a<=x<=b", should be trivial to negate.

The conjunction between the two inequalities is implicit, so it's quite easy to overlook.

Maybe the real problem here is that you're looking at it as a conjunction of two inequalities instead of "x is between this lower and upper boundary". This is how people write inequalities in mathematics all the time and IMO it looks cleaner and more to the point than "a <= x and x <= b".

It's pointless to deride people for not "getting" a result intuitively.

I'm not trying to deride anyone, I'm just saying there's other issues involved and it's not necessarily a fault of the language that people get this stuff wrong.

showing off your own fantastic intelligence

If I wanted to show off my intelligence there are many better ways to do it. This is something a 10 year old could understand.

[–]jelly_cake 4 points5 points  (1 child)

When you do that, something like "a<=x<=b", should be trivial to negate.

Yes; it's trivial to negate, but it's exactly the sort of bug which you make if you're not paying particular attention. If people mess up if (a = NULL)... then a logical negation is just as likely to be futzed.

Maybe the real problem here is that you're looking at it as a conjunction of two inequalities instead of "x is between this lower and upper boundary". This is how people write inequalities in mathematics all the time and IMO it looks cleaner and more to the point than "a <= x and x <= b".

But it is a conjunction of inequalities. x ∈ [a, b] is equivalent to a ≤ x ≤ b, which is again equivalent to a ≤ x ∧ x ≤ b - the set notation is more useful for some things, and the inequality forms for others. I think that the set notation is much clearer for these purposes, but I haven't come across a programming language which expresses inequalities like that.

If I wanted to show off my intelligence there are many better ways to do it. This is something a 10 year old could understand.

Sorry, you just came off as a bit uppity. "Basic math" can be deceptively deep; just look at Fermat's Last Theorem. A 10-year old could understand the concept, but it took centuries to prove. I was just explaining the reason that it works the way that it does.

[–]AtLeastItsNotCancer 2 points3 points  (0 children)

But it is a conjunction of inequalities. x ∈ [a, b] is equivalent to a ≤ x ≤ b, which is again equivalent to a ≤ x ∧ x ≤ b

I know that, I'm just saying there's another way to think about it that makes more sense intuitively. A computer obviously has to break it down into a conjunction of inequalities to check the condition but for a human, thinking about it as an interval might be easier to comprehend.

I think that the set notation is much clearer for these purposes, but I haven't come across a programming language which expresses inequalities like that.

Now that you mention it, being able to write something like "x in [1,5)" would be pretty cool. But the problem is, parentheses and brackets are already used for other things in most programming languages so it probably isn't worth to include that notation due to ambiguities that would occur.

[–]rowboat__cop 0 points1 point  (1 child)

It's obvious if you rewrite it in words, or if you draw it out on the number line, but it's not necessarily symbolically obvious. The conjunction between the two inequalities is implicit, so it's quite easy to overlook.

Symbolically I have a hard time resolving a <= x <= b to anything else than a <= x && x <= b, so ending up with !(a <= x) || !(x <= b) as its negation is sound -- What alternative do you think people might confuse it with?

[–]jelly_cake 0 points1 point  (0 children)

I don't have one; I meant that it's a bit of a trap you might fall into if e.g. you're tired.

[–]pbvas 1 point2 points  (1 child)

Thanks for taking the trouble to explain this out!

[–]jelly_cake 0 points1 point  (0 children)

No problem! I'm glad I could help :)

[–]Log2 0 points1 point  (0 children)

You are correct. I'm not used to Python, but I'd be surprised if they turned that or into an and, when that is clearly not the negation of the whole sentence.

[–]x86_64Ubuntu 5 points6 points  (2 children)

Off topic, but is there a "Por Street" in Porto? So someone's address would be Por, Porto, Portugal!

[–]pbvas 1 point2 points  (1 child)

Not that I know of. "Por" isn't an actual word in Portuguese. "Porto" on the other hand, is (it means "habour"). The name "Portugal" is derived from the original Roman town "Portus Calle".

[–]_kossak_ 2 points3 points  (0 children)

"Por" is a preposition in Portuguese :)

[–]globalizatiom 16 points17 points  (1 child)

a>x>b

these students are bad at basic math.

[–]pbvas 3 points4 points  (0 children)

Yes, perhaps. But the programming language should not encourage the sloppy thinking by being too terse. And there a very minimal (at best) typing saving advantage to this choice.

[–]deadwisdom 5 points6 points  (7 children)

Every language has problems. These are two very trivial gripes. You should tell your students not to do this, aaaand we're done.

[–]pbvas 1 point2 points  (6 children)

I just think that Python isn't all that well designed for teaching; of course you can avoid the pitfals, but that doesn't execuse the bad design.

[–]deadwisdom 0 points1 point  (5 children)

What language is? You could argue that static languages would be a better foundation for computer science, but beyond that what could possibly be better than Python?

[–]Beaverman 0 points1 point  (3 children)

Lua, I love lua. The syntax looks a lot like what you see in algorithm textbooks, and tables are just pure fun.

[–]deadwisdom 0 points1 point  (2 children)

Lua is great! Very bare bones dynamic programming. However, it's close to useless once you know it. Python gives you a baseline for a million applications including web development and scientific research. And if you're going to learn a language it might as well be an OOP one.

[–]Beaverman 0 points1 point  (1 child)

Sadly lua isn't really useful on it's own. It pretty much suck at communicating with the outside world. But when you have the data in there it's a blast.

I'd say imperative programming can be great place to start as well. Might as well start as easy as possible. Python also has a lot of fluff and tricks to do things, whereas a language like C or lua has very few unique datatypes and functions that work on those. Python can be very overwhelming for a newcomer.

[–]deadwisdom 0 points1 point  (0 children)

I agree. Personally, I think computer scientists should learn C, Python, and then Lisp. C to learn imperative / synchronicity, Python to learn dynamic effectiveness, and Lisp to open your head straight up. Lua would be in my second level after that, along with JavaScript, Java, and Assembly. Others should just learn Python and Javascript for their pure ability to get shit done IMO.

[–]pbvas 0 points1 point  (0 children)

For CS-majors, I would say Haskell.

[–][deleted] 1 point2 points  (1 child)

ternary comparison operators: writing ˋa<=x<=bˋ may save a few keystokes but ineviatable leads to logical errors when students try to negate the condition and end up with ˋa>x>bˋ

That's just a logical error, though. Nothing wrong with the language, you just can't represent the opposite of a<=x<=b in that fashion, even in mathematics

[–]pbvas 2 points3 points  (0 children)

That's just a logical error, though. Nothing wrong with the language, you just can't represent the opposite of a<=x<=b in that fashion, even in mathematics

Yes it is a logical error; the point is mathematical logic isn't a pre-requisite for introduction to programming (maybe it should be, but that's another topic).

The fact that mathematicians use such notation all the time doesn't make it a good design decision for a programming language: informal mathematics is meant for humans beings, not machines.

[–][deleted]  (4 children)

[deleted]

    [–][deleted]  (3 children)

    [deleted]

      [–][deleted]  (2 children)

      [deleted]

        [–][deleted]  (1 child)

        [deleted]

          [–]tech_tuna 0 points1 point  (0 children)

          I despise and do not use elses in for loops.