[Tutor] Volunteer teacher

avi.e.gross at gmail.com avi.e.gross at gmail.com
Tue Jul 26 13:19:23 EDT 2022


The way I recall it, Alan, is that many language designers and users were
once looking for some kind of guarantees that a program would run without
crashing AND that every possible path would lead to a valid result. One such
attempt was to impose very strict typing. You could not just add two numbers
without first consciously converting them to the same type and so on.
Programming in these languages rapidly became tedious and lots of people
worked around them to get things done. Other languages were a bit too far in
the other direction and did thigs like flip a character string into a
numeric form if it was being used in a context where that made sense.

My point, perhaps badly made, was that one reason some OOP ideas made it
into languages INCLUDED attempts to do useful things when the original
languages made them hard. Ideas like allowing anything that CLAIMED to
implement an INTERFACE to be allowed in a list whose type was that
interface, could let you create some silly interface that did next to
nothing and add that interface to just about anything and get around
restrictions. But that also meant their programs were not really very safe
in one sense.

Languages like python largely did away with some such mathematical
restrictions and seem easier to new programmers because of that and other
similar things.

I remember getting annoyed at having to spell out every variable before
using it as being of a particular type, sometimes a rather complex type like
address of a pointer to an integer. Many languages now simply make educated
guesses when possible so a=1 makes an integer and b=a^2 is also obviously an
integer while c=a*2.0 must be a float and so on. Such a typing system may
still have the ability to specify things precisely but most people stop
using that except when needed and the language becomes easier, albeit can
develop subtle bugs. What makes some languages really hard to understand,
including some things like JAVA, is their attempt to create sort of generic
functions. There is an elusive syntax that declares abstract types that are
instantiated as needed and if you use the function many times using the
object types allowed, it compiles multiple actual functions with one for
each combo. So if a function takes 4 arguments that call all be 5 kinds, it
may end up compiling as many as 625 functions internally. 

Python does make something like that much easier. You just create a function
that takes ANYTHING and at run time, the arguments arrive with known types
and are simply handled. But the simplicity can cost you as you cannot
trivially restrict  what can be used and may have to work inside the
function to verify you are only getting the types you want to handle.

You make some points about efficiency that make me wonder. There are so many
obvious tradeoffs but it clearly does not always pay to make something
efficient as the original goal for every single project. As noted, parts of
python or added modules are often written first in python then strategic
bits of compiled code are substituted. But in a world where some software
(such as nonsense like making digital money by using lots of electricity)
uses up lots of energy, it makes sense to try to cut back on some more
grandiose software. And it is not just about efficiency. Does a program need
to check if I have new mail in a tight loop or can it check once a second or
even every ten minutes?

I am getting to understand your viewpoint in focusing on ideas not so much
implementations and agree. The method of transmitting a message can vary as
long as you have objects communicating and influencing each other. Arguably
sending interrupts or generating events and many other such things are all
possible implementations. 

I think the ability to try to catch various errors and interrupts is part of
why languages like python can relax some rules as an error need not stop a
program.

Heading out to the beach.



-----Original Message-----
From: Tutor <tutor-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of
Alan Gauld via Tutor
Sent: Tuesday, July 26, 2022 5:22 AM
To: tutor at python.org
Subject: Re: [Tutor] Volunteer teacher

On 26/07/2022 04:03, avi.e.gross at gmail.com wrote:

> <AG-UK> As I said in an earlier post you can do OOP in most any language.
> 
> I differentiate between using IDEAS and code built-in to the language 
> meant to facilitate it. If you mean you can implement a design 
> focusing on objects with serious amounts of work, sure.

That's exactly what I mean. My point is that OOP is a style of programming
not a set of language features (that's an OOPL). It's the same with
functional programming. You can discuss how languages like ML, Lisp, Haskell
or Python implement functional features but you cannot fully discuss FP
purely by using any one of those languages.
And you can write non FP code in any of those languages while still using
the FP features.

> <AG-UK> IME. I'm not saying that nobody has a genuine use for a 
> strictly homogenous container, just that <AG-UK> I've never needed 
> such a thing personally.
> 
> What I was talking about may be subtle. There are times you want to 
> guarantee things or perhaps have automatic conversions. ...

Sure, and I have used arrays when dealing with code from say C libraries
that require type consistency. But that's a requirement of the tools I'm
using and their interface. Efficiency is another pragmatic reason to use
them but I've never needed that much efficiency in my Python projects.

> I will note that many programming languages that tried to force you to 
> have containers that only held on kind of thing, often cheated by 
> techniques like a UNION...
> Languages like JAVA and others inheriting from a common ancestor

That's how most OOPL programs work by defining a collection of "object"
and all objects inherit from "object". And generics allow you to do the same
in non OOPLs like ADA.

> I won't quote what you said about Python being simple or complex 
> except to say that it depends on perspective. As an experienced 
> programmer, I do not want something so simple it is hard to do much 
> with it without lots of extra work.

Sure, and Guido had to walk the tightrope between ease of use for beginners
and experts. In the early days the bias was towards beginners but nowadays
it is towards experts, but we have historic legacy that clearly favours the
learners.

> But as a teaching tool, it reminds me a bit of conversations I have 
> had with my kids where everything I said seemed to have a reference or 
> vocabulary word they did not know.

That's always a problem teaching programming. I tried very hard when writing
my tutorial not to use features before decribing them but it is almost
impossible. You can get away with a cursory explanation then go deeper later
but you can't avoid it completely. I suspect thats true of any complex topic
(music, art etc)

> <AG-UK> That's not OOP, it's information hiding and predates OOP by 
> quite a way.
> 
> I accept that in a sense data hiding may be partially or even 
> completely independent from OOP

> In that sense, we could argue (and I would lose) about what in a 
> language is OOP and what is something else or optional.

My point is that language features are never OOP. They are tools to
facilitate OOP. Data hiding is a curious case because it's a concept that is
separate from OOP but often conflated with OOP in the implementation.

> topic, not just see how each language brags it supports OOP. In 
> particular, your idea it involves message passing is true in some 
> arenas but mostly NOT how it is done elsewhere.

OOP is all about message passing. That's why we have the terminology we do.
Why is a method called that? It's because when a message is received by an
object the object knows the method it should use to service that message.
The fact that the method is implemented as a function with the same name as
the message is purely an implementation detail. There are OOPLs that allow
you to map messages to methods internally and these (correctly from an OOP
standpoint) allow the same method to be used to process multiple messages.

> Calling a member function is not a general message passing method,

No, but that's a language feature not OOP.
Languages like Lisp Flavours used a different approach where you wrote code
like:

(Send (anObject, "messageName", (object list))

The receiving object then mapped the string "messageName" to an internal
method function.

So the important point is that programmers writing OOP code in an OOPL
should *think* that they are passing messages not calling functions. That's
a subtle but very important distinction. And of course, in one sense it's
true because, when you have a class heirarchy (something that is also not an
essential OOP feature!), and send a message to a leaf node you may not in
fact be calling a function in that node, it may well be defined in a totally
different class further up the heirarchy.

[ And we can say the same about calling functions. That's a conceptual thing
inherited from math. It practice we are doing a goto in the assembler code.
But we think of it as a conceptual function invocation like we were taught
at high school. The difference with OOP is that message passing is a new
concept to learn (unless coming from a traditional engineering background)
whereas function calls we already know about from math class.]

> Perhaps it does make sense to not just teach OOP in Python but also 
> snippets of how it is implemented in pseudocode or in other languages 
> that perhaps do it more purely.

Certainly Booch takes that approach in his first and third editions of his
book. But even that leads to confusion between OOP and language features
(OOPLs). The essence of OOP is about how you think about the program. Is it
composed of objects communicating - object *oriented* -  or is it composed
of a functional decomposition that uses objects in the mix (the more common
case). Objects are a powerful tool that can add value to a procedural
solution. But OOP is a far more powerful tool, especially when dealing with
larger systems.

One of the best books IMHO to describe the difference in the approaches is
Peter Coad's book "Object Models, Strategies and Implementations" It's not
an especially well written book and makes some controversial claims, but the
concepts within are clearly explained. But it is written at the UML level
not code.

And of course there comes a point in almost all OOPLs where you have to drop
out of OOP thinking to use low level raw data types.
(Smalltalk and a few others being the exceptions where absolutely everything
is an object) Ultimately, pragmatism has to take over from principle and the
trick is working with OOP at the program structure level and  raw data at
the detailed implementation level. Knowing where that line lives is still
one of the hardest aspects of using any OOPL. But it is still an
implementation issue not an OOP issue.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list