--==========1605285482========== Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: quoted-printable Content-Disposition: inline --On Saturday, February 01, 2003 15:02:51 -0500 Guido van Rossum=20 <guido@python.org> wrote: > Many users have only a vague notion of the difference between a > syntactic construct and a function (witness repeated suggestions here > and elsewhere that confuse these matters), yet nobody has a problem > with understanding the difference in scope rules between 'def' and > 'if' statements, for example. So I hope that learning that some > functions treat a thunk's scope different than others is no huge > burden. I think it's not a burden, and in fact the ability to make such things=20 would be very useful. I've come up with a few examples below. > In some Lisps, I believe a function can determine whether its > arguments are evaluated before the call (=3D=3D normal Python semantics) > or whether they are somehow (I don't know the details!) passed to the > function as parse trees so the function can evaluate them at will. > This does not seem to confuse Lisp users. Or does it? I honestly > don't know if this is popular or considered a wart. It's fundamental. Lisp syntax is almost exactly a representation of the=20 parser output; lisps basically don't have a parser, up to syntactic sugar.=20 So a macro definition can specify in its definition which arguments are=20 passed evaluated or unevaluated (in some lisps, this is done by explicity=20 evaluating the appropriate arguments; elisp is one such). The difference=20 between macros and functions comes down to if arguments are evaluated or=20 not. Lots of ordinary, standard lisp idiom is implemented this way, even such=20 things as 'let', which is the local variable binder and even sometimes=20 'defun', which is the function definer. For example, in xemacs elisp syntax for simplicity, meaning all macro=20 arguments are passed unevaluated, defun is approximately defined as (up to=20 the docstring handling): (defmacro defun (name arglist &optional docstring &rest body) (quote (setf name (function (lambda arglist . body)))) ; return code to set the docstring here ) which has an effect essentially identical to python's 'def' keyword. The=20 return value of the macro (and what is actually compiled) is (setf name (function (lambda arglist . body))) (substituting the passed in arguments) which when executed binds name to=20 the compiled version of the lambda. So if we then do: (defun inc (a) (add 1 a)) it compiles as if it were: (setf 'inc (function (lambda (a) . ((add 1 a)))))) For a really huge demonstration of what lisp macros can do, see advice.el=20 from an emacs distribution. It's a good example because it's extremely=20 well commented, and some of the comments show the downsides of macros as=20 well. > I do worry that if my thunks are to be maximally useful, they may end > up having all variables bound through "cells" (as used for nested > scopes) which may give them a reputation of being slow compared to > in-line code, which would limit their popularity for control flow > statements like synchronized(). > > --Guido van Rossum (home page: http://www.python.org/~guido/) Well, they could be treated like lisp macros, that is as source code (or,=20 potentially, parse tree) transformation functions, and compiled just like=20 any other code. This would probably be the simplest to implement, and=20 would allow such things to work with no slowdown at all. For example, presuming python had a defmacro that took all arguments=20 unevaluated and can return a block, that @block introduces a block=20 argument, and that interpolate(block) compiles the block instead of itself, = we could have: defmacro synchronized(lck, @block): return: lck.acquire() try: interpolate(block) finally: lck.release() synchronized(lock): # text of block here pass which compiles identically to: lck.acquire() try: # text of block here pass finally: lck.release() Then: defmacro property(name, docstring, @get, @set, @delete): def getter interpolate(get.arglist): interpolate(get.block) def setter interpolate(set.arglist): interpolate(set.block) def deleter interpolate(delete.arglist): interpolate(delete.block) return: name =3D property(docstring, getter, setter, deleter) class Circle(object): property circumference, """Circumference of the circle""": get (self): return self.radius*6.283 set (self, value): self.radius =3D value/6.283 delete (self): del self.radius would do the obvious thing using block keyword arguments (I can't think how = to express the anonymous scope implied here in regular Python; the=20 intention is that getter and friends are defined in the local namespace of=20 the macro invocation). Of course the proposed syntax is hypothetical, but I think it's quite = clean. Andrew --==========1605285482========== Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE+PEKNHamGxvX4LwIRAon5AJ9bWwgsr+kmbyThK9Fd2hlrMBzWlACgxMW/ WsHNN+4wPAoRgM52G/ctD70= =KiOp -----END PGP SIGNATURE----- --==========1605285482==========--
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4