datetime object from string

2006-02-06 Thread Douglas Douglas
Hi everybody.

I need to create a datetime object from a string like "20/01/2005 15:10:01". I
know the mxDateTime module can do this with the DateTimeFrom method, but I was
wondering if is possible to do this using only the standard library.

I read the datetime object reference but didn't find a method that does it
directly.

Is it possible to do it with the standard library?

Thanks all.

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
-- 
http://mail.python.org/mailman/listinfo/python-list


Identifying filled circles in a scanned image

2006-03-30 Thread Douglas Douglas
Hi everybody.

I have a paper form that I scan into an image. My user fills some circles in
this paper form using black ink. Every form has ten rows with five circles each
and the user fills only one circle for each row.

I was wondering if I could use the Python Imaging Library to process these
forms. I know the Image class is really powerful, but I can't think of a way of
how to locate wich circle was filled.

Could anybody please give me an advice on this?

Thanks.

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Identifying filled circles in a scanned image

2006-03-30 Thread Douglas Douglas
First of all. Thanks Claudio and nikie for your fast answers.

What I want to do is process the forms automatically. Each circle match a
letter (like in a quiz). So if the user select option A in a row, he fills the
first circle. If he select option C in the next row, he fills the third circle
of that row. Get it?

What I want is to write a script that takes the images and say:
Form 1:
  Options Selected: A, B, C, A, B, C, A, D, E, A
Form 2:
  Options Selected: B, B, B, A, A, A, C, D, E, A
...

I've read the PIL tutorial. I've processed images before using PIL (basic stuff
though). I thought about using the difference method of the ImageChops module.
It almost worked. The problem is that when the scanner takes the pages it
doesn't put it in the same exact position in its bed. There's not a lot of
difference, but there's a little.

I also thought about drawing references in the forms (like a line or an X) I
could look for.

I like to hear your comments now that I explained a little more.



__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
-- 
http://mail.python.org/mailman/listinfo/python-list


Accessing windoze file attributes

2010-09-15 Thread Douglas
Environment: X86, 1Gb RAM, Win XP, latest SP, Excel 2003.

Hi, can anyone direct a relative newbie to the best source of info?
I am writing my own backup app in Python 2.5.2 (all my company will
allow me to use) using IDLE.
I intend to run this app daily via the Task Scheduler to back up a
mission-critical spreadsheet that only I use.
It works well enough, but now I want to make it sensitive to the "A"
attribute (only backup the file if it is set), and update it
afterwards (unset it). This will help me avoid wasted disk due to
needless backups.
I have searched the inter-web and not found any info on how to do
access/alter Windows file attributes.
Please can someone direct me to a web page with suitable info
(preferably with code snyppyts)?
Many thanks, in advance.
-- Douglas
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Accessing windoze file attributes

2010-09-15 Thread Douglas
@Diez and @David
Thanks guys. Both excellent leads. Colour me happy.  I can now make
progress and meet some deadlines. :)

@Lawrence
> Why reinvent rsync?
In what way is rsync relevant to the stated problem? Did you actually
READ the question?
Note: I use Linux at home (yes, even rsync) and very much prefer it to
Windows. However, at work I have no choice but to use the resources
the company provides - which is Windows; have you got that straight
now?
If you have something more helpful and mature to say, relevant to the
actual question, then I will gladly hear it, and even apologise.
Otherwise, don't bother. I already enough from respondents who were
far more adult, knowledgeable and helpful ... and all the more
impressive in comparison.

Sincerely,
-- Douglas
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Accessing windoze file attributes

2010-09-16 Thread Douglas
@Dave
Grateful thanks for your web site suggestions, and I will look them
up.

@Lawrence
Pleasee accept my apologies. I mistook your brevity for a superior
snotty attitude.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python 2.6 and Sqlite3 - Slow

2012-08-27 Thread ian douglas
>From the sqlite documentation he quoted, it appears that ANY network
filesystem, local or otherwise, should be avoided.
On Aug 27, 2012 8:13 PM,  wrote:

> On Monday, August 27, 2012 10:32:47 PM UTC-4, Bryan wrote:
> > bruceg113 wrote:
> >
> > > I selected sqlite for the following reasons:
> >
> > >
> >
> > > 1) Ships with Python.
> >
> > > 2) Familiar with Python.
> >
> > > 3) The Sqlite description athttp://
> www.sqlite.org/whentouse.htmlappears to meet my requirements:
> >
> > > Very low volume and concurrency, small datasets, simple to use.
> >
> >
> >
> > All good reasons, but a database file on a network drive is
> >
> > contraindication for SQLite. A Google site-specific search
> >
> > for "network" on www.sqlite.org, finds such warnings as:
> >
> >
> >
> > "We have received reports of implementations of both Windows network
> >
> > filesystems and NFS in which locking was subtly broken. We can not
> >
> > verify these reports, but as locking is difficult to get right on a
> >
> > network filesystem we have no reason to doubt them. You are advised to
> >
> > avoid using SQLite on a network filesystem in the first place, since
> >
> > performance will be slow."
> >
> >
> >
> > That said, I don't know where your 17 seconds is going.
> >
> >
> >
> > -Bryan
>
> Bryan,
>
> Thank you for your reply.
> Are you saying having a sqlite database file on a shared LOCAL network
> drive is problematic?
>
> Bruce
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: notmm is dead!

2012-10-28 Thread ian douglas

On 10/05/2012 12:37 PM, Prasad, Ramit wrote:
I might be misunderstanding, but I think Etienne wants money in 
exchange for letting someone else take over.


Not to stir up the hornet's nest any more, but it also sounds like now 
he wants money for people to license things as well:
"The license fee is simply because I'm shifting into commercial license 
for new releases"


Wait, new releases? I thought the project was "dead" ?


So, Etienne, are you continuing to maintain the project, or aren't you?
In your original "this project is dead" message, you said you had "been 
bitten by its failure to encourage a free market over one dictated by 
profit"


... yet now your desire is to be making money (presumably profit?) by 
selling us a license, so how does that differentiate from those you 
claim use "cheap tricks to compete" if you hijack a mailing list for 
several days by claiming you're shutting down the project then say 
you're charing for licenses which may lead people to believe you're 
going to KEEP maintaining it? Why on earth would I pay for a license to 
use code that is not being maintained? Seems like very strange logic to me.


Or by having someone pay you some quantity of money to take over as 
maintainer? I can think of no better way to just kill off a project than 
expect someone to pay money to take over as a maintainer. I don't recall 
ever hearing of such a thing in my experience with open-source projects...



I'm all about supporting open source projects when I gain value from 
them (I've donated thousands of dollars and countless hours), but 
Etienne's back-and-forth on this has me turned off from even wanting to 
try his project, much less support him. There are so many free places to 
host code/documentation these days, asking people to donate extra funds 
to maintain a custom domain name and hosting when free alternatives 
exist seems as unnecessary as having to pay money to become the next 
maintainer.


-id

--
http://mail.python.org/mailman/listinfo/python-list


Re: Question regarding mod_python and a script for web.

2012-12-20 Thread ian douglas
Short answer: Use the POST method on the form instead of GET. Depending how
you process the form you might need to make a few changes to the script
that answers the request.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: New to python, do I need an IDE or is vim still good enough?

2012-12-27 Thread ian douglas
Some would argue that vim is always good enough, especially with its plugin
system.

I bounce between vim and Sublime Text 2, and recently bought PyCharm went
it went on sale a week ago.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: random number

2012-03-26 Thread ian douglas
On Mar 26, 2012 12:28 AM, "Steven D'Aprano" <
[email protected]> wrote:
>
> On Mon, 26 Mar 2012 08:40:00 +0200, Michael Poeltl wrote:
>
> > * Nikhil Verma  [2012-03-26 08:09]:
> A truly random six digit number will include any number between 10
> through 99. There are exactly 90 (nine hundred thousand) such
> numbers.

Actually, considering that 00 would still fit the parameter of a 6
"digit" number, there are exactly one million such numbers.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Difference between json.load() and json.loads() [From: RE: question about file handling with "with"]

2012-03-28 Thread ian douglas
On Mar 28, 2012 6:54 AM, "Nadir Sampaoli"  wrote:
>
> Hello everyone (my first message in the mailing list),
>
>>
>> > Is the following function correct?
>> Yes, though I'd use json.load(f) instead of json.loads().
>
>
> The docs aren't very clear (at least for me) about the difference between
json.load() and json.loads (and about "dump()" and "dumps()" too"). Could
you clarify it for me?
>

The functions with an s take string parameters. The others take file
streams.

foo = '{"age": 38}'
my_json = json.loads(foo)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Simple SSL client hangs

2021-07-13 Thread Douglas Wells
In article <[email protected]>,
Loris Bennett  wrote:
>In Perl I have the following
>
>  use IO::Socket::SSL;
>  my $my_socket = new IO::Socket::SSL(PeerAddr => 'some.server.somewhere,
> PeerPort => 12345,
>);
>  my $line = <$my_socket>;
>  print("$line\n");
>  say $my_socket 'ECHO 1';
>  $line = <$my_socket>;
>  print("$line\n");
>
>This runs as expected and I get
>
>  200 Some Server Somewhere - Hello [123.456.789.123]
>  310 Hello Echo
>
>If I try the same with the following Python code:
>
>  import socket
>  import ssl
>  HOST = "some.server.somewhere"
>  PORT = 12345
>  context = ssl.create_default_context()
>  with socket.create_connection((HOST, PORT)) as sock:
>  with context.wrap_socket(sock, server_hostname=HOST) as ssock:
>  data = ssock.recv(1024)
>  print(data.decode())
>  ssock.write(b'ECHO 1')
>  data = ssock.read(1024)
>  print(data.decode())
>
>I get a timeout for the 'ECHO' command:
>
>  200 Some Server Somewhere - Hello [123.456.789.123]
>  501 Timeout
>
>Does anyone have an idea what I might be doing wrong?

Loris,

You don't specify the type of your server, but it looks like a
"normal" SMTP or NNTP or whatever server.  This type of server is line
oriented.

The Perl "say" operation adds a trailing line terminator.  The Python
"ssl:write" does not.  Try adding an appropriate line terminator to
your Python code.  Most likely it needs to be CR-LF.  Perhaps use
"ssock.write(b'ECHO 1\r\n')

 - dmw
-- 
https://mail.python.org/mailman/listinfo/python-list


Canonical way of dealing with null-separated lines?

2005-02-23 Thread Douglas Alan
Is there a canonical way of iterating over the lines of a file that
are null-separated rather than newline-separated?  Sure, I can
implement my own iterator using read() and split(), etc., but
considering that using "find -print0" is so common, it seems like
there should be a more cannonical way.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-02-24 Thread Douglas Alan
Christopher De Vries <[EMAIL PROTECTED]> writes:

> I'm not sure if there is a canonical method, but I would
> recommending using a generator to get something like this, where 'f'
> is a file object:

Thanks for the generator.  It returns an extra blank line at the end
when used with "find -print0", which is probably not ideal, and is
also not how the normal file line iterator behaves.  But don't worry
-- I can fix it.

In any case, as a suggestion to the whomever it is that arranges for
stuff to be put into the standard library, there should be something
like this there, so everyone doesn't have to reinvent the wheel (even
if it's an easy wheel to reinvent) for something that any sysadmin
(and many other users) would want to do on practically a daily basis.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-02-25 Thread Douglas Alan
Okay, here's the definitive version (or so say I).  Some good doobie
please make sure it makes its way into the standard library:

def fileLineIter(inputFile, newline='\n', leaveNewline=False, readSize=8192):
   """Like the normal file iter but you can set what string indicates newline.

   You can also set the read size and control whether or not the newline string
   is left on the end of the iterated lines.  Setting newline to '\0' is
   particularly good for use with an input file created with something like
   "os.popen('find -print0')".
   """
   partialLine = []
   while True:
  charsJustRead = inputFile.read(readSize)
  if not charsJustRead: break
  lines = charsJustRead.split(newline)
  if len(lines) > 1:
 partialLine.append(lines[0])
 lines[0] = "".join(partialLine)
 partialLine = [lines.pop()]
  else:
 partialLine.append(lines.pop())
  for line in lines: yield line + ("", newline)[leaveNewline]
   if partialLine and partialLine[-1] != '': yield "".join(partialLine)

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-02-26 Thread Douglas Alan
I wrote:

> Okay, here's the definitive version (or so say I).  Some good doobie
> please make sure it makes its way into the standard library:

Oops, I just realized that my previously definitive version did not
handle multi-character newlines.  So here is a new definition
version.  Oog, now my brain hurts:

def fileLineIter(inputFile, newline='\n', leaveNewline=False, readSize=8192):
   """Like the normal file iter but you can set what string indicates newline.

   The newline string can be arbitrarily long; it need not be restricted to a
   single character. You can also set the read size and control whether or not
   the newline string is left on the end of the iterated lines.  Setting
   newline to '\0' is particularly good for use with an input file created with
   something like "os.popen('find -print0')".
   """
   isNewlineMultiChar = len(newline) > 1
   outputLineEnd = ("", newline)[leaveNewline]

   # 'partialLine' is a list of strings to be concatinated later:
   partialLine = []

   # Because read() might unfortunately split across our newline string, we
   # have to regularly check to see if the newline string appears in what we
   # previously thought was only a partial line.  We do so with this generator:
   def linesInPartialLine():
  if isNewlineMultiChar:
 linesInPartialLine = "".join(partialLine).split(newline)
 if linesInPartialLine > 1:
partialLine[:] = [linesInPartialLine.pop()]
for line in linesInPartialLine:
   yield line + outputLineEnd

   while True:
  charsJustRead = inputFile.read(readSize)
  if not charsJustRead: break
  lines = charsJustRead.split(newline)
  if len(lines) > 1:
 for line in linesInPartialLine(): yield line
 partialLine.append(lines[0])
 lines[0] = "".join(partialLine)
 partialLine[:] = [lines.pop()]
  else:
 partialLine.append(lines.pop())
 for line in linesInPartialLine(): yield line
  for line in lines: yield line + outputLineEnd
   for line in linesInPartialLine(): yield line
   if partialLine and partialLine[-1] != '':
  yield "".join(partialLine)


|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


yield_all needed in Python

2005-02-28 Thread Douglas Alan
While writing a generator, I was just thinking how Python needs a
"yield_all" statement.  With the help of Google, I found a
pre-existing discussion on this from a while back in the Lightweight
Languages mailing list.  I'll repost it here in order to improve the
chances of this enhancement actually happening someday.  The original
poster from the LL mailing list seems mostly concerned with
algorithmic efficiency, while I'm concerned more about making my
programs shorter and easier to read.  The ensuing discussion on the LL
list talks about how yield_all would be somewhat difficult to
implement if you want to get the efficiency gain desired, but I don't
think it would be very difficult to implement if that goal weren't
required, and the goal were limited to just the expressive elegance:

 A Problem with Python's 'yield'

 * To: LL1 Mailing List <[EMAIL PROTECTED]>
 * Subject: A Problem with Python's 'yield'
 * From: Eric Kidd <[EMAIL PROTECTED]>
 * Date: 27 May 2003 11:15:20 -0400
 * Organization:
 * Sender: [EMAIL PROTECTED]

 I'm going to pick on Python here, but only because the example code will
 be short and sweet. :-) I believe several other implementations of
 generators have the same problem.

 Python's generator system, used naively, turns an O(N) tree traversal
 into an O(N log N) tree traversal:

   class Tree:
   def __init__(self, value, left=None, right=None):
   self.value = value
   self.left = left
   self.right = right

   def in_order(self):
   if self.left is not None:
   for v in self.left.in_order():
   yield v
   yield self.value
   if self.right is not None:
   for v in self.right.in_order():
   yield v

   t=Tree(2, Tree(1), Tree(3))
   for v in yield_bug.t.in_order():
   print v

 This prints:
   1
   2
   3

 Unfortunately, this snippet calls 'yield' 5 times, because the leaf
 values must be yielded twice on their way back up the tree.

 We can shorten the code--and make it run in O(N) time--by adding a new
 keyword to replace the "for v in ...: yield v" pattern:

   def in_order(self):
   if self.left is not None:
   yield_all self.left.in_order():
   yield self.value
   if self.right is not None:
   yield_all self.right.in_order():

 Interestingly enough, this allows you define notions such as
 "tail-recursive generation", and apply the usual bag of
 recursion-optimization techniques.

 Cheers,
 Eric

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-02-28 Thread Douglas Alan
I wrote:

> Oops, I just realized that my previously definitive version did not
> handle multi-character newlines.  So here is a new definitive
> version.  Oog, now my brain hurts:

I dunno what I was thinking.  That version sucked!  Here's a version
that's actually comprehensible, a fraction of the size, and works in
all cases.  (I think.)

def fileLineIter(inputFile, newline='\n', leaveNewline=False, readSize=8192):
   """Like the normal file iter but you can set what string indicates newline.
   
   The newline string can be arbitrarily long; it need not be restricted to a
   single character. You can also set the read size and control whether or not
   the newline string is left on the end of the iterated lines.  Setting
   newline to '\0' is particularly good for use with an input file created with
   something like "os.popen('find -print0')".
   """
   outputLineEnd = ("", newline)[leaveNewline]
   partialLine = ''
   while True:
   charsJustRead = inputFile.read(readSize)
   if not charsJustRead: break
   lines = (partialLine + charsJustRead).split(newline)
   partialLine = lines.pop()
   for line in lines: yield line + outputLineEnd
   if partialLine: yield partialLine

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Andrew Dalke <[EMAIL PROTECTED]> writes:

> On Mon, 28 Feb 2005 18:25:51 -0500, Douglas Alan wrote:

>> While writing a generator, I was just thinking how Python needs a
>> "yield_all" statement.  With the help of Google, I found a
>> pre-existing discussion on this from a while back in the
>> Lightweight Languages mailing list.  I'll repost it here in order
>> to improve the chances of this enhancement actually happening
>> someday.

> You should also have looked for the responses to that. Tim Peter's
> response is available from

>   http://aspn.activestate.com/ASPN/Mail/Message/624273

[...]

> Here is the most relevant parts.

[...]

>BTW, Python almost never worries about worst-case behavior, and people
>using Python dicts instead of, e.g., balanced trees, get to carry their
>shame home with them hours earlier each day  .

If you'll reread what I wrote, you'll see that I'm not concerned with
performance, but rather my concern is that I want the syntactic sugar.
I'm tired of writing code that looks like

   def foogen(arg1):

  def foogen1(arg2):
 # Some code here

  # Some code here
  for e in foogen1(arg3): yield e
  # Some code here
  for e in foogen1(arg4): yield e
  # Some code here
  for e in foogen1(arg5): yield e  
  # Some code here
  for e in foogen1(arg6): yield e  

when it would be much prettier and easier to read if it looked like:

   def foogen(arg1):

  def foogen1(arg2):
 # Some code here

  # Some code here
  yield_all foogen1(arg3)
  # Some code here
  yield_all foogen1(arg4)
  # Some code here
  yield_all foogen1(arg5)
  # Some code here
  yield_all foogen1(arg6)

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> Cetainly, if  iterator> == , I don't see how anything
> is gained except for a few keystrokes.

What's gained is making one's code more readable and maintainable,
which is the one of the primary reasons that I use Python.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-03-01 Thread Douglas Alan
"John Machin" <[EMAIL PROTECTED]> writes:

>>lines = (partialLine + charsJustRead).split(newline)

> The above line is prepending a short string to what will typically be a
> whole buffer full. There's gotta be a better way to do it.

If there is, I'm all ears.  In a previous post I provided code that
doesn't concatinate any strings together until the last possible
moment (i.e. when yielding a value).  The problem with that the code
was that it was complicated and didn't work right in all cases.

One way of solving the string concatination issue would be to write a
string find routine that will work on lists of strings while ignoring
the boundaries between list elements.  (I.e., it will consider the
list of strings to be one long string for its purposes.)  Unless it is
written in C, however, I bet it will typically be much slower than the
code I just provided.

> Perhaps you might like to refer back to CdV's solution which was
> prepending the residue to the first element of the split() result.

The problem with that solution is that it doesn't work in all cases
when the line-separation string is more than one character.

>>for line in lines: yield line + outputLineEnd

> In the case of leaveNewline being false, you are concatenating an empty
> string. IMHO, to quote Jon Bentley, one should "do nothing gracefully".

In Python,

   longString + "" is longString

evaluates to True.  I don't know how you can do nothing more
gracefully than that.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Duncan Booth <[EMAIL PROTECTED]> writes:

> Douglas Alan wrote:

>> "Terry Reedy" <[EMAIL PROTECTED]> writes:

>>> Cetainly, if >> iterator> == , I don't see how anything
>>> is gained except for a few keystrokes.

>> What's gained is making one's code more readable and maintainable,
>> which is the one of the primary reasons that I use Python.

> On of the reasons why Python is readable is that the core language is 
> comparatively small.

It's not that small anymore.  What it *is* is relatively conceptually
simple and readily comprehensible (i.e. "lightweight"), unlike
languages like C++ and Perl.

> Adding a new reserved word simply to save a few 
> characters

It's not to "save a few characters".  It's to make it immediately
clear what is happening.

> is a difficult choice, and each case has to be judged on its merits,
> but it seems to me that in this case the extra syntax is a burden
> that would have to be learned by all Python programmers with very
> little benefit.

The amount of effort to learn what "yield_all" does compared to the
amount of effort to understand generators in general is so miniscule,
as to be negligible.  Besides, by this argument, the standard library
should be kept as small as possible too, since people have to learn
all that stuff in order to understand someone else's code.

> Remember that many generators will want to do slightly more than just yield 
> from another iterator, and the for loop allows you to put in additional 
> processing easily whereas 'yield_all' has very limited application e.g.

>for tok in tokenstream():
>if tok.type != COMMENT:
>yield tok

> I just scanned a random collection of my Python files: out of 50 yield 
> statements I found only 3 which could be rewritten using yield_all.

For me, it's a matter of providing the ability to implement
subroutines elegantly within generators.  Without yield_all, it is not
elegent at all to use subroutines to do some of the yielding, since
the calls to the subroutines are complex, verbose statements, rather
than simple ones.

I vote for the ability to have elegant, readable subroutining,
regardless of how much you in particular would use it.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Francis Girard <[EMAIL PROTECTED]> writes:

> Therefore, the suggestion you make, or something similar, would have
> actually ease my learning, at least for me.

Yes, I agree 100%.  Not having something like "yield_all" hurt my
ability to learn to use Python's generators quickly because I figured
that Python had to have something like yield_all.  But no matter how
hard I looked, I couldn't find anything about it in the manual.

So the argument that adding a feature makes the language harder to
learn is a specious one.  Sometimes an extra feature makes the
language easier to learn.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
David Eppstein <[EMAIL PROTECTED]> writes:

> In article <[EMAIL PROTECTED]>,

>  Douglas Alan <[EMAIL PROTECTED]> wrote:

>> > Cetainly, if > > iterator> == , I don't see how anything
>> > is gained except for a few keystrokes.

>> What's gained is making one's code more readable and maintainable,
>> which is the one of the primary reasons that I use Python.

> I don't see a lot of difference in readability and maintainability 
> between the two versions.

In that case, your brain works nothing like mine.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Steve Holden <[EMAIL PROTECTED]> writes:

> Guido has generally observed a parsimony about the introduction of
> features such as the one you suggest into Python, and in particular
> he is reluctant to add new keywords - even in cases like decorators
> that cried out for a keyword rather than the ugly "@" syntax.

In this case, that is great, since I'd much prefer

   yield *gen1(arg)

than

   yield_all gen1(arg)

anyway, as someone else suggested in this thread (followed by a
demonic laugh).  The only reason I mentioned "yield_all" is because
there was a preexisting discussion that used "yield_all".

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Canonical way of dealing with null-separated lines?

2005-03-01 Thread Douglas Alan
"John Machin" <[EMAIL PROTECTED]> writes:

>> In Python,

>>longString + "" is longString

>> evaluates to True.  I don't know how you can do nothing more
>> gracefully than that.

> And also "" + longString is longString

> The string + operator provides those graceful *external* results by
> ugly special-case testing internally.

I guess I don't know what you are getting at.  If Python peforms ugly
special-case testing internally so that I can write more simple,
elegant code, then more power to it!  Concentrating ugliness in one,
small, reusable place is a good thing.


> It is not graceful IMHO to concatenate a variable which you already
> know refers to a null string.

It's better than making my code bigger, uglier, and putting in extra
tests for no particularly good reason.


> Let's go back to the first point, and indeed further back to the use
> cases:

> (1) multi-byte separator for lines in test files: never heard of one
> apart from '\r\n'; presume this is rare, so test for length of 1 and
> use Chris's simplification of my effort in this case.

I want to ability to handle multibyte separators, and so I coded for
it.  There are plenty of other uses for an iterator that handles
multi-byte separators.  Not all of them would typically be considered
"newline-delimited lines" as opposed to "records delimited by a
separation string", but a rose by any other name

If one wants to special case for single-byte separators in the name of
efficiency, I provided one back there in the thread that never
degrades to N^2, as the ones you and Chris provided.


> (2) keep newline: with the standard file reading routines, if one is
> going to do anything much with the line other than write it out again,
> one does buffer = buffer.rstrip('\n') anyway. In the case of a
> non-standard separator, one is likely to want to write the line out
> with the standard '\n'. So, specialisation for this is indicated:

> ! if keepNewline:
> ! for line in lines: yield line + newline
> ! else:
> ! for line in lines: yield line

I would certainly never want the iterator to tack on a standard "\n"
as a replacement for whatever newline string the input used.  That
seems like completely gratuitous functionality to me.  The standard
(but not the only) reason that I want the line terminator left on the
yielded strings is so that you can tell whether or not there is a
line-separator terminating the very last line of the input.  Usually I
want the line-terminator discarded, and it kind of annoys me that the
standard line iterator leaves it on.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Steven Bethard <[EMAIL PROTECTED]> writes:

> I'm guessing the * syntax is pretty unlikely to win Guido's
> approval. There have been a number of requests[1][2][3] for syntax
> like:

>  x, y, *rest = iterable

Oh, it is so wrong that Guido objects to the above.  Python needs
fully destructuring assignment!

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-01 Thread Douglas Alan
Isaac To <[EMAIL PROTECTED]> writes:

>> "Isaac" == Isaac To <[EMAIL PROTECTED]> writes:
>
> def gen_all(gen):
> for e in gen:
> yield e
>
> def foogen(arg1):
> def foogen1(arg2):
> # Some code here
> # Some code here
> gen_all(arg3)
> ^ I mean foogen1(arg3), obviously, and similar for below
> # Some code here
> gen_all(arg4)
> # Some code here
> gen_all(arg5)
> # Some code here
> gen_all(arg6)
>
> Regards,
> Isaac.

If you actually try doing this, you will see why I want "yield_all".

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: yield_all needed in Python

2005-03-02 Thread Douglas Alan
Nick Coghlan <[EMAIL PROTECTED]> writes:

> If you do write a PEP, try to get genexp syntax supported by the
> yield keyword.

> That is, the following currently triggers a syntax error:
>def f():
>  yield x for x in gen1(arg)

Wouldn't

   yield *(x for x in gen1(arg))

be sufficient, and would already be supported by the proposal at
hand?

Also, with the syntax you suggest, it's not automatically clear
whether you want to yield the generator created by the generator
expression or the values yielded by the expression.  The "*" makes
this much more explicit, if you ask me, without hindering readability.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Editor for Python

2014-01-08 Thread Douglas Duhaime
I've been pleased with Komodo, and certainly prefer it over Notepad++.

Komodo:
http://www.activestate.com/komodo-ide?gclid=COHE4eLj7rsCFQISMwodOUQAiw


On Wed, Jan 8, 2014 at 7:23 AM, Jean-Michel Pichavant <
[email protected]> wrote:

> - Original Message -
> > On Friday, 23 November 2001 04:13:40 UTC+5:30, MANUEL FERNANDEZ PEREZ
> >  wrote:
> > > Hello,
> > > I'm looking for an editor for Python.I' m interested it works on
> > > Windows.Can
> > > anybody help me?
> > >
> > > Thank you
> > >
> > > Manuel
>
> http://lmgtfy.com/?q=python+editor+windows
>
> Otherwise, must of the newcomers will be pleased with
> http://notepad-plus-plus.org/
>
> Ideally, try to use an editor that will allow you to edit any type of
> code, python or anything else.
>
> JM
>
> PS : you could also have searched this archive, this subject has been
> already discussed... a lot.
>
>
> -- IMPORTANT NOTICE:
>
> The contents of this email and any attachments are confidential and may
> also be privileged. If you are not the intended recipient, please notify
> the sender immediately and do not disclose the contents to any other
> person, use it for any purpose, or store or copy the information in any
> medium. Thank you.
> --
> https://mail.python.org/mailman/listinfo/python-list
>



-- 
Douglas Duhaime
Department of English, University of Notre Dame
douglasduhaime.com, [email protected]
-- 
https://mail.python.org/mailman/listinfo/python-list


Dynamic Import with sub module

2015-05-23 Thread Douglas Garstang
All,

Can someone tell me how the following statement:

import slice_fablib_common.common as common

would be replicated with __import__ or import_module?

I'm using fabric and I want the module when imported to appear in the
namespace (which fabric shows as a task), in this case, as 'common.chef'.
With the import statement it works. However, I'm trying to load the modules
dynamically, and I just cannot work out what combination of options when
used with dynamic imports will get me to 'common.chef'.

When I get that to work, I'd like to go one step further as well. If I have
modules called slice_fablib_webapp.webapp.deploy and
slice_fablib_webapp.webapp.info, I'd like to import them as webapp.deploy
and webapp.info.

I suppose the webapp piece is a bit redundant. If I removed it, and ended
up with slice_fablib_webapp.deploy and slice_fablib_webapp.info, I'd like
to import them so that they still appear in fabric's name space as
webapp.deploy and webapp.info.

Thanks,
Doug.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Dynamic Import with sub module

2015-05-23 Thread Douglas Garstang
Replying to my own message.

I just realised that even the case I thought would work, will not. :(

If I have:

import slice_fablib_common.common as common

I end up with fabric showing me these commands:

Available commands:

common.chef.report
common.chef.run Run the chef client.
common.chef.start   Start chef-client service.
common.chef.status  Show chef-client service status.
common.chef.stopStop chef-client service.

However, that's only because slice_fablib_common/common/__init__.py has
'import chef'. I need to be able to individually load sub-modules from
common. I'm essentially loading the entire package here because I need to
put an import for every sub module into __init__.py anyway. :(

Doug.

On Sat, May 23, 2015 at 9:03 AM, Douglas Garstang 
wrote:

> All,
>
> Can someone tell me how the following statement:
>
> import slice_fablib_common.common as common
>
> would be replicated with __import__ or import_module?
>
> I'm using fabric and I want the module when imported to appear in the
> namespace (which fabric shows as a task), in this case, as 'common.chef'.
> With the import statement it works. However, I'm trying to load the modules
> dynamically, and I just cannot work out what combination of options when
> used with dynamic imports will get me to 'common.chef'.
>
> When I get that to work, I'd like to go one step further as well. If I
> have modules called slice_fablib_webapp.webapp.deploy and
> slice_fablib_webapp.webapp.info, I'd like to import them as webapp.deploy
> and webapp.info.
>
> I suppose the webapp piece is a bit redundant. If I removed it, and ended
> up with slice_fablib_webapp.deploy and slice_fablib_webapp.info, I'd like
> to import them so that they still appear in fabric's name space as
> webapp.deploy and webapp.info.
>
> Thanks,
> Doug.
>
>


-- 
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: [email protected]
Cell: +1-805-340-5627
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Doing a HTTP DELETE operation with urllib2?

2011-12-30 Thread Douglas Landgraf

Hi,

On 12/30/2011 12:01 PM, Roy Smith wrote:

Is there some way to make urllib2.urlopen() perform a DELETE instead of a GET 
or POST?

  I'm hoping I don't have to dip way down into httplib.  I've got an 
application test framework built on top of urllib2.  It makes heavy use of 
HTTPCookieProcessor.  If I need to use the httplib calls directly, I'll have to 
re-implement a lot of that machinery.

You might want to look:
https://github.com/dougsland/rhev3-restapi-scripts/blob/master/sample-delete.py

--
Cheers
Douglas

--
http://mail.python.org/mailman/listinfo/python-list


Re: Python script not working on windows 7 but works fine on linux

2013-03-04 Thread ian douglas

On 03/04/2013 11:06 AM, io wrote:

esclusioni_file = open('/home/io/btc_trading/exclusions.txt','r')

Windows error :

Traceback (most recent call last):
   File "C:\btc_trading\scripts
\import_json_2_csv_from_web_and_exclusions.py", line 10, in 
 f = open("/home/io/btc_trading/markets.csv","wb")
IOError: [Errno 2] No such file or directory: '/home/io/btc_trading/
markets.csv'


The error tells you everything you need to know: the file system has no 
path/file called "/home/io/btc_trading/markets.csv"


I imagine your CSV file lives in a different location on your Windows 7 
system (which also uses back-slashes '\' instead of forward-slashes '/', 
so you'll need to maybe do a try/except around the open() call to open a 
Windows path like open("c:\\users\\io\\Documents\\markets.csv") or 
whatever. OR you'll need to do some OS detection ahead of time to set 
the file path properly.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Insert comma in number?

2013-03-06 Thread ian douglas

On 03/06/2013 03:39 PM, eli m wrote:

I have a python program that accepts input and calculates the factorial of that 
number, and i want to know if i can make it so commas get inserted in the 
number.
For example: instead of 1000 it would say 1,000



pip install humanize


import humanize
my_integer = 12345678
commafied_integer = humanize.intcomma(my_integer)
print commafied_integer


output:
12,345,678
--
http://mail.python.org/mailman/listinfo/python-list


Re: MySQLdb not updating rows

2006-06-28 Thread Douglas Andrade
Hello Simon,Take a look at this link: http://python.codezoo.com/pub/component/3583
May autocommit (or commit, as Fredrik pointed out) be the solution.On 28 Jun 2006 06:46:54 -0700, Bowen <[EMAIL PROTECTED]
> wrote:Thanks for that, it appears it was the db.commit() that sorted itout.lesson learnt :)
--http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Use empty string for self

2006-03-01 Thread Douglas Alan
Roy Smith <[EMAIL PROTECTED]> writes:

> Terry Hancock <[EMAIL PROTECTED]> wrote:

>> However, there is a slightly less onerous method which
>> is perfectly legit in present Python -- just use "s"
>> for "self":

> This is being different for the sake of being different.  Everybody *knows* 
> what self means.  If you write your code with s instead of self, it just 
> makes it that much harder for other people to understand it.

I always use "s" rather than "self".  Are the Python police going to
come and arrest me?  Have I committed the terrible crime of being
unPythonic?  (Or should that be un_pythonic?)

I rarely find code that follows clear coding conventions to be hard to
understand, as long as the coding convention is reasonable and
consistent.

Something that I do find difficult to understand, as a contrasting
example, is C++ code that doesn't prefix instance variables with "_"
or "m_" (or what have you), or access them via "this".  Without such a
cue, I have a hard time figuring out where such variables are coming
from.

Regarding why I use "s" rather than "self", I don't do this to be
different; I do it because I find "self" to be large enough that it is
distracting.  It's also a word, which demands to be read.  (Cognitive
psychologists have shown that when words are displayed to you your
brain is compelled to read them, even if you don't want to.  I
experience this personally when I watch TV with my girlfriend who is
hearing impaired.  The captioning is very annoying to me, because
it's hard not to read them, even though I don't want to.  The same
thing is true of "self".)

With too many "self"s everywhere, my brain finds it harder to locate
the stuff I'm really interested in.  "s." is small enough that I can
ignore it, yet big enough to see when I need to know that information.
It's not a word, so my brain doesn't feel compelled to read it when I
don't want to, and it's shorter, so I can fit more useful code on a
line.  Breaking up some code onto multiple lines often makes it
significantly less readable.  (Just ask a typical mathematician, who
when shown notations that Computer Science people often use, laugh in
puzzlement at their verbosity.  Mathematicians probably could not do
what they do without having the more succinct notations that they
use.)

Don't take any of this to mean that succinctness is always better than
brevity.  It quite often is not.  Brevity is good for things that you
do over and over and over again.  Just ask Python -- it often knows
this.  It's why there are no "begin" and "end" statements in Python.
It's why semicolons aren't required to separate statements that are on
different lines.  That stuff is extra text that serves little purpose
other than to clutter up the typical case.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: c[:]()

2007-05-31 Thread Douglas Woodrow
On Thu, 31 May 2007 07:49:22, Warren Stringer <[EMAIL PROTECTED]> wrote
>> >>def a(): return 'b'
>> >>def b(): print 'polly! wakey wakey'
>> >>c = {}
>> >>c['a'] = b
>> >>c[a()]()  #works!
>> >
>> >
>> >(typo correction for other easily-confused newbies like myself)
>> >
>> >I think you mean
[...]


>Hey Douglas,
>
>Perhaps I was being too abstract? Here goes:
>
>,---
>|  def selector():
>|...
>|return funcKey#get down get down
>|
>|  def func():
>|...
>|  funcSwitch = {}
>|  funcSwitch[funcKey] = func
>|  ...
>|  funcSwitch[selector()]()


Thanks Warren, I was merely pointing out the typing mistake you made in 
your first example.

And yes, your abstract names made it difficult to guess the intention of 
the original code.  With the meaningful names you've just provided, I 
can see immediately that you intended to write the 2nd working code 
alternative I suggested:

>> Oh no, I get it, you meant...
>> ,
>> | c['b'] = b
>> | c[a()]()  #works!
>> `

-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: c[:]()

2007-06-01 Thread Douglas Woodrow
On Thu, 31 May 2007 18:42:05, Warren Stringer <[EMAIL PROTECTED]> wrote
>They were copied from working code. Copied *badly*? Yes. Running python via:
>   Windows -> start -> run -> python
>doesn't allow cut and paste

Hi Warren,

Actually you can copy and paste from a Windows cmd/command shell: 
right-click the title-bar of the window, select "Edit" from the pop-up 
menu, then "Mark" from the sub-menu to copy whatever you want to select 
into the Windows clipboard.

HTH,
-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: c[:]()

2007-06-01 Thread Douglas Woodrow
On Fri, 1 Jun 2007 07:23:16, Steve Holden <[EMAIL PROTECTED]> wrote
>>  Actually you can copy and paste from a Windows cmd/command shell: 
>>right-click the title-bar of the window, select "Edit" from the pop-up 
>>menu, then "Mark" from the sub-menu to copy whatever you want to 
>>select  into the Windows clipboard.
>
>Better still, modify your shortcut by bring up the command window's 
>Properties page and setting "Quick Edit Mode". Then you can select with 
>the mouse and hit Enter to copy.

Cool, thanks Steve!

Newsgroups really are a good way of learning new things quickly.
-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: int vs long

2007-06-04 Thread Douglas Woodrow
On Mon, 4 Jun 2007 10:50:14, Peter Otten <[EMAIL PROTECTED]> wrote
>>>
>>> This is fixed in Python2.5:
>>>
>> Hm, my test above was from 2.5!?
>
>Then your installation is broken. What does
>
 import itertools
 itertools
>'/usr/local/lib/python2.5/lib-dynload/itertools.so'>
>
>print?


Maybe it's a problem with the Windows build of Python 2.5

,
| Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310
| 32 bit (Intel)] on win32
| Type "help", "copyright", "credits" or "license" for more information.
| >>> import sys
| >>> import itertools
| >>> itertools
| 
| >>> c = itertools.count(sys.maxint)
| >>> c.next()
| Traceback (most recent call last):
|   File "", line 1, in 
| OverflowError: cannot count beyond LONG_MAX
| >>>
`

-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Strange behavior in Windows

2007-06-05 Thread Douglas Woodrow
On Mon, 4 Jun 2007 21:34:36, David Stockwell wxp <[EMAIL PROTECTED]> 
wrote
>
>in DOS you can try this to see what your path is:
>
>echo "My path is %PATH%"

or more simply:

,
| C:> path
`
-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Proper licensing and copyright attribution for extracted Python code

2007-06-14 Thread Douglas Alan
Hi.  I extracted getpath.c out of Python and modified it to make a
generally useful facility for C and C++ programming.  These comments
are at the top of my .c file, and I would like to know if they pass
muster for meeting licensing, copyright, and aesthetics requirements:

// -*- Mode: C; fill-column: 79 -*-

//=
// Description:
//
//  pathToExecutable.c is a module that allows a Unix program to find the
//  location of its executable.  This capability is extremely useful for
//  writing programs that don't have to recompiled in order to be relocated
//  within the filesystem.  Any auxiliary files (dynamically loaded
//  libraries, help files, configuration files, etc.) can just be placed in
//  the same directory as the executable, and the function
//  pathToExecutable() can be used by the program at runtime to locate its
//  executable file and from there the program can locate any auxiliary
//  files it needs in order to operate.
//
//  pathToExecutable() is smart enough to follow a symlink (or even a chain
//  of symlinks) in order to find the true location of the executable.  In
//  this manner, for instance, you might install all of the files used by a
//  program (let's say it's called "my-program"), including the executable,
//  into the directory /usr/local/lib/my-program, and then put a symlink
//  into /usr/local/bin that points to the executable
//  /usr/local/lib/my-program/my-program.  Initially pathToExecutable()
//  will identify /usr/local/bin/my-program as the executable, but it will
//  then notice that this "file" is really a symbolic link.
//  pathToExecutable() will then follow the symbolic link and return
//  "/usr/local/lib/my-program/my-pogram" instead.
//
//  Before a program can call pathToExecutable(), setArgv() must be called
//  (canonically in main()) so that pathToExecutable() can fetch the value
//  of argv[0] and use it to help figure out where the executable is
//  located.
//
// Copyright and licensing information:
//
//  This software is a heavily modified version of getpath.c from the
//  Python 2.5.1 release.  Both this software and the original software
//  from which it is derived are freely distributable under the terms of
//  the permissive freeware license, Python Software Foundation License
//  Version 2.  You can read more about this license here:
//
//   http://www.python.org/psf/license
//
//  The original software from which this software is derived carries the
//  following copyright:
//
// Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python
// Software Foundation.
//
//  The modifications to the original software, which are contained herein,
//  are
//
// Copyright (c) 2007 Douglas Alan 
//
//=

Thanks,
|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Convert to C/C++?

2007-06-14 Thread Douglas Wells
In article <[EMAIL PROTECTED]>,  SpreadTooThin <[EMAIL PROTECTED]> writes:
> I am wondering if someone who knows the implemention of python's time
> could help converting this to c/c++

First the obligatory sermon:

If you are truly intending to utilize a UUID generator on a UNIX
platform, I urge you to seek out and use a native implementation.
Both Linux and FreeBSD distributions include such a capability,
and there are also functions available in freely available libraries.
Such a native function would offer several advantages over the
code you are attempting to copy:

   1) it could utilize the full capability of the clock rather
  than be limited to the microseconds precision in gettimeofday;
   2) it is probably implemented utilizing a system locking function
  to provide a truly unique-per-system UID;
   3) it would almost certainly incorporate a per-machine unique
  identifier, as called for by the spec, and which is missing
  from your prototype code;
   4) it would have easier access to better pseudo-random number
  generators;
   4) it would probably be coded better than the code you provide,
  which squanders quite a bit of precision (I haven't counted
  exactly, but I would guess about 10 bits worth);
   
Also, it sounds as though you are not comfortable coding in C (as
most of the information that you seek is straight-forwardly available
from the Python and UNIX documentation), and there are numerous
subtleties in the code that you must develop:
   1) the management of endianness will require careful attention
  to your use of this function;
   2) conversion to and from 64-bit numbers requires attention to
  the suffixes.

With that said;

Python doesn't define the time epoch except on UNIX platforms, but
it's almost certainly the same as on UNIX.  So,

time.time() is equivalent to:
double time_time (void) { struct timeval tv;
gettimeofday (&tv, (void *) NULL);
return tv.tv_sec + tv.tv_usec / 1e6); }

random.randrange(value) is approximately equivalent to:
long random_randrange (unsigned long stop) {
return rand () % stop; }
 - with the caveats that:
1) you should choose a better pseudo-random number generator
   than rand();
2) you should be sure to initialize the random function, e.g.,
   via srand();

>   nanoseconds = int(time.time() * 1e9)
>   # 0x01b21dd213814000 is the number of 100-ns intervals between the
>   # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
>   self.timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
>   self.clock_seq = random.randrange(1<<14L) # instead of stable storage
>   self.time_low = self.timestamp & 0xL
>   self.time_mid = (self.timestamp >> 32L) & 0xL
>   self.time_hi_version = (self.timestamp >> 48L) & 0x0fffL
>   self.clock_seq_low = self.clock_seq & 0xffL
>   self.clock_seq_hi_variant = (self.clock_seq >> 8L) & 0x3fL

You should look up the definition of the various fields (e.g.,
clock_seq, time_low, time_mid) in a UUID specification, for example
IETF RFC 4122.  They have precise width requirements.

>   #print 'timestamp ', self.timestamp, self.time_low, self.time_mid, 
> self.time_hi_version
>   #print 'clock_seq ', self.clock_seq, self.clock_seq_low, 
> self.clock_seq_hi_variant
> 
> vs unix gettimeofday
> 
> int gettimeofday(struct timeval *tp, struct timezone *tzp);

By the way, the UNIX gettimeofday function does not include timezone:
the prototype of the second argument is "void *" and must be passed
as NULL.

Good luck, - dmw

-- 
.   Douglas Wells .  Connection Technologies  .
.   Internet:  -sp9804- -at - contek.com- .
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> Try suggesting on a Lisp or Scheme group that having only one type
> of syntax (prefix expressions) lacks something and that they should
> add variety in the form of statement syntax ;-) Hint: some Lispers
> have bragged here about the simplicity of 'one way to do it' and put
> Python down for its mixed syntax.  (Of course, this does not mean
> that some dialects have not sneaked in lists of statements thru a
> back door ;-).

Almost all Lisp dialects have an extremely powerful macro mechanism
that lets users and communities extend the syntax of the language in
very general ways.  Consequently, dialects such a Scheme try to keep
the core language as simple as possible.  Additional ways of doing
things can be loaded in as a library module.

So, a language such as Scheme may have no *obvious* way of something,
and yet may provide excellent means to extend the language so that
many obvious ways might be provided.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> My only point was that Sussman is an odd person to be criticizing
> (somewhat mistakingly) Python for being minimalist.

I think that being a language minimalist is very different from
believing that there should be exactly one obvious way to do
everything.

For instance, I believe that Python is now too big, and that much of
what is in the language itself should be replaced with more general
Scheme-like features.  Then a good macro mechanism should be
implemented so that all the conveniences features of the language can
be implemented via macro definitions in the standard library.

Macros, however, are typically claimed in these parts to violate the
"only one way" manifesto.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> Here's the situation.  Python is making inroads at MIT, Scheme home turf. 
> The co-developer of Scheme, while writing about some other subject, tosses 
> in an off-the-wall slam against Python.  Someone asks what we here think. 
> I think that the comment is a crock and the slam better directed, for 
> instance, at Scheme itself.  Hence 'he should look in a mirror'.

You are ignoring the fact that Scheme has a powerful syntax extension
mechanism (i.e., hygenic macros), which means that anyone in the world
can basically extend Scheme to include practically any language
feature they might like it to have.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
Kay Schluehr <[EMAIL PROTECTED]> writes:

> On 15 Jun., 22:58, Douglas Alan <[EMAIL PROTECTED]> wrote:

>> For instance, I believe that Python is now too big, and that much
>> of what is in the language itself should be replaced with more
>> general Scheme-like features.  Then a good macro mechanism should
>> be implemented so that all the conveniences features of the
>> language can be implemented via macro definitions in the standard
>> library.

> And why sould anyone reimplement the whole standard library using
> macro reductions? Because this is the "one obvious way to do it" for
> people who are addicted to Scheme?

(1) By, "should be replaced", I meant in an ideal world.  I'm not
proposing that this be done in the real world anytime soon.

(2) I didn't suggest that a single line of the standard library be
changed.  What would need to be changed is the core Python language,
not the standard library.  If this idea were implemented, the core
language could be made smaller, and the features that were thereby
removed from the language core could be moved into the standard
library instead.

(3) My reasons for wanting this have nothing to do with being
"addicted to Scheme", which I almost never use.  It has to do more
with my language design and implementation aesthetics, and my desire
for a syntax extension mechanism so that I can add my own language
features to Python without having to hack on the CPython source code.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Fri, 15 Jun 2007 17:05:27 -0400, Douglas Alan wrote:

>> You are ignoring the fact that Scheme has a powerful syntax extension
>> mechanism (i.e., hygenic macros), which means that anyone in the world
>> can basically extend Scheme to include practically any language
>> feature they might like it to have.

> You say that like it is a good thing.

A chaque son gout.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-15 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> > You are ignoring the fact that

> This prefactory clause is false and as such it turns what was a true 
> statement into one that is not.  Better to leave off such ad hominisms and 
> stick with the bare true statement.

You went on about how Gerry Sussman's opinion is a crock and how he
should look in the mirror, and then you get bent out of shape over the
phrase, "you are ignoring"???  For the record, "you are ignoring" is
not an ad hominem; "anyone who doesn't know how to spell 'ad hominem'
has the intelligence of a mealworm" is an ad hominem.

> > Scheme has a powerful syntax extension mechanism

> I did not and do not see this as relevant to the main points of my
> summary above.  Python has powerful extension mechanisms too, but
> comparing the two languages on this basis is a whole other topic.

How do you know that Prof. Sussman doesn't consider the macro issue to
be essential?  Certainly other Lisp aficionados do, as does, I believe
Guy Steele, the other inventor of Scheme.

It appears to me that you are missing the point that having a
minimalist disposition towards programming language design does not
preclude believing that such languages should have features that are
missing from Python.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-16 Thread Douglas Alan
Dennis Lee Bieber <[EMAIL PROTECTED]> writes:

>   Macros? Unfortunately to my world, macros are those things
> found in C, high-powered assemblers, and pre-VBA Office. As such,
> they do anything but keep a language small, and one encounters
> multiple implementations of similar functionality -- each
> implementation the pride of one person, and abhorred by the person
> who now must edit the code.

Comparing C macros to Lisp macros is like comparing a Sawzall to a
scalpel.

Regarding having enough rope to hang yourself, the same claim can be
made about any language abstraction mechanism.  E.g., classes are to
data types as macros are to syntax.  You can abuse classes and you can
abuse macros.  Both abuses will lead to abhorring by your
collaborators. And either abstraction mechanism, when used properly,
will result in more elegant, easier to read and maintain code.

Both abstraction mechanisms also allow language feature exploration to
occur outside of the privileged few who are allowed to commit changes
into the code-base for the interpreter or compiler.  I think that this
is one of the things that Gerry Sussman might be getting at when he
talks about how science works.  (Or at least that's what I would be
getting at if I were in his shoes.)

In the Lisp community, for instance, there have been lots of language
features that were implemented by people who were not part of the core
language development clique, but that were later widely adopted.
E.g., the Common Lisp OO system with mutimethods (CLOS), and the
"loop" macro.  These features didn't require any changes to the core
language implementation, and so you can see that Lisp-style macros are
also a huge modularity boon for language implementation.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-18 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> |>oug writes:

>> Scheme has a powerful syntax extension mechanism

> I did not and do not see this as relevant to the main points of my
> summary above.  Python has powerful extension mechanisms too, but
> comparing the two languages on this basis is a whole other topic.

Please note that Guy Steele in his abstract for "Rabbit: A Compiler
for SCHEME", specifically mentions that Scheme is designed to be a
minimal language in which, "All of the traditional imperative
constructs [...] as well as many standard LISP constructs [...] are
expressed in macros in terms of the applicative basis set. [...] The
macro approach enables speedy implementation of new constructs as
desired without sacrificing efficiency in the generated code."

   http://library.readscheme.org/servlets/cite.ss?pattern=Ste-78b

Do you now see how Scheme's syntax extension mechanism is relevant?

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-19 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> The main point of my original post was that the quoted slam at Python was 
> based on a misquote of Tim Peters

But it wasn't based on a "misquote of Tim Peters"; it was based on an
*exact* quotation of Tim Peters.

> and a mischaracterization of Python

I find Sussman's criticism not to be a mischaracterization at all: I
and others have previous mentioned in this very forum our desire to
have (in an ideal world) a good syntax extension facility for Python,
and when we've done so, we've been thoroughly pounced upon by
prominent members of the Python community as just not understanding
the true "Weltanschauung" of Python.  This despite the fact that I
have been happily and productively programming in Python for more than
a decade, and the fact that Guido himself has at times mentioned that
he's been idly considering the idea of a syntax extension facility.

The reason given for why macros wouldn't gel with Python's
Weltanschauung has typically been the "only one obvious way" koan, or
some variant of it.

> and that it was out-of-place in the quoted discussion of physics
> methods and that it added nothing to that discussion and should
> better have been omitted.  *All of this has nothing to do with
> Scheme.*

I'm not sure what you're getting at.  Gerry Sussman has a philosophy
of language design that is different from Python's (at least as it is
commonly expressed around here), and he was using an analogy to help
illuminate what his differences are.  His analogy is completely clear
to me, and, I in fact agree with it.  I love Python, but I think the
"only one obvious way" philosophy may do more harm than good.  It is
certainly used, in my experience, at times, to attempt to squelch
intelligent debate.

> At the end, I added as a *side note* the irony that the purported author 
> was the co-developer of Scheme, another 'minimalist algorithm
> language 

Sussman's statements are not ironic because Scheme is a language that
is designed to be extended by the end-user (even syntactically), while
keeping the core language minimal.  This is a rather different design
philosophy from that of Python.

> (Wikipedia's characterization) with more uniform syntax than Python and 
> like Python, also with one preferred way to scan sequences (based on my 
> memory of Scheme use in the original SICP, co-authored by the same 
> purported quote author, and also confirmed by Wikipedia).

There is no one preferred way to scan sequences in Scheme.  In fact,
if you were to take SICP at MIT, as I did when I was a freshman, you
would find that many of the problem sets would require you to solve a
problem in several different ways, so you would learn that there are
typically a number of different reasonable ways to approach a problem.
E.g., one of the first problem sets would have you implement something
both iteratively and recursively.  I recall another problem set where
we had to find the way out of a maze first using a depth-first search
and then using a breadth-first search.

> | [Steele quote deleted]
> | Do you now see how Scheme's syntax extension mechanism is relevant?

> No.  This just partly explains why Scheme gets away with being
> minimalist.  I explicitly referred to the core language as delivered
> and as used in SICP.

I suggest that you haven't yet grokked the Weltanschauung of Scheme.
Scheme aficionados would not typically insist that a proposed language
feature is not good because it violates anything like an "only one
obvious way" rule.  Rather they would argue that if it can be
implemented as fuctions and/or macros, then it *should* be implemented
that way, rather than polluting the core language.  The new facility
should then be included in a library.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-19 Thread Douglas Alan
Neil Cerutti <[EMAIL PROTECTED]> writes:

> |>oug writes:

>> Sussman's statements are not ironic because Scheme is a
>> language that is designed to be extended by the end-user (even
>> syntactically), while keeping the core language minimal.  This
>> is a rather different design philosophy from that of Python.

> Which version Scheme, though? Scheme has only formally had macros
> since R4RS, and then only as an extension. Macros are an extension
> to Scheme, rather than a founder.

Macros were only *standardized* in Scheme with R4RS.  This is because
they wanted to figure out the "right" way to do macros before putting
it in stone.  (Common Lisp-like non-hygienic macros were considered
inelegant.)  All the major implementations of Scheme that I know of
implemented some form of powerful macro mechanism.  N.b., Rabbit,
which was Guy Steele's implementation of Scheme, and completed long,
long before the R4RS standard.  (Guy Steele was one of the two
inventors of Scheme.)  And, as far as I am aware, the plan was always
to eventually come up with a macro mechanism that was as elegant as
the rest of Scheme.  The problem with this approach was that achieving
this daunting goal turned out to take quite a while.

> Python could conceivably end up in the same position 15 years
> from now, with macros a well-established late-comer, as
> generators have become.

That would be very cool.  The feeling I get, however, is that there
would be too much complaining from the Python community about how such
a thing would be "un-Pythonic".

> The SRFIs are cool.

> The last time I dipped my toe into the Scheme newsgroup, I was
> overwhelmed by the many impractical discussions of Scheme's dark
> corners. Python is either much more free of dark corners, or else
> simply doesn't attract that kind of aficionado.

I don't really think that Scheme itself has many dark corners -- it's
just that being basically a pristine implementation of lambda
calculus, Scheme lets you directly explore some pretty mind-bending
stuff.  I would agree that most of that kind of stuff is not
particularly practical, but it can be fun in a hackerly,
brain-expanding/brain-teaser kind of way.

I think that most people who program in Scheme these days don't do it
to write practical software.  They either do it to have fun, or for
academic purposes.  On the other hand, most people who program in
Python are trying to get real work done.  Which is precisely why I
program a lot in Python and very little in Scheme these days.  It's
nice to have the batteries included.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-19 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> Nonetheless, picking on and characterizing Tim's statement as
> anti-flexibility and un-scientific is to me writing of a sort that I
> would not tolerate from my middle-school child.

Now it is you who are taking Sussman's comments out of context.
Sussman does not claim that Python is "un-scientific" -- he merely
holds it up as a example of canonical engineering that eschews the
kinds of flexibility that is to be found in biological systems and in
the practice of science.  In this regard, Sussman is merely
criticizing engineering "best practices" in general, not Python in
specific, and is arguing that if we want to engineer systems that are
as robust as biological systems then we need to start exploring
radically different approaches to software design.

> Python is an algorithm language and a tool used to engineering
> information systems, which is something different.  The next
> sections are about exploratory behavior.  Languages do not 'behave',
> let alone 'explore'.

I think you are missing the point.  Sussman is making a broad
criticism of software engineering in general, as it is understood
today.  The essay in questions was written for a graduate-level MIT
computer science class that aims to explore potential avenues of
research into new languages and approaches that encourage and
facilitate more robust software systems.  As good as Python is, it is
still largely an encapsulation of the best ideas about software
engineering as it was understood in the early 80's.  We're now 20+
years on, and it behooves our future Computer Science researchers to
consider if we might not be able to do better than we could in 1984.

> So Python seems to have the sort of flexibility that he implicitly
> claims it does not.

Python most certainly does *not* have the type of flexibility that he
is talking about.  For instance, one of the things that he talks about
exploring for more robust software systems is predicate dispatching,
which is an extension of multiple dispatch.  Although you might be
able to cobble something like this together in Python, it would end up
being very cumbersome to use.  (E.g., Guido wrote an essay on doing
multiple dispatch in Python, but you wouldn't actually want to write
Python code that way, because it would be too syntactically
cumbersome.)  In dialects of Lisp (such as Scheme), however,
subsystems to explore such alternative programming models can be
written completely within the language (due, in part to their syntax
extension facilities).  This is how the Common Lisp Object System came
to be, for instance.  CLOS supports all sorts of OO stuff that even
Python doesn't, and yet Lisp without CLOS isn't even an OO language.

> The general problems of software inflexibility that he mentioned in
> a previous section have nothing specific to do with Python.

Right.  And he never said they did.

> When he gets to solutions, one long section (page 13) somewhat
> specific to languages, versus applications thereof, is about
> extensible generic operations "where it is possible to define what
> is meant by addition, multiplication, etc., for new datatypes
> unimagined by the language designer."  Well, golly gee.  Guess what?
> Not only is Python code generic unless specialized (with isinstance
> tests, for instance), but it is highly extensible for new datatypes,
> just as Sussman advocates.  There is a special method for just about
> every syntactic construct and builtin function.  And 3.0 may add a
> new generic function module to dispatch on multiple arguments and
> possibly predicates.

You didn't read the paper very carefully.  Sussman points out that
traditional OO languages are up to this sort of stuff to some extent,
but not to the extent which he thinks is required to solve future
challenges.  He things, for instance, that predicate dispatching,
backtracking, and first-class continuations will be required.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-19 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Tue, 19 Jun 2007 17:46:35 -0400, Douglas Alan wrote:

>> I think that most people who program in Scheme these days don't do it
>> to write practical software.  They either do it to have fun, or for
>> academic purposes.  On the other hand, most people who program in
>> Python are trying to get real work done.  Which is precisely why I
>> program a lot in Python and very little in Scheme these days.  It's
>> nice to have the batteries included.

> So, once you've succeeded in your campaign to make Python more like
> Scheme, what language will you use for getting real work done?

The problem with using Scheme for real work is that it doesn't come
with enough batteries included and there isn't a big enough of a
community behind it that uses it for real work.

Also, the Scheme standard has progressed at a terribly slow pace.  I
have heard that the reason for this is due to the way that its
standardizing committees were set up.

One of the whole reasons to use Lisp is for its extensible syntax, but
it took more than a decade for macros to make it into the Scheme
standard.  And without a standard macro system, there was no standard
library -- not even for doing OO programming.

> And how long will it take before Schemers start agitating for it to
> become more like Scheme?

> There is a huge gulf between the claim that Python needs to be more
> Scheme-like, and the fact that by your own admission you use Python,
> not Scheme, for real work. What benefit will be gained? The ability
> to "directly explore some pretty mind-bending stuff ... in a
> hackerly, brain-expanding/brain-teaser kind of way"?

Well, go to MIT and take SICP and then the graduate-level sequel to
the class, Adventures in Advanced Symbolic Programming, and then
you'll see what some of the advantages would be.

A good multimethod system, e.g., would make Python a significantly
nicer language for my purposes, for instance.

For the record, I have a huge problem with NIH-syndrome, and think
that every programming language in the world could learn a thing or
two from what other languages have gotten right.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-20 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> | I think you are missing the point. Sussman is making a broad
> | criticism software engineering in general, as it is understood
> | today.

> On the contrary, I understood exactly that and said so.  *My* point
> is that in doing so, he made one jab at one specific language in a
> herky-jerky footnote (a sentence on systems design philosopy, one on
> Python, one on physics) that I consider to be at least misleading.
> And so I feel the essay would be better without that wart.

The footnote is only misleading if you read it out of the context of
the essay.  And Sussman clearly only picked on Python, in specific,
because Python is the only language for which this facet of current
engineering "best practices" has been actually been eloquently
committed to paper.  There is nothing in the essay to suggest that
Python is any worse than any other popular production programming
language with respect to the issues that Sussman is addressing.

> | > So Python seems to have the sort of flexibility that he implicitly
> | > claims it does not.

> | For instance, one of the things that he talks about exploring for
> | more robust software systems is predicate dispatching, which is an
> | extension of multiple dispatch.

> Which I obviously read and responded to by noting "And 3.0 may add a new 
> generic function module to dispatch on multiple arguments and possibly 
> predicates."

So, that's great.  Python will once again adopt a wonderful feature
that has been usable in Lisp implementations for 20 years now.  (This
is a good thing, not a bad thing.  I just don't like so much the
having to wait 20 years.)  The problem with Python's model is that you
have to wait for a rather centralized process to agree on and
implement such a feature.  In the Lisp community, *anyone* can easily
implement such features in order to experiment with them.  This allows
much more experimentation to take place, which is one of the reasons
why Gerry Sussman brought the scientific community into the
discussion.  The ability for people to readily conduct such
experiments benefits me, even if I personally never want to write a
macro or implement a language feature myself.

Related to this is the fact that it's much harder to be able to get
new language features right, unless you can get them wrong a few times
first.  It's no accident that when Python adds features from Lisp and
Haskell, etc., that it does a pretty decent job with them, and that's
because it was able to learn from the mistakes and triumphs of others
who tried out various good and not-so-good language features in other
languages first.

The downside of Python's approach is that it makes Python not such a
very good language for exploring these potentially useful features
within Python in the first place.  The Python community has to watch
what is going on in other programming language communities and then
raid these communities for their good ideas.

Perhaps this is not a bad thing if people just want Python to be a
programming language for getting real work done.  But, personally, I
would prefer to have a language that works well for *both* production
work *and* for exploration.  At the moment, neither Python nor Scheme
fits my bill, which is why I would like to see a programming language
that combines the best of both worlds.

> | Although you might be able to cobble something like this together
> | in Python, it would end up being very cumbersome to use.

> Well, talk about shooting down innovations before they happen.
> Perhaps you could wait and see what Eby and others come up with in
> the next year.

I was referring to implementing these sorts of features within Python
(i.e., by writing Python modules in Python to support them) -- not
waiting for Python 3000, which may or may not have the features that I
want.

> [from your other post]
> | A good multimethod system, e.g., would make Python a significantly
> | nicer language for my purposes, for instance.

> Or better yet, read http://www.python.org/dev/peps/pep-3124/
> (tentatively approved by Guido, pending actual code) and perhaps
> some of the discussion thereof on the Python-3000 dev list and help
> design and code something that would be at least usable if not
> 'good'.

Thanks for the pointer -- I will eagerly check it out.

> | You didn't read the paper very carefully.

> Because I don't agree with you?

No, because he clearly is not criticizing Python, in specific, and the
mention of Python is due *solely* to the fact that Python just happens
to mention, in one of its manifestos, a principle that would be
generally held to be true as a current best engineering practice.  I
feel that a careful reading of the paper would have made this
apparent.

Also, I think it a bit counterproductive to get all up in arms about
such minor jabs.  Python is strong enough to withstand all sorts of
valid criticism, as is Scheme.  Even things that are excellent can be
made better, and also t

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-20 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Tue, 19 Jun 2007 20:16:28 -0400, Douglas Alan wrote:

>> Steven D'Aprano <[EMAIL PROTECTED]> writes:

>>> On Tue, 19 Jun 2007 17:46:35 -0400, Douglas Alan wrote:

>> The problem with using Scheme for real work is that it doesn't come
>> with enough batteries included and there isn't a big enough of a
>> community behind it that uses it for real work.

> And yet there have been so many millions of dollars put into
> developing Lisp...

> I guess this is another example of perfection being the enemy of the
> good.

That's probably a valid criticism of Scheme.  Not so much of Lisp in
general.  The reason that Common Lisp hasn't been widely adopted
outside of the AI community, for instance, has more to do with most
programmers apparently not understanding the joys of Cambridge Polish
Notation.  Also, Lisp was garbage-collected back when
garbage-collection had a bad name, due to it being considered a
resource hog.  And then a large part of the Lisp community decided to
concentrate on building special hardware (i.e. Lisp machines) for
developing Lisp applications, rather than making good Lisp development
environments for Fortran/C machines (i.e., all normal computers).

It was clear to me at the time that it's a very hard sell to convince
people to buy expensive hardware to develop in a programming language
that hasn't yet been popularized.  But apparently what was obvious to
me was not so apparent to those who dreamed of IPO riches.

> All that development into Lisp/Scheme to make it the best, purest,
> most ideal programming language, with such flexibility and
> extensibility.  that nobody wants to use it. You can write any
> library and macro system you need, but nobody has.

Lisp in general has had all sorts of fancy macro packages for it since
the dawn of time.  But Lisp wasn't really standardized until Common
Lisp in the early '80s.  CLOS (the Common Lisp Object System), which
is implemented via macros entirely within Common Lisp itself, was
completed in the latter half of the '80s.

> I don't mean literally nobody, of course. Its a figure of
> speech. But it seems that people tend to program in Scheme for fun,
> or to stretch the boundaries of what's possible, and not to Get The
> Job Done.

Well, most implementations don't have batteries included, the way that
Python does.  Guile attempts to, as does the Scheme Shell, but for
various reasons they didn't catch on the way that Python and Perl and
Ruby have.

>> Well, go to MIT and take SICP and then the graduate-level sequel to
>> the class, Adventures in Advanced Symbolic Programming, and then
>> you'll see what some of the advantages would be.

> Are you suggesting that the only way to see the advantages of Scheme
> is to do a university course?

No, I was just suggesting *one* way of seeing the light.  I think,
though, that it's probably difficult to grasp why Scheme is so
interesting without taking a good class or two on the topic.  Not that
acquiring insight on one's own is impossible, but most people would
also have a hard time seeing why group theory or linear algebra are
really interesting without taking good classes one the subjects.

Python doesn't really require taking a class in it because it's really
very similar to many other programming languages.  So if you already
know any of the others, Python is very easy to pick up.  Scheme, on
the other hand, is more of a departure from what most people would
already be comfortable with.

>> A good multimethod system, e.g., would make Python a significantly nicer
>> language for my purposes, for instance.

> http://en.wikipedia.org/wiki/Multimethod#Python

Sure, you can do it in Python, but I bet that it's neither very fun,
nor efficient.

>> For the record, I have a huge problem with NIH-syndrome, and think that
>> every programming language in the world could learn a thing or two from
>> what other languages have gotten right.

> Of course. And Python, more than most, has shamelessly copied
> features from other languages.

To make myself a bit more clear, I don't think that Python suffers all
that much from NIH.  On the other hand, I think that many people in
discussion forums in general often do.  Here being no exception.

> So the question is, are Scheme macros one of those things that
> "other languages have gotten right"? Could they be a case of
> over-generalization? Or somewhere in between?

I don't know of any language that is not a dialect of Lisp that has a
good syntax extension mechanism.  Lisp dialects tend to get it right,
more or less, but solving the issue is much more difficult for any
language that doesn't have a Lisp-like syntax.  Lisp's syntax is
particularly amenable to syntax extension.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-20 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> All of which makes Douglas Alan's accusations of Not Invented Here 
> syndrome about Python seem rather silly.

I've never made such an accusation about Python itself -- just about
the apparent attitude of some pontiffs.

> The point I was making isn't that Scheme/Lisp features are "bad",
> but that there is no reason to slavishly follow Scheme just because
> it is(?)  technically the most "pure" programming language.

I don't argue in favor of purity.  I argue in favor of functionality
that would help me write better programs more easily.

Having a somewhat pure and minimalistic core language, however,
probably does help to make a language easier to implement, maintain,
and understand.

> I'm glad somebody understands lambda calculus and closures and meta-
> classes, and that those people have created Python so I don't have
> to.  And I suspect that for every Douglas Alan enamored with Scheme,
> there are ten thousand programmers who just want to use a handful of
> pre-built tools to get the work done, never mind using macros to
> create the tools they need before they can even start.

I don't typically want to write that many macros myself.  I want to be
part of a community where cool macro packages are actively developed
that I can then use.  For instance, in Common Lisp, the entire OO
system is just a big macro package that was implemented entirely
within the language.

With macros and first class continuations, as Sussman points out in
his essay, people can then implement very interesting features like
backtracking.  Again, I don't want to implement a backtracking macro
package myself; I want to be able to use what the community might come
up with.

> But "Scheme has macros" isn't a justification for why Python should
> have them.

No one ever gave that justification.  The justification is that they
are *good*.

Macros are a way to abstract syntax the way that objects are used to
abstract data types and that iterators and generators abstract
control, etc.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-20 Thread Douglas Alan
Michele Simionato <[EMAIL PROTECTED]> writes:

> In practice Scheme follows exactly the opposite route: there are
> dozens of different and redundant object systems, module systems,
> even record systems, built just by piling up feature over feature.

The solution to this is to have a standard library which picks the
best of each and standardizes on them.  (E.g., for Common Lisp, CLOS
became the standard object system, but there was certainly competition
for a while.  E.g., Flavors, Common Loops, etc.) The problem with this
for Scheme is that the Scheme standardizing committees operate at a
glacial pace.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-20 Thread Douglas Alan
Robert Kern <[EMAIL PROTECTED]> writes:

>> The problem with Python's model is that you
>> have to wait for a rather centralized process to agree on and
>> implement such a feature.

> No, you don't. Philip Eby has been working on various incarnations
> of generic functions for some time now. The only thing new with 3.0
> is that they may be included in the standard library and parts of
> the rest of the standard library may use them to implement their
> features. Implementing generic functions themselves don't require
> anyone to convince python-dev of anything.

>   http://python.org/pypi/simplegeneric/0.6
>   http://peak.telecommunity.com/DevCenter/RulesReadme

The first one doesn't do multiple dispatch.  I'll have to have a look
at the second one.  It looks interesting.  This link

   http://www.ibm.com/developerworks/library/l-cppeak2/

shows PEAK being used to do multiple dispatch based on predicates, but
the code to implement the predicates is in strings!  Sure, if you
don't have macros, you can always use eval instead if you have it, but
(1) doing so is ugly and dangerous, and (2) it's inefficient.  Lisp
implementations these days do fancy stuff (multiple dispatch, etc.)
implemented as macros and yet typically end up generating code that
runs within a factor of 2 of the speed of C code.

In addition to having to code predicates in strings, using PEAK seems
syntactically rather cumbersome.  Macros would help solve this
problem.  Decorators seem to help to a large extent, but they don't
help as much as macros would.

Thanks for the pointers.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-21 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Wed, 20 Jun 2007 17:23:42 -0400, Douglas Alan wrote:

>> Macros are a way to abstract syntax the way that objects are used to
>> abstract data types and that iterators and generators abstract control,
>> etc.

> But why is the ability to abstract syntax good?

It allows the community to develop language features in a modular way
without having to sully the code base for the language itself.  A
prime example of this is how CLOS, the Common Lisp Object System was
implemented completely as a loadable library (with the help of many
macros) into Common Lisp, which was not an OO language prior to the
adoption of CLOS.

The fact that CLOS could be developed in a modular way allowed for a
number of different groups to work on competing object systems.  After
some experience with the pros and cons of the various object systems,
the developers of CLOS were able to incorporate most of the best ideas
from the entire field and then get it adopted as a defacto standard.

This allowed, for instance, the inclusion of multimethods, which are
an extremely nice feature for modular code development.  In prior Lisp
dialects I had used, the object systems were more like the
single-object dispatching OO system in Python, which is substantially
inferior.  The fact that the entire OO system in Common Lisp could be
loaded as a module that is coded entirely within Common Lisp allowed
for a large jump in the quality of its OO subsystem.

> One criticism of operator overloading is that when you see X + Y you
> have no real idea of whether it is adding X and Y together, or doing
> something bizarre.

Yes, and despite this, operator overloading is an essential feature
for a modern language.  (Java's lack of it notwithstanding.)

> Now allow syntax to be over-ridden as well, and not only can't you tell 
> what X + Y does, but you can't even tell what it *means*. Maybe its a for-
> loop, calling the function Y X times.

(1) With operator overloading you have no idea what X + Y *means*.  It
could be feeding the cat, for all you know.  If that turns out to
be the case, you fire the programmer in question.  Just because a
language feature *can* be abused is no reason to leave it out of a
language.  Power always comes with responsibility, but we still
need powerful programming languages.

(2) In Lisp, you cannot redefine existing syntax (without modifying
the standard library, which would be considered very rude), so the
problem that you are talking about is moot.  You can only add
*new* syntactic constructs.  I would suggest that any proposed
syntax extension mechanisms for other languages behave like Lisp
in this regard.

> Sometimes, more freedom is not better. If you had a language that
> let you redefine the literal 1 to mean the integer zero, wouldn't
> that make it much harder to understand what even basic arithmetic
> meant?

But we're not talking about anything like this.  E.g., in some
dialects of Lisp it used to be possible to set the variable that
contained the value for *true* to the value for *false*.  If you
actually did this, however, just imagine the havoc that it would
wreak.  So ultimately, this capability was removed.

Alas, in Python, you can still do such a crazy thing!

> But that doesn't mean I want a language where anything goes

You are imagining something very different from what is proposed.
Lisp-like macros don't allow "anything goes".

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-21 Thread Douglas Alan
Neil Cerutti <[EMAIL PROTECTED]> writes:

>>> But why is the ability to abstract syntax good?

>> It allows the community to develop language features in a
>> modular way without having to sully the code base for the
>> language itself.  

> That's not an advantage exclusive to macros, though.

No, but macros are often are necessary to be able to implement such
features in (1) an efficient-enough manner, and (2) in a manner that
is syntactically palatable.  E.g., PEAK for Python implements multiple
predicate-based dispatch, but you have to define the predicates as
Python code within strings.  That's not very pretty.  And probably not
very fast either.  Though Python, in general, is not very fast, so
perhaps that doesn't matter too much for Python.

> Some time last week I found myself writing the following thing in
> Python:

> [...]

> I deleted it right after I tried to use it the first time. Using it
> is more cumbersome than simply repeating myself, due to syntax
> limitations of Python.

See what I mean!

> And other, more bizarre syntax extensions have been perpetrated.
> mx.TextTools uses Python tuples to write a completely different
> programming language.

Sounds like "the Loop macro" for Lisp, which implements a mini sort of
Cobol-like language just for coding gnarly loops within Lisp.  It
turns out that when restricted to just coding gnarly loops, this is a
much better idea than it sounds.

Yes, you can do this sort of thing, sort of, without macros, but, as
we discussed above, the result is often ugly and slow.

>> A prime example of this is how CLOS, the Common Lisp Object
>> System was implemented completely as a loadable library (with
>> the help of many macros) into Common Lisp, which was not an OO
>> language prior to the adoption of CLOS.

> Is there a second example? ;)

Why yes, now that you mention it: the Loop macro.  Also, in many
implementations of Lisp, much of the core language is actually
implemented using macros against an even smaller core.  Keeping this
inside core as small as possible helps make the implementation easier
to construct, maintain, and optimize.

Also, way back when, when I used to code in Maclisp, I implemented my
own object system and exception handling system in macros, as Maclisp
had neither of these off the shelf.  The object system took me a
couple of weeks to do, and the exception handing system a couple of
days.  They worked well, looked good, and ran fast.

> Seriously, maybe Python looks like 'blub' (thanks, Paul Graham), to
> the skilled Lisp user, but it makes a lot of other languages look
> like 'blub', too, including, sometimes, Lisp: Lisp has to 'blub'
> generators.

Actually, Scheme has first class continuations, and with continuations
and macros you could easily implement generators, and I'm sure someone
has.  Whether such a library has been widely adopted for Scheme,
though, I have no idea.

You're probably right about Common Lisp, which is probably missing
generators due to efficiency concerns.  Lisp Machines had "stack
groups", which were basically the same thing as generators, but making
a call to a stack group was 100 times slower than a normal function
call.  This meant that people generally didn't use them even when it
would make their code more elegant, due to the huge performance cost.

Now, since Python is like 100 times slower than Common Lisp anyway,
you don't notice this performance issue with Python's generators.
They just happen to be only as slow as the rest of Python.

|>oug

"Lisp is worth learning for the profound enlightenment experience you
will have when you finally get it; that experience will make you a
better programmer for the rest of your days, even if you never
actually use Lisp itself a lot." -- Eric Raymond
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-21 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> | It allows the community to develop language features in a modular way
> | without having to sully the code base for the language itself.
> [etc]

> Some of the strongest opposition to adding macros to Python comes
> from people like Alex Martelli who have had experience with them in
> *multi-person production* projects.  He claimed in various posts
> that the net effect was to reduce productivity.  So convince us (and
> Guido!) that he is wrong ;-)

I'm not convinced that Guido is wrong because I know that he has at
least occasionally mused that he might someday consider a macro
facility for Python.

Alex Martelli, on the other hand, although an extremely smart guy,
seems to me to often be over-opinionated and dismissive.

Regarding being on a project where people used macros poorly, I've
also been on projects where people did a poor job of OO design, and a
non-OO design would have been better than the crappy OO design that
was ultimately used.  Does that mean that we should remove the OO
features from Python?

Paul Graham made it rich implementing Yahoo Stores in Lisp, and claims
that heavy use of macros is one of the reasons that he was able to
stay well-ahead of all the competition.  So, maybe Paul and Alex can
duke it out.  Personally, I like Paul's style better.  And he's made a
lot more money using his theory of software design.

> But I would prefer you somehow try to help make usable multi-arg and 
> predicate dispatch a reality.

Alas, I can't stand programming in C, so there's no way I'm going to
dive that deeply into the CPython code base.  If I could help
implement it in Python itself, using a good macro facility, sign me up!

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-22 Thread Douglas Alan
Neil Cerutti <[EMAIL PROTECTED]> writes:

> That said, I wouldn't give up the summer I spent studying _Simply
> Scheme_.

Sounds like fun.  Is this like a kinder, gentler version of SICP?

I'm not sure, though, that I could have learned computer science
properly without the immortal characters of Ben Bittwiddler and Harry
Reasoner intruding into every problem set.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-22 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Thu, 21 Jun 2007 15:25:37 -0400, Douglas Alan wrote:

>> You are imagining something very different from what is proposed.
>> Lisp-like macros don't allow "anything goes".

> Provided people avoid doing anything "which would be considered very 
> rude" (your own words).

No, Lisp macros are entirely contained within a begin and end
delimiter, which is introduced by the name of the macro.  E.g., here
is a real example of some Lisp code that I wrote aeons ago using the
loop macro:

   (loop for index from 0 below size
  for element in contents
  do (store (arraycall t array index)
element)
  finally (return (make-htable BUCKETS size
   ARRAY array
   KEY-PRINTER key-printer
   ITEM-PRINTER item-printer)

The syntactical extensions supported by the loop macro can only begin
starting immediately after "(loop " and they end with the matching
closing parenthesis.  There's no way in Lisp to write a macro whose
syntactical extensions can extend outside of this very explicitly
delimited scope.  Nor can they mess with Lisp's tokenization.

> Python already allows me to shoot myself in the foot, if I wish. I'm 
> comfortable with that level of freedom. I'm not necessarily comfortable 
> with extensions to the language that would allow me the freedom to shoot 
> myself in the head.

Lisp macros don't let you shoot yourself in the head -- only in the
foot.  Being able to do

   True = False

is being able to shoot yourself in the head.  And Python certainly
lets you do that.

> I would need to be convinced of the advantages, as would many other
> people, including the BDFL.

The proof is in the pudding for anyone who has seen the advantages it
brings to Lisp.  As Paul Graham points out, it's hard to look up and
see the advantages of what is up there in a more powerful language.
It's only easy to look down and see the disadvantages of what is
missing from a less powerful language.  To understand the advantages,
one has to be willing to climb the hill and take in the view.

> It isn't clear exactly what functionality a hypothetical Python macro 
> system would include,

It should be largely equivalent to what is provided by Lisp.
Admittedly this is a bit more difficult for Python, as Lisp's syntax
is eminently suited for macros, while Python's is not.  One would
probably want to take a look at how Dylan solved this problem, as
Dylan implements Lisp-like macros even though it has an Algol-like
syntax.  Or you could look at the paper I wrote (for a class) on the
design of Python-like language that would support macros.  My paper is
only a rough sketch, however.

> let alone whether the benefits would outweigh the costs,

They pay off in boatloads in the Lisp community.

> (It took Lisp half a century and millions of dollars of corporate
> funding to reach where it is now.

Ummm, not really.  Lisp hasn't really changed very much since the late
'70s, and prior to that, most of the work on Lisp was just done in a
few university labs (e.g., MIT) and at Xerox Parc.  Any work and money
that has been spent on Lisp since then has just been in trying to
market it, or standardize it, or design hardware suited to running it
faster, or build better development environments for it, or optimizing
compilers, etc.

Lisp, itself, is rather easily to implement.  (Getting it to run as
fast as C is more of a challenge, what with good garbage collectors
and all being non-trivial to implement, but performance doesn't seem
to be much of an issue for the Python community.)  I made my own Lisp
implementation in C++ in two weeks.  (Not really a production dialect,
but it worked.)  Kyoto Common Lisp, which was definitely a production
implementation, was implemented by two people in a couple of years.
(It compiled Common Lisp into C.)

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-22 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> "Douglas Alan" <[EMAIL PROTECTED]> wrote in message 

> | > But why is the ability to abstract syntax good?

> | It allows the community to develop language features in a modular way
> | without having to sully the code base for the language itself.

> Anyone can write modules, experimental or otherwise, without touching the 
> code base for any particular implementation.

> For those whose know one of the implementation languages, source code 
> control systems allow one to do experiments on branches without 'sullying' 
> the trunk or impeding the development thereof.

When I said "without having to sully the code base", I meant that one
can implement a language feature for the target language as a loadable
module written entirely within the language itself, and without having
to understand anything particularly deep or specific about the language
implementation details.

I.e., I could write a new object system for Lisp faster than I could
even begin to fathom the internal of CPython.  Not only that, I have
absolutely no desire to spend my valuable free time writing C code.
I'd much rather be hacking in Python, thank you very much.

> One of the goals of the PyPy project was to allow people to experiment with 
> syntax extensions in Python itself.  (But I don't know how easy that is 
> yet.)

PyPy sounds like a very interesting project indeed!

> But I think that overall the problem of designing new syntax is more
> in the design than the implementation.  Anything new has to be
> usable, readable, not clash too much with existing style, not
> introduce ambiguities, and not move the extended language outside
> the LL(1) [I believe that is right] subset of CFLs.

People (myself included) haven't had much trouble implementing nice
and useful macro packages for Lisp.  Admittedly, it's a harder problem
for a language that doesn't have a Lisp-like syntax.  I believe that
Dylan has macros without having a Lisp-like syntax, but Dylan is
really a dialect of Lisp, only with a more traditional Algol-like
syntax veneered onto it.  My guess is that a macro developer for Dylan
would have to be familiar with an underlying hidden intermediate Lisp
syntax.  (Though I'm just really just spouting that guess out of my
butt.)

A few years back, I designed a somewhat Python-like language with a
macro facility for a class on dynamic languages and their
implementations.  I didn't implement it, however, and I doubt that
I'll have time to get around to it in this lifetime.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-22 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> | But why is the ability to abstract syntax good?

> I think this points to where Sussman went wrong in his footnote and
> Alan in his defense thereof.  Flexibility of function -- being able
> to do many different things -- is quite different from flexibility
> of syntax 

I think you are setting up a false dichotomy.  One that is related to
the false unification that annoying people used to always make when
they would perpetually argue that it wasn't important which
programming language you programmed in, as they are all Turing
equivalent anyway.  Well, I sure as hell don't want to write all my
programs for a Turning machine, and a Turing machine is certainly
Turing equivalent!

Functionality is no good if it's too cumbersome to use.  For instance,
Scheme gives you first class continuations, which Python doesn't.
Continuations let you do *all sorts* of interesting things that you
just cannot do in Python.  Like backtracking, for instance.  (Well
maybe you could do backtracking in Python with lots of putting code
into strings and liberal use of eval, for all I know, but the results
would almost certainly be too much of a bear to actually use.)

Now, continuations, by themselves, in Scheme actually don't buy you
very much, because although they let you do some crazy powerful
things, making use of them to do so, is too confusing and verbose.  In
order to actually use this very cool functionality, you need macros so
that you can wrap a pretty and easy-to-use face on top of all the
delicious continuation goodness.

You'll, just have to trust me on this one.  I've written code with
continuations, and I just couldn't make heads or tails out of the code
a few hours later.  But when prettied-up with a nice macro layer, they
can be a joy to behold.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-22 Thread Douglas Alan
"Terry Reedy" <[EMAIL PROTECTED]> writes:

> "Douglas Alan" <[EMAIL PROTECTED]> wrote in message 

> | "Terry Reedy" <[EMAIL PROTECTED]> writes:

> | > I think this points to where Sussman went wrong in his footnote
> | > and Alan in his defense thereof.  Flexibility of function --
> | > being able to do many different things -- is quite different
> | > from flexibility of syntax

> | I think you are setting up a false dichotomy.

> I think this denial of reality is your way of avoiding admitting, perhaps 
> to yourself, that your god Sussman made a mistake.

Sussman isn't my god -- Kate Bush is.

Just because I'm right and you're wrong, doesn't mean that I'm in
denial.  It is you who are in denial if you believe that syntax is
unimportant, as long as one is provided the required functionality.
In fact, that's stereotypical Computer Science denial.  Computer
Science academics will typically state as a truism that semantics are
what is important and syntax is just a boring trifle in comparison.
But time and time again, you'll see programming languages succeed or
fail more on their syntax than on their semantics.  And issues of
syntax is often where you see the most inflamed debates.  Just look at
all the flames one used to hear about Python using whitespace
significantly.  Or all the flames that one will still hear about Lisp
using a lot of parentheses.

You seem oblivious to the fact that one of the huge benefits of Python
is its elegant and readable syntax.  The problem with not having a
"flexible syntax", is that a programming language can't provide
off-the-shelf an elegant syntax for all functionality that will ever
be needed.  Eventually programmers find themselves in need of new
elegant functionality, but without a corresponding elegant syntax to
go along with the new functionality, the result is code that does not
look elegant and is therefore difficult to read and thus maintain.

Consequently, "flexibility of function" is often moot without
"flexibility of syntax".  I don't know how I can make it any clearer
than this.  I'm sorry if you don't understand what I am saying, but
just because you don't understand, or if you do, that you don't agree,
doesn't mean that I don't have a reasoned and reasonable point of
view.

> | One that is related to the false unification that annoying people
> | used to always make when they would perpetually argue that it
> | wasn't important which programming language you programmed in, as
> | they are all Turing equivalent anyway.  Well, I sure as hell don't
> | want to write all my programs for a Turning machine, and a Turing
> | machine is certainly Turing equivalent!

> Diversionary crap unrelated to the previous discussion.

Take the issue up with Paul Graham.  Since making a fortune developing
software in Lisp (making heavy use of macros), he now has much more
free time to write essays defending the truth than I do:

   http://www.paulgraham.com/avg.html

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-23 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> Nevertheless, in Python 1+2 always equals 3. You can't say the same thing
> about Lisp.

Well, I can't say much of *anything* about "1 + 2" in Lisp, since
that's not the syntax for adding numbers in Lisp.  In Lisp, numbers
are typically added using the "+" function, which might be invoked
like so:

   (+ 1 2 3)

This would return 6.

It's true that some dialects of Lisp will let you redefine the "+"
function, which would typically be a bad idea.  Other dialects would
give you an error or a warning if you tried to redefine "+".  I would
fall more into the latter camp.  (Though sometimes you might want a
way to escape such restrictions with some sort of "yes, I really want
to shoot myself in the head" declaration, as you may want to
experiment, not with changing the meaning of "(+ 1 2"), but rather
with adding some additional useful capability to the "+" function that
it doesn't already have.

Back on the Python front, although "1 + 2" might always equal 3 in
Python, this is really rather cold comfort, since no useful code would
ever do that.  Useful code might include "a + 1", but since you can
overload operators in Python, you can say little about what "a + 1"
might do or mean on the basis of the syntax alone.

Furthermore, in Python you can redefine the "int" data type so that
int.__add__ does a subtraction instead.  Then you end up with such
weirdness as

   >>> int(1.0) + int(2.0)
   -1

Also, you can redefine the sum() function in Python.

So, we see that Python offers you a multitude of ways to shoot
yourself in the head.

One of the things that annoys me when coding in Python (and this is a
flaw that even lowly Perl has a good solution for), is that if you do
something like

 longVarableName = foo(longVariableName)

You end up with a bug that can be very hard to track down.  So one use
for macros would be so that I can define "let" and "set" statements so
that I might code like this:

 let longVariableName = 0
 set longVarableName = foo(longVariableName)

Then if longVarableName didn't already exist, an error would be
raised, rather than a new variable being automatically created for me.

The last time I mentioned this, Alex Martelli basically accused me of
being an idiot for having such trivial concerns.  But, ya know -- it
isn't really a trivial concern, despite Martelli's obviously high
intellect.  A woman I work with who is bringing up a CMS using Drupal
was complaining to me bitterly that this very same issue in PHP was
causing her bugs that were hard to track down.  Unfortunately, I could
not gloat over her with my Python superiority, because if Drupal were
written in Python, rather than PHP, she'd have the very same problem
-- at least in this regard.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-23 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> But if you really want declarations, you can have them.
>
 import variables
 variables.declare(x=1, y=2.5, z=[1, 2, 4])
 variables.x = None
 variables.w = 0
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "variables.py", line 15, in __setattr__
> raise self.DeclarationError("Variable '%s' not declared" % name)
> variables.DeclarationError: Variable 'w' not declared

Oh, I forgot to mention that I work a lot on preexisting code, which I
am surely not going to go to all the effort to retype and then retest.
With the "let" and "set" macros I can use "set" without a matching
"let".  "set" just checks to make sure that a variable already exists
before assigning to it, and "let" just prevents against
double-declarations.  They can be used independently or together.
With your "variables" class, they have to be used together.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-23 Thread Douglas Alan
Michele Simionato <[EMAIL PROTECTED]> writes:

> Been there, done that. So what? Your example will not convince any
> Pythonista.

I'm a Pythonista, and it convinces me.

> The Pythonista expects Guido to do the language job and the
> application developer to do the application job.

I'm happy to hear that there is a brain washing device built into
Python that provides all Python programmers with exactly the same
mindset, as that will certainly aid in having a consistent look and
feel to all Python code.

> Consider for instance generators.

Yes, consider them!  If Python had first class continuations (like
Ruby does) and macros in 1991, it could have had generators in 1992,
rather than in 2002.  (I implemented generators using macros and stack
groups for Lisp Machines in 1983, and it took me all of a few hours.)

> In Python they are already implemented in the core language and the
> application developer does not care at all about implementing them.

And if they were implemented as macros in a library, then the
application developer doesn't have to care about implementing them
either.

> In Scheme I am supposed to implement them myself with continuations,
> but why should I do that, except as a learning exercise?

Well, when I get around to giving my sage advice to the Scheme
community, I'll let them know that generators need to be in the
standard library, not a roll-your-own exercise.

> It is much better if competent people are in charge of the very low
> level stuff and give me just the high level tools.

Even many competent people don't want to hack in the implementation
language and have to understand the language implementation internals
to design and implement language features.  By your argument,
Pythonistas might as well insist that the entire standard library be
coded in C.

> BTW, there are already Python-like languages with macros
> (i.e. logix) and still nobody use them, including people with a
> Scheme/Lisp background. That /should be telling you something.

It only tells me what I've known for at least a couple decades now --
that languages live and die on issues that often have little to do
with the language's intrinsic merits.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-23 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

>> So one use for macros would be so that I can define "let" and "set"
>> statements so that I might code like this:
>> 
>>  let longVariableName = 0
>>  set longVarableName = foo(longVariableName)
>> 
>> Then if longVarableName didn't already exist, an error would be
>> raised, rather than a new variable being automatically created for me.

> So "let" is the initial declaration, and "set" modifies the existing
> variable? 

Yes.

> What happens is you declare a variable twice?

The same thing that would happen in Perl or any other language that
supports this type of variable declaration and setting: it would raise
an error.

The big debate you get next, is then whether you should be allowed to
shadow variables in nested scopes with new variables of the same
name.  Given that Python already allows this, my guess is that the
answer should be yes.

> How long did it take you to write the macros, and use them, compared
> to running Pylint or Pychecker or equivalent?

An hour?  Who cares?  You write it once and then you have it for the
rest of your life.  You put it in a widely available library, and then
*every* programmer also has it for the rest of their lives.  The
amortized cost: $0.00.  The value: priceless.

> But if you really want declarations, you can have them.

 import variables
 variables.declare(x=1, y=2.5, z=[1, 2, 4])
 variables.x = None
 variables.w = 0
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "variables.py", line 15, in __setattr__
> raise self.DeclarationError("Variable '%s' not declared" % name)
> variables.DeclarationError: Variable 'w' not declared

Thanks, but that's just too syntactically ugly and verbose for me to
use.  Not only that, but my fellow Python programmers would be sure to
come and shoot me if I were to code that way.

One of the reasons that I want to use Python is because I like reading
and writing code that is easy to read and looks good.  I don't want to
bend it to my will at the expense of ugly looking code.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-24 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

> On Sat, 23 Jun 2007 14:56:35 -0400, Douglas Alan wrote:
>
>>> How long did it take you to write the macros, and use them, compared
>>> to running Pylint or Pychecker or equivalent?

>> An hour?  Who cares?  You write it once and then you have it for the
>> rest of your life.  You put it in a widely available library, and then
>> *every* programmer also has it for the rest of their lives.  The
>> amortized cost: $0.00.  The value: priceless.

> Really? Where do I download this macro? How do I find out about it? How
> many Lisp programmers are using it now?

(1) I didn't have to write such a macro for Lisp, as Lisp works
differently.  For one thing, Lisp already has let and set special
forms.  (Lisp uses the term "special form" for what Python would call
a "statement", but Lisp doesn't call them statements since they return
values.)

(2) You act as if I have no heavy criticisms of Lisp or the Lisp
community.  I critique everything with equal vigor, and keep an eye
out for the good aspects and ideas of everything with equal vigor.

> How does your glib response jib with your earlier claims that the
> weakness of Lisp/Scheme is the lack of good libraries?

(1) See above. (2) My response wasn't glib.

> Googling for ' "Douglas Allen" download lisp OR scheme ' wasn't very
> promising.

(1) You spelled my name wrong.  (2) I haven't written any libraries
for any mainstream dialects of Lisp since there was a web.  I did
write a multiple dispatch lookup cacher for a research dialect of
Lisp, but it  was just an exercise for a version of Lisp that few
people have ever used.

> In fairness, the various Python lints/checkers aren't part of the standard
> library either, but they are well-know "standards".

In general I don't like such checkers, as I tend to find them more
annoying than useful.

>> Thanks, but that's just too syntactically ugly and verbose for me to
>> use.

> "Syntactically ugly"? "Verbose"?

> Compare yours with mine:

> let x = 0
> let y = 1
> let z = 2
> set x = 99 

> (Looks like BASIC, circa 1979.)

It looks like a lot of languages.  And there's a reason for that -- it
was a good idea.

> variables.declare(x=0, y=1, z=2)
> variables.x = 99

> (Standard Python syntax.)

> I don't think having two easily confused names, let and set is an
> advantage,

Let and set are not easily confused.  Lisp programmers have had
absolutely no problem keeping the distinction separate for the last 47
years now.

> but if you don't like the word "declare" you could change it to
> "let", or change the name of the module to "set" (although that runs the
> risk of confusing it with sets).

> Because this uses perfectly stock-standard Python syntax, you could even
> do this, so you type fewer characters:

> v = variables
> v.x = 99

> and it would Just Work. 

I wouldn't program that way, and no one that I know would either.

In this regard you sound exactly like all the C++ folks, who when you
point out that something in C++ is inadequate for one's needs, they
point you at some cumbersome and ugly solution and then tell you that
since C++ can already deal with the complaint, that there's no good
reason to consider changing C++.  Consequently, C++ still doesn't have
a "finally" statement, and it requires either making instance
variables public or forcing the programmer to write lots of
boilerplate code writing setter and getter functions.  Fortunately,
the Python developers finally saw the errors of their ways in this
regard and fixed the situation.  But, it seems to me that you would
have been one of those people saying that there's no need to have a
way of overriding attribute assignment and fetching, as you can always
just write all that extra boilerplate code, or instead add an extra
layer of indirection (proxy objects) in your instance data to have
things done the way you want, at the expense of ugly code.

>> Not only that, but my fellow Python programmers would be sure to
>> come and shoot me if I were to code that way.

> *shrug* They'd shoot you if you used "let x = 0" too.

Clearly you are not familiar with the programmers that I work with.
As I mentioned previously, at least one of them is quite upset about
the auto-declaration feature of most scripting languages, and your
suggestion would not make her any happier.

>> One of the reasons that I want to use Python is because I like reading
>> and writing code that is easy to read and looks good.  I don't want to
>> bend it to my will at the expense of ugly looking code.

> But the "ugly looking code" is stock-s

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-24 Thread Douglas Alan
Steven D'Aprano <[EMAIL PROTECTED]> writes:

>> You seem oblivious to the fact that one of the huge benefits of Python
>> is its elegant and readable syntax.  The problem with not having a
>> "flexible syntax", is that a programming language can't provide
>> off-the-shelf an elegant syntax for all functionality that will ever
>> be needed.

> It is hardly "off-the-shelf" if somebody has to create new syntax
> for it.

Ummm. that's my point.  No language can provide all the syntax that
will ever be needed to write elegant code.  If module authors can
provide the syntax needed to use their module elegantly, then problem
solved.

>> Eventually programmers find themselves in need of new
>> elegant functionality, but without a corresponding elegant syntax to
>> go along with the new functionality, the result is code that does not
>> look elegant and is therefore difficult to read and thus maintain.

> That's true, as far as it goes, but I think you over-state your
> case.

I do not.

It is so easy for you, without *any* experience with a language (i.e.,
Lisp) or its community to completely dismiss the knowledge and wisdom
acquired by that community.  Doesn't that disturb you a bit?

> The syntax included in Python is excellent for most things, and even
> at its weakest, is still good. I can't think of any part of Python's
> syntax that is out-and-out bad.

The proposed syntax for using the proposed predicate-based multimethod
library is ungainly.

Until decorators were added to the language, the way to do things that
decorators are good for was ugly.  Decorators patch up one ugliness,
but who wants Python to become an old boat with lots of patches?

Nearly every addition made to Python since 1.5 could have been done in
the standard library, rather than being made to the core language, if
Python had a good macro system.  The exceptions, I think, being
objects all the way down, and generators.  Though generators could
have been done in the standard library too, if Python had first class
continuations, like Scheme and Ruby do.

Over time, an infinite number of examples will turn up like this, and
I claim (1) that it is better to modify the standard library than to
modify the language implementation, and that (2) it is better to allow
people to experiment with language features without having to modify
the implementation, and (3) that it is better to allow people to
distribute new language features for experimentation or production in
a loadable modular fashion, and (4) that it is better to allow
application developers to develope new language features for their
application frameworks than to not.

> The reality is, one can go a long, long, long distance with Python's
> syntax.

And you can go a long, long way with Basic, or Fortran, or C, or C++,
or Haskell, or Lisp.  None of this implies that there aren't
deficiencies in all of these languages.  Python is no exception.
Python just happens to be better than most in a number of significant
regards.

> Most requests for "new syntax" I've seen fall into a few
> categories:

> * optimization, e.g. case, repeat, multi-line lambda

I don't give a hoot about case or repeat, though a Lisp-like "loop
macro" might be nice.  (The loop macro is a little mini language
optimized for coding complicated loops.)  A multi-line lambda would
be very nice.

> * "language Foo looks like this, it is kewl"

Sometimes language Foo has features that are actually important to for
a specific application or problem domain.  It's no accident, for
instance, that Lisp is still the preferred language for doing AI
research.  It's better for Python if Python can accommodate these
applications and domains than for Python to give up these markets to
Foo.

> * the usual braces/whitespace flamewars
> * trying to get static type checking into the language
>
>
> So let's be specific -- what do you think Python's syntax is missing? If
> Python did have a macro facility, what would you change?

In addition to the examples given above, symbols would be nice.  Lisp
has 'em, Ruby has 'em, Python doesn't.  They are very useful.

An elegant multimethod based object system will be essential
for every language someday, when the time is right for people to
understand the advantages.

Manifest typing will be essential.

A backtracking system is important for some applications.  Perhaps all
applications, someday.

The ability to make mini-languages for specific domains, like fields
of math and science, is very useful, so the mathematicians and
scientists can denote things in a notation that is closer to the
notation that they actually work in.

Etc., etc., etc.  The future is long, and our ability to peer into it
is blurry, and languages that can adapt to the unforeseen needs of that
blurry future are the ones that will survive.

For instance, I can state with almost 100% certainty that one hundred
years from now, some dialect of Lisp will still be around and in
common usage.  I can't say the same thing about Python

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-24 Thread Douglas Alan
Graham Breed <[EMAIL PROTECTED]> writes:

> Another way is to decorate functions with their local variables:

 from strict import my
 @my("item")
> ... def f(x=1, y=2.5, z=[1,2,4]):
> ... x = float(x)
> ... w = float(y)
> ... return [item+x-y for item in z]

Well, I suppose that's a bit better than the previous suggestion, but
(1) it breaks the style rule of not declaring variables until you need
them, and (2) it doesn't catch double initialization.

> The best way to catch false rebindings is to stick a comment with
> the word "rebound" after every statement where you think you're
> rebinding a variable.

No, the best way to catch false rebindings is to have the computers
catch such errors for you.  That's what you pay them for.

> Then you can search your code for cases where there's a "rebound"
> comment but no rebinding.

And how do I easily do that?  And how do I know if I even need to in
the face of sometimes subtle bugs?

> Assuming you're the kind of person who knows that false rebindings
> can lead to perplexing bugs, but doesn't check apparent rebindings
> in a paranoid way every time a perplexing bug comes up, anyway.
> (They aren't that common in modern python code, after all.)

They're not that uncommon, either.

I've certainly had it happen to me on several occasions, and sometimes
they've been hard to find as I might not even see the mispeling even
if I read the code 20 times.

(Like the time I spent all day trying to figure out why my assembly
code wasn't working when I was a student and finally I decided to ask
the TA for help, and while talking him through my code so that he
could tell me what I was doing wrong, I finally noticed the "rO" where
there was supposed to be an "r0".  It's amazing how useful a TA can
be, while doing nothing at all!)

> And you're also the kind of person who's troubled by perplexing bugs
> but doesn't run a fully fledged lint.

Maybe PyLint is better than Lint for C was (hated it!), but my idea of
RAD does not include wading through piles of useless warning messages
looking for the needle warning in the warning haystack.  Or running
any other programs in the midst of my code, run, code, run, ..., loop.

> Maybe that's the kind of person who wouldn't put up with anything
> short of a macro as in the original proposal.  All I know is that
> it's the kind of person I don't want to second guess.

As it is, I code in Python the way that a normal Python programmer
would, and when I have a bug, I track it down through sometimes
painstaking debugging as a normal Python programmer would.  Just as
any other normal Python programmer, I would not use the alternatives
suggested so far, as I'd find them cumbersome and inelegant.  I'd
prefer not to have been bit by the bugs to begin with.  Consequently,
I'd use let and set statements, if they were provided (or if I could
implement them), just as I have the equivalents to let and set in
every other programming language that I commonly program in other than
Python.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-24 Thread Douglas Alan
Michele Simionato <[EMAIL PROTECTED]> writes:

> You should really be using pychecker (as well as Emacs autocompletion
> feature ...):

I *do* use Emacs's autocompletion, but sometimes these sorts of bugs
creep in anyway.  (E.g., sometimes I autocomplete in the wrong variable!)

> ~$ pychecker -v x.py
> Processing x...
>
> Warnings...
>
> x.py:4: Variable (longVarableName) not used
>
> [I know you will not be satisfied with this, but pychecker is really
> useful,

Okay, I'll check out PyChecker and PyLint, though I'm sure they will
annoy the hell out of me.  They're probably less annoying than
spending all day tracking down some stupid bug.

> since it catches many other errors that no amount of
> macroprogramming would evere remove].

And likewise, good macro programming can solve some problems that no
amount of linting could ever solve.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-25 Thread Douglas Alan
Paul Rubin <http://[EMAIL PROTECTED]> writes:

> Douglas Alan <[EMAIL PROTECTED]> writes:
>> And likewise, good macro programming can solve some problems that no
>> amount of linting could ever solve.

> I think Lisp is more needful of macros than other languages, because
> its underlying primitives are too, well, primitive.  You have to write
> all the abstractions yourself.

Well, not really beause you typically use Common Lisp with CLOS and a
class library.  If you ask me, the more things that can (elegantly) be
moved out of the core language and into a standard library, the
better.

> Python has built-in abstractions for a few container types like
> lists and dicts, and now a new and more general one (iterators), so
> it's the next level up.

Common Lisp has had all these things for ages.

> And a bunch of stuff that Python could use macros for, are easily
> done in Haskell using delayed evaluation and monads.  And Haskell is
> starting to grow its own macro system (templates) but that's
> probably a sign that an even higher level language (maybe with
> dependent types or something) would make the templates unnecessary.

Alas, I can't comment too much on Haskell, as, although I am familiar
with it to some extent, I am far from proficient in it.  Don't worry
-- it's on my to-do list.

I think that first I'd like to take Gerry Sussman's new graduate
class, first, though, and I'll find out how it can all be done in
Scheme.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-25 Thread Douglas Alan
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> Douglas Alan <[EMAIL PROTECTED]> writes:

>>> Python has built-in abstractions for a few container types like
>>> lists and dicts, and now a new and more general one (iterators), so
>>> it's the next level up.

>> Common Lisp has had all these things for ages.

> Rubbish. Do you actually know any common lisp?

Yes, though it's been quite a while, and it was mostly on Lisp
Machines, which, at the time, Common Lisp was still being
standardized, and so Lisp Machine "Chine Nual" Lisp wasn't quite
Common Lisp compliant at the time.  Also, Lisp Machine Lisp had a lot
of features, such as stack groups, that weren't put into Common Lisp.
Also, my experience predates CLOS, as at the time Lisp Machines used
Flavors.

Most of my Lisp experience is actually in MacLisp (and Ulisp and
Proto, neither of which you've likely heard of).  MacLisp was an
immediate precursor of Common Lisp, and didn't have a standard object
system at all (I rolled one myself for my applications), but it had
the Loop macro and if I recall correctly, the MacLisp Loop macro
(which was nearly identical to the Chine Nual Loop macro, which I
thought was ported rather unsullied for Common Lisp).  In any case,
IIRC, there were hooks in the Loop macro for dealing with iterators
and I actually used this for providing an iterator-like interface to
generators (for Lisp Machines) that I coded up with macros and stack
groups.

It may be that these hooks didn't make it into the Common Lisp Loop
macro, or that my memory of what was provided by the macro is a little
off.  What's not off, is that it was really easy to implement these
things, and it wasn't like I was some sort of Lisp guru -- I was just
an undergraduate student.

I will certainly admit that Lisp programmers at the time were (and
likely still are) much more enamored of mapping functions than of
iterators.  Mapping functions certainly get the job done as elegantly
as iterators most of the time, although I would agree that they are
not quite so general.  Of course, using generators, I was easily able
to make a converter that would take a mapping function and return a
corresponding iterator.

Scheme, on, the other hand, at least by idiom, has computation
"streams", and streams are equivalent to iterators.

> There is precisely no way to express
>
> for x in xs:
> blah(x)

The canonical way to do this in Lisp would be something like:

   (mapcar (lambda (x) (blah x))
   xs)

Though there would (at least in MacLisp) be a differently named
mapping function for each sequence type, which makes things a bit less
convenient, as you have to know the name of the mapping function
for each type.

> or
> x = xs[key]

I'm not sure what you are asserting?  That Common Lisp doesn't have
hash tables?  That's certainly not the case.  Or that it doesn't
provide standard generic functions for accessing them, so you can
provide your own dictionaries that are implemented differently and
then use exactly the same interface?  The latter I would believe, as
that would be one of my criticisms of Lisp -- although it's pretty
cool that you can load whatever object system you would like (CLOS
being by far the most common), it also means that the core language
itself is a bit deficient in OO terms.

This problem would be significantly mitigated by defining new
standards for such things in terms of CLOS, but unfortunately
standards change unbearably slowly.  There are certainly many
implementations of Lisp that solve these issues, but they have a hard
time achieving wide adoption.  A language like Python, which is
defined by its implementation, rather than by a standard, can move
much more quickly.  This debate though is really one more of
what is the best model for language definition, rather than one on
what the ideal language is like.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-25 Thread Douglas Alan
Paul Rubin <http://[EMAIL PROTECTED]> writes:

> Douglas Alan <[EMAIL PROTECTED]> writes:

>> I will certainly admit that Lisp programmers at the time were (and
>> likely still are) much more enamored of mapping functions than of
>> iterators.  Mapping functions certainly get the job done as elegantly
>> as iterators most of the time, although I would agree that they are
>> not quite so general.

> In the Maclisp era functions like mapcar worked on lists, and
> generated equally long lists in memory.

I'm aware, but there were various different mapping functions.  "map",
as opposed to "mapcar" didn't return any values at all, and so you had
to rely on side effects with it.

> It was sort of before my time but I have the impression that Maclisp
> was completely dynamically scoped and as such,

Yes, that's right.

> it couldn't cleanly make anything like generators (since it had no
> way to make lexical closures).

That's right, generators would have been quite difficult to do in
MacLisp.  But a Lisp Machine (with stack groups) could have done them,
and did, with or without closures.

>> Scheme, on, the other hand, at least by idiom, has computation
>> "streams", and streams are equivalent to iterators.

> No not really, they (in SICP) are at best more like class instances
> with a method that mutates some state.  There's nothing like a yield
> statement in the idiom.

Right -- I wrote "iterators", not "generators".

> You could do it with call/cc but SICP just uses ordinary closures to
> implement streams.

Yes, that's right.

>> The canonical way to do this in Lisp would be something like:
>>(mapcar (lambda (x) (blah x)) xs)

> At least you could spare our eyesight by writing that as 
> (mapcar #'blah xs) ;-).

Good point!  But I just love lambda -- even when I'm just using it as
a NOP  (Also I couldn't remember the syntax for accessing the
function property of a symbol in MacLisp.)

> The point is that mapcar (as the name implies) advances down a list
> using cdr, i.e. it only operates on lists, not general iterators or
> streams or whatever.

Right, but each sequence type had it's own corresponding mapping
fuctions.

>> > x = xs[key]

>> I'm not sure what you are asserting?  That Common Lisp doesn't have
>> hash tables?  That's certainly not the case.  Or that it doesn't
>> provide standard generic functions for accessing them

> The latter.  Of course there are getf/setf, but those are necessarily
> macros.

Right.  OO on primitive data types is kind of hard in a non OO
language.  So, when writing an application in MacLisp, or Lisp Machine
lisp, I might have had to spend a bit of time writing an application
framework that provided the OO features I needed.  This was not
particularly hard to do in Lisp, but surely not nearly as nice as if
they had standardized such things.  This would not be particularly
difficult to do, other than the getting everyone to agree on just what
the interfaces should be.  But Lisp programmers, are of course, just
as recalcitrant as Python programmers.

>> A language like Python, which is defined by its implementation,
>> rather than by a standard, can move much more quickly.  This debate
>> though is really one more of what is the best model for language
>> definition, rather than one on what the ideal language is like.

> Python is not Perl and it has in principle always been defined by its
> reference manual,

And in Python's case, the reference manual is just an incomplete
description of the features offered by the implementation, and people
revel in features that are not yet in the reference manual.

> though until fairly recently it's fostered a style of relying on
> various ugly CPython artifacts like the reference counting GC.

That's not ugly.  The fact that CPython has a reference-counting GC
makes the lifetime of object predictable, which means that like in
C++, and unlike in Java, you can use destructors to good effect.  This
is one of the huge boons of C++.  The predictability of lifespan makes
the language more expressive and powerful.  The move to deprecate
relying on this feature in Python is a bad thing, if you ask me, and
removes one of the advantages that Python had over Lisp.

> Lisp accumulated a lot of cruft over the decades and it kept some
> baggage that it really could have done without.

Indeed -- true of most languages.  Of course, there have been quite a
few Lisp dialects that have been cleaned up in quite a few ways (e.g.,
Dylan), but they, of course, have a hard time achieving any
significant traction.

> I don't think Python's designers learned nearly as much from Lisp as
> they could hav

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-26 Thread Douglas Alan
Paul Rubin  writes:

> Andy Freeman <[EMAIL PROTECTED]> writes:

>> Compare that with what a programmer using Python 2.4 has to do if
>> she'd like the functionality provided by 2.5's with statement.  Yes,
>> with is "just syntax", but it's extremely useful syntax, syntax that
>> can be easily implemented with lisp-style macros.

> Not really.  The with statement's binding targets all have to support
> the protocol, which means a lot of different libraries need redesign.
> You can't do that with macros.

But that's a library issue, not a language issue.  The technology
exists completely within Lisp to accomplish these things, and most
Lisp programmers even know how to do this, as application frameworks
in Lisp often do this kind.  The problem is getting anything put into
the standard.  Standardizing committees just suck.

I just saw a presentation today on the Boost library for C++.  This
project started because the standard library for C++ is woefully
inadequate for today's programming needs, but any chance of getting
big additions into the standard library will take 5-10 years.
Apparently this is true for all computer language standards.  And even
then, the new standard will be seriously lacking, because it is
usually based on armchair thinking rather than real-world usage.

So the Boost guys are making a defacto standard (or so they hope)
library for C++ that has more of the stuff you want, and then when the
standardizing committees get around to revising the actual standard,
the new standard will already be in wide use, meaning they just have
to sign off on it (and perhaps suggest a few tweaks).

Alas, the Lisp standards are stuck in this sort of morass, even while
many implementations do all the right things.

Python doesn't have this problem because it operates like Boost to
begin with, rather than having a zillion implementations tracking some
slow moving standard that then mandates things that might be nearly
impossible to implement, while leaving out much of what people need.

But then again, neither do many dialects of Lisp, which are developed
more or less like Python is.  But then they aren't standards
compliant, and so they don't receive wide adoption.

> Macros can handle some narrow special cases such as file-like
> objects, handled in Python with contextlib.closing.

Macros handle the language part of things in Lisp perfectly well in
this regard.  But you are right -- they certainly can't make
standardizing committees do the right thing.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-26 Thread Douglas Alan
Paul Rubin <http://[EMAIL PROTECTED]> writes:

> Douglas Alan <[EMAIL PROTECTED]> writes:

>> > In the Maclisp era functions like mapcar worked on lists, and
>> > generated equally long lists in memory.

>> I'm aware, but there were various different mapping functions.  "map",
>> as opposed to "mapcar" didn't return any values at all, and so you had
>> to rely on side effects with it.

> The thing is there was no standard way in Maclisp to write something
> like Python's "count" function and map over it.  This could be done in
> Scheme with streams, of course.

I'm not sure that you can blame MacLisp for not being object-oriented.
The idea hadn't even been invented yet when MacLisp was implemented
(unless you count Simula).  If someone went to make an OO version of
MacLisp, I'm sure they'd get all this more or less right, and people
have certainly implemented dialects of Lisp that are consistently OO.

>> Right -- I wrote "iterators", not "generators".

> Python iterators (the __iter__ methods on classes) are written with
> yield statements as often as not.

I certainly agree that iterators can be implemented with generators,
but generators are a language feature that are impossible to provide
without deep language support, while iterators are just an OO
interface that any OO language can provide.  Though without a good
macro facility the syntax to use them may not be so nice.

>> That's not ugly.  The fact that CPython has a reference-counting GC
>> makes the lifetime of object predictable, which means that like in
>> C++, and unlike in Java, you can use destructors to good effect.  This
>> is one of the huge boons of C++.  The predictability of lifespan makes
>> the language more expressive and powerful.  The move to deprecate
>> relying on this feature in Python is a bad thing, if you ask me, and
>> removes one of the advantages that Python had over Lisp.

> No that's wrong, C++ has no GC at all, reference counting or
> otherwise, so its destructors only run when the object is manually
> released or goes out of scope.

Right, but implementing generic reference-counted smart pointers is
about a page of code in C++, and nearly every large C++ application
I've seen uses such things.

> Python (as of 2.5) does that using the new "with" statement, which
> finally makes it possible to escape from that losing GC-dependent
> idiom.  The "with" statement handles most cases that C++ destructors
> normally handle.

Gee, that's back to the future with 1975 Lisp technology.  Destructors
are a much better model for dealing with such things (see not *all*
good ideas come from Lisp -- a few come from C++) and I am dismayed
that Python is deprecating their use in favor of explicit resource
management.  Explicit resource management means needlessly verbose
code and more opportunity for resource leaks.

The C++ folks feel so strongly about this, that they refuse to provide
"finally", and insist instead that you use destructors and RAII to do
resource deallocation.  Personally, I think that's taking things a bit
too far, but I'd rather it be that way than lose the usefulness of
destructors and have to use "when" or "finally" to explicitly
deallocate resources.

> Python object lifetimes are in fact NOT predictable because the ref
> counting doesn't (and can't) pick up cyclic structure.

Right, but that doesn't mean that 99.9% of the time, the programmer
can't immediately tell that cycles aren't going to be an issue.

I love having a *real* garbage collector, but I've also dealt with C++
programs that are 100,000+ lines long and I wrote plenty of Python
code before it had a real garbage collector, and I never had any
problem with cyclic data structures causing leaks.  Cycles are really
not all that common, and when they do occur, it's usually not very
difficult to figure out where to add a few lines to a destructor to
break the cycle.

> And the refcounts are a performance pig in multithreaded code,
> because of how often they have to be incremented and updated.

I'm willing to pay the performance penalty to have the advantage of
not having to use constructs like "when".

Also, I'm not convinced that it has to be a huge performance hit.
Some Lisp implementations had a 1,2,3, many (or something like that)
reference-counter for reclaiming short-lived objects.  This bypassed
the real GC and was considered a performance optimization.  (It was
probably on a Lisp Machine, though, where they had special hardware to
help.)

> That's why CPython has the notorious GIL (a giant lock around the
> whole interpreter that stops more than one interpreter thread from

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-27 Thread Douglas Woodrow
On Wed, 27 Jun 2007 01:45:44, Douglas Alan <[EMAIL PROTECTED]> wrote
>A chaque son gout

I apologise for this irrelevant interruption to the conversation, but 
this isn't the first time you've written that.

The word "chaque" is not a pronoun.

http://grammaire.reverso.net/index_alpha/Fiches/Fiche220.htm
-- 
Doug Woodrow

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-27 Thread Douglas Alan
"Chris Mellon" <[EMAIL PROTECTED]> writes:

> Is this where I get to call Lispers Blub programmers, because they
> can't see the clear benefit to a generic iteration interface?

I think you overstate your case.  Lispers understand iteration
interfaces perfectly well, but tend to prefer mapping fuctions to
iteration because mapping functions are both easier to code (they are
basically equivalent to coding generators) and efficient (like
non-generator-implemented iterators).  The downside is that they are
not quite as flexible as iterators (which can be hard to code) and
generators, which are slow.

Lispers have long since understood how to write mapping function to
iterator converters using stack groups or continuations, but Common
Lisp never mandated stack groups or continuations for conforming
implementations.  Scheme, of course, has continuations, and there are
implementations of Common Lisp with stack groups.

>> The difference is that lisp users can easily define python-like for
>> while python folks have to wait for the implementation.

> Yes, but Python already has it (so the wait time is 0), and the Lisp
> user doesn't.

So do Lispers, provided that they use an implementation of Lisp that
has the aforementioned extensions to the standard.  If they don't,
they are the unfortunately prisoners of the standardizing committees.

And, I guarantee you, that if Python were specified by a standardizing
committee, it would suffer this very same fate.

Regarding there being way too many good but incompatible
implementations of Lisp -- I understand.  The very same thing has
caused Ruby to incredibly rapidly close the lead that Python has
traditionally had over Ruby.  There reason for this is that there are
too many good but incompatible Python web dev frameworks, and only one
good one for Ruby.  So, we see that while Lisp suffers from too much
of a good thing, so does Python, and that may be the death of it if
Ruby on Rails keeps barreling down on Python like a runaway train.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-27 Thread Douglas Alan
"Chris Mellon" <[EMAIL PROTECTED]> writes:

> On 6/27/07, Douglas Alan <[EMAIL PROTECTED]> wrote:

>> The C++ folks feel so strongly about this, that they refuse to provide
>> "finally", and insist instead that you use destructors and RAII to do
>> resource deallocation.  Personally, I think that's taking things a bit
>> too far, but I'd rather it be that way than lose the usefulness of
>> destructors and have to use "when" or "finally" to explicitly
>> deallocate resources.

> This totally misrepresents the case. The with statement and the
> context manager is a superset of the RAII functionality.

No, it isn't.  C++ allows you to define smart pointers (one of many
RAII techniques), which can use refcounting or other tracking
techniques.  Refcounting smart pointers are part of Boost and have
made it into TR1, which means they're on track to be included in the
next standard library.  One need not have waited for Boost, as they can
be implemented in about a page of code.

The standard library also has auto_ptr, which is a different sort of
smart pointer, which allows for somewhat fancier RAII than
scope-based.

> It doesn't overload object lifetimes, rather it makes the intent
> (code execution upon entrance and exit of a block) explicit.

But I don't typically wish for this sort of intent to be made
explicit.  TMI!  I used "with" for *many* years in Lisp, since this is
how non-memory resource deallocation has been dealt with in Lisp since
the dawn of time.  I can tell you from many years of experience that
relying on Python's refcounter is superior.

Shouldn't you be happy that there's something I like more about Python
than Lisp?

> Nobody in their right mind has ever tried to get rid of explicit
> resource management - explicit resource management is exactly what you
> do every time you create an object, or you use RAII, or you open a
> file.

This just isn't true.  For many years I have not had to explicitly
close files in Python.  Nor have I had to do so in C++.  They have
been closed for me implicitly.  "With" is not implicit -- or at least
not nearly as implicit as was previous practice in Python, or as is
current practice in C++.

> *Manual* memory management, where the tracking of references and
> scopes is placed upon the programmer, is what people are trying to
> get rid of and the with statement contributes to that goal, it
> doesn't detract from it.

As far as I am concerned, memory is just one resource amongst many,
and the programmer's life should be made easier in dealing with all
such resources.

> Before the with statement, you could do the same thing but you
> needed nested try/finally blocks

No, you didn't -- you could just encapsulate the resource acquisition
into an object and allow the destructor to deallocate the resource.

> RAII is a good technique, but don't get caught up on the
> implementation details.

I'm not -- I'm caught up in the loss of power and elegance that will
be caused by deprecating the use of destructors for resource
deallocation.

> The with statement does exactly the same thing, but is actually
> superior because
>
> a) It doesn't tie the resource managment to object creation. This
> means you can use, for example, with lock: instead of the C++ style
> Locker(lock)

I know all about "with".  As I mentioned above, Lisp has had it since
the dawn of time.  And I have nothing against it, since it is at times
quite useful.  I'm just dismayed at the idea of deprecating reliance
on destructors in favor of "with" for the majority of cases when the
destructor usage works well and is more elegant.

> b) You can tell whether you exited with an exception, and what that
> exception is, so you can take different actions based on error
> conditions vs expected exit. This is a significant benefit, it
> allows the application of context managers to cases where RAII is
> weak. For example, controlling transactions.

Yes, for the case where you might want to do fancy handling of
exceptions raised during resource deallocation, then "when" is
superior, which is why it is good to have in addition to the
traditional Python mechanism, not as a replacement for it.

>> Right, but that doesn't mean that 99.9% of the time, the programmer
>> can't immediately tell that cycles aren't going to be an issue.

> They can occur in the most bizarre and unexpected places. To the point
> where I suspect that the reality is simply that you never noticed your
> cycles, not that they didn't exist.

Purify tells me that I know more about the behavior of my code than
you do: I've *never* had any memory leaks in large C++ programs that
used refco

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-27 Thread Douglas Alan
Douglas Woodrow <[EMAIL PROTECTED]> writes:

> On Wed, 27 Jun 2007 01:45:44, Douglas Alan <[EMAIL PROTECTED]> wrote

>>A chaque son gout

> I apologise for this irrelevant interruption to the conversation, but
> this isn't the first time you've written that.

> The word "chaque" is not a pronoun.

A chacun son epellation.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-27 Thread Douglas Alan
Dennis Lee Bieber <[EMAIL PROTECTED]> writes:

>   But if these "macros" are supposed to allow one to sort of extend
> Python syntax, are you really going to code things like
>
>   macrolib1.keyword
> everywhere?

No -- I would expect that macros (if done the way that I would like
them to be done) would work something like so:

   from setMacro import macro set, macro let
   let x = 1
   set x += 1

The macros "let" and "set" (like all macro invocations) would have to
be the first tokens on a line.  They would be passed either the
strings "x = 1" and "x += 1", or some tokenized version thereof.
There would be parsing libraries to help them from there.

For macros that need to continue over more than one line, e.g.,
perhaps something like

   let x = 1
   y = 2
   z = 3
   set x = y + z
   y = x + z
   z = x + y
   print x, y, z

the macro would parse up to when the indentation returns to the previous
level.

For macros that need to return values, a new bracketing syntax would
be needed.  Perhaps something like:

   while $(let x = foo()):
  print x

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-28 Thread Douglas Alan
Steve Holden <[EMAIL PROTECTED]> writes:

> Douglas Woodrow wrote:

>> On Wed, 27 Jun 2007 01:45:44, Douglas Alan <[EMAIL PROTECTED]> wrote

>>> A chaque son gout

>> I apologise for this irrelevant interruption to the conversation,
>> but this isn't the first time you've written that.  The word
>> "chaque" is not a pronoun.

>> http://grammaire.reverso.net/index_alpha/Fiches/Fiche220.htm

> Right, he probably means "Chaqu'un à son gout" (roughly, each to his
> own taste).

Actually, it's "chacun".  And the "à" may precede the "chacun".

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-28 Thread Douglas Alan
Steve Holden <[EMAIL PROTECTED]> writes:

>> Actually, it's "chacun".  And the "à" may precede the "chacun".

>> |>oug

> "chacun" is an elision of the two words "Chaque" (each) and "un"
> (one), and use of those two words is at least equally correct, though
> where it stands in modern usage I must confess I have no idea.

Google can answer that: 158,000 hits for "chaqu'un", 57 million for
"chacun".

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-28 Thread Douglas Alan
"Chris Mellon" <[EMAIL PROTECTED]> writes:

> Obviously. But theres nothing about the with statement that's
> different than using smart pointers in this regard.

Sure there is -- smart pointers handle many sorts of situations, while
"with" only handles the case where the lifetime of the object
corresponds to the scope.

>> But I don't typically wish for this sort of intent to be made
>> explicit.  TMI!  I used "with" for *many* years in Lisp, since this
>> is how non-memory resource deallocation has been dealt with in Lisp
>> since the dawn of time.  I can tell you from many years of
>> experience that relying on Python's refcounter is superior.

> I question the relevance of your experience, then.

Gee, thanks.

> Refcounting is fine for memory, but as you mention below, memory is
> only one kind of resource and refcounting is not necessarily the
> best technique for all resources.

I never said that it is the best technique for *all* resources.  Just
the most typical ones.

>> This just isn't true.  For many years I have not had to explicitly
>> close files in Python.  Nor have I had to do so in C++.  They have
>> been closed for me implicitly.  "With" is not implicit -- or at least
>> not nearly as implicit as was previous practice in Python, or as is
>> current practice in C++.

> You still don't have to manually close files. But you cannot, and
> never could, rely on them being closed at a given time unless you
> did so.

You could for most intents and purposes.

> If you need a file to be closed in a deterministic manner, then you
> must close it explicitly.

You don't typically need them to be closed in a completely fool-proof
deterministic fashion.  If some other code catches your exceptions and
holds onto the traceback then it must know that can be delaying a few
file-closings, or the like.

> The with statement is not implicit and never has been. Implicit
> resource management is *insufficient* for the general resource
> management case. It works fine for memory, it's okay for files
> (until it isn't), it's terrible for thread locks and network
> connections and database transactions. Those things require
> *explicit* resource management.

Yes, I agree there are certain situations in which you certainly want
"with", or something like it.  I've never disagreed with that
assertion at all.  I just don't agree that for most Python code this
is the *typical* case.

> To the extent that your code ever worked when you relied on this
> detail, it will continue to work.

I've written plenty of Python code that relied on destructors to
deallocate resources, and the code always worked.

> There are no plans to replace pythons refcounting with fancier GC
> schemes that I am aware of.

This is counter to what other people have been saying.  They have been
worrying me by saying that the refcounter may go away and so you may
not be able to rely on predictable object lifetimes in the future.

> Nothing about Pythons memory management has changed. I know I'm
> repeating myself here, but you just don't seem to grasp this
> concept.  Python has *never* had deterministic destruction of
> objects. It was never guaranteed, and code that seemed like it
> benefited from it was fragile.

It was not fragile in my experience.  If a resource *positively*,
*absolutely* needed to be deallocated at a certain point in the code
(and occasionally that was the case), then I would code that way.  But
that has been far from the typical case for me.

>> Purify tells me that I know more about the behavior of my code than
>> you do: I've *never* had any memory leaks in large C++ programs that
>> used refcounted smart pointers that were caused by cycles in my data
>> structures that I didn't know about.

> I'm talking about Python refcounts. For example, a subtle resource
> leak that has caught me before is that tracebacks hold references to
> locals in the unwound stack.

Yes, I'm aware of that.  Most programs don't hold onto tracebacks for
long.  If you are working with software that does, then, I agree, that
sometimes one will have to code things more precisely.

> If you relied on refcounting to clean up a resource, and you needed
> exception handling, the resource wasn't released until *after* the
> exception unwound, which could be a problem. Also holding onto
> tracebacks for latter processing (not uncommon in event based
> programs) would artificially extend the lifetime of the resource. If
> the resource you were managing was a thread lock this could be a
> real problem.

Right -- I've always explicitly managed thread locks.

>> I really have no desire to code in C, thank you.  I'd rather be coding
>> in Python.  (Hence my [idle] desire for macros in Python, so that I
>> could do even more of my work in Python.)

> In this particular conversation, I really don't think that theres much
> to say beyond put up or shut up.

I think your attitude here is unPythonic.

> The experts in the field have said that it's not practical.

Gu

Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Michele Simionato <[EMAIL PROTECTED]> writes:

>> I've written plenty of Python code that relied on destructors to
>> deallocate resources, and the code always worked.

> You have been lucky:

No I haven't been lucky -- I just know what I'm doing.

> $ cat deallocating.py
> import logging
>
> class C(object):
> def __init__(self):
> logging.warn('Allocating resource ...')
>
> def __del__(self):
> logging.warn('De-allocating resource ...')
> print 'THIS IS NEVER REACHED!'
>
> if __name__ == '__main__':
> c = C()
>
> $ python deallocating.py
> WARNING:root:Allocating resource ...
> Exception exceptions.AttributeError: "'NoneType' object has no
> attribute 'warn'" in  0xb7b9436c>> ignored

Right.  So?  I understand this issue completely and I code
accordingly.

> Just because your experience has been positive, you should not
> dismiss the opinion who have clearly more experience than you on
> the subtilities of Python.

I don't dismiss their opinion at all.  All I've stated is that for my
purposes I find that the refcounting semantics of Python to be useful,
expressive, and dependable, and that I wouldn't like it one bit if
they were removed from Python.

Those who claim that the refcounting semantics are not useful are the
ones who are dismissing my experience.  (And the experience of
zillions of other Python programmers who have happily been relying on
them.)

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Dennis Lee Bieber <[EMAIL PROTECTED]> writes:

>   LISP and FORTH are cousins...

Not really.  Their only real similarity (other than the similarities
shared by most programming languages) is that they both use a form of
Polish notation.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Hrvoje Niksic <[EMAIL PROTECTED]> writes:

> Douglas Alan <[EMAIL PROTECTED]> writes:

>> I think you overstate your case.  Lispers understand iteration
>> interfaces perfectly well, but tend to prefer mapping fuctions to
>> iteration because mapping functions are both easier to code (they
>> are basically equivalent to coding generators) and efficient (like
>> non-generator-implemented iterators).  The downside is that they are
>> not quite as flexible as iterators (which can be hard to code) and
>> generators, which are slow.

> Why do you think generators are any slower than hand-coded iterators?

Generators aren't slower than hand-coded iterators in *Python*, but
that's because Python is a slow language.  In a fast language, such as
a Lisp, generators are like 100 times slower than mapping functions.
(At least they were on Lisp Machines, where generators were
implemented using a more generator coroutining mechanism [i.e., stack
groups].  *Perhaps* there would be some opportunities for more
optimization if they had used a less general mechanism.)

CLU, which I believe is the language that invented generators, limited
them to the power of mapping functions (i.e., you couldn't have
multiple generators instantiated in parallel), making them really
syntactic sugar for mapping functions.  The reason for this limitation
was performance.  CLU was a fast language.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
"Chris Mellon" <[EMAIL PROTECTED]> writes:

> You're arguing against explicit resource management with the argument
> that you don't need to manage resources. Can you not see how
> ridiculously circular this is?

No.  It is insane to leave files unclosed in Java (unless you know for
sure that your program is not going to be opening many files) because
you don't even know that the garbage collector will ever even run, and
you could easily run out of file descriptors, and hog system
resources.

On the other hand, in Python, you can be 100% sure that your files
will be closed in a timely manner without explicitly closing them, as
long as you are safe in making certain assumptions about how your code
will be used.  Such assumptions are called "preconditions", which are
an understood notion in software engineering and by me when I write
software.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
"Chris Mellon" <[EMAIL PROTECTED]> writes:

>> On the other hand, in Python, you can be 100% sure that your files
>> will be closed in a timely manner without explicitly closing them, as
>> long as you are safe in making certain assumptions about how your code
>> will be used.  Such assumptions are called "preconditions", which are
>> an understood notion in software engineering and by me when I write
>> software.

> Next time theres one of those "software development isn't really
> engineering" debates going on I'm sure that we'll be able to settle
> the argument by pointing out that relying on *explicitly* unreliable
> implementation details is defined as "engineering" by some people.

The proof of the pudding is in it's eating.  I've worked on very large
programs that exhibited very few bugs, and ran flawlessly for many
years.  One managed the memory remotely of a space telescope, and the
code was pretty tricky.  I was sure when writing the code that there
would be a number of obscure bugs that I would end up having to pull
my hair out debugging, but it's been running flawlessly for more than
a decade now, without require nearly any debugging at all.

Engineering to a large degree is knowing where to dedicate your
efforts.  If you dedicate them to where they are not needed, then you
have less time to dedicate them to where they truly are.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Jean-Paul Calderone <[EMAIL PROTECTED]> writes:

>>On the other hand, in Python, you can be 100% sure that your files
>>will be closed in a timely manner without explicitly closing them, as
>>long as you are safe in making certain assumptions about how your code
>>will be used.  Such assumptions are called "preconditions", which are
>>an understood notion in software engineering and by me when I write
>>software.

> You realize that Python has exceptions, right?

Yes, of course.

> Have you ever encountered a traceback object?

Yes, of course.

> Is one of your preconditions that no one will ever handle an
> exception raised by your code or by their own code when it is
> invoked by yours?

A precondition of much of my Python code is that callers won't
squirrel away large numbers of tracebacks for long periods of time.  I
can live with that.  Another precondition of much of my code is that
the caller doesn't assume that it is thread-safe.  Another
precondition is that the caller doesn't assume that it is likely to
meet real-time constraints.  Another precondition is that the caller
doesn't need my functions to promise not to generate any garbage that
might call the GC to invoked.

If I had to write all my code to work well without making *any*
assumptions about what the needs of the caller might be, then my code
would have to be much more complicated, and then I'd spend more effort
making my code handle situations that it won't face for my purposes.
Consequently, I'd have less time to make my software have the
functionality that I actually require.

Regarding, specifically, tracebacks holding onto references to open
files -- have you considered that you may actually *want* to see the
file in the state that it was in when the exception was raised for the
purposes of debugging, rather than having it forcefully closed on you?

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Hrvoje Niksic <[EMAIL PROTECTED]> writes:

>> Generators aren't slower than hand-coded iterators in *Python*, but
>> that's because Python is a slow language.

> But then it should be slow for both generators and iterators.

Python *is* slow for both generators and iterators.  It's slow for
*everything*, except for cases when you can have most of the work done
within C-coded functions or operations that perform a lot of work
within a single call.  (Or, of course, cases where you are i/o
limited, or whatever.)

>> *Perhaps* there would be some opportunities for more optimization if
>> they had used a less general mechanism.)

> Or if the generators were built into the language and directly
> supported by the compiler.  In some cases implementing a feature is
> *not* a simple case of writing a macro, even in Lisp.  Generators may
> well be one such case.

You can't implement generators in Lisp (with or without macros)
without support for generators within the Lisp implementation.  This
support was provided as "stack groups" on Lisp Machines and as
continuations in Scheme.  Both stack groups and continuations are
slow.  I strongly suspect that if they had provided direct support for
generators, rather than indirectly via stack groups and continuations,
that that support would have been slow as well.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Steve Holden <[EMAIL PROTECTED]> writes:

> "Python" doesn't *have* any refcounting semantics.

I'm not convinced that Python has *any* semantics at all outside of
specific implementations.  It has never been standardized to the rigor
of your typical barely-readable language standards document.

> If you rely on the behavior of CPython's memory allocation and
> garbage collection you run the risk of producing programs that won't
> port tp Jython, or IronPython, or PyPy, or ...

> This is a trade-off that many users *are* willing to make.

Yes, I have no interest at the moment in trying to make my code
portable between every possible implementation of Python, since I have
no idea what features such implementations may or may not support.
When I code in Python, I'm coding for CPython.  In the future, I may
do some stuff in Jython, but I wouldn't call it "Python" -- it'd call
it "Jython".  When I do code for Jython, I'd be using it to get to
Java libraries that would make my code non-portable to CPython, so
portability here seems to be a red herring.

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's "only one way to do it" philosophy isn't good?

2007-06-29 Thread Douglas Alan
Duncan Booth <[EMAIL PROTECTED]> writes:

>> A precondition of much of my Python code is that callers won't
>> squirrel away large numbers of tracebacks for long periods of time.  I
>> can live with that.  Another precondition of much of my code is that
>> the caller doesn't assume that it is thread-safe.  Another
>> precondition is that the caller doesn't assume that it is likely to
>> meet real-time constraints.  Another precondition is that the caller
>> doesn't need my functions to promise not to generate any garbage that
>> might call the GC to invoked.

> None of that is relevant.

Of course it is.  I said "large number of tracebacks" up there, and
you promptly ignored that precondition in your subsequent
counterexample.

> Have you ever seen any code looking roughly like this?

> def mainloop():
>while somecondition:
>   try:
>   dosomestuff()
>   except SomeExceptions:
>   handletheexception()

Of course.

> Now, imagine somewhere deep inside dosomestuff an exception is
> raised while you have a file open and the exception is handled in
> mainloop. If the loop then continues with a fresh call to
> dosomestuff the traceback object will continue to exist until the
> next exception is thrown or until mainloop returns.

It's typically okay in my software for a single (or a few) files to
remain open for longer than I might expect.  What it couldn't handle
is running out of file descriptors, or the like.  (Just like it
couldn't handle running out of memory.)  But that's not going to
happen with your counterexample.

If I were worried about a file or two remaining open too long, I'd
clear the exception in the mainloop above, after handling it.  Python
lets you do that, doesn't it?

|>oug
-- 
http://mail.python.org/mailman/listinfo/python-list


  1   2   3   >