Re: A critic of Guido's blog on Python's lambda

2006-05-24 Thread Kay Schluehr
Michele Simionato wrote:
> Kay Schluehr wrote:
> > http://www.fiber-space.de/EasyExtend/doc/EE.html
>
> Well, I have not read that page yet, but the name "fiber space" reminds
> me of old
> memories, when I was doing less prosaic things than now. Old times ..
> ;)
>
>  Michele Simionato

But I guess that time this stuff was taught to you as "fiber bundles",
right? Oh, yes. Old times ;)

Well, besides the cute rhyme on "cyberspace" I had this analogy in mind
and that's why I called the extension languages "fibers". The
association is "fibers over a base space" or a base language as in this
case. The terms are not used strictly of course. I could not even say
what triviality could be in this context. But I still seek for an
acceptable glue mechanism which is beyond the scope of the current
first release :)

Kay

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


Re: A critic of Guido's blog on Python's lambda

2006-05-24 Thread Michele Simionato
Kay Schluehr wrote:
> http://www.fiber-space.de/EasyExtend/doc/EE.html

Well, I have not read that page yet, but the name "fiber space" reminds
me of old
memories, when I was doing less prosaic things than now. Old times ..
;)

 Michele Simionato

> It fits quite nice with Python and is conceptually simple, safe and
> reasonably fast. Using EasyExtend PyCells could be made an own language
> ( including Python ) defined in a Python package ( i.e. no C-code and
> complex build process is required ).  I would be interested in user
> experience. I wouldn't consider EE as "experimental" i.e. open for
> severe changes. It still lacks some comfort but it also improves
> gradually in this respect.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-23 Thread Kay Schluehr
Ken Tilton wrote:

> Is there any experiemntal macro package out there for Python? Maybe a
> preprocessor, at least? Or are there ways to actually hack Python to
> extend the syntax?

Yes. I've just released EasyExtend that does this kind of job:

http://www.fiber-space.de/EasyExtend/doc/EE.html

It fits quite nice with Python and is conceptually simple, safe and
reasonably fast. Using EasyExtend PyCells could be made an own language
( including Python ) defined in a Python package ( i.e. no C-code and
complex build process is required ).  I would be interested in user
experience. I wouldn't consider EE as "experimental" i.e. open for
severe changes. It still lacks some comfort but it also improves
gradually in this respect.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-16 Thread Ken Tilton


Lasse Rasinen wrote:
> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> 
>>If you want to insist on how perfect your code is, please go find
>>ltktest-cells-inside.lisp in the source you downloaded and read the long
>>comment detailing the requirements I have identified for "data integrity".
>>Then (a) tell me how your code fails at integrity, (b) fix it, and (c)
>>tell me again how easy Cells is. :)
> 
> 
> Found it and read it; it was most enlightening. I claim my system fulfills
> the first three requirements(*), while most likely failing gloriously on
> the two last ones.



 From #1: "recompute all and (for efficiency) only state computed off X 
(directly or indirectly through some intermediate datapoint)"

Bzzzt! Another 47hrs, directions from a mentor, and a reference 
implementation and you /still/ do not even understand the requirements, 
let alone have a working port. The good news is that it is not an 
integrity requirement that is being missed, it is the efficiency 
requirement I snuck in there. The bad news is, see below.

Want to find the efficiency shortcoming yourself, or should I tell you? 
You are entitled to the latter given the rules of the game (simulating a 
pythonista student making off with five thousand undeserved dollars). :)

> 
> I'll postpone (b) while I've had a chance to think it over(**), but in the
> face of the evidence I'm willing to admit my earlier work estimates (which
> should have had a smiley next to them anyway ;-) were in error.

Aw, shucks, then I will admit that, before today, I never actually 
looked at your code. :)

Well, I followed the URL and glanced at it, but I missed the use of the 
timestamp. Speaking of which, Holy Granularity, Batman! You use 
Time.time() to determine currency of a computation?!:

"time()
 Return the time as a floating point number expressed in seconds 
since the epoch, in UTC. Note that even though the time is always 
returned as a floating point number, not all systems provide time with a 
better precision than 1 second."

One /second/?! Exactly how slow is Python? I know you guys love that 
issue as much as Lispniks. In un-compiled Lisp:

  CTK(4): (loop repeat 2 do (print (get-internal-real-time)))
  464033837
  464033837

And you have no idea how slow PRINT is. btw, I thought Python was 
portable. What is with the Time class and "not all systems..."? Check 
out the Lisp:

(defun zoom ()
   (loop with start = (get-internal-real-time)
 while (= start (get-internal-real-time))
 count 1 into cities-destroyed
 finally (format t "~a cities destroyed in 1/~a of a second"
   cities-destroyed internal-time-units-per-second)))

internal-time-units-per-second is (from the standard):

"Constant Value:
A positive integer, the magnitude of which is 
implementation-dependent. "

So we vary, too, but my Lisp has to tell me so I can normalize. Anyway, 
running that repeatedly I get pretty wild variation. My high score is:

CTK(18): 11637 cities destroyed in 1/1000 of a second

My low was under a thousand! I guess I have to wait until we cross a 
millisecond boundary:

(defun zoom ()
   (symbol-macrolet ((now (get-internal-real-time)))
 (loop with start = (loop for mid = now
while (= mid now)
finally (return now))
 while (= start now)
 count 1 into cities-destroyed
 finally (format t "~a cities destroyed in 1/~a of a second"
   cities-destroyed
   internal-time-units-per-second

Ok, now I am consistently taking out about 11.5k Russian cities. And you 
need to fix your system.

Just use a counter -- does Python have bignums? if not, you'll have to 
worry about wrapping. (the sound you hear is a project schedule 
slipping. )

> 
> I won't admit to destroying Moscow, though. See (*).

Sorry, you actually /have/ violated the data integrity requirement. You 
confess below to missing this one:

"a corollary: should a client observer SETF a datapoint Y, all the above 
must happen with values current with not just X, but also with the value 
of Y /prior/ to the change to Y."

Well, how can you claim integrity when some values do not get 
recalculated until the world has moved on to state N+2, if you will? 
State N+1 had the information that headed off the launch.

Bye bye, Kremlin.

The easiest way to construct such a scenario would be with an ephemeral 
cell. As you know... oops. Maybe you do not. Well, spreadsheets are 
kinda steady state in orientation. Given a world of other values, this 
is what my value should be. But what about events? You have been using 
your version of PyCells in real-world applications for a while... oops. 
No you have not. Well, when you start trying to handle events from an 
event loop, you will discover a need to model events. (Trust your 
mentor.) You need a slot that can be assigned normally, propagate 
according to the above rules and regulations, and 

Re: A critic of Guido's blog on Python's lambda

2006-05-16 Thread Lasse Rasinen
Ken Tilton <[EMAIL PROTECTED]> writes:

> If you want to insist on how perfect your code is, please go find
> ltktest-cells-inside.lisp in the source you downloaded and read the long
> comment detailing the requirements I have identified for "data integrity".
> Then (a) tell me how your code fails at integrity, (b) fix it, and (c)
> tell me again how easy Cells is. :)

Found it and read it; it was most enlightening. I claim my system fulfills
the first three requirements(*), while most likely failing gloriously on
the two last ones.

I'll postpone (b) while I've had a chance to think it over(**), but in the
face of the evidence I'm willing to admit my earlier work estimates (which
should have had a smiley next to them anyway ;-) were in error.

I won't admit to destroying Moscow, though. See (*).

(*) All values depending on the changed cell are marked as invalid before
anything else is done; trying to access an invalid value forces a
recalculation which also marks the cell as valid again, and so on
recursively down to cells that have already converged to a proper value.

Setting input cells in callbacks will f*** that up, though.

(**) Which probably doesn't occur until July or something ;(

> > [Decorator example]
> 
> Wow. I thought Python did not have macros.

Calling decorators macros is an insult to CL macros ;-)
All they do is make it a bit more convinent to apply transformations to
functions, or as the abstract in the original spec[1] says:

  The current method for transforming functions and methods (for instance,
  declaring them as a class or static method) is awkward and can lead to
  code that is difficult to understand. Ideally, these transformations
  should be made at the same point in the code where the declaration
  itself is made.

> This project is looking better all the time. Thx.

In that case I have something else you might like: The "with" Statement[2]

>From the abstract:
This PEP adds a new statement "with" to the Python language to make
it possible to factor out standard uses of try/finally statements.

In practice one can use it implement some of the with-macros in a pretty
straightforward manner, especially those that are expanded into
(call-with-* (lambda () ,@body)). I believe the previously advertised
with-integrity macro could also be made to work in a satisfying manner.

To quote from the examples:

2. A template for opening a file that ensures the file is closed
   when the block is left:

@contextmanager
def opened(filename, mode="r"):
f = open(filename, mode)
try:
yield f
finally:
f.close()

   Used as follows:

with opened("/etc/passwd") as f:
for line in f:
print line.rstrip()

Does that last part look familiar to you?)

The problem with this is that this is Python 2.5 syntax, which currently
appears to be planned for release in late August, a bit late for SoC.
Alpha(*) versions are available, so if you want to take a chance and live
on the bleeding edge, you can probably gain from it.

(*) I don't keep a very close eye on the alpha releases, which is why I
didn't remember this yesterday. I like my programming tools steady
and stable ;-)

[1] http://www.python.org/dev/peps/pep-0318/#abstract
[2] http://www.python.org/dev/peps/pep-0343/
-- 
Lasse Rasinen
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-16 Thread Ken Tilton


Ben wrote:
> This kind of discussions between two groups of people,
> neither of who know the other person's language very well just wind me
> up something chronic!

I must say, it is pretty funny how a flamewar turned into a pretty 
interesting SoC project.

> Anything that makes programming more fun is good, and I hope the Lisp
> true way explodes into my head at some point.

Here is an excerpt of an excerpt from famous Gears demo. I notice it 
really makes concrete what Lispniks are talking about in re macros and 
multi-line lambda (pity about the formatting):

(defmodel gears-demo (window)
   ((gear-ct :initform (c-in 1) :accessor gear-ct :initarg :gear-ct))
   (:default-initargs
 :title$ "Rotating Gear Widget Test"
 :kids (c? (the-kids
(mk-stack (:packing (c?pack-self))
  (mk-row ()
 (mk-button-ex ("  Add " (incf (gear-ct .tkw
 (mk-button-ex ("Remove" (when (plusp (gear-ct .tkw))
 (decf (gear-ct .tkw)
 (mk-entry :id :vtime
 :md-value (c-in "10")))
  (make-instance 'gears
:fm-parent *parent*
:width 400 :height 400
:timer-interval (max 1
  (or (parse-integer (fm^v :vtime))
:junk-allowed t)
0)))

Don't worry, Lispniks cannot read that either. It is a delarative 
construction of a hierarchical GUI. That is such a common task, that I 
have rolled up a bunch of GUI-building macrology so that just the stuff 
specific to this GUI gets typed in. Since the Gears widget is a custom 
widget I have no macrology for that, and the wiring shows in the 
expression ":fm-parent *parent*" (which itself leverages Lisp special 
variables).

And no, I cannot remember all my macrology. I can certainly read it and 
easily modify my GUI, because all the wiring is hidden, but if I have to 
build a new GUI I cut and paste from other GUIs.

Let's look at just one form, which I believe destroys Alex's whole case 
for naming every lambda:

   (mk-button-ex ("Remove" (when (plusp (gear-ct .tkw))
  (decf (gear-ct .tkw)

"mk-button-ex" (a) makes fun of MS$ naming standards and (b) expands to:

  (make-instance 'button
   :fm-parent *parent*
   :text "remove"
   :on-command (c? (lambda (self)
 (when (plusp (gear-ct .tkw))
   (decf (gear-ct .tkw))

The above is what one really needs to write to stick something in my GUI 
framework, but who wants to look at all of that when most of it is 
boilerplate? I need ":fm-parent *parent*" on every label and widget 
because of some internals requirements, I just do not want to look at it 
or have to remember to code it all the time (the latter not being a huge 
problem because I really am cutting/pasting when I build a new GUI).

Is mk-button-ex some mysterious new language construct that will make 
multi-programmer projects collapse in a heap of programmer-specific 
constructs inscrutable to anyone else on the team?

(a) mk-button-ex kinda tells you (1) it makes a button and (2) no, this 
is not part of Common Lisp, so where is the confusion?

(b) control-alt-. in my IDE shows me:

  (defmacro mk-button-ex ((text command) &rest initargs)
`(make-instance 'button
  :fm-parent *parent*
  :text ,text
  :on-command (c? (lambda (self)
(declare (ignorable self))
,command))
  ,@initargs))

Looks a lot like the expansion, right? That is really important in 
making macrology easy. Once one has mastered the syntax (` , @), writing 
a macro gets as natural as writing out the code. (In case you are 
wondering, in my little example I did not need any other customizations 
on the button, so it is hard to make out what the initargs are doign up 
there. here is how they would work (also getting a little fancier by 
actually disabling the "Remove" button, not just making it do nothing 
when pressed, if the gear count is zero):

(mk-button-ex ("Remove" (decf (gear-ct .tkw)))
   :fore-color 'red ;; Tcl/Tk will understand
   :enabled (c? (plusp (gear-ct .tkw

becomes:

  (make-instance 'button
   :fm-parent *parent*
   :text "remove"
   :on-command (c? (lambda (self)
 (decf (gear-ct .tkw
   :fore-color 'red
   :enabled (c? (plusp (gear-ct .tkw

[ps. Do not try that at home, i invented the enabled thing. It really 
should be the Tk syntax, which I forget.]

ie, I created mk-button-ex because, jeez, every button I put in a GUI I 
/know/ needs its own label and its own command (and the parent thing), 
but there are other options, too. They have to be supported if the macro 
is to get used all the time (we want that), but I do not want to make 
them positional argum

Re: A critic of Guido's blog on Python's lambda

2006-05-16 Thread A. Rogowski
[EMAIL PROTECTED] (Alex Martelli) writes:

> Bill Atkins <[EMAIL PROTECTED]> wrote:
>...
> > > ``allow ( as an ordinary single-character identifier'' as for the
> > > unneded feature ``allow unnamed functions with all the flexibility of
> > > named ones''.
> > 
> > Not so infeasible:
> > 
> >   (let ((|bizarrely(named()symbol| 3))
> >  (+ |bizarrely(named()symbol| 4))
> > 
> >;; => 7
> 
> Read again what I wrote: I very specifically said "ordinary
> *single-character* identifier" (as opposed to "one of many characters
> inside a multi-character identifier").  Why do you think I said
> otherwise, when you just quoted what I had written?  (Even just a
> _leading_ ( at the start of an identifier may be problematic -- and just
> as trivial as having to give names to functions, of course, see below).

bah...

[1]> (setq rtbl (copy-readtable))
#
[2]> (set-syntax-from-char #\{ #\()
T
[3]> (set-syntax-from-char #\( #\a)
T
[4]> {defun ( {a) {1+ a))
(
[5]> {( 1)
2
[6]> {( 4)
5
[7]> {setq *readtable* rtbl)
#
[8]> (1+ 1)
2

With readtable and reader macros you can change the syntax as you
wish.

ajr.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-16 Thread Ben
Ok, I'm sorry. This kind of discussions between two groups of people,
neither of who know the other person's language very well just wind me
up something chronic! It wasn't your post as such, just reading through
most of the thread in one go.

That will teach me to post while cross :). Sorry for any offence.

Anything that makes programming more fun is good, and I hope the Lisp
true way explodes into my head at some point.

Cheers,
Ben

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


Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Rob Warnock
Ken Tilton  <[EMAIL PROTECTED]> wrote:
+---
| Having the reference implementation is the only thing that makes this 
| conceivably doable in a summer. What you are missing is something I have 
| often also gotten wrong: the core, cool functionality always comes easy 
| in the proof-of-concept stage. We make these ridiculous extrapolations 
| from that to a shipped product and come in five times over budget.
+---

Or as Fred Brooks said it in "The Mythical Man-Month" [paraphrased],
if a program takes one unit of effort, a programming *system* takes
three units of effort, and a programming systems *product* takes nine
units of effort.


-Rob

-
Rob Warnock <[EMAIL PROTECTED]>
627 26th Avenue http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

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


Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Ken Tilton


Lasse Rasinen wrote:
> [I trimmed some of the newsgroups away; this mostly concerns Python and Lisp]
> 
> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> 
>>Lasse Rasinen wrote:
>>
>>>Ken Tilton <[EMAIL PROTECTED]> writes:
>>>
>>>
>if any concepts have survived to the Python version. Since Python's object
>model is sufficiently different, the system is based on rules being
>defined per-class...

That will be a total disaster for PyCells, if true. But I do not think it
is. You just need a constructor that takes some slot initializers, and
initialize the slots to one of: a normal value; an InputCell itself
initialized with a starting value, if only nil; or a RuledCell itself
initialized with a lambda.
>>>
>>>Hmm, just tried it:
>>>
>>>[snip example]
>>>
>>>So it does work out-of-the-box ;-)
>>
>>So why exactly did you say that the differences in the object model made
>>it impossible? I was really stunned by that claim. And you sounded so
>>confident. What went wrong there? It was trivial, right? How did you miss
>>that?
> 
> 
> Simple: I didn't think to try that before you asked.
> 
> I did not say the differences in the object model made it impossible, I
> said the system is based on rules defined per-class. 

Oh, please: "Since Python's object model is sufficiently different, the 
system is based on rules being defined per-class".

> I also think(*) that while one would have the option to define
> per-instance rules, in a Python implementation one would structure the
> code so that common rules would be class-related,..

What has Python got to do with it? What you describing is the way every 
OO system other than a prototype-based system works. It is why OO failed 
to deliver on the Grail of object reuse: every time you need different 
behavior, you need a new subclass. Literal values only go so far in 
making instances authorable. But when an instance can have a rule with 
itself as an argument, and when instances exist in a runtime hierarchy 
navigable up and down such that rules have effectively global scope, 
yowza, now you have authorability, amd now you have object reuse.


> and the per-instance
> rules would be used less frequently, used only when you absolutely need
> them.

You will see, but not until you have the capability. Then you will 
discover you absolutely need them all the time. GUIs are dynamic things, 
so you cannot just author a widget with a literal value, it has to be a 
rule sensitive to the state of other GUI elements and the model itself, 
which might be changing underfoot in response to I/O events.

I happened to be discussing this just now over in comp.lang.tcl, 
comparing Cells with Actions, a kindred package motivated by this:

"Two large problems exist for developers of such user interfaces. One is 
the need to constantly synchronize the controls with the ever-changing 
state of the application or data. When no text is selected, for example, 
the cut and copy buttons should be disabled.

"Another problem is that as programs evolve over time it can become 
tedious and error prone to update the parts of the code that act upon 
these controls."

Found here:

http://www.tcl.tk/community/tcl2004/Papers/BryanOakley/oakley.pdf

> 
> (*) Unfounded Gut Feeling(TM); if your project is successful, we can
> revisit this prediction in September ;-) 

No need for gut feelings. Anyone working in GUIs knows the problem 
(stated by Mr Oakley above) and many partial solutions exist, such as 
Tcl/Tk's builtin mechanisms for automatic state management. They called 
the company ActiveState for a reason, you know. :)

One person did his homework. vasilsi margioulas sent me cells-gtk, a 
two-week marriage of cells and Gtk derived from my Cells-Tk effort. He 
was curious if Cells would be useful. he decided, yes. :)


> 
> 
PyCells looks like it will be a project for SoC2006, so you may as well
relax.
>>>
>>>You really want to start a SoC project on something that takes about two
>>>weeks ...
>>
>>You sound so confident. :)
> 
> 
> Indeed. Having reread the post I do think the tone was possibly a tad
> arrogant. However:
> 
> 
>>A new test suite, documentation (a first, there is none now), a full port
>>of Cells in all their ten years of sophisticated evolution and variety
>>(no, not your stupid pet trick), and as a demo project an entire
>>cells-driven GUI, probably a port of my new Celtk (+ Cells Tk) work, all
>>in a language without macros, without special variables, with a more
>>modest OO system, and limited first class functions... oh, I think we'll
>>keep him busy. :)
> 
> 
> I did not know all this. The list above does sound like a full summer of
> work ;)
> 
> I assumed that PyCells referred to the core dependency tracking module
> which (even now) does not sound like a such huge task, especially when one
> has the reference implementation ;-)

I think the real problem here is that you have no idea how fast twelve 
weeks can go while programming. T

Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Lasse Rasinen
[I trimmed some of the newsgroups away; this mostly concerns Python and Lisp]

Ken Tilton <[EMAIL PROTECTED]> writes:

> Lasse Rasinen wrote:
> > Ken Tilton <[EMAIL PROTECTED]> writes:
> >
> >>>if any concepts have survived to the Python version. Since Python's object
> >>>model is sufficiently different, the system is based on rules being
> >>>defined per-class...
> >>
> >>That will be a total disaster for PyCells, if true. But I do not think it
> >>is. You just need a constructor that takes some slot initializers, and
> >>initialize the slots to one of: a normal value; an InputCell itself
> >>initialized with a starting value, if only nil; or a RuledCell itself
> >>initialized with a lambda.
> > Hmm, just tried it:
> >
> > [snip example]
> >
> > So it does work out-of-the-box ;-)
> 
> So why exactly did you say that the differences in the object model made
> it impossible? I was really stunned by that claim. And you sounded so
> confident. What went wrong there? It was trivial, right? How did you miss
> that?

Simple: I didn't think to try that before you asked.

I did not say the differences in the object model made it impossible, I
said the system is based on rules defined per-class. My goal was to
explore the how one would go about defining data flow in Python, which is
why I concentrated on class-level definitions first.

The situation is similar to functions in classes. Normally you'd define
them like this:

class X:
  def function(self, ...):
...

However, you can just as well set them, even on per instance basis:
x = X()
x.another_function = lambda self, x: return x+2


I also think(*) that while one would have the option to define
per-instance rules, in a Python implementation one would structure the
code so that common rules would be class-related, and the per-instance
rules would be used less frequently, used only when you absolutely need
them.

(*) Unfounded Gut Feeling(TM); if your project is successful, we can
revisit this prediction in September ;-) 

> >>PyCells looks like it will be a project for SoC2006, so you may as well
> >>relax.
> > You really want to start a SoC project on something that takes about two
> > weeks ...
> 
> You sound so confident. :)

Indeed. Having reread the post I do think the tone was possibly a tad
arrogant. However:

> A new test suite, documentation (a first, there is none now), a full port
> of Cells in all their ten years of sophisticated evolution and variety
> (no, not your stupid pet trick), and as a demo project an entire
> cells-driven GUI, probably a port of my new Celtk (+ Cells Tk) work, all
> in a language without macros, without special variables, with a more
> modest OO system, and limited first class functions... oh, I think we'll
> keep him busy. :)

I did not know all this. The list above does sound like a full summer of
work ;)

I assumed that PyCells referred to the core dependency tracking module
which (even now) does not sound like a such huge task, especially when one
has the reference implementation ;-)

As I said above, I was mostly concerned with exploring how the data flow
system would work, so I haven't implemented the various different types of
cells in Cells. So there would obviously be a bit more work if one is
implementing all that, but still, two caffeine and youth powered student
weeks can achieve a lot ;-)

What "your stupid pet trick" would be referring to? The use of the
__getattribute__ method (which is quite close to SLOT-VALUE-USING-CLASS),
or the use of @decorator syntax to reduce typing and redundancy?

> Now since you are such a genius, maybe you can help with something. Trust
> me on this: this is one place where macros would be able to hide a ton of
> implementation wiring it does no one any good to look at, and actually
> turns into a maintenance nightmare whenever Cells might get revised.

I'd probably use decorators a lot, since they let you play around with
function objects. If they are suitably chosen and designed, the interface
should stay pretty stable even while the wiring is changed.

(Decorator background:

The regular python Python function definition would be
as follows:

def foo(x,y,z):
  ...

would be in CL (if CL were Lisp-1 with symbol-function-or-value) more or less:

(setf (symbol-function-or-value 'foo) (lambda (x y z) ...)

The decorated syntax would be:

@magic_decorator
def foo(x,y,z):
  ...

and the translation:
(setf (symbol-function-or-value 'foo)
 (funcall magic-decorator #'(lambda (x y z)
  ...)))
)
-- 
Lasse Rasinen
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Ken Tilton


Ken Tilton wrote:
> 
> 
> Ben wrote:
> 
>>
>> Nothing you have described sounds that complicated, and you never come
>> up with concrete objections to other peoples code (apart that it took
>> 10 years to write in Lisp, so it must be really hard)
> 
> 
> Oh, now I have to spend an hour dissecting any code you people toss-off 
> that does no more than pick the low-hanging fruit? I do not spend enough 
> time on Usenet already? :)

I want to clarify something. I did look at the code. It was the same 
thing we had with Cells after four-five hours. Yet the author admitted 
he had looked at the Cells source, so he should have known he had not 
implemented, inter alia, synapses, kid-slotting, ephemerals, optional 
laziness, and worst of all he had omitted the data integrity mechanism 
encapsulated by with-integrity. In the next exchange we discover he 
missed the ability to author Python instances individually while 
mistakenly thinking it was impossible.

Exactly how much time am I supposed to spend on someone not willing to 
spend enough time to understand Cells? I recognize, tho, a kindred 
spirit more interested in writing their own code than reading and 
understanding someone else's. :)

You too are more eager to flame me over misperceived slights to The 
Sacred Python than in Python having a wicked cool constraints package, 
and I am wasting too much time on you. I recognize, tho, a fellow Usenet 
dlamewar enthusiast. :)

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Ken Tilton


Ben wrote:
> 
> Nothing you have described sounds that complicated, and you never come
> up with concrete objections to other peoples code (apart that it took
> 10 years to write in Lisp, so it must be really hard)

Oh, now I have to spend an hour dissecting any code you people toss-off 
that does no more than pick the low-hanging fruit? I do not spend enough 
time on Usenet already? :)

> 
> Why are you running a SoC project for PyCells...

You do not even know what Cells are and have not taken the trouble to 
understand, so i will save my breath. Pythonistas will love PyCells, I 
promise. Please recall that it is not just me, there is a ton of prior 
and current art.

> if you dislike the
> language so much.

There is a difference between disliking a language and thinking PyCells 
might end up persuading folks that macros and/or true lambda might be 
worth the trouble to extend the language.

Try to think a little more precisely, OK? Thx.

> People who do like Python can implement it if they
> need it (which I haven't seen any good examples that they do)
> 
> Please don't force a student to create a macro system just to port a
> system to Python,

You are getting hysterical, sit down, breathe. I asked a question, 
because (unlike you) I can see where this is going. But as you say...

> There are already plenty of ways to hide
> complicated functionality,

I know. And that is why the mentor is a Pythonista, not me. I made a 
simple inquiry as to the options available should Python have trouble 
hiding the wiring. just looking ahead a little (as are the student and 
mentor). Something wrong with thinking ahead a few moves?

You on the other hand have made up your mind about something you admit 
you do not understand, have now ascribed to me a half dozen sentiments I 
do not hold, and are feeling absolutely miserable because you think this 
is a flamewar.

No, we are just discussing language synatx and how it impacts language 
semantics, which has led inadvertently to a few of us starting an SoC 
project to put together a Python version of a very successful dataflow 
hack I did for Lisp.

I use it every day, and it just plain makes me smile. I wrote more code 
than you can imagine Before Cells, and have now used them intensively 
and in more ways than you can imagince since. Even if the wiring cannot 
be hidden, the productivity win will be trememndous. Note that this 
translates ineluctably to "programming will be more fun".

Even you will love them.

:)

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-15 Thread Ben


Nothing you have described sounds that complicated, and you never come
up with concrete objections to other peoples code (apart that it took
10 years to write in Lisp, so it must be really hard)

Why are you running a SoC project for PyCells if you dislike the
language so much. People who do like Python can implement it if they
need it (which I haven't seen any good examples that they do)

Please don't force a student to create a macro system just to port a
system to Python, as it won't really be python then. Use Pythonic
methodology instead. There are already plenty of ways to hide
complicated functionality, just not necessarily the way you want to do
it.

Cheers,
Ben

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


Re: A critic of Guido's blog on Python's lambda

2006-05-14 Thread Ken Tilton


Lasse Rasinen wrote:
> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> 
>>>if any concepts have survived to the Python version. Since Python's object
>>>model is sufficiently different, the system is based on rules being
>>>defined per-class...
>>
>>That will be a total disaster for PyCells, if true. But I do not think it
>>is. You just need a constructor that takes some slot initializers, and
>>initialize the slots to one of: a normal value; an InputCell itself
>>initialized with a starting value, if only nil; or a RuledCell itself
>>initialized with a lambda.
> 
> 
> Hmm, just tried it:
> 
> 
class A(cells.cellular):
> 
> ...   def __init__(self):
> ... self.a = cells.InputCell(10)
> ... self.b = cells.RuleCell(lambda self: self.a+1, self, None)
> 
> 
a = A()
a.a
> 
> 10
> 
a.b
> 
> 11
> 
> So it does work out-of-the-box ;-)

So why exactly did you say that the differences in the object model made 
it impossible? I was really stunned by that claim. And you sounded so 
confident. What went wrong there? It was trivial, right? How did you 
miss that?

> 
> 
>>PyCells looks like it will be a project for SoC2006, so you may as well
>>relax.
> 
> 
> You really want to start a SoC project on something that takes about two
> weeks ...

You sound so confident. :)

Do you know the deliverables? I know you do not know Cells. You say you 
looked at the code -- it does not show. I can also tell you have not 
done much serious programming, or you would know that twelve weeks is 
more like twelve minutes than three months.

A new test suite, documentation (a first, there is none now), a full 
port of Cells in all their ten years of sophisticated evolution and 
variety (no, not your stupid pet trick), and as a demo project an entire 
cells-driven GUI, probably a port of my new Celtk (+ Cells Tk) work, all 
in a language without macros, without special variables, with a more 
modest OO system, and limited first class functions... oh, I think we'll 
keep him busy. :)

Now since you are such a genius, maybe you can help with something. 
Trust me on this: this is one place where macros would be able to hide a 
ton of implementation wiring it does no one any good to look at, and 
actually turns into a maintenance nightmare whenever Cells might get 
revised.

Is there any experiemntal macro package out there for Python? Maybe a 
preprocessor, at least? Or are there ways to actually hack Python to 
extend the syntax? My honest guess is that Cells will port readily to 
Python but leave everyone very interested in finding some way to hide 
implementation boilerplate. Got anything on that?

kenny

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


Re: A critic of Guido's blog on Python's lambda

2006-05-14 Thread Lasse Rasinen
Ken Tilton <[EMAIL PROTECTED]> writes:

> > if any concepts have survived to the Python version. Since Python's object
> > model is sufficiently different, the system is based on rules being
> > defined per-class...
> 
> That will be a total disaster for PyCells, if true. But I do not think it
> is. You just need a constructor that takes some slot initializers, and
> initialize the slots to one of: a normal value; an InputCell itself
> initialized with a starting value, if only nil; or a RuledCell itself
> initialized with a lambda.

Hmm, just tried it:

>>> class A(cells.cellular):
...   def __init__(self):
... self.a = cells.InputCell(10)
... self.b = cells.RuleCell(lambda self: self.a+1, self, None)

>>> a = A()
>>> a.a
10
>>> a.b
11

So it does work out-of-the-box ;-)

> PyCells looks like it will be a project for SoC2006, so you may as well
> relax.

You really want to start a SoC project on something that takes about two
weeks from an average Python programmer? What does the guy do for the rest
of the summer?

(I think I spent 4-5 hours on this actually sitting on the computer,
sandwiched between remodeling and cleaning and work. The rest of the two
weeks would be making it more robust ;-)

> > Features:
> > - Tracks changes to input cells dynamically (normal attributes are not 
> > tracked)
> 
> Ha! All your rules depend on the input cell itself! How about A depends on
> B depends on C? :)

Oops. I'm sorry for the inaccurate terminology. They depend only the cells
they use as inputs (their "children"), and not only on InputCells.

(I use the parent-child terminology because as English is not my native
language, I had trouble remembering which depend* variable was which ;-)

> Quite hard to test deliberately, but it happens "in nature". But it will
> not happen until you do A->B->C. Once you have /that/ working, make A the
> input, then have B and C both use A. But also have B use C, and jiggle
> things around until A happens to think it should update B first, then C.
> What happens is that B runs and uses C, but C has not been updated yet. C
> is inconsistent with A, but is being used to calculate a new value for B
> which does see the new value of A. Mismatch! B will get sorted out in a
> moment when C gets recalculated and tells B to calculate a second time,
> but meanwhile after the first recalculation of B the on-change callback
> for that got invoked, missiles were launched, and Moscow has been
> destroyed.

If you check the testcase, you'll see there are such dependencies, and all
the callbacks fire just once (and in dependency-related order).

Furthermore, the timestamp mechanism SHOULD take care of those (if the
cell is older than its children, it gets recalculated before it will
provide any data, and thus C will get recalculated before B uses it.

> ps. In the getattr for any Cell-mediated slot, look to see if "parent" is
> non-nil. If so, set up a dependency. k

Already done, see BaseCell.value() ;-)
-- 
Lasse Rasinen
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-14 Thread Ken Tilton


Lasse Rasinen wrote:
> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> 
>>ps. flaming aside, PyCells really would be amazingly good for Python. And
>>so Google. (Now your job is on the line. ) k
> 
> 
> Here's something I wrote this week, mostly as a mental exercise ;-)

It's fun, right? But what you have is a complete wreck. :)

> The whole code is available at ,
> I'll include a test example below. Feel free to flame away ;-)
> 
> (As for background: I like CL better as a language, but I also like Python
> a lot. However, I was employed for 3 years as a developer and maintainer
> in a Python data mining application, so I'm more fluent in Python than CL.)
> 
> The code is mostly based on Kenny's descriptions of Cells in the following
> messages:
> <[EMAIL PROTECTED]>
> <[EMAIL PROTECTED]>
> <[EMAIL PROTECTED]>
> 
> In addition, I have looked at the CL source code briefly, but I'm not sure
> if any concepts have survived to the Python version. Since Python's object
> model is sufficiently different, the system is based on rules being
> defined per-class...

That will be a total disaster for PyCells, if true. But I do not think 
it is. You just need a constructor that takes some slot initializers, 
and initialize the slots to one of: a normal value; an InputCell itself 
initialized with a starting value, if only nil; or a RuledCell itself 
initialized with a lambda.

Trust me, you lose a vast amount of power unless different instances of 
the same class can have different rules for the same slot.

>... (however, if you define a rule by hand in the __init__
> function, it'll work also. I think; haven't tested).
> 
> I can possibly be persuaded to fix bugs in the code and/or to implement
> new features ;-)

PyCells looks like it will be a project for SoC2006, so you may as well 
relax. But I understand if you want to keep going, it is great fun. btw, 
I have met more than a few people who had done something like Cells 
independently, and there are many full-blown similar implementations 
around. Mine is just the best.  Kidding, i do not really know, there 
are so many.

> 
> Features:
> - Tracks changes to input cells dynamically (normal attributes are not 
> tracked)

Ha! All your rules depend on the input cell itself! How about A depends 
on B depends on C? :)

> - Callbacks for changes (see caveats)
> - Requires Python 2.4 for the decorator syntax (@stuff)
> - Should calculate a cell only once per change (haven't tested ;-)

Quite hard to test deliberately, but it happens "in nature". But it will 
not happen until you do A->B->C. Once you have /that/ working, make A 
the input, then have B and C both use A. But also have B use C, and 
jiggle things around until A happens to think it should update B first, 
then C. What happens is that B runs and uses C, but C has not been 
updated yet. C is inconsistent with A, but is being used to calculate a 
new value for B which does see the new value of A. Mismatch! B will get 
sorted out in a moment when C gets recalculated and tells B to calculate 
a second time, but meanwhile after the first recalculation of B the 
on-change callback for that got invoked, missiles were launched, and 
Moscow has been destroyed.

> 
> Caveats:
> - The input cell callbacks are not called with the class instance 
>   as the first argument, while the rule cell callback are. This
>   is mostly due to laziness.

And unacceptable!

have fun. :)

kenny

ps. In the getattr for any Cell-mediated slot, look to see if "parent" 
is non-nil. If so, set up a dependency. k

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-14 Thread Lasse Rasinen
Ken Tilton <[EMAIL PROTECTED]> writes:

> ps. flaming aside, PyCells really would be amazingly good for Python. And
> so Google. (Now your job is on the line. ) k

Here's something I wrote this week, mostly as a mental exercise ;-)
The whole code is available at ,
I'll include a test example below. Feel free to flame away ;-)

(As for background: I like CL better as a language, but I also like Python
a lot. However, I was employed for 3 years as a developer and maintainer
in a Python data mining application, so I'm more fluent in Python than CL.)

The code is mostly based on Kenny's descriptions of Cells in the following
messages:
<[EMAIL PROTECTED]>
<[EMAIL PROTECTED]>
<[EMAIL PROTECTED]>

In addition, I have looked at the CL source code briefly, but I'm not sure
if any concepts have survived to the Python version. Since Python's object
model is sufficiently different, the system is based on rules being
defined per-class (however, if you define a rule by hand in the __init__
function, it'll work also. I think; haven't tested).

I can possibly be persuaded to fix bugs in the code and/or to implement
new features ;-)

Features:
- Tracks changes to input cells dynamically (normal attributes are not tracked)
- Callbacks for changes (see caveats)
- Requires Python 2.4 for the decorator syntax (@stuff)
- Should calculate a cell only once per change (haven't tested ;-)

Caveats:
- The input cell callbacks are not called with the class instance 
  as the first argument, while the rule cell callback are. This
  is mostly due to laziness.
- There is no cycle detection. If you write cyclic dependencies, you lose.
- There is very little error checking.

Example follows:

def x_callback(oldval, newval):
print "x changed: %s => %s" % (oldval, newval)

class Test(cellular):
   def __init__(self):
   self.x = InputCell(10, callback=x_callback)

   def y_callback(self, oldval, newval):
   print "y changed: %s => %s" %(oldval, newval)

   def a_callback(self, oldval, newval):
   print "a changed: %s => %s" %(oldval, newval)

   def g_callback(self, oldval, newval):
   print "g changed: %s => %s" %(oldval, newval)
   
   @rule(callback=y_callback)
   def y(self):
   return self.x ** 2

   @rule(callback=a_callback)
   def a(self):
   return self.y + self.x

   @rule(callback=g_callback)
   def g(self):
   if self.x % 2 == 0:
   return self.y
   else:
   return self.a


$ python cells.py

y changed: __main__.unbound => 100
a changed: __main__.unbound => 110
g changed: __main__.unbound => 100
=
x changed: 10 => 4
y changed: 100 => 16
a changed: 110 => 20
g changed: 100 => 16
=
x changed: 4 => 5
y changed: 16 => 25
a changed: 20 => 30
g changed: 16 => 30
-- 
Lasse Rasinen
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-13 Thread Marcin 'Qrczak' Kowalczyk
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> I'd like to see a demonstration that using the same binding syntax
> for special and lexical variables buys you something apart from bugs.

There are 3 fundamental operations related to plain mutable variables:

A1. Making a new mutable variable with an initial value.
A2. Getting the current value.
A3. Setting the new value.

and 4 operations related to dynamically scoped variables:

B1. Making a new dynamic variable with an initial value.
B2. Getting the current value.
B3. Setting the new value.
B4. Local rebinding with a new initial value.

If you don't ever use B4, dynamic variables behave exactly like plain
variables. For this reason I see no point in distinguishing A2 from B2,
or A3 from B3. Dynamic variables are a pure extension of plain variables
by providing an additional operation.

Distinguishing the syntax of A1 and B1 is natural: somehow it must be
indicated what kind of variable is created.

Mutability is orthogonal to dynamic scoping. It makes sense to have a
variable which is like a plain variable but without A3, and a variable
which is like a dynamic variable but without B3, although it doesn't
provide anything new, only allows to express more constraints with a
potential for optimization. I won't consider them here.

Common Lisp does something weird: it uses the same syntax for A1 and B4,
where the meaning is distinguished by a special declaration. Here is
its syntax:

Directly named plain variables:
A1. (let ((name value)) body) and other forms
A2. name
A3. (setq name value), (setf name value)

First-class dynamic variables:
B1. (gensym)
B2. (symbol-value variable)
B3. (set variable value), (setf (symbol-value variable) value)
B4. (progv `(variable) `(value) body)

Directly named dynamic variables:
B1. (defvar name value), (defparameter name value)
B2. name
B3. (setq name value), (setf name value)
B4. (let ((name value)) body) and other forms

Dynamic variables in Lisp come in two flavors: first-class variables
and directly named variables. Directly named variables are always
global. You can convert a direct name to a first-class variable by
(quote name).

Plain variables have only the directly named flavor and they are
always local. You can emulate the first-class flavor by wrapping a
variable in a pair of closures or a closure with dual getting/setting
interface (needs a helper macro in order to be convenient). You can
emulate a global plain variable by wrapping a dynamic variable in a
symbol macro, ignoring its potential for local rebinding. You can
emulate creation of a new first-class variable by using a dynamic
variable and ignoring its potential for local rebinding, but this
can't be used to refer to an existing directly named plain variable.

In order to create a plain variable, you must be sure that its name is
not already used by a dynamic variable in the same scope.

So any essential functionality is possible to obtain, but the syntax
is very irregular.

-- 
   __("< Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-13 Thread Marcin 'Qrczak' Kowalczyk
Ken Tilton <[EMAIL PROTECTED]> writes:

> I think the point is that, with the variable actually being just
> a string and with dedicated new explicit functions required as
> "accessors", well, you could hack that up in any language with
> dictionaries. It is the beginnings of an interpreter, not Python
> itself even feigning special behavior.

If the semantics and the global structure of the code is right, only
you don't like the local concrete syntax, then the complaint is at
most as justified as complaints against Lisp parentheses.

-- 
   __("< Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-13 Thread Duane Rettig
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> I think that in most contexts lexical transparency is desirable so that
> deviations from lexical transparency ought to be well motivated. I also
> believe that a construct that is usually used to establish a lexically
> transparent binding shouldn't be equally used for dynamic bindings so that it
> isn't syntactically obvious what's going on. I've already provided some
> reasons why CL's design wrt. binding special and lexical variables seems bad
> to me. I don't think these reasons were terribly forceful but as I'm not aware
> of any strong motivation why the current behaviour would be useful I'm
> currently considering it a minor wart.
>
> To make things more concrete: What would be the downside of, instead of doing
> something like:
>
> (let ((*x* ...)) [(declare (special *x*))] ...) ; where [X] denotes maybe X

Let's start with this.  You seem to be saying that the above construct is 
inferior
to the alternatives you are about to suggest.  Why?  And since you are adding
an optional form, let's break it down into its separate situations:

1. (let ((*x* ...)) (declare (special *x*)) ...)

Here there is no question about the specialness of *x*; it is textually
obvious what the binding is - that it is not a lexical binding but a special
binding.

2. (let ((*x* ...)) ...)

[where there is no special declaration for *x* within the form]

Here, the issue is that it is not obvious that *x* is special (in this case,
it would have to already be a dynamic variable (what we internally call
"globally special"), because a special declaration within a lexical context
does not affect inner bindings.  Perhaps this form is the one you are really
having trouble with.

> doing any of the below:
>
> a) using a different construct e.g. (fluid-let ((*x* ...)) ...) for binding
>special variables

Unless you also _remove_ the #2 case above, this seems no diferent than writing
a macro for the #1 case, above.

> b) having to use *...* (or some other syntax) for special variables

In fact, the spec does suggest precisely this (see
http://www.franz.com/support/documentation/8.0/ansicl/dictentr/defparam.htm,
in the Notes section), and to the extent that programmers obey the suggestion,
the textual prompting is present in the name.

> c) using (let ((q (special *x*) (,a ,b ,@c)) (values 1 2 '(3 4 5 6)))
>   (list q ((lambda () (incf *x*))) a b c)) ; => (1 3 3 4 (5 6))
>
> (It's getting late, but hopefully this makes some vague sense)

Well, sort of; this seems simply like a sometimes-fluid-let, whose syntax could
easily be established by a macro (with destructurings whose form is (special X)
could be specially [sic] treated.

Now if in the above example you would have trouble with (a) and/or (c)
based on the absence of a "lexical" declaration (i.e. one that would undo
the effect of a globally special declaration), thus guaranteeing that a
fluid-let or a "sometimes-fluid-let" would work, you should know that while
I was working on the Environments Access module I theorized and demonstrated
that such a declaration could be easily done within a conforming Common Lisp.
I leave you with that demonstration here (though it really is only for
demonstration purposes only; I don't necessarily propose that CL should add
a lexical declaration to the language):

[This only works on Allegro CL 8.0]:

CL-USER(1): (defvar pie pi)
PIE
CL-USER(2): (compile (defun circ (rad) (* pie rad rad)))
CIRC
NIL
NIL
CL-USER(3): (circ 10)
314.1592653589793d0
CL-USER(4): (compile (defun foo (x) (let ((pie 22/7)) (circ x
FOO
NIL
NIL
CL-USER(5): (foo 10)
2200/7
CL-USER(6): (float *)
314.2857
CL-USER(7): (sys:define-declaration sys::lexical (&rest vars)
  nil
  :variable
  (lambda (declaration env)
(declare (ignore env))
(let* ((spec '(lexical t))
   (res (mapcar #'(lambda (x) (cons x spec))
(cdr declaration
  (values :variable res
SYSTEM::LEXICAL
CL-USER(8): (compile (defun foo (x) (let ((pie 22/7)) (declare (sys::lexical 
pie)) (circ x
; While compiling FOO:
Warning: Variable PIE is never used.
FOO
T
NIL
CL-USER(9): (foo 10)
314.1592653589793d0
CL-USER(10): 

-- 
Duane Rettig[EMAIL PROTECTED]Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450   http://www.555citycenter.com/
Oakland, Ca. 94607Phone: (510) 452-2000; Fax: (510) 452-0182   
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton
Everything else responded to separately, but...

> I'd like to see a demonstration that using the same binding syntax for special
> and lexical variables buys you something apart from bugs.

Buys me something? Why do I have to sell simplicity, transparency, and 
clean syntax on c.l.python?

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton


Paul Rubin wrote:
> Alexander Schmolck <[EMAIL PROTECTED]> writes:
> 
>>>(defvar *x*) ;; makes it special
>>>(setf *x* 1)
>>>(print *x*) ;;-> 1
>>>(let ((*x* 2))
>>>   (print *x*)) ;; -> 2
>>>(print *x*) ;; -> 1
>>
>>You seem to think that conflating special variable binding and lexical
>>variable binding is a feature and not a bug. What's your rationale?
> 
> 
> I thought special variables meant dynamic binding, i.e.
> 
>(defvar *x* 1)
>(defun f ()
>(print *x*)  ;; -> 2 
>(let ((*x* 3))
>(g)))
>(defun g ()
>(print *x*)) ;; - > 3 
> 
> That was normal behavior in most Lisps before Scheme popularlized
> lexical binding.  IMO it was mostly an implementation convenience hack
> since it was implemented with a very efficient shallow binding cell.
> That Common Lisp adapted Scheme's lexical bindings was considered a
> big sign of CL's couthness.  So I'm a little confused about what Ken
> Tilton is getting at.

Paul, there is no conflict between your example and mine, but I can see 
why you think mine does not demonstrate dynamic binding: I did not 
demonstrate the binding applying across a function call.

What might be even more entertaining would be a nested dynamic binding 
with the same function called at different levels and before and after 
each binding.

I just had the sense that this chat was between folks who fully grokked 
special vars. Sorr if I threw you a curve.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton


Alexander Schmolck wrote:
> Duane Rettig <[EMAIL PROTECTED]> writes:
> 
> 
>>Alexander Schmolck <[EMAIL PROTECTED]> writes:
>>
>>
>>>Ken Tilton <[EMAIL PROTECTED]> writes:
>>>
>>>
In Common Lisp we would have:

(defvar *x*) ;; makes it special
(setf *x* 1)
(print *x*) ;;-> 1
(let ((*x* 2))
   (print *x*)) ;; -> 2
(print *x*) ;; -> 1
>>>
>>>You seem to think that conflating special variable binding and lexical
>>>variable binding is a feature and not a bug. What's your rationale?

I will expand on my earlier "transparency" rationale with a further 
rationale for transparency: I do not need no stinkin' rationale. A 
special variable is still a variable. They should be set, read, and 
bound (say, by "let") the same way as any other variable.

You need a rationale. It sounds as if you want some noisey syntax to 
advertise the specialness. I do not think the Python community will 
appreciate you messing up their pretty code.

You are right about one thing: specialness needs advertising. You know 
what we do in Lisp? We obediently name special variables with bracketing 
*s, like *this*. Too simple?

>>
>>A bug is a non-conformance to spec. 
> 
> 
> There is a world beyond specs, you know. If copies of allegro CL accidently
> sent out death-threats to the US president on a weekly basis, because someone
> at franz accidently or purposefully left in some pranky debugging code the
> fact that this behaviour would likely neither violate the ansi spec nor any
> other specs that ACL officially purports to adhere to wouldn't make it any
> less of a bug (or help to pacify your customers).
> 
> 
>>Kenny's statement was specifically about Common Lisp
> 
> 
> No Kenny's statement was about contrasting the way something is done in python
> and the way something is done in common lisp (with the implication that the
> latter is preferable).

Close,  but no. The question I was weighing in was "has Michele 
replicated special variables?". My implication was, "Not yet -- can you 
match the transparency?", and it was an honest question, I do not know. 
Again, transparency is a qualitative difference.

I liked your solution better, btw, because it does minimize the noise. 
For fun, you should call the class ** instead of special, so we end up 
with:**.b = 42

We'll understand. :)

> Of course the way something is done in common lisp is
> almost tautologically in closer agreement with the ansi common lisp spec than
> the way it is done in python, so agreement with the clhs is not a useful
> criterion when talking about design features and misfeatures when contrasting
> languages.

Again, no, it is not the spec, it is the highly-valued Python quality of 
  clean code. Also, the consistency of treating variables as variables, 
regardless of some special/dynamic quality.

Some background. Lisp is a big language, and I am self taught and do not 
like to read, grew up in Lisp in isolation. Not many Lispers in the 
exercise yard. Discovered special variables only when we hired an old 
hand who gently corrected a howler:

(let* ((old-x *x*))
   (setf *x* 42)
   
   (setf *x* old-x))

I still laugh at that. Anyway, as soon as I learned that, I was able to 
make Cells syntax infinitely more transparent. And guess what? It also 
made dependency identification automatic instead of cooperative, and 
when I rebuilt a huge Cells-based app I discovered two or three cases 
where I had neglected to publish a dependency.

It's a mystery, but somehow simpler syntax... oh, wait, this is 
c.l.python, I am preaching to the choir.

> 
> I just don't think the way special variable binding (or variable binding in
> general[1]) is handled in common lisp is particularly well designed or
> elegant.

See above. There is nothing like a concrete experience of implementing a 
hairy library like Cells /without/ leveraging specials and then 
converting to specials. Talk about an Aha! experience. I mean, bugs ran 
screaming from their nests simply because of the implementation change-- 
  we call that A Message From God that the design has taken a correct turn.

> 
> Special variables and lexical variables have different semantics and using
> convention and abusing[2] the declaration mechanism to differentiate between
> special and lexical variables doesn't strike me as a great idea.

I know what you mean, but I like reading tea leaves, and I find it 
fascinating that *this* somehow eliminates all ambiguity. Background: 
don't know where I might find it, but I once saw a thread demonstrating 
the astonishing confusion one could create with a special variable such 
as a plain X (no *s). Absolutely mind-bogglingly confusing. Go back and 
rename the special version *x*, and use *x* where you want to rebind it. 
Result? Utterly lucid code. Scary, right?
> 
> I can certainly think of problems that can occur because of it (E.g. ignoring
> or messing up a special declaration somewhere; setf on

Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
Ken Tilton <[EMAIL PROTECTED]> writes:

> Alexander Schmolck wrote:
> > Ken Tilton <[EMAIL PROTECTED]> writes:
> >
> 
> >>In Common Lisp we would have:
> >>
> >>(defvar *x*) ;; makes it special
> >>(setf *x* 1)
> >>(print *x*) ;;-> 1
> >>(let ((*x* 2))
> >>   (print *x*)) ;; -> 2
> >>(print *x*) ;; -> 1
> > You seem to think that conflating special variable binding and lexical
> 
> > variable binding is a feature and not a bug. What's your rationale?
> 
> Transparency. 

That's is circular. You might be right, but you failed to provide a rationale
and not just a restatement.

> That is where power comes from. I did the same things with Cells. Reading a
> slot with the usual Lisp reader method transparently creates a dependency on
> the variable. 

Let me see if I understand it right -- if an instance of class A has a ruled
slot a that reads an instance of class B's slot b then it is noted somewhere
that A's a depends on b?

> To change a variable and have it propagate throughout the datamodel, Just
> Change It.
> 
> 
> Exposed wiring means more work and agonizing refactoring.

Well, you claim that in that instance python suffers from exposed wiring and I
claim that CL suffers from a (minor) booby trap. You can't typically safely
ignore whether a variable is special as a mere wiring detail or your code
won't work reliably (just as you can't typically safely ignore whether
something is rigged or not even if booby-trapness is pretty transparent) --
it's as simple as that (actually its a bit worse because the bug can be hard
to detect as lexical and special variables will result in the same behaviour
in many contexts).

So in the case of booby traps and special variables, I generally prefer some
exposed wiring (or strong visual clues) to transparency.

I'd like to see a demonstration that using the same binding syntax for special
and lexical variables buys you something apart from bugs.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
jayessay <[EMAIL PROTECTED]> writes:

> > Great -- so can I see some code? Can't be that difficult, it takes about 
> > 10-15
> > lines in python (and less in scheme).
> 
> Do you actually need the code to understand this relatively simple concept???

Yes. I'd be genuinely curious to see how an implementation in Java, Pascal, C,
(or any other language that has little more than dictionaries) compares to
python and CL.

In my limited understanding I have trouble seeing how you'd do without either
unwind-protect/try-finally or reliable finalizers for starters.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
Duane Rettig <[EMAIL PROTECTED]> writes:

> My reason for responding to you in the first place was due to your poor use
> of the often misused term "bug".  You could have used many other words or
> phrases to describe the situation, and I would have left any of those alone.

I'm happy to accept your terminology of bug (not conforming to a certain
specification) for the remainder of this discussion so that we can stop
quibbling over words.

[...]
> > I'd be even more interested in what you think (seriously; should
> > you consider it a design feature (for reasons other than backwards
> > compatiblity constraints), I'm pretty sure you would also give a 
> > justification
> > that would merrit consideration).
> 
> Well, OK, let's change the conversation away from "bug"-ness and toward any of
> the other negatives we discussed above.  I actually doubt that I can provide
> a justification in a small space without first understanding who you are
> and from what background you are coming, so let me turn it around and ask
> you instead to knock down a straw-man:
> 
> You seem to be saying that pure lexical transparency is always preferable
> to statefulness (e.g. context).

No.

> Can we make that leap? If not, set me straight. 

I think that in most contexts lexical transparency is desirable so that
deviations from lexical transparency ought to be well motivated. I also
believe that a construct that is usually used to establish a lexically
transparent binding shouldn't be equally used for dynamic bindings so that it
isn't syntactically obvious what's going on. I've already provided some
reasons why CL's design wrt. binding special and lexical variables seems bad
to me. I don't think these reasons were terribly forceful but as I'm not aware
of any strong motivation why the current behaviour would be useful I'm
currently considering it a minor wart.

To make things more concrete: What would be the downside of, instead of doing
something like:

(let ((*x* ...)) [(declare (special *x*))] ...) ; where [X] denotes maybe X

doing any of the below:

a) using a different construct e.g. (fluid-let ((*x* ...)) ...) for binding
   special variables
b) having to use *...* (or some other syntax) for special variables
c) using (let ((q (special *x*) (,a ,b ,@c)) (values 1 2 '(3 4 5 6)))
  (list q ((lambda () (incf *x*))) a b c)) ; => (1 3 3 4 (5 6))

(It's getting late, but hopefully this makes some vague sense)

> If so, tell me: how do we programmatically model those situations in life
> which are inherently contextual in nature, where you might get a small piece
> of information and must make sense of it by drawing on information that is
> _not_ given in that information, but is (globally, if you will) "just known"
> by you? How about conversations in English? And, by the way, how do you
> really know I'm writing to you in English, and not some coded language that
> means something entirely different?

We can skip that part.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Duane Rettig
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> Duane Rettig <[EMAIL PROTECTED]> writes:
>
>> Alexander Schmolck <[EMAIL PROTECTED]> writes:
>> 
>> > Ken Tilton <[EMAIL PROTECTED]> writes:
>> >
>> >> In Common Lisp we would have:
>> >> 
>> >> (defvar *x*) ;; makes it special
>> >> (setf *x* 1)
>> >> (print *x*) ;;-> 1
>> >> (let ((*x* 2))
>> >>(print *x*)) ;; -> 2
>> >> (print *x*) ;; -> 1
>> >
>> > You seem to think that conflating special variable binding and lexical
>> > variable binding is a feature and not a bug. What's your rationale?
>> 
>> A bug is a non-conformance to spec. 
>
> There is a world beyond specs, you know. If copies of allegro CL accidently
> sent out death-threats to the US president on a weekly basis, because someone
> at franz accidently or purposefully left in some pranky debugging code the
> fact that this behaviour would likely neither violate the ansi spec nor any
> other specs that ACL officially purports to adhere to wouldn't make it any
> less of a bug (or help to pacify your customers).

It wouldn't be a bug in Allegro CL, because it would never happen in an Allegro 
CL
that hasn't been enhanced with some kind of program.  And although that program
itself could have a bug whereby such a threat were accidental, I would tend not
to call it accidental, I would tend to call it expicit, and thus not a bug but
an intended consequence of such explicit programming.

My reason for responding to you in the first place was due to your poor use
of the often misused term "bug".  You could have used many other words or
phrases to describe the situation, and I would have left any of those alone.

For example:

>> Kenny's statement was specifically about Common Lisp
>
> No Kenny's statement was about contrasting the way something is done in python
> and the way something is done in common lisp (with the implication that the
> latter is preferable). Of course the way something is done in common lisp is
> almost tautologically in closer agreement with the ansi common lisp spec than
> the way it is done in python, so agreement with the clhs is not a useful
> criterion when talking about design features and misfeatures when contrasting
> languages.
>
> I thought it would have been pretty obvious that I was talking about language
> design features and language design misfeatures (Indeed the infamously post
> hoc, "It's a feature, not a bug" I was obviously alluding too doesn't make
> much sense in a world were everything is tightly specified, because in it
> nothing is post-hoc).

Whether it is preferable is a matter of opinion, and whether Kenny meant it
to infer preferability (I suspect so) or not has nothing to due with whether
it is a bug.  Instead, you should call it a "design misfeature", which would
set the stage for a more cogent argumentation on the point, rather than on the
hyperbole.  By the way, if you do call it a design misfeature, I would be
arguing against you, but that is another conversation.

>>, which has a spec.
>
> Bah -- so does fortran. But scheme also has operational semantics.
>
>> Now, what was your rationale for it _being_ a bug?
>
> I just don't think the way special variable binding (or variable binding in
> general[1]) is handled in common lisp is particularly well designed or
> elegant.

Then call it "misdesigned" or "inelegant".

> Special variables and lexical variables have different semantics and using
> convention and abusing[2] the declaration mechanism to differentiate between
> special and lexical variables doesn't strike me as a great idea.

Then call it a "bad idea".

> I can certainly think of problems that can occur because of it (E.g. ignoring
> or messing up a special declaration somewhere; setf on a non-declared variable
> anyone? There are also inconsistent conventions for naming (local) special
> variables within the community (I've seen %x%, *x* and x)).

Then call it "not fully standardized or normative".

> Thus I don't see having to use syntactically different binding and assignment
> forms for special and lexical variables as inherently inferior.

Then call it "inherently inferior".

> But I might be wrong -- which is why was asking for the rationale of Kenny's
> preference.

But you _didn't_ ask him what rationale he had for his _preference_, you
asked him his rationale for considering it not a _bug_.

> I'd be even more interested in what you think (seriously; should
> you consider it a design feature (for reasons other than backwards
> compatiblity constraints), I'm pretty sure you would also give a justification
> that would merrit consideration).

Well, OK, let's change the conversation away from "bug"-ness and toward any of
the other negatives we discussed above.  I actually doubt that I can provide
a justification in a small space without first understanding who you are
and from what background you are coming, so let me turn it around and ask
you instead to knock down a straw-man:

You seem to be saying t

Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread jayessay
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> > Alexander Schmolck wrote:
> > > jayessay <[EMAIL PROTECTED]> writes:
> > >
> > 
> > >>"Michele Simionato" <[EMAIL PROTECTED]> writes:
> > >>
> > >>
> > >>>I was interested in a proof of concept, to show that Python can
> > >>>emulate Lisp special variables with no big effort.
> > >>
> > >>OK, but the sort of "proof of concept" given here is something you can
> > >> hack up in pretty much anything.
> > 
> > > Care to provide e.g. a java equivalent?
> > 
> > 
> > I think the point is that, with the variable actually being just a string 
> > and
> > with dedicated new explicit functions required as "accessors", well, you 
> > could
> > hack that up in any language with dictionaries. 
> 
> Great -- so can I see some code? Can't be that difficult, it takes about 10-15
> lines in python (and less in scheme).

Do you actually need the code to understand this relatively simple concept???

/Jon


-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread jayessay
Ken Tilton <[EMAIL PROTECTED]> writes:

> Alexander Schmolck wrote:
> > jayessay <[EMAIL PROTECTED]> writes:
> >
> >>"Michele Simionato" <[EMAIL PROTECTED]> writes:
> >>
> >>
> >>>I was interested in a proof of concept, to show that Python can
> >>>emulate Lisp special variables with no big effort.
> >>
> >>OK, but the sort of "proof of concept" given here is something you can
> >> hack up in pretty much anything.
> > Care to provide e.g. a java equivalent?
> 
> I think the point is that, with the variable actually being just a
> string and with dedicated new explicit functions required as
> "accessors", well, you could hack that up in any language with
> dictionaries. It is the beginnings of an interpreter, not Python
> itself even feigning special behavior.

Exactly.  Of course this is going to be totally lost on the intended
audience...


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread jayessay
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> > In Common Lisp we would have:
> > 
> > (defvar *x*) ;; makes it special
> > (setf *x* 1)
> > (print *x*) ;;-> 1
> > (let ((*x* 2))
> >(print *x*)) ;; -> 2
> > (print *x*) ;; -> 1
> 
> You seem to think that conflating special variable binding and lexical
> variable binding is a feature and not a bug. What's your rationale?

And the particularly ugly, crappy, half baked python emulation is what?
A feature?  Right.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton


Alexander Schmolck wrote:
> Ken Tilton <[EMAIL PROTECTED]> writes:
> 
> 
>>In Common Lisp we would have:
>>
>>(defvar *x*) ;; makes it special
>>(setf *x* 1)
>>(print *x*) ;;-> 1
>>(let ((*x* 2))
>>   (print *x*)) ;; -> 2
>>(print *x*) ;; -> 1
> 
> 
> You seem to think that conflating special variable binding and lexical
> variable binding is a feature and not a bug. What's your rationale?

Transparency. That is where power comes from. I did the same things with 
Cells. Reading a slot with the usual Lisp reader method transparently 
creates a dependency on the variable. To change a variable and have it 
propagate throughout the datamodel, Just Change It.

Exposed wiring means more work and agonizing refactoring.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
Duane Rettig <[EMAIL PROTECTED]> writes:

> Alexander Schmolck <[EMAIL PROTECTED]> writes:
> 
> > Ken Tilton <[EMAIL PROTECTED]> writes:
> >
> >> In Common Lisp we would have:
> >> 
> >> (defvar *x*) ;; makes it special
> >> (setf *x* 1)
> >> (print *x*) ;;-> 1
> >> (let ((*x* 2))
> >>(print *x*)) ;; -> 2
> >> (print *x*) ;; -> 1
> >
> > You seem to think that conflating special variable binding and lexical
> > variable binding is a feature and not a bug. What's your rationale?
> 
> A bug is a non-conformance to spec. 

There is a world beyond specs, you know. If copies of allegro CL accidently
sent out death-threats to the US president on a weekly basis, because someone
at franz accidently or purposefully left in some pranky debugging code the
fact that this behaviour would likely neither violate the ansi spec nor any
other specs that ACL officially purports to adhere to wouldn't make it any
less of a bug (or help to pacify your customers).

> Kenny's statement was specifically about Common Lisp

No Kenny's statement was about contrasting the way something is done in python
and the way something is done in common lisp (with the implication that the
latter is preferable). Of course the way something is done in common lisp is
almost tautologically in closer agreement with the ansi common lisp spec than
the way it is done in python, so agreement with the clhs is not a useful
criterion when talking about design features and misfeatures when contrasting
languages.

I thought it would have been pretty obvious that I was talking about language
design features and language design misfeatures (Indeed the infamously post
hoc, "It's a feature, not a bug" I was obviously alluding too doesn't make
much sense in a world were everything is tightly specified, because in it
nothing is post-hoc).

>, which has a spec.

Bah -- so does fortran. But scheme also has operational semantics.

> Now, what was your rationale for it _being_ a bug?

I just don't think the way special variable binding (or variable binding in
general[1]) is handled in common lisp is particularly well designed or
elegant.

Special variables and lexical variables have different semantics and using
convention and abusing[2] the declaration mechanism to differentiate between
special and lexical variables doesn't strike me as a great idea.

I can certainly think of problems that can occur because of it (E.g. ignoring
or messing up a special declaration somewhere; setf on a non-declared variable
anyone? There are also inconsistent conventions for naming (local) special
variables within the community (I've seen %x%, *x* and x)).

Thus I don't see having to use syntactically different binding and assignment
forms for special and lexical variables as inherently inferior.

But I might be wrong -- which is why was asking for the rationale of Kenny's
preference. I'd be even more interested in what you think (seriously; should
you consider it a design feature (for reasons other than backwards
compatiblity constraints), I'm pretty sure you would also give a justification
that would merrit consideration).

'as

Footnotes: 
[1] The space of what I see as orthogonal features (parallel vs. serial
binding, single vs. multiple values and destructuring vs non-destructuring
etc.) is sliced in what appear to me pretty arbitrary, non-orthogonal and
annoying (esp. superfluous typing and indentation) ways in CL.

[2] Generally declarations don't change the meaning of an otherwise
well-defined program. The special declaration does. It's also a potential
source of errors as the declaration forces you to repeat yourself and to
pay attention to two places rather than one.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Paul Rubin
Alexander Schmolck <[EMAIL PROTECTED]> writes:
> > (defvar *x*) ;; makes it special
> > (setf *x* 1)
> > (print *x*) ;;-> 1
> > (let ((*x* 2))
> >(print *x*)) ;; -> 2
> > (print *x*) ;; -> 1
> 
> You seem to think that conflating special variable binding and lexical
> variable binding is a feature and not a bug. What's your rationale?

I thought special variables meant dynamic binding, i.e.

   (defvar *x* 1)
   (defun f ()
   (print *x*)  ;; -> 2 
   (let ((*x* 3))
   (g)))
   (defun g ()
   (print *x*)) ;; - > 3 

That was normal behavior in most Lisps before Scheme popularlized
lexical binding.  IMO it was mostly an implementation convenience hack
since it was implemented with a very efficient shallow binding cell.
That Common Lisp adapted Scheme's lexical bindings was considered a
big sign of CL's couthness.  So I'm a little confused about what Ken
Tilton is getting at.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
Ken Tilton <[EMAIL PROTECTED]> writes:

> Alexander Schmolck wrote:
> > jayessay <[EMAIL PROTECTED]> writes:
> >
> 
> >>"Michele Simionato" <[EMAIL PROTECTED]> writes:
> >>
> >>
> >>>I was interested in a proof of concept, to show that Python can
> >>>emulate Lisp special variables with no big effort.
> >>
> >>OK, but the sort of "proof of concept" given here is something you can
> >> hack up in pretty much anything.
> 
> > Care to provide e.g. a java equivalent?
> 
> 
> I think the point is that, with the variable actually being just a string and
> with dedicated new explicit functions required as "accessors", well, you could
> hack that up in any language with dictionaries. 

Great -- so can I see some code? Can't be that difficult, it takes about 10-15
lines in python (and less in scheme).

> It is the beginnings of an interpreter, not Python itself even feigning
> special behavior.
> 
> 
> perhaps the way to go is to take the Common Lisp:
> 
>  (DEFVAR *x*)
> 
>  *x* = special_var(v=42) ;; I made this syntax up
> 
> that could make for cleaner code:
> 
>  *x*.v = 1
> 
>  print *x*.v -> 1
> 
> (Can we hide the .v?) 

I'd presumably write special variable access as something like:

with specials('x','y','z'):
 special.x = 3 + 4
 special.y = special.x + 10
 ...

I haven't tested this because I haven't got the python 2.5 alpha and won't go
through the trouble of installing it for this usenet discussion, but I'm
pretty sure this would work fine (I'm sure someone else can post an
implementation or prove me wrong). I also can't see how one could sensibly
claim that this doesn't qualify as an implementation of dynamically scoped
variables. Doesn't look any worse to me than

(let (x y z)
 (declare (special x y z))
 ...)

-- in fact it looks better.

> But there is still the problem of knowing when to revert a value to its
> prior binding when the scope of some WITH block is left.

Can you explain what you mean by this statement? I'm not quite sure but I've
got the impression you're a possibly confused. Have you had a look at
 or some other explanation
of the with statement?

> Of course that is what indentation is for in Python, so... is that extensible
> by application code? 

The meaning of indentation? No.

> Or would this require Python internals work?

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Duane Rettig
Alexander Schmolck <[EMAIL PROTECTED]> writes:

> Ken Tilton <[EMAIL PROTECTED]> writes:
>
>> In Common Lisp we would have:
>> 
>> (defvar *x*) ;; makes it special
>> (setf *x* 1)
>> (print *x*) ;;-> 1
>> (let ((*x* 2))
>>(print *x*)) ;; -> 2
>> (print *x*) ;; -> 1
>
> You seem to think that conflating special variable binding and lexical
> variable binding is a feature and not a bug. What's your rationale?

A bug is a non-conformance to spec.  Kenny's statement was specifically
about Common Lisp, which has a spec.  Now, what was your rationale for
it _being_ a bug?

-- 
Duane Rettig[EMAIL PROTECTED]Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450   http://www.555citycenter.com/
Oakland, Ca. 94607Phone: (510) 452-2000; Fax: (510) 452-0182   
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
Ken Tilton <[EMAIL PROTECTED]> writes:

> In Common Lisp we would have:
> 
> (defvar *x*) ;; makes it special
> (setf *x* 1)
> (print *x*) ;;-> 1
> (let ((*x* 2))
>(print *x*)) ;; -> 2
> (print *x*) ;; -> 1

You seem to think that conflating special variable binding and lexical
variable binding is a feature and not a bug. What's your rationale?

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton


Alexander Schmolck wrote:
> jayessay <[EMAIL PROTECTED]> writes:
> 
> 
>>"Michele Simionato" <[EMAIL PROTECTED]> writes:
>>
>>
>>>I was interested in a proof of concept, to show that Python can
>>>emulate Lisp special variables with no big effort.
>>
>>OK, but the sort of "proof of concept" given here is something you can
>>hack up in pretty much anything. 
> 
> 
> Care to provide e.g. a java equivalent?

I think the point is that, with the variable actually being just a 
string and with dedicated new explicit functions required as 
"accessors", well, you could hack that up in any language with 
dictionaries. It is the beginnings of an interpreter, not Python itself 
even feigning special behavior.

perhaps the way to go is to take the Common Lisp:

 (DEFVAR *x*)

 *x* = special_var(v=42) ;; I made this syntax up

that could make for cleaner code:

 *x*.v = 1

 print *x*.v -> 1

(Can we hide the .v?) But there is still the problem of knowing when to 
revert a value to its prior binding when the scope of some WITH block is 
left.

Of course that is what indentation is for in Python, so... is that 
extensible by application code? Or would this require Python internals work?

kenny


-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Ken Tilton


Michele Simionato wrote:
> jayessay wrote:
> 
>>I was saying that you are mistaken in that pep-0343 could be used to
>>implement dynamically scoped variables.  That stands.
> 
> 
> Proof by counter example:
> 
> from __future__ import with_statement
> import threading
> 
> special = threading.local()
> 
> def getvar(name):
> return getattr(special, name)
> 
> def setvar(name, value):
> return setattr(special, name, value)
> 
> class dynamically_scoped(object):
> def __init__(self, name, value):
> self.name = name
> self.value = value
> def __context__(self):
> return self
> def __enter__(self):
> self.orig_value = getvar(self.name)
> setvar(self.name, self.value)
> def __exit__(self, Exc, msg, tb):
> setvar(self.name, self.orig_value)
> 
> if __name__ == '__main__': # test
> setvar("*x*", 1)
> print getvar("*x*") # => 1
> with dynamically_scoped("*x*", 2):
> print getvar("*x*") # => 2
> print getvar("*x*") # => 1
> 
> If you are not happy with this implementation, please clarify.

Can you make it look a little more as if it were part of the language, 
or at least conceal the wiring better? I am especially bothered by the 
double-quotes and having to use setvar and getvar.

In Common Lisp we would have:

(defvar *x*) ;; makes it special
(setf *x* 1)
(print *x*) ;;-> 1
(let ((*x* 2))
   (print *x*)) ;; -> 2
(print *x*) ;; -> 1

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Alexander Schmolck
jayessay <[EMAIL PROTECTED]> writes:

> "Michele Simionato" <[EMAIL PROTECTED]> writes:
> 
> > I was interested in a proof of concept, to show that Python can
> > emulate Lisp special variables with no big effort.
> 
> OK, but the sort of "proof of concept" given here is something you can
> hack up in pretty much anything. 

Care to provide e.g. a java equivalent?

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


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread jayessay
"Michele Simionato" <[EMAIL PROTECTED]> writes:

> I was interested in a proof of concept, to show that Python can
> emulate Lisp special variables with no big effort.

OK, but the sort of "proof of concept" given here is something you can
hack up in pretty much anything.  So, I wouldn't call it especially
convincing in its effect and capability.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-12 Thread Michele Simionato
jayessay wrote:
> "Michele Simionato" <[EMAIL PROTECTED]> writes:
> I can't get this to work at all - syntax errors (presumably you must
> have 2.5?, I only have 2.4).

You can download Python 2.5 from www.python.org, but the important bit,
i.e. the use of threading.local to get thread-local variables is
already there in Python 2.4.
'with' gives you just a nicer lisp-like syntax.

> This has not so much to do with WITH as relying on a special "global"
> object which you must reference specially, which keeps track (more or
> less) of its attribute values, which you use as "faked up" variables.
> Actually you probably need to hack this a bit more to even get that as
> it doesn't appear to stack the values beyond a single level.

Yes, but it would not be difficult, I would just instantiate
threading.local inside
the __init__ method of the dynamically_scoped class, so each 'with'
block
would have its own variables (and I should change getvar and setvar a
bit).

I was interested in a proof of concept, to show that Python can emulate
Lisp
special variables with no big effort.

  Michele Simionato

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


Re: A critic of Guido's blog on Python's lambda

2006-05-11 Thread Boris Borcic
jayessay wrote:
> "Michele Simionato" <[EMAIL PROTECTED]> writes:
> 
>> jayessay wrote:
>>> I was saying that you are mistaken in that pep-0343 could be used to
>>> implement dynamically scoped variables.  That stands.
>> Proof by counter example:
>>
>> from __future__ import with_statement
>> import threading
>>
>> special = threading.local()
>>
>> def getvar(name):
>> return getattr(special, name)
>>
>> def setvar(name, value):
>> return setattr(special, name, value)
>>
>> class dynamically_scoped(object):
>> def __init__(self, name, value):
>> self.name = name
>> self.value = value
>> def __context__(self):
>> return self
>> def __enter__(self):
>> self.orig_value = getvar(self.name)
>> setvar(self.name, self.value)
>> def __exit__(self, Exc, msg, tb):
>> setvar(self.name, self.orig_value)
>>
>> if __name__ == '__main__': # test
>> setvar("*x*", 1)
>> print getvar("*x*") # => 1
>> with dynamically_scoped("*x*", 2):
>> print getvar("*x*") # => 2
>> print getvar("*x*") # => 1
>>
>> If you are not happy with this implementation, please clarify.
> 
> I can't get this to work at all - syntax errors (presumably you must
> have 2.5?, I only have 2.4).  But anyway:
> 
> This has not so much to do with WITH as relying on a special "global"
> object which you must reference specially, which keeps track (more or
> less) of its attribute values, which you use as "faked up" variable
> Actually you probably need to hack this a bit more to even get that as
> it doesn't appear to stack the values beyond a single level.

Actually there's no problem there. hint : dynamically_scoped is a class that 
the 
with statement will instantiate before (any) entry. OTOH, as it is written, I 
am 
not convinced it will work in a multithreaded setting : isn't it the case that 
all threads that will import eg dynamically_scoped/getvar/setvar will act 
without sync on the /single/ special object of the /single/ thread that 
initialized the module ?

But I'm not sure, it's been ages since I used python threading.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-11 Thread jayessay
"Michele Simionato" <[EMAIL PROTECTED]> writes:

> jayessay wrote:
> > I was saying that you are mistaken in that pep-0343 could be used to
> > implement dynamically scoped variables.  That stands.
> 
> Proof by counter example:
> 
> from __future__ import with_statement
> import threading
> 
> special = threading.local()
> 
> def getvar(name):
> return getattr(special, name)
> 
> def setvar(name, value):
> return setattr(special, name, value)
> 
> class dynamically_scoped(object):
> def __init__(self, name, value):
> self.name = name
> self.value = value
> def __context__(self):
> return self
> def __enter__(self):
> self.orig_value = getvar(self.name)
> setvar(self.name, self.value)
> def __exit__(self, Exc, msg, tb):
> setvar(self.name, self.orig_value)
> 
> if __name__ == '__main__': # test
> setvar("*x*", 1)
> print getvar("*x*") # => 1
> with dynamically_scoped("*x*", 2):
> print getvar("*x*") # => 2
> print getvar("*x*") # => 1
> 
> If you are not happy with this implementation, please clarify.

I can't get this to work at all - syntax errors (presumably you must
have 2.5?, I only have 2.4).  But anyway:

This has not so much to do with WITH as relying on a special "global"
object which you must reference specially, which keeps track (more or
less) of its attribute values, which you use as "faked up" variables.
Actually you probably need to hack this a bit more to even get that as
it doesn't appear to stack the values beyond a single level.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-11 Thread Thomas F. Burdick
Ken Tilton <[EMAIL PROTECTED]> writes:

> David C. Ullrich wrote:
>
> > But duh, if that's how things are then we can't have transitive
> > dependencies working out right; surely we
> > want to be able to have B depend on A and then C
> > depend on B...
> > (And also if A and B are allowed to depend on each
> > other then the programmer has to ensure that the
> > two rules are inverses of each other, which seems
> > like a bad constraint in general, something non-trivial
> > that the programmer has to get right.)
> 
> Right, when I considered multi-way dependencies I realized I would
> have to figure out some new syntax to declare in one place the rules
> for two slots, and that would be weird because in Cells it is the
> instance that gets a rule at make-instance time, so i would really
> have to have some new make-instance-pair capability. Talk about a
> slippery slope. IMO, the big constraints research program kicked off
> by Steele's thesis withered into a niche technology because they
> sniffed at the "trivial" spreadsheet model of linear dataflow and
> tried to do partial and multi-way dependencies. I call it "a bridge
> too far", and in my experience of Cells (ten years of pretty intense
> use), guess what?, all we need as developers is one-way, linear,
> fully-specified dependencies.

It may also be that the bridge too far was in trying to do big,
multi-way constraints in a general-purpose manner.  Cells provides you
with the basics, and you can build a special-purpose multi-way system
on top of it, much like you can use it as a toolkit for doing KR.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-11 Thread Petr Prikryl

"Chris Uppal" wrote:
> Petr Prikryl wrote:
>
> > for element in aCollection:
> > if element > 0:
> > return True
> > return False
>
> [I'm not sure whether this is supposed to be an example of some specific
> language (Python ?) or just a generic illustration.  I'll take it as the
> latter, since it makes my point easier to express.  I'll also exaggerate,
just
> a little...]

Sorry, I do not know Smalltalk, but this was meant as the transcription
of your...
  | E.g. consider the Smalltalk code (assumed to be the body of a method):
  |
  | aCollection
  | do: [:each |
  | each > 0 ifTrue: [^ true]].
  | ^ false.

into Python

> But now, in order to hack around the absence of a sensible and useful
> feature -- /only/ in order to do so -- you have added two horrible new
> complications to your language.  You have introduced a special syntax to
> express conditionals, and (worse!) a special syntax to express looping.
Not
> only does that add a huge burden of complexity to the syntax, and
semantics, of
> the language (and, to a lesser extent, its implementation), but it also
throws
> out any semblance of uniformity.

I guess that it is not me who is confused here. The subject clearly
says that the thread is related to Python and to lambda supported
by Python. It was only crossposted to other groups and I did
not want to remove them -- other people may want to read
the thread in the other newsgroups.

So, I did not introduced any horible syntax, nor looping
construct that would look strange to people used to
classical procedural languages. The lambda syntax
in Python is the thing that could be viewed as a complication,
not the "for" loop or the "if" construction.

If you take any English speaking human (even the non-programmer),
I could bet that the Python transcription will be more understandable
than your Smalltalk example.

> E.g. in Java there's an unresolved, and irresolvable, tension between
whether a
> failing operation should return an error condition or throw an exception
[...].

It is more a design problem than the language problem. And it is also
the implementation problem (i.e. what is the price of exceptions
in comparison with the other code). In Python, the exceptions
are intesively used.

> E.g. can you add three-way comparisons (less-than, same-as, greater-than
to,
> say, Python with corresponding three-way conditional control structures to
> supplement "if" etc ?  Are they on a semantic and syntactic par with the
> existing ones ?  In Smalltalk that is trivial (too trivial to be
particularly
> interesting, even), and I presume the same must be true of Lisp (though I
> suspect you might be forced to use macros).

Such built-in function already is in Python. But you could add it
by hand if it were not:

def cmp(x, y):
if x < y:
return -1
if x == y:
return 0
return 1

and the "if" supplement (the "switch" or "case" command) could be
replaced easily in Python using the hash-table (dictionary) structure.

> I should say that if your example /is/ in fact Python, then I believe that
> language allows fairly deep hooks into the execution mechanism, so that at
> least the "for" bit can be mediated by the collection itself -- which is
better
> than nothing, but nowhere near what I would call "good".

It is a dual point of view. Should the collection be passive data, or not?
I believe that the "pure" object oriented view (there are no functions,
only the object methods) is not very practical and does not reflect
well the big part of the reality that is simulated by programs.
Python and C++, for example, allow mixing functions and objects.

You should try Python. The "for" construct iterates through
a sequence or through all values of the generator, thus making
the for loop much more generic than for example in C or other
languages.

Every language forms the way of thinking. Every language has its strong
and weak points. Every language has its followers and haters.
Not every language is practical enough to fly around the Earth
in the space ship.

pepr

(Sorry for my broken English.)


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


Re: A critic of Guido's blog on Python's lambda

2006-05-11 Thread Michele Simionato
jayessay wrote:
> I was saying that you are mistaken in that pep-0343 could be used to
> implement dynamically scoped variables.  That stands.

Proof by counter example:

from __future__ import with_statement
import threading

special = threading.local()

def getvar(name):
return getattr(special, name)

def setvar(name, value):
return setattr(special, name, value)

class dynamically_scoped(object):
def __init__(self, name, value):
self.name = name
self.value = value
def __context__(self):
return self
def __enter__(self):
self.orig_value = getvar(self.name)
setvar(self.name, self.value)
def __exit__(self, Exc, msg, tb):
setvar(self.name, self.orig_value)

if __name__ == '__main__': # test
setvar("*x*", 1)
print getvar("*x*") # => 1
with dynamically_scoped("*x*", 2):
print getvar("*x*") # => 2
print getvar("*x*") # => 1

If you are not happy with this implementation, please clarify.

  Michele Simionato

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread M Jared Finder
Chris Uppal wrote:

> E.g. can you add three-way comparisons (less-than, same-as, greater-than to,
> say, Python with corresponding three-way conditional control structures to
> supplement "if" etc ?  Are they on a semantic and syntactic par with the
> existing ones ?  In Smalltalk that is trivial (too trivial to be particularly
> interesting, even), and I presume the same must be true of Lisp (though I
> suspect you might be forced to use macros).

As an illustration, here's the definition and usage of such a numeric-if 
in Lisp.

Using raw lambdas, it's ugly, but doable:

(defun fnumeric-if (value lt-body eq-body gt-body)
   (cond ((< value 0) (funcall lt-body))
 ((= value 0) (funcall eq-body))
 ((> value 0) (funcall gt-body

(fnumeric-if (- a b)
   (lambda () (print "a < b"))
   (lambda () (print "a = b"))
   (lambda () (print "a > b")))

A macro helps clean that up and make it look prettier:

(defmacro numeric-if (value lt-body eq-body gt-body)
   `(fnumeric-if ,value
 (lambda () ,lt-body)
 (lambda () ,eq-body)
 (lambda () ,gt-body)))

(numeric-if (- a b)
   (print "a < b")
   (print "a = b")
   (print "a > b"))

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread M Jared Finder
Alex Martelli wrote:
> M Jared Finder <[EMAIL PROTECTED]> wrote:
>...
>> Your reasoning, taken to the extreme, implies that an assembly language,
>> by virtue of having the fewest constructs, is the best designed language
> 
> Except that the major premise is faulty!  Try e.g.
>  and count the
> number of distinct instructions -- general purpose, floating point,
> SIMD, MMX, SSE, SSE2, OS support... there's *hundreds*, each with its
> own rules as to what operand(s) are allowed plus variants such as (e.g.)
> cmovbe{w,l,q} for "conditional move if below or equal" for word, long,
> quadword (no byte variant) -- but e.g cmpxchg{b,w,l,q} DOES have a byte
> variant too, while setbe for "set if below or equal" ONLY has a byte
> variant, etc, etc -- endless memorization;-).
> 
> When you set up your strawman arguments, try to have at least ONE of the
> premises appear sensible, will you?-)
> 
> I never argued against keeping languages at a high level, of course
> (that's why your so utterly unfounded argument would be a "strawman"
> even if it WAS better founded;-).
> 
>> prone, code.  I think the advantages of anonymous functions:
>...
>> e) making the language simpler to implement
> 
> Adding one construct (e.g., in Python, having both def and lambda with
> vast semantic overlap, rather than just one) cannot "make the language
> simpler to implement" -- no doubt this kind of "reasoning" (?) is what
> ended up making the instruction-set architecture of the dominant
> families of CPUs so bizarre, intricate, and abstruse!-)

It sure can.  First, let's cover the cost.  I'll be measuring everything 
in terms of lines of code, with the assumption that the code has been 
kept readable.

Here's an implementation of lambda (anonymous functions) in Lisp based 
on flet (lexically scoped functions):

(defmacro lambda (args &rest body)
   (let ((name (gensym)))
 `(flet ((,name ,args ,@body)) (function ,name

That's three lines of code to implement.  An almost trivial amount.

Now by using anonymous functions, you can implement many other language 
level features simpler.  Looping can be made into a regular function 
call.  Branching can be made into a regular function call.  Defining 
virtual functions can be made into a regular function call.  Anything 
that deals with code blocks can be made into a regular function call.

By removing the special syntax and semantics from these language level 
features and making them just pain old function calls, you can reuse the 
same evaluator, optimizer, code parser, introspector, and other code 
analyzing parts of your language for these (no longer) special 
constructs.   That's a HUGE savings, well over 100 lines of code.

Net simplification, at least 97 lines of code.  For a concrete example 
of this in action, see Smalltalk.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


Alex Martelli wrote:
> Stefan Nobis <[EMAIL PROTECTED]> wrote:
> 
> 
>>[EMAIL PROTECTED] (Alex Martelli) writes:
>>
>>
>>>if anonymous functions are available, they're used in even more
>>>cases where naming would help
>>
>>Yes, you're right. But don't stop here. What about expressions? Many
>>people write very complex expression, that are hard to understand. A
>>good language should forbid these abuse and don't allow expressions
>>with more than 2 or maybe 3 operators!
> 
> 
> That would _complicate_ the language (by adding a rule).  I repeat what
> I've already stated repeatedly: a good criterion for deciding which good
> practices a language should enforce and which ones it should just
> facilitate is _language simplicity_.  If the enforcement is done by
> adding rules or constructs it's probably not worth it; if the
> "enforcements" is done by NOT adding extra constructs it's a double win
> (keep the language simpler AND push good practices).

Gosh, that looks like fancy footwork. But maybe I misunderstand, so I 
will just ask you to clarify.

In the case of (all syntax imaginary and not meant ot be Python):

  if whatever = 42
 dothis
 do that
 do something else
  else
 go ahead
 make my day

You do not have a problem with unnamed series of statements. But in the 
case of:

 treeTravers( myTree, lambda (node):
  if xxx(node)
 print "wow"
 return 1
  else
 print "yawn"
 return 0)

...no, no good, you want a named yawnOrWow function? And though they 
look similar, the justification above was that IF-ELSE was lucky enough 
to get multiline branches In the Beginning, so banning it now would be 
"adding a rule", whereas lambda did not get multiline In the Beginning, 
so allowing it would mean "adding a construct". So by positing "adding a 
rule or construct" as always bad (even if they enforce a good practice 
such as naming an IF branch they are bad since one is /adding/ to the 
language), the inconsistency becomes a consistency in that keeping IF 
powerful and denying lambda the same power each avoids a change?

In other words, we are no longer discussing whether unnamed multi-line 
statements are a problem. The question is, would adding them to lambda 
mean a change?

Oh, yeah, it would. :)

hth, kenny


-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Alex Martelli
Joe Marshall <[EMAIL PROTECTED]> wrote:

> Alex Martelli wrote:
> > Joe Marshall <[EMAIL PROTECTED]> wrote:
> >...
> > > The problem is that a `name' is a mapping from a symbolic identifier to
> > > an object and that this mapping must either be global (with the
> > > attendant name collision issues) or within a context (with the
> > > attendant question of `in which context').
> >
> > Why is that a problem?  Even for so-called "global" names, Python
> > supports a structured, hierarchical namespace, so there can never be any
> > collision betwen the "globals" of distinct modules (including modules
> > which happen to have the same name but live in distinct packages or
> > subpackages) -- I did mention that names could usefully be displayed in
> > some strcutured form such as apackage.somemodule.thefunction but perhaps
> > I was too tangential about it;-).
> 
> Can you refer to inner functions from the global context?  Suppose I
> have this Python code:
> 
> def make_adder(x):
> def adder_func(y):
> sum = x + y
> return sum
> return adder_func
> 
> Can I refer to the inner adder_func in any meaningful way?

You can refer to one instance/closure (which make_adder returns), of
course -- you can't refer to the def statement itself (but that's a
statement, ready to create a function/closure each time it executes, not
a function, thus, not an object) except through introspection. Maybe I
don't understand what you mean by this question...


> > If I used continuations (I assume you mean in the call/cc sense rather
> > than some in which I'm not familiar?) I might feel the same way, or not,
> > but I don't (alas), so I can't really argue the point either way for
> > lack of real-world experience.
> 
> I meant continuations as in the receiver function in
> continuation-passing-style.  If you have a function that has to act
> differently in response to certain conditions, and you want to
> parameterize the behavior, then one possibility is to pass one or more
> thunks to the function in addition to the normal arguments.  The

Ah, OK, I would refer to this as "callbacks", since no
call-with-continuation is involved, just ordinary function calls; your
use case, while pretty alien to Python's typical style, isn't all that
different from other uses of callbacks which _are_ very popular in
Python (cfr the key= argument to the sort methods of list for a typical
example).  I would guess that callbacks of all kinds (with absolutely
trivial functions) is the one use case which swayed Guido to keep lambda
(strictly limited to just one expression -- anything more is presumably
worth naming), as well as to add an if/else ternary-operator.  I still
disagree deeply, as you guessed I would -- if I had to work with a
framework using callbacks in your style, I'd name my callbacks, and I
wish Python's functools module provided for the elementary cases, such
as:

def constant(k):
def ignore_args(*a): return k
return ignore_args

def identity(v): return v

and so on -- I find, for example, that to translate your

> (define (option3 key table default-value)
>   (lookup key table
> (lambda (value) value)
> (lambda () default-value)))

I prefer to use:

def option3(key, table, default_value):
return lookup(key, table, identity, constant(default_value))

as being more readable than:

def option3(key, table, default_value):
return lookup(key, table, lambda v: v, lambda: default_value)

After all, if I have in >1 place in my code the construct "lambda v: v"
(and if I'm using a framework that requires a lot of function passing
I'm likely to be!), the "Don't Repeat Yourself" (DRY) principle suggests
expressing the construct *ONCE*, naming it, and using the name.

By providing unnamed functions, the language aids and abets violations
of DRY, while having the library provide named elementary functions (in
the already-existing appropriate module) DRY is reinforced and strongly
supported, which, IMHO, is a very good thing.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Frank Goenninger DG1SBG
Ken Tilton <[EMAIL PROTECTED]> writes:

> sross wrote:
>>>I do wonder what would happen to Cells if I ever want to support
>>>multiple threads. Or in a parallel processing environment.
>> AFAIK It should be fine.
>> In LW, SBCL and ACL all bindings of dynamic variables are thread-local.
>> 
>
> Ah, I was guilty of making an unspoken segue: the problem is not with
> the *dependent* special variable, but with the sequentially growing
> numeric *datapulse-id* ("the ID") that tells a cell if it needs to
> recompute its value. The ID is not dynamically bound. If threads T1
> and T2 each execute a toplevel, imperative assignment, two threads
> will start propagating change up the same dependency
> graph... 
>
> Might need to specify a "main" thread that gets to play with Cells and
> restrict other threads to intense computations but no Cells?

Hmmm. I am wondering if a Cells Manager class could be the home for
all Cells. Each thread could the have its own Cells Manager...

>
> Actually, I got along quite a while without an ID, I just propagated
> to dependents and ran rules. This led sometimes to a rule running
> twice for one change and transiently taking on a garbage value, when
> the dependency graph of a Cell had two paths back to some changed
> Cell.
>
> Well, Cells have always been reengineered in the face of actual use
> cases, because I am not really smart enough to work these things out
> in the abstract. Or too lazy or something. Probably all three.

Nah. It's me asking again and again those silly questions about 
real Cells usage in some real life apps ;-)

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Chris F Clark
Kenny replied to me saying:
> Yep. But with Cells the dependency graph is just a shifting record of
> who asked who, shifting because all of a sudden some outlier data will
> enter the system and a rule will branch to code for the first time,
> and suddenly "depend on" on some new other cell (new as in never
> before used by this cell). This is not subject to static analysis
> because, in fact, lexically everyone can get to everything else, what
> with closures, first-class functions, runtime branching we cannot
> predict... fuggedaboutit.
> 
> So we cannot say, OK, here is "the graph" of our application
> model. All we can do is let her rip and cross our fingers. :)

Yes, if you have Turing completeness in your dependency graph, the
problem is unsolvable.  However, it's like the static v. dynamic
typing debate, you can pick how much you want to allow your graph to
be dynamic versus how much "safety" you want.  In particular, I
suspect that in many applications, one can compute the set of
potentially problematic dependencies (and that set will be empty).
It's just a matter of structuring and annotating them correctly.  Just
like one can create type systems that work for ML and Haskell.  Of
course, if you treat your cell references like C pointers, then you
get what you deserve.

Note that you can even run the analysis dynamically, recomputing
whether the graph is cycle free as each dependency changes.  Most
updates have local effect.  Moreover, if you have used topological
sort to compute an ordering as well as proving cycle-free-ness, the
edge is only pontentially problemantic when it goes from a later
vertex in the order to an earlier one.  I wouldn't be surprised to
find efficient algorithms for calculating and updating a topological
sort already in the literature.

It is worth noting that in typical chip circuitry there are
constructions, generally called "busses" where the flow of information
is sometimes "in" via an edge and sometimes "out" via the same edge
and we can model them in a cycle-free manner.

If you want to throw up your hands and say the problem is intractable
in general, you can.  However, in my opinion one doesn't have to give
up quite that easily.

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


Re: Python's DSLs (was: A critic of Guido's blog on Python's lambda)

2006-05-10 Thread aaronwmail-usenet
Cameron Laird wrote:
> In article <[EMAIL PROTECTED]>,
> Alex Martelli <[EMAIL PROTECTED]> wrote:
... .
> >Of course, the choice of Python does mean that, when we really truly
> >need a "domain specific little language", we have to implement it as a
> >language in its own right, rather than piggybacking it on top of a
> >general-purpose language as Lisp would no doubt afford; see
> > for such a DSLL developed
> >at Google. However, I think this tradeoff is worthwhile, and, in
> >particular, does not impede scaling
>
> I'm confused, Alex:  I sure
> think *I* have been writing DSLs as specializations of Python,
> and NOT as "a language in its own right"

I think Alex is suggesting that if they used, for example, a version of
scheme
with a good optimizing compiler they could implement sawzall like
convenience
with almost the same performance, including startup, etc. whereas even
a
highly optimized python based approach would at least have a
comparatively
large startup penalty.  For an environment like Google where they
scrape
thru their logs of various sorts doing lots of trivial scans you can
probably save
a lot of money and time on lots of machines by optimizing such scrapes
(but keep your bactine handy).  And as the sawzall paper pointed out,
even static
type checks can prevent a lot of wasted machine bandwidth by avoiding
dumb
errors.

But the real question for someone like Rob Pike is why use scheme when
you
can invent another little language instead, I suspect :).

  -- Aaron Watters

===

Stop procrastinating soon.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Robert Uhl
Ken Tilton <[EMAIL PROTECTED]> writes:
>
> Set Kelvin, and make Celsius and Fahrneheit functions of that.

Or Rankine:-)

-- 
Robert Uhl 
Brought to you by 'Ouchies', the sharp, prickly toy you bathe with...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread jayessay
"Michele Simionato" <[EMAIL PROTECTED]> writes:

> jayessay wrote:
> > "Michele Simionato" <[EMAIL PROTECTED]> writes:
> >
> > > Ken Tilton wrote:
> > > > I was not thinking about the thread issue (of which I know little). The
> > > > big deal for Cells is the dynamic bit:
> > > >
> > > > (let ((*dependent* me))
> > > >  (funcall (rule me) me))
> > > >
> > > > Then if a rule forces another cell to recalculate itself, *dependent*
> > > > gets rebound and (the fun part) reverts back to the original dependent
> > > > as soon as the scope of the let is exited.
> > >
> > > Python 2.5 has a "with" statement (yes, the name is Lispish on purpose)
> > > that could be used to implement this. See
> > > http://www.python.org/dev/peps/pep-0343
> >
> > You are mistaken.  In particular, VAR doesn't have dynamic scope.
> >
> 
> I said "it could be used to implement this", and since in a previous
> post on mine in this
> same thread I have shown how to implement thread local variables in
> Python I figured
> out people would be able to do the exercise for themselves.

I was saying that you are mistaken in that pep-0343 could be used to
implement dynamically scoped variables.  That stands.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Joe Marshall

Alex Martelli wrote:
> Joe Marshall <[EMAIL PROTECTED]> wrote:
>...
> > The problem is that a `name' is a mapping from a symbolic identifier to
> > an object and that this mapping must either be global (with the
> > attendant name collision issues) or within a context (with the
> > attendant question of `in which context').
>
> Why is that a problem?  Even for so-called "global" names, Python
> supports a structured, hierarchical namespace, so there can never be any
> collision betwen the "globals" of distinct modules (including modules
> which happen to have the same name but live in distinct packages or
> subpackages) -- I did mention that names could usefully be displayed in
> some strcutured form such as apackage.somemodule.thefunction but perhaps
> I was too tangential about it;-).

Can you refer to inner functions from the global context?  Suppose I
have this Python code:

def make_adder(x):
def adder_func(y):
sum = x + y
return sum
return adder_func

Can I refer to the inner adder_func in any meaningful way?


>
>
> > Matthias Felleisen once suggested that *every* internal function should
> > be named.  I just said `continuations'.  He immediately amended his
> > statement with `except those'.
>
> If I used continuations (I assume you mean in the call/cc sense rather
> than some in which I'm not familiar?) I might feel the same way, or not,
> but I don't (alas), so I can't really argue the point either way for
> lack of real-world experience.

I meant continuations as in the receiver function in
continuation-passing-style.  If you have a function that has to act
differently in response to certain conditions, and you want to
parameterize the behavior, then one possibility is to pass one or more
thunks to the function in addition to the normal arguments.  The
function acts by selecting and invoking one of the thunks.  A classic
example is table lookup.  It is often the case you wish to proceed
differently depending upon whether a key exists in a table or not.
There are several ways to provide this functionality.  One is to have a
separate `key-exists?' predicate.  Another is to have a special return
value for `key not found'.  Another is to throw an exception when a key
is not found.  There are obvious advantages and drawbacks to all of
these methods.  By using continuation-passing-style, we can
parameterize how the table lookup proceeds once it determines whether
or not the key is found.  We have the lookup procedure take two thunks
in addition to the key.  If the key is found, the first thunk is
invoked on the associated value.  If the key is not found, the second
thunk is invoked.  We can subsume all the previous behaviors:

(define (key-exists? key table)
  (lookup key table
 (lambda (value) #t) ;; if found, ignore value, return true
 (lambda () #f)))  ;; if not found, return false.

(define (option1 key table)
  (lookup key table
(lambda (value) value)
(lambda () 'key-not-found)))

(define (option2 key table)
  (lookup key table
(lambda (value) value)
(lambda () (raise 'key-not-found-exception

(define (option3 key table default-value)
  (lookup key table
(lambda (value) value)
(lambda () default-value)))

The unnamed functions act in this regard much like a `local label'.  We
wrap two chunks of code in a lambda and the lookup function `jumps' to
the appropriate chunk.  (If the compiler knows about thunks, the
generated assembly code really will have local labels and jump
instructions.  It can be quite efficient.)

This may look odd and cumbersome, but with a little practice the
lambdas fade into the background and it becomes easy to read.

My point with Matthias, however, was that defining all these
continuations (the thunks) as named internal functions was not only
cumbersome, but it obscured the control flow.  Notice:

(define (named-option3 key table default-value)
  (define (if-found value)
 value)
  (define (if-not-found)
 default-value)
  (lookup key table if-found if-not-found))

When we enter the function, we skip down to the bottom (past the
internal definitions) to run lookup, which transfers control to a
function defined earlier in the code.

There are many reasons to avoid this style in Python, so this probably
won't win you over, but my point is that there are times where
anonymous functions have an advantage over the named alternative and
that disallowing anonymous functions can be as cumbersome as
disallowing anonymous integers.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Boris Borcic
Ken Tilton wrote:
> 
> 
> Boris Borcic wrote:
>> Ken Tilton wrote:
>>
>>> "Now if you are like most people, you think that means X. It does not."
>>
>>
>> As far as natural language and understanding are concerned, "to mean" 
>> means conformity to what most people understand, Humpty Dumpties 
>> notwithstanding.
> 
> Nonsense.

:)

> You are confusing that quality of natural language with most 
> people's quality of being sloppy readers,  or in your case, a sloppy
> thinker.  Misapplying an analogy is not a question of usage -- when I
> said spreadsheet and they thought of spreadsheets, so far so good, 
> right?

No, as Adam Jones pointed out. Like Bush speaking of "crUSAde" after 9/11.

> -- it just sloppiness and laziness.
> 
> I do it, too, all the time. :)

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


Ketil Malde wrote:

> 
> Sometimes the best documentation is the code itself.  Sometimes the
> best name for a function is the code itself.

Absolutely. When I take over someone else's code I begin by deleting all 
the comments. Then I read the code. If a variable or function name makes 
no sense (once I have figured out what they /really/ do) I do a global 
change. Pretty soon the system is "documented". And I usually find a 
couple of bugs as the renaming produces things like:

 count = count + weight

I think one good argument for anonymous functions is a hefty Cells 
application, with literally hundreds of rules. The context is set by the 
instance and slot name, and as you say, the rule speaks for itself:

 (make-instance 'frame-widget
 :bounds (c? (apply 'rect-union (all-bounds (subwidgets self)

Why do I have to give that a name? And if the algorithm gets hairier, 
well, why is the reader looking at my code? If the reader is debugging 
or intending to modify the rule, they damn well better be looking at the 
code, not the name and not the comments. (Never a problem with my code. )

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Michele Simionato
jayessay wrote:
> "Michele Simionato" <[EMAIL PROTECTED]> writes:
>
> > Ken Tilton wrote:
> > > I was not thinking about the thread issue (of which I know little). The
> > > big deal for Cells is the dynamic bit:
> > >
> > > (let ((*dependent* me))
> > >  (funcall (rule me) me))
> > >
> > > Then if a rule forces another cell to recalculate itself, *dependent*
> > > gets rebound and (the fun part) reverts back to the original dependent
> > > as soon as the scope of the let is exited.
> >
> > Python 2.5 has a "with" statement (yes, the name is Lispish on purpose)
> > that could be used to implement this. See
> > http://www.python.org/dev/peps/pep-0343
>
> You are mistaken.  In particular, VAR doesn't have dynamic scope.
>

I said "it could be used to implement this", and since in a previous
post on mine in this
same thread I have shown how to implement thread local variables in
Python I figured
out people would be able to do the exercise for themselves.

  Michele Simionato

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


Chris F Clark wrote:
> David C Ullrich asked:
> 
>>Q: How do we ensure there are no loops in the dependencies?
>>
>>Do we actually run the whole graph through some algorithm
>>to verify there are no loops?
> 
> 
> The question you are asking is the dependency graph a "directed
> acyclic graph" (commonly called a DAG)?  One algorithm to determine if
> it is, is called "topological sort".  That algorithm tells you where
> there are cyclces in your graph,

Yep. But with Cells the dependency graph is just a shifting record of 
who asked who, shifting because all of a sudden some outlier data will 
enter the system and a rule will branch to code for the first time, and 
suddenly "depend on" on some new other cell (new as in never before used 
by this cell). This is not subject to static analysis because, in fact, 
lexically everyone can get to everything else, what with closures, 
first-class functions, runtime branching we cannot predict... fuggedaboutit.

So we cannot say, OK, here is "the graph" of our application model. All 
we can do is let her rip and cross our fingers. :)

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Jonathan Ellis
Randal L. Schwartz wrote:
> > "Alex" == Alex Martelli <[EMAIL PROTECTED]> writes:
>
> Alex> The difference, if any, is that gurus of Java, C++ and Python get to
> Alex> practice and/or keep developing their respectively favorite languages
> Alex> (since those three are the "blessed" general purpose languages for
> Alex> Google - I say "general purpose" to avoid listing javascript for
> Alex> within-browser interactivity, SQL for databases, XML for data
> Alex> interchange, HTML for web output, &c, &c), while the gurus of Lisp,
> Alex> Limbo, Dylan and Smalltalk don't (Rob Pike, for example, is one of the
> Alex> architects of sawzall -- I already pointed to the whitepaper on that
> Alex> special-purpose language, and he co-authored that paper, too).
>
> That's crazy.  Some of the key developers of Smalltalk continue to work
> on the Squeak project (Alan Kay, Dan Ingalls, and I'm leaving someone
> out, I know it...).  So please remove Smalltalk from that list.

I thought it was clear that Alex was talking about "smalltalk gurus who
work for Google."

-Jonathan

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread jayessay
"Michele Simionato" <[EMAIL PROTECTED]> writes:

> Ken Tilton wrote:
> > I was not thinking about the thread issue (of which I know little). The
> > big deal for Cells is the dynamic bit:
> >
> > (let ((*dependent* me))
> >  (funcall (rule me) me))
> >
> > Then if a rule forces another cell to recalculate itself, *dependent*
> > gets rebound and (the fun part) reverts back to the original dependent
> > as soon as the scope of the let is exited.
> 
> Python 2.5 has a "with" statement (yes, the name is Lispish on purpose)
> that could be used to implement this. See
> http://www.python.org/dev/peps/pep-0343

You are mistaken.  In particular, VAR doesn't have dynamic scope.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton
[Sorry, I missed this one originally.]


David C. Ullrich wrote:
> On Tue, 09 May 2006 05:35:47 -0500, David C. Ullrich
> <[EMAIL PROTECTED]> wrote:
> 
> 
>>On Mon, 08 May 2006 18:46:57 -0400, Ken Tilton <[EMAIL PROTECTED]>
>>wrote:
>>[...]
>>
>>If you, um, look at the code you see that "cells.a = 42" triggers
>>cells.__setattr__, which fires a's callback; the callback then
>>reaches inside and sets the value of b _without_ going through
>>__setattr__, hence without triggering b's callback.
>>
>>In Cells you can't have A depend on B and also B depend on A?
>>That seems like an unfortunate restriction - I'd want to be
>>able to have Celsius and Farenheit, so that setting either
>>one sets the other.

Set Kelvin, and make Celsius and Fahrneheit functions of that. ie, There 
is only one datapoint, the temperature. No conflict unless one creates one.

> 
> 
> Realized later that I hadn't thought this through.
> 
> I'd been assuming that of course we should be allowed to
> have A and B depend on each other. Hence if a change in
> A propagates to a change in B that change in B has to
> be a non-propagating change - thought I was just so
> clever seeing a way to do that.

I think it could be arranged, if one were willing to tolerate a little 
fuzziness: no, there would be no strictly correct snapshot at which 
point everyone had their "right value". Instead, A changes so B 
recomputes, B changes so A recomputes... our model has now come to life, 
we just have to poll for OS events or socket data, and A and B never get 
to a point where they are self-consistent, because one or the other 
always needs to be recalculated.

I sometimes wonder if the physical universe is like that, explaining why 
gravity slows time: it is not the gravity, it is the mass and we are 
seeing system degradation as the matrix gets bogged down recomputing all 
that matter.

[Cue Xah]


> 
> But duh, if that's how things are then we can't have 
> transitive dependencies working out right; surely we
> want to be able to have B depend on A and then C
> depend on B...
> 
> (And also if A and B are allowed to depend on each
> other then the programmer has to ensure that the
> two rules are inverses of each other, which seems
> like a bad constraint in general, something non-trivial
> that the programmer has to get right.)

Right, when I considered multi-way dependencies I realized I would have 
to figure out some new syntax to declare in one place the rules for two 
slots, and that would be weird because in Cells it is the instance that 
gets a rule at make-instance time, so i would really have to have some 
new make-instance-pair capability. Talk about a slippery slope. IMO, the 
big constraints research program kicked off by Steele's thesis withered 
into a niche technology because they sniffed at the "trivial" 
spreadsheet model of linear dataflow and tried to do partial and 
multi-way dependencies. I call it "a bridge too far", and in my 
experience of Cells (ten years of pretty intense use), guess what?, all 
we need as developers is one-way, linear, fully-specified dependencies.

> 
> So fine, no loops. If anything, if we know that
> there are no loops in the dependencies that simplifies
> the rest of the programming, no need for the sort of
> finagling described in the first paragraph above.

Actually, I do allow an on-change callback ("observer" in Cells 
parlance) to kick off a toplevel, imperative state change to the model. 
Two cells who do that to each other will run until one decides not to do 
so. I solve some GUI situations (the classic being a scrollbar thumb and 
the text offset, which each at different times control the other, by 
having them simply set the other in an observer. On the second 
iteration, B is setting A to the value A has already, so propagation 
stops (a longstanding Cells feature).

These feel like GOTOs, by the way, and are definitely to be avoided 
because they break the declarative paradigm of Cells in which I can 
always look at one (anonymous!) rule and see without question from where 
any value it might hold comes. (And observers define where they take 
effect outside the model, but those I have to track down by slot name 
using OO browsing tools.)


> But this raises a question:
> 
> Q: How do we ensure there are no loops in the dependencies?

Elsewhere I suggested the code was:

 (let ((*dependent* this-cell))
(funcall (rule this-cell) (object this-cell)))

It is actually:

 (let ((*dependents* (list* this-cell *dependents*)))
(funcall (rule this-cell) (object this-cell)))

So /before/ that I can say:

 (assert (not (find this-cell *dependents*)))

> 
> Do we actually run the whole graph through some algorithm
> to verify there are no loops?
> 
> The simplest solution seems like adding the cells one
> at a time, and only allowing a cell to depend on 
> previously added cells. It's clear that that would
> prevent loops, but it's not clear to me whether or
> not that disallow

Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


Boris Borcic wrote:
> Bill Atkins wrote:
> 
>>
>> It's interesting how much people who don't have macros like to put
>> them down and treat them as some arcane art that are too "*insane*"ly
>> powerful to be used well.
>>
>> They're actually very straightforward and can often (shock of shocks!)
>> make your code more readable,  without your efficiency taking a hit.
> 
> 
> Not even efficiency of debugging ? A real problem with macros is that 
> run-time tracebacks etc, list macro outputs and not your macro'ed source 
> code. And that becomes an acute problem if you leave code for somebody 
> else to update. Or did lisp IDEs make progress on that front ?

AllegroCL now shows macros in the stack frame. Relatively recent 
feature, and their IDE really stands out above the rest.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


Boris Borcic wrote:
> Ken Tilton wrote:
> 
>> "Now if you are like most people, you think that means X. It does not."
> 
> 
> As far as natural language and understanding are concerned, "to mean" 
> means conformity to what most people understand, Humpty Dumpties 
> notwithstanding.

Nonsense. You are confusing that quality of natural language with most 
people's quality of being sloppy readers, or in your case, a sloppy 
thinker. Misapplying an analogy is not a question of usage -- when I 
said spreadsheet and they thought of spreadsheets, so far so good, 
right? -- it just sloppiness and laziness.

I do it, too, all the time. :) Life is too short, we get by precisely by 
  using partial information.

You remind me of American educators recent (past several decades, that 
is) history of apologizing for asking students to work and softening the 
curriculum until they all get A's.

Here is another analogy. Sometimes people hit the gas and think they hit 
the brake pedal. They crash around a parking lot pushing the gas pedal 
down harder and harder. Did they take out the brake pedal to avoid that 
confusion? No, they put an interlock between the brake and the ignition key.

Same thing. :)

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread David Hopwood
M Jared Finder wrote:
> Alex Martelli wrote:
>> Stefan Nobis <[EMAIL PROTECTED]> wrote:
>>> [EMAIL PROTECTED] (Alex Martelli) writes:
>>>
 if anonymous functions are available, they're used in even more
 cases where naming would help
>>>
>>> Yes, you're right. But don't stop here. What about expressions? Many
>>> people write very complex expression, that are hard to understand. A
>>> good language should forbid these abuse and don't allow expressions
>>> with more than 2 or maybe 3 operators!
>>
>> That would _complicate_ the language (by adding a rule).  I repeat what
>> I've already stated repeatedly: a good criterion for deciding which good
>> practices a language should enforce and which ones it should just
>> facilitate is _language simplicity_.  If the enforcement is done by
>> adding rules or constructs it's probably not worth it; if the
>> "enforcements" is done by NOT adding extra constructs it's a double win
>> (keep the language simpler AND push good practices).
> 
> Your reasoning, taken to the extreme, implies that an assembly language,
> by virtue of having the fewest constructs, is the best designed language
> ever.

Assembly languages don't have the fewest constructs; kernel languages such
as Core ML or Kernel-Oz do. In any case, I didn't read Alex's point as
being that simplicity was the only criterion on which to make decisions
about what practices a language should enforce or facilitate; just
"a good criterion".

However, IMHO anonymous lambdas do not significantly increase the complexity
of the language or of programs, and they can definitely simplify programs in
functional languages, or languages that use them for control constructs.

-- 
David Hopwood <[EMAIL PROTECTED]>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Alex Martelli
M Jared Finder <[EMAIL PROTECTED]> wrote:
   ...
> Your reasoning, taken to the extreme, implies that an assembly language,
> by virtue of having the fewest constructs, is the best designed language

Except that the major premise is faulty!  Try e.g.
 and count the
number of distinct instructions -- general purpose, floating point,
SIMD, MMX, SSE, SSE2, OS support... there's *hundreds*, each with its
own rules as to what operand(s) are allowed plus variants such as (e.g.)
cmovbe{w,l,q} for "conditional move if below or equal" for word, long,
quadword (no byte variant) -- but e.g cmpxchg{b,w,l,q} DOES have a byte
variant too, while setbe for "set if below or equal" ONLY has a byte
variant, etc, etc -- endless memorization;-).

When you set up your strawman arguments, try to have at least ONE of the
premises appear sensible, will you?-)

I never argued against keeping languages at a high level, of course
(that's why your so utterly unfounded argument would be a "strawman"
even if it WAS better founded;-).

> prone, code.  I think the advantages of anonymous functions:
   ...
> e) making the language simpler to implement

Adding one construct (e.g., in Python, having both def and lambda with
vast semantic overlap, rather than just one) cannot "make the language
simpler to implement" -- no doubt this kind of "reasoning" (?) is what
ended up making the instruction-set architecture of the dominant
families of CPUs so bizarre, intricate, and abstruse!-)


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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ken Tilton


sross wrote:
>>I do wonder what would happen to Cells if I ever want to support
>>multiple threads. Or in a parallel processing environment.
> 
> 
> AFAIK It should be fine.
> In LW, SBCL and ACL all bindings of dynamic variables are thread-local.
> 

Ah, I was guilty of making an unspoken segue: the problem is not with 
the *dependent* special variable, but with the sequentially growing 
numeric *datapulse-id* ("the ID") that tells a cell if it needs to 
recompute its value. The ID is not dynamically bound. If threads T1 and 
T2 each execute a toplevel, imperative assignment, two threads will 
start propagating change up the same dependency graph... 

Might need to specify a "main" thread that gets to play with Cells and 
restrict other threads to intense computations but no Cells?

Actually, I got along quite a while without an ID, I just propagated to 
dependents and ran rules. This led sometimes to a rule running twice for 
one change and transiently taking on a garbage value, when the 
dependency graph of a Cell had two paths back to some changed Cell.

Well, Cells have always been reengineered in the face of actual use 
cases, because I am not really smart enough to work these things out in 
the abstract. Or too lazy or something. Probably all three.

kenny

-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Chris F Clark
David C Ullrich asked:
> Q: How do we ensure there are no loops in the dependencies?
> 
> Do we actually run the whole graph through some algorithm
> to verify there are no loops?

The question you are asking is the dependency graph a "directed
acyclic graph" (commonly called a DAG)?  One algorithm to determine if
it is, is called "topological sort".  That algorithm tells you where
there are cyclces in your graph, if any, and also tells you the order
of the dependencies, i.e. if x is updated, what you have to update
downstream AND THE ORDER you have to perform the downstream
computations in.  We use this algorithm for solving just the kind of
dataflow problems you are talking about in our circuit design tools.
Circuit designs have one-way dependencies that we want to sort and
resolve--similarly, we don't want cycles in our circuits except ones
that pass through clocked flip-flops.  We solve such problems on
circuits with millions of gates, i.e. enough gates to represent the
CPU of your computer or a disk controller chip or a router.

I believe there are also algorithms that allow you to construct only
acyclic (the technical term for non-looping) graphs and don't require
you to enter the vertexes (verticies if you prefer) of the graph in
any specific order, and in the worst case you can always run the
topological sort on any graph and determine if the graph is cyclic.

The area is well-studied and you can find a variety of algorithms that
solve most interesting graph problems as they all occur over-and-over
in numerous diverse fields.

Hope this helps,
-Chris

*
Chris ClarkInternet   :  [EMAIL PROTECTED]
Compiler Resources, Inc.   Web Site   :  http://world.std.com/~compres  
23 Bailey Rd   voice  :  (508) 435-5016
Berlin, MA  01503  USA fax:  (978) 838-0263  (24 hours)
--
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Marcin 'Qrczak' Kowalczyk
Followup-To: comp.lang.lisp

Bill Atkins <[EMAIL PROTECTED]> writes:

> The cool thing about ITERATE is that it lets you express looping
> concepts in a language designed explicitly for such a purpose, e.g.
>
>   (iter (for x in '(1 3 3))
> (summing x))  => 7
>
>   (iter (for x in '(1 -3 2))
> (finding x maximizing (abs x))) => -3
>
>   (iter (for x in '(a b c 1 d 3 e))
> (when (symbolp x)
>   (collect x)))  => (a b c d e)

While such macros indeed allow to generate efficient code, I don't
find these examples convincing in terms of readability. The same
examples in my language where iteration is based on higher order
functions are shorter and also clear:

Sum [1 3 3]
=> 7

[1 (-3) 2]->MaximumBy Abs
=> -3

[#a #b #c 1 #d 3 #e]->Select (_ %Is SYMBOL)
=> [#a #b #c #d #e]

-- 
   __("< Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread David C.Ullrich
On Tue, 09 May 2006 05:35:47 -0500, David C. Ullrich
<[EMAIL PROTECTED]> wrote:

>On Mon, 08 May 2006 18:46:57 -0400, Ken Tilton <[EMAIL PROTECTED]>
>wrote:
>[...]
>
>If you, um, look at the code you see that "cells.a = 42" triggers
>cells.__setattr__, which fires a's callback; the callback then
>reaches inside and sets the value of b _without_ going through
>__setattr__, hence without triggering b's callback.
>
>In Cells you can't have A depend on B and also B depend on A?
>That seems like an unfortunate restriction - I'd want to be
>able to have Celsius and Farenheit, so that setting either
>one sets the other.

Realized later that I hadn't thought this through.

I'd been assuming that of course we should be allowed to
have A and B depend on each other. Hence if a change in
A propagates to a change in B that change in B has to
be a non-propagating change - thought I was just so
clever seeing a way to do that.

But duh, if that's how things are then we can't have 
transitive dependencies working out right; surely we
want to be able to have B depend on A and then C
depend on B...

(And also if A and B are allowed to depend on each
other then the programmer has to ensure that the
two rules are inverses of each other, which seems
like a bad constraint in general, something non-trivial
that the programmer has to get right.)

So fine, no loops. If anything, if we know that
there are no loops in the dependencies that simplifies
the rest of the programming, no need for the sort of
finagling described in the first paragraph above.
But this raises a question:

Q: How do we ensure there are no loops in the dependencies?

Do we actually run the whole graph through some algorithm
to verify there are no loops?

The simplest solution seems like adding the cells one
at a time, and only allowing a cell to depend on 
previously added cells. It's clear that that would
prevent loops, but it's not clear to me whether or
not that disallows some non-looping graphs. A
math question the answer to which is not immediately
clear to me (possibly trivial, the question just
ocurred to me this second):

Say G is a (finite) directed graph with no loops. Is it always
possible to order the vertices in such a way that
every edge goes from a vertex to a _previous_ vertex?

>Of course if there are no loops it's easier to see how
>you managed to do the stuff you were talking about elsewhere,
>(at least sometimes) delaying execution until needed.
>
>>Anyway...)
>>
>>> 
>>> 
all
the *programmer* has to care about is what values a slot depends on --
Cells takes care of inverting that for you, which is important because
that's a job that a computer is much better at than a human.
>>> 
>>> 
>>> Fine. I suppose that is better; if b is going to return a + 1
>>> the fact that this is what b returns should belong to b, not
>>> to a. So a has an update list including b, so when a's value
>>> is set a tells b it needs to update itself.
>>> 
>>> If we're allowed to pass (at some point, to some constructor
>>> or other) something like (b, a + 1, [a]), which sets up a
>>> cell b that shall return a + 1, and where the [a] is used
>>> in the constructor to tell a to add b to a's update list
>>> then this seems like no big deal.
>>> 
>>> And doing that doesn't seem so bad - now when the programmer
>>> is writing b he has to decide that it should return a + 1
>>> and also explicitly state that b shall depend on a; this
>>> is all nice and localized, it's still _b_ telling _a_ to
>>> add b to a's update list, and the programmer only has
>>> to figure out what _b_ depends on when he's writing _b_.
>>> Doesn't seem so bad. 
>>> 
>>> But of course it would be better to be able to pass just 
>>> something morally equivalent to (b, a + 1) to whatever 
>>> constructor and have the system figure out automatically 
>>> that since b returns a + 1 it has to add a to b's update 
>>> list. There must be some simple trick to accomplish that 
>>> (using Python, without parsing code).
>>
>>Right, you do not want to parse code. It really would not work as 
>>powerfully as Cells, which notice any dynamic access to another cell 
>>while a rule is running. So my rule can call a function on "self" (the 
>>instance that wons the slot being calculated, and since self can have 
>>pointers to other instances, the algorithm can navigate high and low 
>>calling other functions before finally reading another ruled slot. You 
>>want to track those.
>>
>>> Exactly what the trick is I 
>>> don't see immediately.
>>
>>To compute a value for a slot that happens to have a rule associated 
>>with it, have a little cell datastructure that implements all this and 
>>associate the cell with the slot and store a pointer to the rule in the 
>>cell. Then have a global variable called *dependent* and locally:
>>
>> currentdependent = *dependent*
>> oldvalue = cell.value
>> newvalue = call cell.rule, passing it the self instance
>> *dependent* = currentvalue
>>
>> i

Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Chris Uppal
Bill Atkins wrote:

> My favorite macro is ITERATE [...]

Thanks for the examples.

-- chris


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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Michele Simionato
Ken Tilton wrote:
> I was not thinking about the thread issue (of which I know little). The
> big deal for Cells is the dynamic bit:
>
> (let ((*dependent* me))
>  (funcall (rule me) me))
>
> Then if a rule forces another cell to recalculate itself, *dependent*
> gets rebound and (the fun part) reverts back to the original dependent
> as soon as the scope of the let is exited.

Python 2.5 has a "with" statement (yes, the name is Lispish on purpose)
that could be used to implement this. See
http://www.python.org/dev/peps/pep-0343

  Michele Simionato

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Chris Uppal
Petr Prikryl wrote:

> for element in aCollection:
> if element > 0:
> return True
> return False

[I'm not sure whether this is supposed to be an example of some specific
language (Python ?) or just a generic illustration.  I'll take it as the
latter, since it makes my point easier to express.  I'll also exaggerate, just
a little...]

But now, in order to hack around the absence of a sensible and useful
feature -- /only/ in order to do so -- you have added two horrible new
complications to your language.  You have introduced a special syntax to
express conditionals, and (worse!) a special syntax to express looping.  Not
only does that add a huge burden of complexity to the syntax, and semantics, of
the language (and, to a lesser extent, its implementation), but it also throws
out any semblance of uniformity.

Once you've started down that route then you've lost all hope of user-defined
control structures which operate on a par with the built-in ones.  And please
note that "control structures" are not limited to C-style "for" "while" etc.

E.g. in Java there's an unresolved, and irresolvable, tension between whether a
failing operation should return an error condition or throw an exception -- the
problem is that exceptions are (IMO and most other peoples' here) intended for
exceptional conditions, and for many operations "failure" is not exceptional.
One, highly effective, resolution to the problem is for the operation to be
parameterised with the action to take if it fails (defaulting to code to raise
an exception).  In Java that approach, though technically possible, is totally
infeasible due to the pathetic overuse of unwanted syntax, and the underuse of
simple and powerful primitives.

E.g. can you add three-way comparisons (less-than, same-as, greater-than to,
say, Python with corresponding three-way conditional control structures to
supplement "if" etc ?  Are they on a semantic and syntactic par with the
existing ones ?  In Smalltalk that is trivial (too trivial to be particularly
interesting, even), and I presume the same must be true of Lisp (though I
suspect you might be forced to use macros).

I should say that if your example /is/ in fact Python, then I believe that
language allows fairly deep hooks into the execution mechanism, so that at
least the "for" bit can be mediated by the collection itself -- which is better
than nothing, but nowhere near what I would call "good".

-- chris


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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Petr Prikryl

"Chris Uppal" wrote...
> Alex Martelli wrote:
>
> > I think it's reasonable to make a name a part of functions, classes and
> > modules because they may often be involved in tracebacks (in case of
> > uncaught errors): to me, it makes sense to let an error-diagnosing
> > tracebacks display packages, modules, classes and functions/methods
> > involved in the chain of calls leading to the point of error _by name_.
[...]
> E.g. consider the Smalltalk code (assumed to be the body of a method):
>
> aCollection
> do: [:each |
> each > 0 ifTrue: [^ true]].
> ^ false.
>
> which iterates over a collection checking to see if any element is > 0. If
so
> then the method answers true ("^" -- spelled "return" in Java), otherwise
it
> answers false.  In that code,
> [^ true]
> is syntactically and semantically an anonymous function, which is only
invoked
> if the antecedent is true (in point of fact the compiler inlines that
function
> away but I don't think that's relevant here).  The passage beginning
> [:each | ...
> and reaching to the matching ] is also an anonymous function with one
parameter
> (each) which is applied to each element of the collection in turn.  (In
this
> case it really is an anonymous function, even at the implementation
level.)
> What "name" would you give to either of them ?  I don't believe that /any/
name
> is possible, and certainly that no name is desirable.

for element in aCollection:
if element > 0:
return True
return False

And adding "def test(aCollection):" does not make it more complex,
in my opinion. And possibly, the chunk of code may be written
in some other way, more Pythonically. Maybe the attempt to
rewrite programs from other languages into Python and
the effort to use the same "tricks" like in the original program,
causes the cry for preserving lambda in future Python.

pepr


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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Boris Borcic
Bill Atkins wrote:
> 
> It's interesting how much people who don't have macros like to put
> them down and treat them as some arcane art that are too "*insane*"ly
> powerful to be used well.
> 
> They're actually very straightforward and can often (shock of shocks!)
> make your code more readable,  without your efficiency taking a hit.

Not even efficiency of debugging ? A real problem with macros is that run-time 
tracebacks etc, list macro outputs and not your macro'ed source code. And that 
becomes an acute problem if you leave code for somebody else to update. Or did 
lisp IDEs make progress on that front ?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Boris Borcic
Ken Tilton wrote:

> "Now if you are like most 
> people, you think that means X. It does not."

As far as natural language and understanding are concerned, "to mean" means 
conformity to what most people understand, Humpty Dumpties notwithstanding.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread sross
> I do wonder what would happen to Cells if I ever want to support
> multiple threads. Or in a parallel processing environment.

AFAIK It should be fine.
In LW, SBCL and ACL all bindings of dynamic variables are thread-local.

Cheers,
 Sean.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Rob Warnock
Ketil Malde  <[EMAIL PROTECTED]> wrote:
+---
| Sometimes the best documentation is the code itself.
| Sometimes the best name for a function is the code itself.
+---

And there's no reason that an anonymous LAMBDA [even if compiled]
couldn't store its source code in the "name" slot for debugging
printouts [e.g., stack backtraces].


-Rob

-
Rob Warnock <[EMAIL PROTECTED]>
627 26th Avenue http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

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


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Ketil Malde
[EMAIL PROTECTED] (Alex Martelli) writes:

> But if we can agree to name every function except continuations I'll be
> content

FWIW, I disagree:

A simple example, doubling each entry in a list:

map (*2) xs 
vs. let double x = x*2 in map double xs

Here's another example, extracting all lines that contain at least one
word:

filter (not.null) . map words . lines

Note that I'm using the following anonymous functions:

 not . null 
 filter (not . null)
 map words
 filter (not.null) . map words

Would it really improve anything if I named these?  It seems
incredibly pedestrian, along the lines of requiring a comments for
every source line:

  x++; /* increase x by one */
  a[x] = ' ';  /* insert a space in a at position x */

Sometimes the best documentation is the code itself.  Sometimes the
best name for a function is the code itself.

-k 
-- 
If I haven't seen further, it is by standing in the footprints of giants
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-10 Thread Antoon Pardon
Op 2006-05-09, Pisin Bootvong schreef <[EMAIL PROTECTED]>:
>
> Antoon Pardon wrote:
>> Op 2006-05-09, Pisin Bootvong schreef <[EMAIL PROTECTED]>:
>> >
>> > Antoon Pardon wrote:
>> >> Op 2006-05-09, Pisin Bootvong schreef <[EMAIL PROTECTED]>:
>> >> > Is this a Slippery Slope fallacious argument?
>> >> > (http://c2.com/cgi/wiki?SlipperySlope)
>> >>
>> >> No it is not.
>> >>
>> >> [...]
>> >>
>> >> So the question I have is: Why is requiring me to give this function
>> >> a name considered a good thing, when it leads to a situation that
>> >> is considered bad practice in case of a number.
>> >>
>> >> --
>> >
>> > Slippery Slope::
>> >"Argumentation that A is bad, because A might lead to B, and B
>> > to C, and we all know C is very bad."
>>
>> But I have seen noone here argue that requiring functions to be named
>> leads to requiring all variables to be named.
>>
>
> If I misinterpret your intended meaning, then I'm terribly sorry.
> However let me clarify how I understand your statements -- English is
> not my native language but I'm quite sure I have good English skill.
>
> you said:
>
>> >> Why is requiring me to give this function
>> >> a name considered a good thing, when it leads to a situation that
>> >> is considered bad practice in case of a number.
>
> So in that question, one of the your assumption is that:
>
>"it (required function naming) ***LEADS*** to a situation that is
> considered bad practice in case of a number (required number naming)"

The bad practice I was talking about was that the number was essentially
given a meaningless name that didn't add any information. There is
no adavantage using 'one' as a variable name over using 1 directly.

If for some reason I needed a 2 in the code every time 'one' was
used, I can hardy turn 

  one = 1
  
into

  one = 2

Because people would still see things like:

  foo(one)

In the cade and would expect this to be equivallent with

  foo(1)

and not the equivallent of

  foo(2)

> You have not seen anyone here
> >> "argue that requiring functions to be named leads to requiring all
> variables to be named"
>
> But obviously I have seen someone "argue that requiring functions to be
> named leads to requiring **NUMBER** to be named"

IMO you misinterpreted someome's word that way.

> And you said that requiring number to be named is bad.

Yes that is the starting point. But that is just an
example of what bad practices will follow: the use
of meaningless names.

> Where did I misunderstand that you, with all good faith, were not
> trying to say that "A leads B which is bad so "why is A considered a
> good thing""? And how is it not slippery argument?

This is my argument:

1) Using meaningless names is a bad coding practice. (with the number example)
2) Requiring names in particular circumstances will
   lead to meaninless names in those circumstances.
3) Requiring names for functions will lead to
   meanless names for some functions.
4) Requiring names for functions will thus lead to
   bad coding practice in a number of cases.

> To put my response another way, I would ask:
> Does Python require you to name all your number? expression? (Hint: the
> answer is no)
>
> So where did you get the idea that requiring function to be named, as
> Python does, leads to requiring number to be named? Is it in a research
> anywhere? Or do majority of people here agree so (that it leads to)?

I didn't get that idea.

>> >> Why is requiring me to give this function
>> >> a name considered a good thing, when it leads to a situation that
>> >> is considered bad practice in case of a number.
>> >
>> > A === "requiring me to give function a name"
>> > no B
>> > C === "requiring me to give number a name"
>> >
>> > "Argumentation that requiring one to give function a name is bad,
>> > because that might lead to requiring one to give number a name, and we
>> > all know that that is very bad."
>>
>> That is not the arguement I'm making.
>>
>> The argument is that a particular pratice is considered bad coding,
>> (with an example giving a number) and then showing that requiring
>> a name for a function, almost makes such a practice inevitable (for
>> certain functions used as parameters)
>>
>
> Your example:
>
>  def incr_cnt_by_one(obj):
>obj.cnt += 1
>
>  treat_all(lst, incr_cnt_by_one)
>
> Did not in anyway show that the number one is required to be named. 1
> in that code is written literally; you didn't have to write "one = 1"
> first. The function to increment obj.cnt by one is named. but the
> number 1 itself is not named.

You missed the point entirely. Isn't "one" a horrible name to use?
It doesn't buy you anything over the use of 1 and may even cause
confusion should anyone ever write something like one = 2.

And isn't incr_cnt_by_one just as horrible a name to use. If I ever
needed another function I couldn't just use another body with
the same function name because something like

   def incr_cnt_by_one(obj):
 obj.buzy = False

would probabl

Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread M Jared Finder
Alex Martelli wrote:
> Stefan Nobis <[EMAIL PROTECTED]> wrote:
> 
>> [EMAIL PROTECTED] (Alex Martelli) writes:
>>
>>> if anonymous functions are available, they're used in even more
>>> cases where naming would help
>> Yes, you're right. But don't stop here. What about expressions? Many
>> people write very complex expression, that are hard to understand. A
>> good language should forbid these abuse and don't allow expressions
>> with more than 2 or maybe 3 operators!
> 
> That would _complicate_ the language (by adding a rule).  I repeat what
> I've already stated repeatedly: a good criterion for deciding which good
> practices a language should enforce and which ones it should just
> facilitate is _language simplicity_.  If the enforcement is done by
> adding rules or constructs it's probably not worth it; if the
> "enforcements" is done by NOT adding extra constructs it's a double win
> (keep the language simpler AND push good practices).

Your reasoning, taken to the extreme, implies that an assembly language, 
by virtue of having the fewest constructs, is the best designed language 
ever.  But we know that not to be the case -- rarely do even embedded 
developers program in assembly language any more.  Why?

Because assembly language is so simple that it's very tedious to write. 
   There's no function call primitive -- you have to manually generate a 
function call pattern yourself.  There's no looping primitive -- you 
have to manually generate a looping pattern yourself.  I feel sorry for 
the person who's debugging an assembly program using manually generated 
code that implements a vtable-based dynamic dispatch.

Any feature that allows me to write less code to do the same thing has a 
huge positive -- the reduction of human generated, and therefore error 
prone, code.  I think the advantages of anonymous functions:
a) explicitly documenting that the function is used in only one place
b) enabling generic iteration and looping routines
c) not having to maintain a unique name for the function
d) making the language more elegant
e) making the language simpler to implement
greatly outweigh the small disadvantage of adding one additional 
construct to the language.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Petr Prikryl
"Alex Martelli" wrote...
> Joe Marshall  wrote:
>...
> > If you language allows unnamed integers, unnamed strings, unnamed
> > characters, unnamed arrays or aggregates, unnamed floats, unnamed
> > expressions, unnamed statements, unnamed argument lists, etc.  why
> > *require* a name for trivial functions?

Event the trivial function can have a name. Does it make
the trivial function more understandable if I do not give a name?
I understand what lambda means, but it is clearer for me to see
something like (with more meaningful name than shown here):

>>> def fn(x):
... return x + 5

and to use it like...

>>> fn(3)
8

Still, I can anonymize it later, if I really need

>>> a = [fn]

or I can give it another name

   >>> z = fn

In my opinion, the cry for lambda in Python comes
from people used to functional languages, because
they are not used to the procedural style and it
does not fit them at the beginning.
Frankly, functional style seems "more strange" to me
(i.e. the counter example). Still, I do not say it is bad.
But it never came to my mind to say "Please, rewrite
the LISP so that it looked more like Pascal. I do not like
the lambda."

Also, Python is compiled (to bytecode), imperative language,
and the form of definition of the chunks of code is more
natural to the compiler and to the customs
how the procedural program is written and how its parts
are referenced and put together to form bigger chunks
of code.

> I think it's reasonable to make a name a part of functions, classes and
> modules because they may often be involved in tracebacks (in case of
> uncaught errors): to me, it makes sense to let an error-diagnosing
> tracebacks display packages, modules, classes and functions/methods
> involved in the chain of calls leading to the point of error _by name_.

I agree with Alex here. I USUALLY do not need debugger, but sometimes
it is exremely handy to discover what happens (through debugger or few
print commands, its a matter of taste). And Python is very fine here:

>>> dir(fn)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
'__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name']
>>> fn.__name__
'fn'

and even the anonymized function still knows its original name and type

>>> a[0].__name__
'fn'
>>> type(a[0])


If lambda functions in Python are tweaked internally into normal Python
functions...

>>> z = lambda x: x * 3
>>> dir(z)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
'__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name']
>>> z.__name__
''
>>> type(z)


... what makes them better, than the named function? If I do not loose
anything by simplification, I want to have it simpler.

pepr


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Joe Marshall <[EMAIL PROTECTED]> wrote:

> Pisin Bootvong wrote:
> > Is this a Slippery Slope fallacious argument?
> > (http://c2.com/cgi/wiki?SlipperySlope)
> >
> > "if python required you to name every function then soon it will
> > require you to name every number, every string, every immediate result,
> > etc. And we know that is bad. Therefore requiring you to name your
> > function is bad So Python is bad"
> 
> No, it is a question about consistency.  Why are functions singled out?

They're not: packages, modules and classes also have names; as I pointed
out, the common factor among these four types is that instance of these
types are liable to occur in tracebacks &c, where a (good) name is
particularly useful as a summary reminder of what the thing is.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Paul Rubin  wrote:

> [EMAIL PROTECTED] (Alex Martelli) writes:
> > I think it's reasonable to make a name a part of functions, classes and
> > modules because they may often be involved in tracebacks (in case of
> > uncaught errors): to me, it makes sense to let an error-diagnosing
> > tracebacks display packages, modules, classes and functions/methods
> > involved in the chain of calls leading to the point of error _by name_.
> 
> But it would be even nicer if the traceback could point back to the
> exact location in the source code where the function definition
> occurred, and that wouldn't need any name for the function.

I believe a name is a useful "summary" or "conceptual handle" for a
thing, saving us from having to describe/analyze/recognize it in more
detail each and every time.  "Need" may be too strong a word, but I
maintain there's _usefulness_ (and reasonableness, and good common
sense) in the naming.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Joe Marshall <[EMAIL PROTECTED]> wrote:
   ...
> The problem is that a `name' is a mapping from a symbolic identifier to
> an object and that this mapping must either be global (with the
> attendant name collision issues) or within a context (with the
> attendant question of `in which context').

Why is that a problem?  Even for so-called "global" names, Python
supports a structured, hierarchical namespace, so there can never be any
collision betwen the "globals" of distinct modules (including modules
which happen to have the same name but live in distinct packages or
subpackages) -- I did mention that names could usefully be displayed in
some strcutured form such as apackage.somemodule.thefunction but perhaps
I was too tangential about it;-).


> Matthias Felleisen once suggested that *every* internal function should
> be named.  I just said `continuations'.  He immediately amended his
> statement with `except those'.

If I used continuations (I assume you mean in the call/cc sense rather
than some in which I'm not familiar?) I might feel the same way, or not,
but I don't (alas), so I can't really argue the point either way for
lack of real-world experience.

But if we can agree to name every function except continuations I'll be
content: Python doesn't support continuations, so it's consistent for it
to require every function to be named (since in its case "every
function" and "every function except continuations" coincide;-).


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Paul Rubin
rydis (Martin Rydstr|m) @CD.Chalmers.SE writes:
> [Emacs] is written in Lisp, which is the only computer language that is
> beautiful.  -- Neal Stephenson, _In the Beginning was the Command Line_

I don't remember seeing these lyrics in the thread yet, but obviously
it's a requirement:

http://www.songworm.com/lyrics/songworm-parody/EternalFlame.html
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Martin Rydstr|m
[EMAIL PROTECTED] (Alex Martelli) writes:
> Didn't want to trigger some flamewar;-), but, yes, if that was my only
> choice, I'd much rather use small, simple Scheme than huge, complicated,
> rich, powerful Common Lisp.  ((But in this case I'm biased by early
> experiences, since when I learned and used Lisp-ish languages there WAS
> no Common Lisp, while Scheme was already there, although not quite the
> same language level as today, I'm sure;-)).

If that was in the early to mid eighties, which I seem to recall you
mentioning, the Lisp dialects mostly in use were huger, more
complicated, richer and more powerful than Common Lisp in many, if not
most, respects, as far as I can tell.  Common Lisp is a (later)
augmented least common denominator of those Lisps. The really big
thing that's newer and greater in CL is CLOS and the condition system.

',mr

-- 
[Emacs] is written in Lisp, which is the only computer language that is
beautiful.  -- Neal Stephenson, _In the Beginning was the Command Line_
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Paul Rubin
[EMAIL PROTECTED] (Alex Martelli) writes:
> I think it's reasonable to make a name a part of functions, classes and
> modules because they may often be involved in tracebacks (in case of
> uncaught errors): to me, it makes sense to let an error-diagnosing
> tracebacks display packages, modules, classes and functions/methods
> involved in the chain of calls leading to the point of error _by name_.

But it would be even nicer if the traceback could point back to the
exact location in the source code where the function definition
occurred, and that wouldn't need any name for the function.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Joe Marshall

Alex Martelli wrote:
>
> I think it's reasonable to make a name a part of functions, classes and
> modules because they may often be involved in tracebacks (in case of
> uncaught errors): to me, it makes sense to let an error-diagnosing
> tracebacks display packages, modules, classes and functions/methods
> involved in the chain of calls leading to the point of error _by name_.
>
> I think it's reasonable to make a name a part of types for a different
> reason: new types are rarely meant to be used "just once"; but also, if
> during debugging any object is displayed, it's nice to be able to show,
> as part of the display, "this object is of type X and ...", with X shown
> as a name rather than as a complete (thus lengthy) description. (any
> decent interactive shell/debugger will let you drill down into the
> details as and when you need to, of course, but a well-chosen name can
> be often sufficient during such interactive exploration/debugging
> sessions, and therefore save time and effort).

I agree that symbolic debugging info is a good thing.

> Indeed, "given an object, how do I get its NAME" (for inspection and
> debugging purposes) is the most frequently asked question on
> comp.lang.python, and I've grown a bit tired of answering "you can't, an
> object in general intrinsically ``has no name'', it might have many or
> none at all, blah blah" -- yeah, this is technically true (in today's
> Python), but there's no real reason why it should stay that way forever
> (IMHO).  If we at least ALLOWED named objects everywhere, this would
> further promote the use of names as against mysterious "magic numbers",
> since the programmer would KNOW that after
> VAT_MULTIPLIER = 1.19
> then displaying in a debugger or other interactive session that
> PARTICULAR instance of the value 1.19 would show the name string
> 'VAT_MULTIPLIER' as well (or no doubt a more structured name constructed
> on the fly, identifying package and module-within-package too).

The problem is that a `name' is a mapping from a symbolic identifier to
an object and that this mapping must either be global (with the
attendant name collision issues) or within a context (with the
attendant question of `in which context').

> Mandating names for _everything_ would complicate the language by
> forcing it to provide builtin names for a lot of elementary building
> blocks: so for most types of objects it's best to "gently nudge".  For
> functions, classes, modules, and packages, I think the naming is
> important enough (as explained above) to warrant a syntax including the
> name; better, therefore, not to complicate the language by providing
> another different syntax in each case just to allow the name to be
> omitted -- why encourage a pratice that's best discouraged, at the price
> of language simplicity?

I agree.  This is why I write
(defun foo (x) ...)

rather than
(setf (symbol-function 'foo) (lambda (x) ...))

However, there are places where names are cumbersome.  They are
certainly cumbersome for most literal objects like numbers and strings.
 There are circumstances where they are cumbersome for function
objects.  The function (lambda (x) (+ x 3)) doesn't really need a name.
 It isn't any big deal if you give it a name, but it's a trivial
annoyance to be forced to give it a name.  It becomes a major annoyance
when you write code in continuation-passing-style or monadic style.

It is an annoyance when refactoring code, too.  Suppose you had written
(mapcar #'sin list-of-numbers)

and you realize that the numbers are in degrees.  With an unnamed
function, this is an easy fix:
(mapcar (lambda (x) (sin (deg->rad x))) list-of-numbers)

With a named function, you have to do one of these:
(flet ((sin-d (x) (sin (deg->rad x
  (mapcar #'sin-d list-of-numbers))

or
(mapcar (flet ((sin-d (x) (sin (deg->rad x #'sin-d)
list-of-numbers)


Matthias Felleisen once suggested that *every* internal function should
be named.  I just said `continuations'.  He immediately amended his
statement with `except those'.

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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Joe Marshall

Pisin Bootvong wrote:
> Is this a Slippery Slope fallacious argument?
> (http://c2.com/cgi/wiki?SlipperySlope)
>
> "if python required you to name every function then soon it will
> require you to name every number, every string, every immediate result,
> etc. And we know that is bad. Therefore requiring you to name your
> function is bad So Python is bad"

No, it is a question about consistency.  Why are functions singled out?

Or is this an attempt to apply an Argumentum ad Logicam fallacy?

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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Ken Tilton


[EMAIL PROTECTED] wrote:
> Ken Tilton wrote:
> 
>>Python has a weak lambda, statements do not always
>>return values, it does not have macros, and I do not know if it has
>>special variables.
> 
> 
> I am pretty much ignorant of Common Lisp, but I have the impression
> they are the
> same as Scheme parameters, i.e. thread-local dynamically scoped
> variables
> (feel free to correct me if I am mistaken). If I am right, here is how
> you would emulate them in recent versions of Python:
> 
> import threading, time
> 
> special = threading.local()
> special.x = 0
> 
> def getx():
> return special.x
> 
> def set_x(value):
> special.x = value
> time.sleep(3-value) # thread-2 completes after thread-1
> print "%s is setting x to %s" % (threading.currentThread(), getx())
> 
> if __name__ == '__main__':
> print getx() # => 0
> threading.Thread(None, lambda : set_x(1)).start() # => 1
> threading.Thread(None, lambda : set_x(2)).start() # => 2
> time.sleep(3)
> print getx() # => 0
> 
>Michele Simionato
> 

I was not thinking about the thread issue (of which I know little). The 
big deal for Cells is the dynamic bit:

(let ((*dependent* me))
 (funcall (rule me) me))

Then if a rule forces another cell to recalculate itself, *dependent* 
gets rebound and (the fun part) reverts back to the original dependent 
as soon as the scope of the let is exited.

In this case, because my code is so brilliant , there is only one 
place in the code where a rule gets called, so it would be easy enough 
to manage by saving/restoring the existing value around storing a new 
value there.

I do wonder what would happen to Cells if I ever want to support 
multiple threads. Or in a parallel processing environment.

kenny


-- 
Cells: http://common-lisp.net/project/cells/

"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Rob Warnock <[EMAIL PROTECTED]> wrote:
   ...
> If "only" being useful is enough, 100 cycles is enough for a DNS server,
> or an NTP server, or even a stub HTTP server that delivers some small
> piece of real-time data, like a few realtime environmental sensors
> [temperature, voltages, etc.].

Reminds me of Stuart Cheshire's description of how they managed to
shoehorn zeroconf (aka bonjour, the artist formerly known as rendezvous)
into a risible amount of ROM (less than 1K byte, if I recall correctly)
left in an embedded microcontroller (for a video camera, I think).
Zeroconf is at heart a few clever tricks on top of DNS (plus 169.254.*
IPs), and in the end they managed by one more clever trick (the thingy
ignores WHAT the request is for, and just spits out the same response
each and every time -- pushing the boundaries of DNS but, it seems,
still technically staying within those boundaries;-).

Not directly relevant to the scaling debate (the camera's expected to be
on a LAN, serving a few requests per second at most), but the limit
being on bits rather than cycles somehow "tastes" similar to me.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Pisin Bootvong <[EMAIL PROTECTED]> wrote:
   ...
> Is there such language that allow scalability without any need for
> design on the underlying architecture?

Perhaps Erlang...?  I have no specific experience with it, but according
to the rumor mill it forces or cajoles you into an architecture that's
quite appropriate for scaling -- i.e., sure that architecture needed to
be designed, but (if I understand Erlang correctly) it's now built into
the language and you're more or less going to use the right paradigm.


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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Pisin Bootvong

Antoon Pardon wrote:
> Op 2006-05-09, Pisin Bootvong schreef <[EMAIL PROTECTED]>:
> >
> > Antoon Pardon wrote:
> >> Op 2006-05-09, Pisin Bootvong schreef <[EMAIL PROTECTED]>:
> >> > Is this a Slippery Slope fallacious argument?
> >> > (http://c2.com/cgi/wiki?SlipperySlope)
> >>
> >> No it is not.
> >>
> >> [...]
> >>
> >> So the question I have is: Why is requiring me to give this function
> >> a name considered a good thing, when it leads to a situation that
> >> is considered bad practice in case of a number.
> >>
> >> --
> >
> > Slippery Slope::
> >"Argumentation that A is bad, because A might lead to B, and B
> > to C, and we all know C is very bad."
>
> But I have seen noone here argue that requiring functions to be named
> leads to requiring all variables to be named.
>

If I misinterpret your intended meaning, then I'm terribly sorry.
However let me clarify how I understand your statements -- English is
not my native language but I'm quite sure I have good English skill.

you said:

> >> Why is requiring me to give this function
> >> a name considered a good thing, when it leads to a situation that
> >> is considered bad practice in case of a number.

So in that question, one of the your assumption is that:

   "it (required function naming) ***LEADS*** to a situation that is
considered bad practice in case of a number (required number naming)"

You have not seen anyone here
 >> "argue that requiring functions to be named leads to requiring all
variables to be named"

But obviously I have seen someone "argue that requiring functions to be
named leads to requiring **NUMBER** to be named"

And you said that requiring number to be named is bad.
Where did I misunderstand that you, with all good faith, were not
trying to say that "A leads B which is bad so "why is A considered a
good thing""? And how is it not slippery argument?

To put my response another way, I would ask:
Does Python require you to name all your number? expression? (Hint: the
answer is no)

So where did you get the idea that requiring function to be named, as
Python does, leads to requiring number to be named? Is it in a research
anywhere? Or do majority of people here agree so (that it leads to)?


> >> Why is requiring me to give this function
> >> a name considered a good thing, when it leads to a situation that
> >> is considered bad practice in case of a number.
> >
> > A === "requiring me to give function a name"
> > no B
> > C === "requiring me to give number a name"
> >
> > "Argumentation that requiring one to give function a name is bad,
> > because that might lead to requiring one to give number a name, and we
> > all know that that is very bad."
>
> That is not the arguement I'm making.
>
> The argument is that a particular pratice is considered bad coding,
> (with an example giving a number) and then showing that requiring
> a name for a function, almost makes such a practice inevitable (for
> certain functions used as parameters)
>

Your example:

 def incr_cnt_by_one(obj):
   obj.cnt += 1

 treat_all(lst, incr_cnt_by_one)

Did not in anyway show that the number one is required to be named. 1
in that code is written literally; you didn't have to write "one = 1"
first. The function to increment obj.cnt by one is named. but the
number 1 itself is not named.

> Antoon Pardon

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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Randal L. Schwartz
> "Alex" == Alex Martelli <[EMAIL PROTECTED]> writes:

Alex> The difference, if any, is that gurus of Java, C++ and Python get to
Alex> practice and/or keep developing their respectively favorite languages
Alex> (since those three are the "blessed" general purpose languages for
Alex> Google - I say "general purpose" to avoid listing javascript for
Alex> within-browser interactivity, SQL for databases, XML for data
Alex> interchange, HTML for web output, &c, &c), while the gurus of Lisp,
Alex> Limbo, Dylan and Smalltalk don't (Rob Pike, for example, is one of the
Alex> architects of sawzall -- I already pointed to the whitepaper on that
Alex> special-purpose language, and he co-authored that paper, too).

That's crazy.  Some of the key developers of Smalltalk continue to work
on the Squeak project (Alan Kay, Dan Ingalls, and I'm leaving someone
out, I know it...).  So please remove Smalltalk from that list.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
 http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

*** Posted via a free Usenet account from http://www.teranews.com ***
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Alex Martelli
Stefan Nobis <[EMAIL PROTECTED]> wrote:

> [EMAIL PROTECTED] (Alex Martelli) writes:
> 
> > if anonymous functions are available, they're used in even more
> > cases where naming would help
> 
> Yes, you're right. But don't stop here. What about expressions? Many
> people write very complex expression, that are hard to understand. A
> good language should forbid these abuse and don't allow expressions
> with more than 2 or maybe 3 operators!

That would _complicate_ the language (by adding a rule).  I repeat what
I've already stated repeatedly: a good criterion for deciding which good
practices a language should enforce and which ones it should just
facilitate is _language simplicity_.  If the enforcement is done by
adding rules or constructs it's probably not worth it; if the
"enforcements" is done by NOT adding extra constructs it's a double win
(keep the language simpler AND push good practices).


Alex

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


Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread David C.Ullrich
On Mon, 08 May 2006 18:46:57 -0400, Ken Tilton <[EMAIL PROTECTED]>
wrote:

>
>
>David C. Ullrich wrote:
>> On 08 May 2006 12:53:09 -0700, [EMAIL PROTECTED] (Thomas
>> F. Burdick) wrote:
>> 
>> 
>>>Ken Tilton <[EMAIL PROTECTED]> writes:
>>>
>>>
No, you do not want on-change handlers propagating data to other
slots, though that is a sound albeit primitive way of improving
self-consistency of data in big apps. The productivity win with
VisiCalc was that one simply writes rules that use other cells, and
the system keeps track of what to update as any cell changes for
you. You have that exactly backwards: every slot has to know what
other slots to update. Ick.
>>>
>>>No no, that's fine and the way it should be: when you change a slot,
>>>it should know who to update.  And that's also the way it works in
>>>Cells.  The trick is that Cells takes care of that part for you:
>> 
>> 
>> I'm glad you said that - this may be what he meant, but it seems
>> more plausible than what he actually said.
>
>There may be some confusion here because there are two places for code 
>being discussed at the same time, and two sense of propagation.
>
>the two places for code are (1) the rule attached to A which is 
>responsible for computing a value for A and (2) a callback for A to be 
>invoked whenever A changes. Why the difference?
>
>In Cells, A is a slot such as 'background-color'. Whenever that changes, 
>we have to do something more. On Mac OS9 it was "InvalidateRect" of the 
>widget. In Cells-Tk, it is:
> (Tcl_interp "mywidget configure -background ")
>
>In my OpenGL GUI, it is to rebuild the display-list for the widget.
>
>That is the same no matter what rule some instance has for the slot 
>background-color, and different instances will have different rules.
>
>As for propagating, yes, Cells propagates automatically. More below on 
>that. What I saw in the example offered was a hardcoded on-change 
>callback that was doing /user/ propagation form B to A (and B to A! ... 
>doesn't that loop, btw? 

No, there's no looping in the example. Yes, the code determining what
b returns should be attached to b instead of to a, but the code I
gave does work as advertised. (I mean give me a break - I provided
a sample use so you could simply run it. Installing Python is not
hard.)

If you, um, look at the code you see that "cells.a = 42" triggers
cells.__setattr__, which fires a's callback; the callback then
reaches inside and sets the value of b _without_ going through
__setattr__, hence without triggering b's callback.

In Cells you can't have A depend on B and also B depend on A?
That seems like an unfortunate restriction - I'd want to be
able to have Celsius and Farenheit, so that setting either
one sets the other.

Of course if there are no loops it's easier to see how
you managed to do the stuff you were talking about elsewhere,
(at least sometimes) delaying execution until needed.

>Anyway...)
>
>> 
>> 
>>>all
>>>the *programmer* has to care about is what values a slot depends on --
>>>Cells takes care of inverting that for you, which is important because
>>>that's a job that a computer is much better at than a human.
>> 
>> 
>> Fine. I suppose that is better; if b is going to return a + 1
>> the fact that this is what b returns should belong to b, not
>> to a. So a has an update list including b, so when a's value
>> is set a tells b it needs to update itself.
>> 
>> If we're allowed to pass (at some point, to some constructor
>> or other) something like (b, a + 1, [a]), which sets up a
>> cell b that shall return a + 1, and where the [a] is used
>> in the constructor to tell a to add b to a's update list
>> then this seems like no big deal.
>> 
>> And doing that doesn't seem so bad - now when the programmer
>> is writing b he has to decide that it should return a + 1
>> and also explicitly state that b shall depend on a; this
>> is all nice and localized, it's still _b_ telling _a_ to
>> add b to a's update list, and the programmer only has
>> to figure out what _b_ depends on when he's writing _b_.
>> Doesn't seem so bad. 
>> 
>> But of course it would be better to be able to pass just 
>> something morally equivalent to (b, a + 1) to whatever 
>> constructor and have the system figure out automatically 
>> that since b returns a + 1 it has to add a to b's update 
>> list. There must be some simple trick to accomplish that 
>> (using Python, without parsing code).
>
>Right, you do not want to parse code. It really would not work as 
>powerfully as Cells, which notice any dynamic access to another cell 
>while a rule is running. So my rule can call a function on "self" (the 
>instance that wons the slot being calculated, and since self can have 
>pointers to other instances, the algorithm can navigate high and low 
>calling other functions before finally reading another ruled slot. You 
>want to track those.
>
>> Exactly what the trick is I 
>> don't see immediately.
>
>To compute a value for a 

Re: A critic of Guido's blog on Python's lambda

2006-05-09 Thread Chris Uppal
Pisin Bootvong wrote:

> Slippery Slope::
>"Argumentation that A is bad, because A might lead to B, and B
> to C, and we all know C is very bad."

For the Slippery Slope criticism to be applicable, there would have to be some
suggestion that removing anonymous functions /would actually/ (tend to) lead to
removing anonymous values in general.  There was no such suggestion.

The form of the argument was more like reasoning by analogy: if context A has
features like context B, and in B some feature is known to be good (bad) then
the analogous feature in A is also good (bad).  In that case an attack on the
validity of the argument would centre on the relevance and accuracy of the
analogy.

Alternatively the argument might be seen as a generalisation/specialisation
approach.  Functions are special cases of the more general notion of values.
We all agree that anonymous values are a good thing, so anonymous functions
should be too.  If you parse the argument like that, then the attack should
centre on showing that functions have relevant special features which are not
shared by values in general, and so that we cannot validly deduce that
anonymous functions are good.

-- chris


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


  1   2   3   >