Re: CLPython (was Re: merits of Lisp vs Python)
Paul Rubin wrote: > I thought it was of some interest though I'm a little surprise by the > choice of CL rather than Scheme as a target. In many aspects Python is a subset of CL. In CLPython, exceptions are Lisp conditions with a custom metaclass (strictly spoken not portable CL), Python (meta)classes are CLOS classes, methods are implemented using hashtables and functions and CLOS generic functions, strings and numbers have direct equivalents, hash tables implement dicts, Python functions are funcallable CLOS instances, tuples and lists are Lisp lists and vectors, generators are closures. Thus a great part of implementing CLPython consisted of connecting already existing dots. I found that quite amazing. > I'm still not sure about the mapping of Python strings to Lisp strings. > What happens with the following in CLPython? > > a = 'hello' > a[0] = 'H' # attempt to change first letter to upper case As CLPython mirrors Python semantics, this results in a TypeError. The internal representation of an immutable Python string is a mutable Lisp string, but there is no way you can actually modify it from within CLPython. Now in some cases modifying strings is dangerous (e.g. when stored in an instance dict to represent an attribute), but in other cases it can be completely safe. And modifying strings is a normal Lisp feature, so it sounds strange to disallow it at all times. Maybe there should be a way for the user to declare that he knows what he is doing, and does not want the Python implementation to be "crippled" w.r.t. the host language. Normally you start the CLPython interpreter using (repl); maybe something like this would allow dangerous statements: (let ((*strict-python-semantics* nil)) (repl)) Oh, and there is actually one way to modify Python strings in the interpreter, namely using Lisp commands: PYTHON(12): (repl) [CLPython -- type `:q' to quit, `:help' for help] >>> s = "abc" 'abc' >>> (setf (aref _ 0) #\x) #\x >>> s 'xbc' >>> type(s) # >>> type(s) == str 1 >>> s 'xbc' >>> (inspect _) A NEW simple-string (3) "xbc" @ #x11548f6a 0-> The character #\x [#x0078] 1-> The character #\b [#x0062] 2-> The character #\c [#x0063] [1i] PYTHON(13): :ptl >>> -- http://mail.python.org/mailman/listinfo/python-list
Re: CLPython (was Re: merits of Lisp vs Python)
Paul Rubin wrote: > [EMAIL PROTECTED] writes: > > > a = 'hello' > > > a[0] = 'H' # attempt to change first letter to upper case > > > > As CLPython mirrors Python semantics, this results in a TypeError. The > > internal representation of an immutable Python string is a mutable Lisp > > string, but there is no way you can actually modify it from within CLPython. > > How do you manage that? The compiler can't check. Is there some kind > of special dispatch on the assignment statement instead of turning it > into a setf? Indeed, the assignment of subitems is dynamically dispatched, and always goes via __setitem__ methods, as specified in the language. The __setitem__ methods for strings and tuples raise exceptions. The ones for lists and vectors could be translated into a simple (setf (aref ..) ..) and (setf (nth ..) ..), unless the index is actually a slice and actually a subsequence must be replaced. Now, the above description using __setitem__ methods is how it apparently works, as observed from the outside. Internally there is a generic function (setf py-subs) that does the work itself, skipping the lookup and calling of __setitem__, if the object is a vector or dict. (The user can call x.__setitem__ explicitly, so that method must exist internally.) Maybe you were thinking that CLPython, given Python code, outputs a big pile of self-contained equivalent Lisp code that can be run independently, and then CLPython is finished. Instead, only a small amount of Lisp code is generated, but that code can only be run when the CLPython environment is loaded. The generated code refers to that environment, e.g. s[0] = 'x' is translated into a call to (setf (py-subs ..) ..), and function (setf py-subs) is part of the CLPython environment that must be loaded at run-time. If you compile a Python function, the result is a (mostly) normal Lisp function - its origin from the Python world does not really matter. Also, all Python data structures are first-class Lisp data. Thus CLPython objects live happily together with "normal" Lisp objects in the same image. And now we arrive at the most exciting part: other Lisp libraries can be loaded in the same image, and we can create connections. Like, after loading CLIM and defining how CLPython objects should be presented, we should get a Python interpreter where classes are displayed graphically and where you can inspect and modify them by mouse. Imagine that you have interactively added a method to a class by dragging a function to a class, then being able to right-click and select "write method", which will write the definition of the method in the right place in the class definition source code in your Climacs (CLIM-based Emacs) buffer. That's the kind of features I have in mind, and the best thing is that conceptually a lot of the work consists of connecting dots that already out there. But as there are so many of them, a few extra pencils would be quite welcome - Willem -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested For and While Statements
On Sep 24, 10:10 pm, Zentrader <[EMAIL PROTECTED]> wrote: > > Your for loops both use the same counting index. > > Since those variables are local to the for loop, No, "for" loops don't introduce a scope. The one variable named "j" is shared. > for j in range( 10 ): > print j, "first loop" > for j in range( 5 ): > print " ", j, "2nd loop" The reason it does work as hoped, is that the generators, including those created by the call to "range", keep internal state to know the next value to yield. The existence or current value of iteration variables like "j" is completely irrelevant. Here, the first the call to "range" creates a generator, and binds j to the first value yielded, which is 0. Then the second range- generator is created, iterated over using the same variable. Then the first generator is asked for its second value (= 1), and j is bound to that regardless its current value. - Willem -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested For and While Statements
On Sep 25, 7:07 pm, Zentrader <[EMAIL PROTECTED]> wrote: > Note that in list comprehension, [x for x in (1, 2, 3)], the > for loop allocates memory the same way, but the scope changes so that > "x" is visible outside the for loop, How is this different? The variable spilling of list comprehension is the same as for regular for loops. The (#) and (##) lines below don't print the same value of j. >>> for j in range(3): ... print j, "first loop" (#) ... for j in range(3): ... print " ", j, "2nd loop" ... print j, "first loop, again?" (##) - Willem -- http://mail.python.org/mailman/listinfo/python-list