473,396 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Favorite non-python language trick?

As someone who learned C first, when I came to Python everytime I read
about a new feature it was like, "Whoa! I can do that?!" Slicing, dir(),
getattr/setattr, the % operator, all of this was very different from C.

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?

Here's my current candidate:

So the other day I was looking at the language Lua. In Lua, you make a
line a comment with two dashes:

-- hey, this is a comment.

And you can do block comments with --[[ and ---]].

--[[
hey
this
is
a
big
comment
--]]

This syntax lets you do a nifty trick, where you can add or subtract a
third dash to change whether or not code runs:

--This code won't run because it's in a comment block
--[[
print(10)
--]]

--This code will, because the first two dashes make the rest a comment,
breaking the block
---[[
print(10)
--]]

So you can change whether or not code is commented out just by adding a
dash. This is much nicer than in C or Python having to get rid of """ or
/* and */. Of course, the IDE can compensate. But it's still neat :)
Jul 19 '05
134 5950
Steven D'Aprano wrote:
with colour do begin
red := 0; blue := 255; green := 0;
end;

instead of:

colour.red := 0; colour.blue := 255; colour.green := 0;


c = colour
c.red = 0; c.blue = 255; c.green = 0
del c # Not strictly needed, but limits the scope of c

When everything's a reference, the Pascal 'with' syntax doesn't gain
you anything over a single-letter variable name. As I recall, it's
handy in Pascal because record assignment has value semantics rather
than reference semantics.

Cheers,
Nick.

Jul 19 '05 #101
Terry Hancock wrote:
http://www.logilab.org/projects/python-logic/ This is something pretty new to me, so I can't comment on how well
it would meet your expectations, but I see now that the site does mention
OZ/Mozart as comparables.


I've used both, the logilab stuff is cool, but no where near the
maturity (or speed) of OZ/Mozart. OTOH, I can actually get things
done with the logilab code. But that might say more about me than
Mozart. :)
--
Benji York
Jul 19 '05 #102
If I had to choose one feature, I would like to see better support for
nested lexical scopes. However, I imagine this is no easy "trick" to
add to the language.
I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


Jul 19 '05 #103

"Paddy" <pa*******@netscape.net> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Sadly, its not a solution that I'm after, but a particular toolkit that
can be used for solving that type of problem.


Presuming this is an anwer to my comment about generators... I was pointing
you more to the method used than the particular solutions. Whether your
constraint problems are similar enough, I have no idea.

Terry J. Reedy

Jul 19 '05 #104
On Thursday 30 June 2005 10:21 am, to********@gmail.com wrote:
If I had to choose one feature, I would like to see better support for
nested lexical scopes. However, I imagine this is no easy "trick" to
add to the language.


Doesn't that already happen in versions 2.2+?

What exactly do you mean by "better" support for nested lexical
scopes? Can you give an example of something that doesn't work,
but should?

I'm just curious. The whole question of lexical scoping seemed
a bit esoteric to me at the time --- I think I must instinctively
avoid situations where it causes trouble. The most important
exception would have to be the behavior of lambda and locally-defined
functions --- I still expect them to know the variables in the defining
function's namespace. But I think that lexical scoping fixed this
so that they do, IIRC (I don't use them often, so I'm not so sure).

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Jul 19 '05 #105
ncf
Eh, just figured it'd be worth noting...map, filter, and reduce should
be possible with the extended list syntaxes. Well, filter I know is,
but hte others /should/ be possible.

filter(lambda: <<condition>>, <<seq>>)
[some_var for some_var in <<seq>> if <<condition>>]
Honestly, though, I hope they don't drop the map functions and such.
That's one of the stronger functions of the language (IMO).

-Wes

Jul 19 '05 #106
ncf
Hmm...I think it's time I do better justice to what I previously wrote.
http://www.artima.com/weblogs/viewpost.jsp?thread=98196

The above article was linked by Python's PEP...

Jul 19 '05 #107
ncf wrote:
Eh, just figured it'd be worth noting...map, filter, and reduce should
be possible with the extended list syntaxes. Well, filter I know is,
but hte others /should/ be possible.

filter(lambda: <<condition>>, <<seq>>)
[some_var for some_var in <<seq>> if <<condition>>]


reduce isn't.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
Who needs a dream / Who needs ambition
-- The Russian, _Chess_
Jul 19 '05 #108
ncf
Sorry, I realized that shortly after my post =X

Jul 19 '05 #109
In article <ma**************************************@python.o rg>, Joseph Garvin wrote:
I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


Being able to use my native language without a hitch when naming my
variables &c. Java allows that because it supports almost any Unicode
character in its identifiers. With Python I occasionally have to stop and
think: "I can't name it that. What's better?"

Not everyone always writes their programs in English. Once you get used
to Java's naming possibilities, it's plain annoying to go back, even if
it's just a couple of letters that're lacking in my case.

--
Pekka Karjalainen - Oulu, Finland

Jul 19 '05 #110
With the exception of reduce(lambda x,y:x*y, sequence), reduce can be
replaced with sum, and Guido wants to add a product function.

Jul 19 '05 #111
On Fri, 24 Jun 2005 21:17:09 GMT, rumours say that Ron Adam
<rr*@ronadam.com> might have written:
I think some sort of inline or deferred local statement would be useful
also. It would serve as a limited lambda (after it's removed), eval
alternative, and as a inlined function in some situations as well I think.

Something like:

name = defer <expression>

then used as:

result = name()

The expression name() will never have arguments as it's meant to
reference it's variables as locals and probably will be replaced
directly with names's byte code contents at compile time.

Defer could be shortened to def I suppose, but I think defer would be
clearer. Anyway, it's only a wish list item for now.


This is similar:

http://groups-beta.google.com/group/...c884147852d23d
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians
Jul 19 '05 #112
Joseph Garvin wrote:
I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


I'm not aware of a language that allows it, but recently I've found
myself wanting the ability to transparently replace objects. For
example, if you have a transparent wrapper class around a certain
object, and then determine that you no longer need to wrap the object,
you can say the magic incantation, and the wrapper instance is replaced
by what it is wrapping everywhere in the program. Or you have a complex
math object, and you realize you can reduce it to a simple integer, you
can substitue the integer for the math object, everywhere.

I mainly look for it in the "object replaces self" form, but I guess you
could also have it for arbitrary objects, e.g. to wrap a logging object
around a function, even if you don't have access to all references of
that function.

Why isn't it in Python? It's completely counter to the conventional
object semantics.
Jul 19 '05 #113
Joseph Garvin wrote:

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


1. Lisp's "dynamically scoped" variables (Perl has them, and calls them
"local", but as far as I've seen their use their is discouraged). These
are global variables which are given time-local bindings. That is,
structuring the syntax after what's used for globals,

x=10
def foo():
# No need to define x as it is only read -- same as globals
print x

def bar():
dynamic x
x = 11
foo()

def baz():
bar() # prints 11
foo() # prints 10; the binding in bar is undone when bar exits

This feature makes using "globals" sensible, providing a way to avoid
many important uses (and some say, misuses) of objects if you are so
inclined. It allows you to do some things better than objects do,
because it does to library parameters, what exceptions do to return
codes: instead of passing them in all the way from outside until a
piece of code which actually uses them, they are only mentioned where
you set them and where you really need to access them.

It would not be too hard to implement a version of this (inefficiently)
in the existing language, if frame objects could carry a modifiable
dictionary.

I suppose it is not in Python because (most) Pythoners are not looking
(hard enough) for alternatives to OOP.

2. Prolog's ability to add operators to the language. Though this
facility is quite clanky in Prolog (because there is no elegant way to
specify precedence), the idea is appealing to me. It would allow a
better implementation of my (awkward, granted) recipe for adding logic
programming constructs to Python. It is not in the language because it
might fragmentize it, and because it is very hard to make
recursive-descent parsers like CPython's programmable this way.

3. Lisp's Macros, of course, which have been mentioned already in this
thread. Even Boo-like macros, which are nowhere as strong as Lisp's,
would be very useful. Not in the language, besides its being hard in
any non-lisp-like language, for the reasons mentioned for adding
operators.

On the other hand, there's no end to the features I wish I could copy
from Python to other languages...

Jul 19 '05 #114
Rocco Moretti wrote:
Joseph Garvin wrote:

I'm not aware of a language that allows it, but recently I've found
myself wanting the ability to transparently replace objects....
I mainly look for it in the "object replaces self" form, but I guess you
could also have it for arbitrary objects, e.g. to wrap a logging object
around a function, even if you don't have access to all references of
that function.

Why isn't it in Python? It's completely counter to the conventional
object semantics.


Actually this is the old (and terrifying) Smalltalk message 'becomes:'.
There is a concrete reason it is not in python: objects are represented
as pointers to their data structures, do not have identical sizes, and
therefore cannot be copied into each others data space. Smalltalk
implementations often have a level of indirection that allows it to
simply tweak an indirection table to implement this method.

The reason I find it terrifying is that I can be passed an object,
place it in a dictionary (for example) based on its value, and then
it can magically be changed into something else which does not fit
in that spot in the dictionary.

--Scott David Daniels
Sc***********@Acm.Org
Jul 19 '05 #115
"Shai" <sh**@platonix.com> writes:
Joseph Garvin wrote:

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?
1. Lisp's "dynamically scoped" variables (Perl has them, and calls them
"local", but as far as I've seen their use their is discouraged). These
are global variables which are given time-local bindings. That is,
structuring the syntax after what's used for globals,


Perl started life with nothing but dynamically scoped variables. They
added lexical scoping after they realized what a crock dynamic scoping
was.
x=10
def foo():
# No need to define x as it is only read -- same as globals
print x

def bar():
dynamic x
x = 11
foo()

def baz():
bar() # prints 11
foo() # prints 10; the binding in bar is undone when bar exits

This feature makes using "globals" sensible, providing a way to avoid
many important uses (and some say, misuses) of objects if you are so
inclined. It allows you to do some things better than objects do,
because it does to library parameters, what exceptions do to return
codes: instead of passing them in all the way from outside until a
piece of code which actually uses them, they are only mentioned where
you set them and where you really need to access them.

It would not be too hard to implement a version of this (inefficiently)
in the existing language, if frame objects could carry a modifiable
dictionary.

I suppose it is not in Python because (most) Pythoners are not looking
(hard enough) for alternatives to OOP.


Last time I checked, dynamic binding variables were frowned on in LISP
systems as well. Scheme doesn't have them. Common LISP requires
special forms to use them.

The problem with the given use case is that it lets every routine in
the call chain substitute it's own variable for the library parameter
you want to use, with no local indication that this is going
on. This makes bugs in dynamically scoped variables a PITA to find.

Given that it's a feature I don't want programmers using, I'd only be
willing to see it added to the language if you can show that it has no
overhead so long as you don't use it. I'm not sure that can be done.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 19 '05 #116
My personal favorite would be ruby's iterators and blocks.
Instead of writing a bunch of repetitive list comprehensions or
defining a bunch of utility functions, you just use the iterators
supported by container objects.
For instance,

[f(x) for x in y]

could be written in Ruby as

y.collect |x| do
#body of f
end

You don't have to use a lambda or define f() externally.
Best of all, Ruby's containers come with many iterators for common
cases builtin.

Joseph Garvin wrote:
As someone who learned C first, when I came to Python everytime I read
about a new feature it was like, "Whoa! I can do that?!" Slicing, dir(),
getattr/setattr, the % operator, all of this was very different from C.

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?

Here's my current candidate:

So the other day I was looking at the language Lua. In Lua, you make a
line a comment with two dashes:

-- hey, this is a comment.

And you can do block comments with --[[ and ---]].

--[[
hey
this
is
a
big
comment
--]]

This syntax lets you do a nifty trick, where you can add or subtract a
third dash to change whether or not code runs:

--This code won't run because it's in a comment block
--[[
print(10)
--]]

--This code will, because the first two dashes make the rest a comment,
breaking the block
---[[
print(10)
--]]

So you can change whether or not code is commented out just by adding a
dash. This is much nicer than in C or Python having to get rid of """ or
/* and */. Of course, the IDE can compensate. But it's still neat :)


Jul 19 '05 #117
[Lots of quoted text left in...]

I started thinking about this, and realized that there was a way to do
what you wanted, with no execution time overhead, and without
providing ways to radically change the program behavior behind the
scenes.

Mike Meyer <mw*@mired.org> writes:
"Shai" <sh**@platonix.com> writes:
Joseph Garvin wrote:

I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?
1. Lisp's "dynamically scoped" variables (Perl has them, and calls them
"local", but as far as I've seen their use their is discouraged). These
are global variables which are given time-local bindings. That is,
structuring the syntax after what's used for globals,


Perl started life with nothing but dynamically scoped variables. They
added lexical scoping after they realized what a crock dynamic scoping
was.


That's a bit harsher than I intended. I mean that having nothing but
dynamically scoped variables - like early Perl and LISP - is a
crock. I'll add that dynamic scoping as the default is a crock. But
you aren't asking for those.
x=10
def foo():
# No need to define x as it is only read -- same as globals
print x

def bar():
dynamic x
x = 11
foo()

def baz():
bar() # prints 11
foo() # prints 10; the binding in bar is undone when bar exits


Here's the problem with that. Consider this script:

import foo
x = 10
def bar():
print x

foo.foogle(bar)

If foo.foogle includes "dynamic x" and then invokes bar, bar could
print anything. This makes the behavior of bar unpredictable by
examining the sourc, with no hint that that is going on.
Given that it's a feature I don't want programmers using, I'd only be
willing to see it added to the language if you can show that it has no
overhead so long as you don't use it. I'm not sure that can be done.


Here's a proposal for dynamically bound variables that you should be
able to implement without affecting the runtime behavior of code that
doesn't use it.

Instead of dynamic meaning "all references to the named variable(s)
will be dynamic until this function exits", have it mean "the named
variable(s) will be dynamic in this function." Whether it should only
check local variables in the calling routines, check local + global,
or check for all free variables, is an open question.

I.e. - your example would be written:

x = 10
def foo():
dynamic x
print x

def bar():
x = 11
foo()

def baz():
bar() # prints 11
foo() # Possibly an error?

For my example above, bar would *always* print 10. Nothing that
foo.foogle did would change that. However, you could write:

import foo
def bar():
dynamic x
print x

foo.foogle(bar)

In this case, bar will print whatever foo.foogle sets x to - and it's
noted in the source to bar. This means that functions that don't
declare a dynamic variable can be compiled to the same code they are
compiled to now.

Would this version provide the functionality you wanted?

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 19 '05 #118
I like C++ templates so that you can ensure that a list only contain
items of one type. I also like the JMP instruction in x86 assembler,
you could do some nasty tricks with that.

--
mvh Björn
Jul 19 '05 #119

"Devan L" <de****@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
With the exception of reduce(lambda x,y:x*y, sequence), reduce can be
replaced with sum, and Guido wants to add a product function.


The update function is not at all limited to sums and products, but can be
any callable with the appropriate signature. The new any() and all()
functions are examples that use other updates.

Terry J. Reedy

Jul 19 '05 #120
Scott David Daniels <Sc***********@Acm.Org> writes:
Rocco Moretti wrote:
Joseph Garvin wrote:

I'm not aware of a language that allows it, but recently I've found
myself wanting the ability to transparently replace objects....
I mainly look for it in the "object replaces self" form, but I guess
you could also have it for arbitrary objects, e.g. to wrap a logging
object around a function, even if you don't have access to all
references of that function.
Why isn't it in Python? It's completely counter to the conventional
object semantics.


Actually this is the old (and terrifying) Smalltalk message 'becomes:'.
There is a concrete reason it is not in python: objects are represented
as pointers to their data structures, do not have identical sizes, and
therefore cannot be copied into each others data space.


That limitation applies only some of the time, e.g. when you inherit
from built-in types. But for ordinary classes it can be done:
class A(object): .... def __init__(self, x):
.... self.x = x
.... class B(object): .... def __init__(self, y):
.... self.y = y
.... a = A(1)
b = B(2)
vars(a) {'x': 1} vars(b) {'y': 2} a.__class__, b.__class__ = b.__class__, a.__class__
a.__dict__, b.__dict__ = b.__dict__, a.__dict__
vars(a) {'y': 2} isinstance(a, B)

True
Bernhard

--
Intevation GmbH http://intevation.de/
Skencil http://skencil.org/
Thuban http://thuban.intevation.org/
Jul 19 '05 #121
On Fri, 01 Jul 2005 12:24:44 -0700, Devan L wrote:
With the exception of reduce(lambda x,y:x*y, sequence), reduce can be
replaced with sum, and Guido wants to add a product function.


How do you replace:

reduce(lambda x,y: x*y-1/y, sequence)

with sum?
Inquiring minds want to know.
--
Steven.

Jul 19 '05 #122
Steven D'Aprano wrote:
On Fri, 01 Jul 2005 12:24:44 -0700, Devan L wrote:

With the exception of reduce(lambda x,y:x*y, sequence), reduce can be
replaced with sum, and Guido wants to add a product function.

How do you replace:

reduce(lambda x,y: x*y-1/y, sequence)

with sum?


You don't, but an almost equally short replacement works just as well,
and doesn't even need the lambda:
sequence=range(1,100)
_res = 0.0
for x in sequence: _res = _res*x + 1/x
<blank line if in interactive mode>
_res 9.3326215443944096e+155

Sure, this isn't a sum, but I'd argue that the for loop solution is
superior:

1) For single expressions, the guts of the operation is still a single line
2) This completely avoids lambda -- while I myself am ambivalent about
the idea of lambda going away, lambda syntax can get hairy for
complicated expressions -- the comma changes meaning halfway through the
expression, from 'parameter delimiter in lambda' to 'next parameter in
reduce'
3) This trivially extends to a block of code, which a lambda doesn't
4) Behavior for zero- and one-length lists is explicit and obvious.

There are, of course, a few disadvantages, but I think they're more
corner corner cases.
1) This solution obviously isn't itself an expression (although the
result is a single variable), so it can't be used in totality as a
component to a larger call.
[Rebuttal: When exactly would this be a good thing, anyway? Reduce
statements are at least 11 characters long, 13 with a one-character
default value. Using this as a parameter to just about anything else,
even a function call, seems a bit unreadable to me.]
2) An explicit intermediate/result value is needed. This seems to be
more of a 'cleanliness' argument than anything.

Besides, rewriting this as a for loop actually improves performance: sequence = range(1,100)
def f1(): j = 0.0
for x in sequence: j = j*x+1/x
return j
def f2(): return reduce(lambda x,y: x*y - 1/y, sequence) def runtime(f,n): starttime = time.time()
for i in xrange(n):
f()
print time.time()-starttime runtime(f1,10000) 1.37199997902 runtime(f2,10000) 3.67499995232

Making the series bigger results in even worse relative performance (no
idea why): sequence = range(1,1000)
runtime(f1,10000) 18.4169998169 runtime(f2,10000)

125.491000175

So really, 'reduce' is already useless for large anonymous blocks of
code (which can't be defined in lambdas), and it seems slower than 'for
... in' for even simple expressions.
Jul 19 '05 #123
sum(sequence[0] + [1/element for element in sequence[1:]])

I think that should work.

Jul 19 '05 #124
Devan L wrote:
sum(sequence[0] + [1/element for element in sequence[1:]])

I think that should work.


That won't work, because it misses the x*y part of the expression
(x[n]*x[n+1] + 1/x[n+1], for people who haven't immediately read the
grandparent).

Personally, I think demanding that it be writable as a sum (or product,
or any, or all) is a false standard -- nobody's claimed that these would
replace all cases of reduce, just the most common ones.
Jul 19 '05 #125
Okay, maybe that was too restrictive, reduce can *usually* be replaced
with sum. Sorry about that.

Jul 21 '05 #126

(sorry, my NUA had lost the original article)
I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


Ability to tag some methods 'deprecated' as in Java (from 1.5
onwards?). However, Python interpreter doesn't have to do it: pydoc and
similar tools could detect, say, '@deprecated' in method comment string and
warn user about it.

Currently I just document deprecated methods, and if I feel like it, I also
add

def some_method_which_is_badly_named_or_just_plain_wro ng(..)
"""docstring

This method is now deprecated. Use frob() instead.
"""

sys.stderr.write('warning: method some_method_which_is_badly_named_or_just_plain_wro ng is now deprecated')
--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!
You shouldn't verb verbs.
Jul 21 '05 #127
Edvard Majakari <ed*********@majakari.net> writes:
(sorry, my NUA had lost the original article)
I'm curious -- what is everyone's favorite trick from a non-python
language? And -- why isn't it in Python?


Ability to tag some methods 'deprecated' as in Java (from 1.5
onwards?). However, Python interpreter doesn't have to do it: pydoc and
similar tools could detect, say, '@deprecated' in method comment string and
warn user about it.


I don't see what's wrong with this code, and if one wanted, one could
also implement a decorator which calls warnings.warn when the function
is called:

def c_buffer(init, size=None):
"deprecated, use create_string_buffer instead"
import warnings
warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
DeprecationWarning, stacklevel=2)
return create_string_buffer(init, size)

Thomas
Jul 21 '05 #128
Thomas Heller <th*****@python.net> writes:
I don't see what's wrong with this code, and if one wanted, one could
also implement a decorator which calls warnings.warn when the function
is called:

def c_buffer(init, size=None):
"deprecated, use create_string_buffer instead"
import warnings
warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
DeprecationWarning, stacklevel=2)
return create_string_buffer(init, size)


Well, nothing's wrong there, and the same could be done with Java
before. However, having a consistent deprecated string everywhere allows
easier eg. automatic finding of such methods from documentation.

Decorators also help here, but that requires version 2.3 or newer (which
usually isn't a problem, but can be)

Hey! I hadn't realized category parameter nor stacklevel in warnings module
(just used a few times, never read the doc because I didn't need to). Neat,
thanks.

--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!

$_ = '456476617264204d616a616b6172692c20612043687269737 469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";
Jul 21 '05 #129
On 7/6/05, Edvard Majakari <ed*********@majakari.net> wrote:
Ability to tag some methods 'deprecated' as in Java (from 1.5
onwards?). However, Python interpreter doesn't have to do it: pydoc and
similar tools could detect, say, '@deprecated' in method comment string and
warn user about it.


http://wiki.python.org/moin/PythonDe...8cc6feb022e7bb

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Jul 21 '05 #130
I only saw this today... sorry about the late response. Anyway,
replying to your two messages at once:

Mike Meyer wrote:
Last time I checked, dynamic binding variables were frowned on in LISP
systems as well. Scheme doesn't have them. Common LISP requires
special forms to use them.
They're called "Special vars", and you need to define them (unlike
local LISP variables, which behave essentially like Python vars), but
then you use them just like other vars (that is, you usually bind them
with LET). This is the first I hear about them being ill-considered in
LISP; http://www.gigamonkeys.com/book/ is a recently published LISP
book which recommends them. I don't know about Scheme, but I think it
does have them.

The one "special" thing you see in every use of these vars in LISP is a
naming convention; as LISP symbols can contain most characters, they
are usually named with asterisks on both ends to distinguish them.
Thus, in the example above, the dynamic var would be named "*x*".
The problem with the given use case is that it lets every routine in
the call chain substitute it's own variable for the library parameter
you want to use, with no local indication that this is going
on. This makes bugs in dynamically scoped variables a PITA to find.
In LISP, the naming convention indeed takes care of that; and indeed, I
consider taking the LISP way would be better. The definition of x as
dynamic would then be not in bar nor its callers, but in the definition
of x, as in

dynamic x=10
def bar():
print x

I specified the syntax as I did, specifically to make it match the
current definition of globals, which "enjoys" the same problems you
noted with my dynamics.
x=10
def foo():
# No need to define x as it is only read -- same as globals
print x

def bar():
dynamic x
x = 11
foo()

def baz():
bar() # prints 11
foo() # prints 10; the binding in bar is undone when bar exits
Here's the problem with that. Consider this script:

import foo
x = 10
def bar():
print x

foo.foogle(bar)

If foo.foogle includes "dynamic x" and then invokes bar, bar could
print anything. This makes the behavior of bar unpredictable by
examining the sourc, with no hint that that is going on.
While I didn't write it explicitly, if both LISP and Python globals are
to be followed, the dynamic x should somehow be defined in the scope of
its module. On second thought, this means "dynamic" _must_ be added in
the variable definition, for foo.foogle will simply access it as
"othermodule.x", which doesn't differentiate globals from dynamics.

Either way, Python as it is now allows foo.foogle to change x even
without dynamic variables; it is accessible as barmodule.x. bar()
should expect to have other functions mess with its globals, and
dynamics are no different.
Given that it's a feature I don't want programmers using, I'd only be
willing to see it added to the language if you can show that it has no
overhead so long as you don't use it. I'm not sure that can be done.

That sounds like a fine requirement. Now, with my corrected
proposition, it would be implementable at the module-object level, so
that only module which use the feature, and modules which use them,
would be affected.
Here's a proposal for dynamically bound variables that you should be
able to implement without affecting the runtime behavior of code that
doesn't use it.

Instead of dynamic meaning "all references to the named variable(s)
will be dynamic until this function exits", have it mean "the named
variable(s) will be dynamic in this function." Whether it should only
check local variables in the calling routines, check local + global,
or check for all free variables, is an open question.

I.e. - your example would be written:

x = 10
def foo():
dynamic x
print x

def bar():
x = 11
foo()

def baz():
bar() # prints 11
foo() # Possibly an error?

This introduces the same problem you noted with my original proposal,
but in reverse: Now, in bar(), you define and use a local variable, and
suddenly some library function changes its behavior misteriously.
For my example above, bar would *always* print 10. Nothing that
foo.foogle did would change that. However, you could write:

import foo
def bar():
dynamic x
print x

foo.foogle(bar)

In this case, bar will print whatever foo.foogle sets x to - and it's
noted in the source to bar. This means that functions that don't
declare a dynamic variable can be compiled to the same code they are
compiled to now.


This is, I believe, disproved by my comment above.

Thanks for your time and effort,

Shai.

Jul 21 '05 #131
"Shai" <sh**@platonix.com> writes:
They're called "Special vars", and you need to define them (unlike
local LISP variables, which behave essentially like Python vars), but
then you use them just like other vars (that is, you usually bind them
with LET). This is the first I hear about them being ill-considered in
LISP; http://www.gigamonkeys.com/book/ is a recently published LISP
book which recommends them. I don't know about Scheme, but I think it
does have them.
I'm pretty sure scheme doesn't have dynamically bound variables. I
just went through r5rs to check, and couldn't find them.
dynamic x=10
def bar():
print x

I specified the syntax as I did, specifically to make it match the
current definition of globals, which "enjoys" the same problems you
noted with my dynamics.
This looks different from what I understood before. You're now
declaring the variable dynamic in the global scope, rather than in the
function that makes it dynamic. This is a *much* more palatable
situation.

Globals are lexically scoped. As such, you can find the defintion of
the variable by examining the module that includes the function. Yes,
other modules can reach into your module and change them - but you can
find those, because they reference your module by name.

A dynamic variable declared so in a function has no such clue
associated with it. If the variable is declared dynamic in the module
of the enclosed function, that provides a contextual clue.

Of course, you can do pretty much anything you want if you're willing
to grovel over the guts of the environment enough, but some things
shouldn't be easy.
While I didn't write it explicitly, if both LISP and Python globals are
to be followed, the dynamic x should somehow be defined in the scope of
its module. On second thought, this means "dynamic" _must_ be added in
the variable definition, for foo.foogle will simply access it as
"othermodule.x", which doesn't differentiate globals from dynamics.

Either way, Python as it is now allows foo.foogle to change x even
without dynamic variables; it is accessible as barmodule.x. bar()
should expect to have other functions mess with its globals, and
dynamics are no different.


The question is, how hard is it to find the other people who are
messing with bar()'s globals? Normal usage with the current situation
makes it fairly starightforward. How does adding dynamicly bound
variables change this?

Of course, if you add the requirement that the variable be tagged in
the scope of the module, you're making things a lot better. That way,
readers of the module know that they need to look back along the call
chain for functions that use such variables. That makes them much
saner to find.
Instead of dynamic meaning "all references to the named variable(s)
will be dynamic until this function exits", have it mean "the named
variable(s) will be dynamic in this function." Whether it should only
check local variables in the calling routines, check local + global,
or check for all free variables, is an open question.

I.e. - your example would be written:

x = 10
def foo():
dynamic x
print x

def bar():
x = 11
foo()

def baz():
bar() # prints 11
foo() # Possibly an error?


This introduces the same problem you noted with my original proposal,
but in reverse: Now, in bar(), you define and use a local variable, and
suddenly some library function changes its behavior misteriously.


True. That pretty much kills my proposal.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jul 21 '05 #132
Simon Brunning <si************@gmail.com> writes:
http://wiki.python.org/moin/PythonDe...8cc6feb022e7bb


Neat.

I guess about 75% about programming-related things classified as neat-o or
"convenient!" are already implemented by some Pythonista(s). Spoils all the
fun for reinventing the wheel, doesn't it. :)

--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!

$_ = '456476617264204d616a616b6172692c20612043687269737 469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";
Jul 21 '05 #133
Mike Meyer wrote:
"Shai" <sh**@platonix.com> writes:
They're called "Special vars", and you need to define them (unlike
local LISP variables, which behave essentially like Python vars), but
then you use them just like other vars (that is, you usually bind them
with LET). This is the first I hear about them being ill-considered in
LISP; http://www.gigamonkeys.com/book/ is a recently published LISP
book which recommends them. I don't know about Scheme, but I think it
does have them.
I'm pretty sure scheme doesn't have dynamically bound variables. I
just went through r5rs to check, and couldn't find them.


Yes, you're right. One learns.
dynamic x=10
def bar():
print x


This looks different from what I understood before. You're now
declaring the variable dynamic in the global scope, rather than in the
function that makes it dynamic. This is a *much* more palatable
situation.


This is indeed different from what I said first. It copies the Common
LISP construct without regard to consistency with the Python global
construct.
Globals are lexically scoped. As such, you can find the defintion of
the variable by examining the module that includes the function. Yes,
other modules can reach into your module and change them - but you can
find those, because they reference your module by name.

A dynamic variable declared so in a function has no such clue
associated with it. If the variable is declared dynamic in the module
of the enclosed function, that provides a contextual clue.


In my original proposal, dynamic variables are seen as globals from the
function in their module which reads them; no more, no less. The
important point I want from dynamic scope is the time-locality of
asignments, that
is, the fact that they are undone when the (lexical) scope of the new
binding ends. This allows the use of globals, with a lot less fear of
unintended interactions between users of the module (well, this is only
accurate until multithreading enters the picture, but that can be
handled
too).

[rest snipped]

Jul 21 '05 #134
Edvard Majakari wrote:
Simon Brunning <si************@gmail.com> writes:
http://wiki.python.org/moin/PythonDe...8cc6feb022e7bb


Neat.

I guess about 75% about programming-related things classified as neat-o or
"convenient!" are already implemented by some Pythonista(s). Spoils all the
fun for reinventing the wheel, doesn't it. :)


Doesn't seem to stop most Pythonistas from trying, though. :-)

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Jul 21 '05 #135

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Randy Given | last post by:
What is your favorite Java development environment? What others have you tried? What are some pros and cons of each? Thanks!
0
by: Vic Cekvenich | last post by:
Here is my favorite tag: http://displaytag.sf.net and see examples (in upper right). Grid, Sorting, nested, group, export, everything you like, plus it's free. Here is example code of how I used...
2
by: Matthew Louden | last post by:
I want to make a link that allows users to add my web site to the favorite in IE. Anyone knows how to do that?
9
by: Scott McNair | last post by:
What's your favorite bit of "short-cut" code that you use? One of my favorite shortcuts I'll use when coding a page is to create a sub along the lines of the following: Sub Print(myText)...
1
by: edunetgen | last post by:
I have a Web Aplication. I want an own image when an user adds me to favorite. Thanks, Edu
2
by: zhaoyandong | last post by:
One of my interviewers ask me "Two favorite features of C++, and over-rated, and misued features" Could anybody give me some advice on this? Thanks
2
by: Les | last post by:
In ancient times I had a desire to make a game and I started to do so, I quickly found the project was beyond the hardware's capability for that era (even in assembler) and had to shelf the...
3
by: Jensen bredal | last post by:
Hello, I need to offer the visitors of my siste to add it to the favorite list but only when it is ot there. the code below: window.external.AddFavorite(location.href, document.title) add...
1
by: clintonG | last post by:
Want to give up your most treasured posession? Post the URL for your favorite RegEx library you've found most useful for validating form input. <%= Clinton Gallagher METROmilwaukee (sm) "A...
4
by: fiversen | last post by:
Hello, I have a site for the collegue with a football winning game. ...fussball.html there I redirect the user to an cgi-page ../f11.cgi
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.