[Edu-sig] Visual Programming in Python?

Ian Bicking ianb at colorstudy.com
Fri Apr 21 22:18:06 CEST 2006

Jeff Sandys wrote:
> Ian Bicking wrote:
>>As to the merits of Logo as a language and Python as a language, 
>>I'm not sure.  Logo is grammatically simpler.  Generally it is 
>>more insulated from the underlying implementation.  It isn't 
>>burdened with ideas like "good software engineering".
> I will respectively disagree with your comments, but arguements 
> about these points would be counterproductive.

How so?

I don't have a chip on my shoulder about Logo or anything, so I'm not 
particularly set in my opinion.  (But you'd have to try hard to convince 
me that children should have to type turtle.set_pen_color((r,g,b))).

>>Jeff Sandys wrote:
>>>What I would like to see in a turtle environment comes from 
>>>StarLogo ( http://education.mit.edu/starlogo/ ).  StarLogo has 
>>>multiple turtles, the turtles can inherit methods to make new 
>>>turtle classes, and the background also has methods for its cells, 
>>>implementing Conway's Life only takes several lines.  ...
>>>I think that creating a StarPython, with Python syntax, would be 
>>>... valuable ...
>>That's hard, or maybe easy.
>>With CPython, something like StarPython is hard. The kind of 
>>concurrency it does isn't practical with OS threads.  Maybe with 
>>Greenlets, though I must admit I don't understand them.
> Why?  StarLogo is written in Java, I do not believe that it is 
> threaded.  Threads would be nice but I don't think they are 
> necessary to create StarLogo functionality in Python.

I think StarLogo is interpreted.  At least, I assume so, and seem to 
remember something about that.  Meaning that it is a language built on 
the JVM, not interacting with the JVM.  Given that, they have tremendous 
freedom in how they deal with concurrency.

You could build a similarly concurrent language on top of Python, but 
that language would not be Python anymore than StarLogo is Java.

You could introduce that kind of concurrency into Python, but to do so 
you need to explore things like Greenlets or Stackless Python.  Which 
isn't so bad!  Those projects exist and are intended to serve just this 
kind of purpose.

Or you could reimplement Python, but I think that's a little silly. 
Neither Jython nor IronPython are compatible with the concurrency 
concepts of StarPython, and that probably won't change soon because they 
want to interact smoothly with their environments.  PyPy is actively 
pursuing those kinds of ideas for concurrency, and would not be an 
unreasonable basis, but it's more reasonable to start with a more 
conservative implementation (both Greenlets and Stackless were written 
by PyPy developers).

>>>Python would be easier to teach if it had clearer error messages. 
>>Error messages are indeed hard.  It's easier when you have a 
>>clear idea of system and user code.  In a typical Logo 
>>implementation where the library is implemented in a language 
>>other than Logo, it's easy to tell what is inside and outside -- 
>>everything in Logo belongs to the programmer, everything not in 
>>Logo belongs to the system.  In Python it is not so easy, 
>>especially because errors often bubble up from deep in system 
>>code, and you actually have to inspect the system code to 
>>understand what it means in the context of your code.  As an 
>>shutil(None, 'tmp'):
>>Traceback (most recent call last):
>>   File "<stdin>", line 1, in ?
>>   File "/usr/lib/python2.4/shutil.py", line 81, in copy
>>     copyfile(src, dst)
>>   File "/usr/lib/python2.4/shutil.py", line 41, in copyfile
>>     if _samefile(src, dst):
>>   File "/usr/lib/python2.4/shutil.py", line 31, in _samefile
>>     return os.path.samefile(src, dst)
>>   File "/usr/lib/python2.4/posixpath.py", line 218, in samefile
>>     s1 = os.stat(f1)
>>TypeError: coercing to Unicode: need string or buffer, NoneType found
>>Sigh.  It's not like hiding that traceback can make that error 
>>more understandable.  I really don't know how to resolve that.
>>Though it definitely is possible to trim exceptions down.  For 
>>instance, not to show code that is part of the standard library 
>>(or at least filter that out unless explicitly expanded).  That 
>>won't make the exception make sense (coerce to Unicode?! talk 
>>about obscure), but at least it will better highlight the 
>>problem code.
> How would you attack this problem to get a Logo like error message,
> "shutil didn't like None as an input"?  I would be interested in
> contributing to an errors for beginners project.

I really don't know.  It's a very hard problem.  Again, the system/user 
divide makes this an easier problem to tackle in other languages (*not* 
including Smalltalk).  Especially a dynamic language buit on a static 
language (like PHP, but due to Python's rich Python-based standard 
library even CPython doesn't count here).  With an underlying static 
language (often including a clear idea of "primitives") all the type 
checking and general error checking occur very close to where the user 
code exists.  In Python the error checking might occur far away -- like 
in this case, where there's three shutil frames and a posixpath frame 
before you get to a real primitive (os.stat).

In this particular case the "coercing..." message is not very good.  It 
could be "string or unicode object required, not %r" % obj.  That would 
help considerably.  I've never looked into why these errors look like 
they do, so I don't know if there's a reason for the current form.

I think some careful consideration of tracebacks could take you some 
distance here.  For instance, highlight the TypeError, which is accurate 
even if the message is rather distracting.  Hide the frames from the 
standard library.  Highlight the line of user code that produced the 
problem (and any other bits of user code that might have called it). 
Make sure you get rid of system code that precedes the user code, not 
just system code below the user code.  (For instance, in a web framework 
there will always be system code that does dispatching about the user 
code; in GUI code there will probably be system code that calls the user 
code callbacks in response to events)

If it was possible to highlight the exact expression that caused the 
problem, that would be nice.  I don't think this is currently possible 
in Python, or at least not easy.  That means if you did:

   x = None
   y = 10
   print "You are %s inches away" % (math.sqrt(x**2+y**2))

It would highlight or point to "x**2".

On another tack, I personally have found it very helpful to be able to 
explore local scopes when encountering exceptions, especially for type 
errors like this.  What I'm using personally in my web framework (Paste) 
gives a traceback (that is somewhat trimmed, but not as aggressively as 
I suggest here), and you can interact with each frame.  So you could 
look at the actual values of the expressions passed into 
shutil.copyfile, or look at x in that previous example.  This is like 
pdb, but pdb does a whole lot more than this -- just this one feature 
gives me 90% of what I want to do, and in a more usable form than pdb 
IMHO (I haven't had a chance to try debuggers like winpdb, which might 
be more usable than pdb).

This debugging interaction is something Squeak/Smalltalk also offers and 
emphasizes as a primary means of debugging.  I've never tried the etoys 
stuff, so I don't know how debugging works there.  Anyway, all the 
mechanisms are there in Python, we just aren't using them as actively as 
we should.

Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org

More information about the Edu-sig mailing list