Групи новин: comp.lang.lisp
Від: "Piotr Kuchta" <pi...@itam.zabrze.pl>
Дата: Fri, 6 Jul 2001 13:54:46 +0200
Місцевий час: Пт 6 Лип 2001 14:54
Тема: Recursive lambda
Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kalle Olavi Niemitalo <k...@iki.fi>
Дата: 06 Jul 2001 16:17:46 +0300
Місцевий час: Пт 6 Лип 2001 16:17
Тема: Re: Recursive lambda
"Piotr Kuchta" <pi...@itam.zabrze.pl> writes: You could give the function to itself as a parameter. > Just curious: is it possible for a lambda (unnamed) function to call itself? Although then it isn't really unnamed any more... (let ((unnamed (lambda (me obj) I'm not aware of a syntax for getting the innermost enclosing function. Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Ingvar Mattsson <ing...@bofh.se>
Дата: 06 Jul 2001 14:43:36 +0100
Місцевий час: Пт 6 Лип 2001 16:43
Тема: Re: Recursive lambda
Kalle Olavi Niemitalo <k...@iki.fi> writes:
Or use Ugly Macros. I have (once or twice) used something along the lines of: (defmacro fakelambda (args &body body) `(lambda ,args (labels ((me ,args ,@body)) (me ,@args)))) This lets you get to call "the unnamed lambda" as ME within its body. //Ingvar Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kalle Olavi Niemitalo <k...@iki.fi>
Дата: 06 Jul 2001 17:53:46 +0300
Місцевий час: Пт 6 Лип 2001 17:53
Тема: Re: Recursive lambda
Ingvar Mattsson <ing...@bofh.se> writes: This can't handle lambda list keywords. A simple workaround would be: > (defmacro fakelambda (args &body body) > `(lambda ,args (labels ((me ,args ,@body)) (me ,@args)))) (defmacro fakelambda (lambda-list &body body) but then the returned function can't be usefully inspected. I wonder (defmacro fakelambda (lambda-list &body body) Functions made with LABELS have indefinite extent, right? :-) Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kent M Pitman <pit...@world.std.com>
Дата: Fri, 6 Jul 2001 16:21:21 GMT
Місцевий час: Пт 6 Лип 2001 19:21
Тема: Re: Recursive lambda
Kalle Olavi Niemitalo <k...@iki.fi> writes:
There is none. It's not really very well-defined. It would defeat the ability of other macros surrounding any given form to insert additional layers of function-boundary for dataflow purposes. Consider the problem of introducing extra unnamed blocks around something. RETURN returns to the innermost block NIL, but we had to add BLOCK and RETURN-FROM in order to have a transparent way to add extra blocks around a form without interfering with people's expectations about where BLOCK boundaries would be. If we had the facility you're talking about, there would have to be named and unnamed versions of "enclosing functions" in order to not violate referential transparency. Anyway, it's not done. > I'd be surprised if there was one, as LET is almost a LAMBDA too. I'm not sure what that means or why it's relevant, but see below. > &WHOLE arguments spring to mind, but IIRC those are for macros only. Yes, &whole is of no help here. It would only point back to the source form, not to the resulting function. Forms are not callable. A lambda expression evaluates to a function, it is not itself a function. The implementation in most Scheme implementations is the same as how (defmacro letrec (bindings &body forms) The only difference is that in Common Lisp, because we have two namespaces, (letrec ((fact (lambda (x) Not that you couldn't put some syntactic sugar around that if (defmacro fletrec (bindings &body forms) (fletrec ((fact (lambda (x) Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kalle Olavi Niemitalo <k...@iki.fi>
Дата: 07 Jul 2001 16:08:55 +0300
Місцевий час: Сб 7 Лип 2001 16:08
Тема: Re: Recursive lambda
Kent M Pitman <pit...@world.std.com> writes:
> Kalle Olavi Niemitalo <k...@iki.fi> writes: I meant (LET ((VAR VAL)) BODY) = ((LAMBDA (VAR) BODY) VAL); > > I'd be surprised if there was one, as LET is almost a LAMBDA too. > I'm not sure what that means or why it's relevant, but see below. making LAMBDA also save the function for retrieval with ENCLOSING-FUNCTION (or whatever it would be called) would break the equivalence. > Yes, &whole is of no help here. It would only point back to the source You can COERCE the lambda expression to a function... but then > form, not to the resulting function. Forms are not callable. A lambda > expression evaluates to a function, it is not itself a function. you lose local bindings. Hm. Perhaps with &ENVIRONMENT and EVAL... except that's restricted to macros too. > (defmacro letrec (bindings &body forms) The indentation of ,@forms confused me for several minutes. > `(let ,(mapcar #'car bindings) > (setq ,@(mapcan #'copy-list bindings)) > ,@forms)) When you write macros in production code, do you make them Is there a function like MAPCAN that would use APPEND rather than Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kent M Pitman <pit...@world.std.com>
Дата: Sat, 7 Jul 2001 17:06:39 GMT
Місцевий час: Сб 7 Лип 2001 20:06
Тема: Re: Recursive lambda
Kalle Olavi Niemitalo <k...@iki.fi> writes:
> When you write macros in production code, do you make them Sometimes I check, sometimes not. The user is obliged, regardless, > strictly check the syntax of arguments and signal errors for > things like (LETREC ((VAR 'VAL EXTRA)))? Is DESTRUCTURING-BIND > good for that? not to put stuff there, so I consider it "helpful but optional" to do that checking. > Is there a function like MAPCAN that would use APPEND rather than There isn't any. > NCONC, so that COPY-LIST wouldn't be needed? > I didn't find such a thing in the HyperSpec. But there are about 117 other ways to win, so it's not like you're stuck. LOOP has an appending collection mechanism. And (reduce #'append lists) or (apply #'append lists) probably would have I said "mostly" above in one place because my version did copy the last Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kalle Olavi Niemitalo <k...@iki.fi>
Дата: 08 Jul 2001 04:15:38 +0300
Місцевий час: Нд 8 Лип 2001 04:15
Тема: Re: Recursive lambda
Kent M Pitman <pit...@world.std.com> writes:
> In spite of what you've perhaps been told, NCONC is not evil nor to be I was thinking that COPY-LIST scans each list, and MAPCAN must > avoided, nor are all cases of COPY-LIST wasteful. scan it again to find the end. The slowdown pales to the time spent compiling the result, but if there were an easy-to-use operator that did the same thing with only one scan, I'd rather use it. > LOOP has an appending collection mechanism. I see. It's a bit verbose to use, though. > And (reduce #'append lists) or (apply #'append lists) probably would have The first one needs :FROM-END T to avoid quadratic complexity. > done it. Unfortunately, CMUCL 2.5.1 implements that by reversing the list first, and consing is even worse than scanning. Does any implementation behave otherwise? I don't see any obvious algorithm. The second one is bounded by CALL-ARGUMENTS-LIMIT. (Is there any Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kent M Pitman <pit...@world.std.com>
Дата: Sun, 8 Jul 2001 16:20:07 GMT
Місцевий час: Нд 8 Лип 2001 19:20
Тема: Re: Recursive lambda
Kalle Olavi Niemitalo <k...@iki.fi> writes:
> Kent M Pitman <pit...@world.std.com> writes: This doesn't add materially to the algorithmic complexity of the operation. > > In spite of what you've perhaps been told, NCONC is not evil nor to be > I was thinking that COPY-LIST scans each list, and MAPCAN must An O(n) operation plus another O(n) operation is still O(n). It's true that it adds a tiny amount of extra work in the rescan, but > The slowdown pales to the time You could make one. But the number of times you'd use it in your lifetime > spent compiling the result, but if there were an easy-to-use > operator that did the same thing with only one scan, I'd rather > use it. might not add up to the time it takes you to write it. Seriously, the time to do optimizations of this nitpicking level (that is, operations that don't improve the algorithmic complexity of code, but merely change tiny constant factors in code that is hardly ever called) is when you have a product delivered or about to be delivered and you think it's going to be unsuitable for some customer if its speed is not enough. Programmers waste too much of their lives optimizing things that do not > > LOOP has an appending collection mechanism. Learn to live with it. > I see. It's a bit verbose to use, though. I am not kidding. Common Lisp is about doing things in practical ways. LOOP, for all If you really, really want to spend your whole life nitpicking about small (It's not like I myself never obsess on things that don't matter, mind you. > > And (reduce #'append lists) or (apply #'append lists) probably would have Right. But even so, I was assuming this set of lists would be quite small > > done it. > The first one needs :FROM-END T to avoid quadratic complexity. and so I just didn't worry a lot about that... APPLY is probably the cheapest in this case if you know the set of > Unfortunately, CMUCL 2.5.1 implements that by reversing the list Well, it's possible to stack-allocate such a reversed list, so the gc > first, and consing is even worse than scanning. Does any > implementation behave otherwise? I don't see any obvious > algorithm. issue can be made a non-issue. Also, one can use real recursion (stacks) to simulate the effect, again if you dont' mind pushing LOTS of stack. Most gc experts will tell you, though, that consing that is immediately dropped is gc'd quite efficiently by generational systems (which a lot of people use), so the cost of just heap-allocating the reversed list and discarding it isn't as great as you might think. And, btw, optimization is almost always a per-vendor activity. Each vendor Incidentally, even keyword calling (the :FROM-END T) can introduce extra > The second one is bounded by CALL-ARGUMENTS-LIMIT. (Is there any No. The compiler is supposed to split the LET if it needs to, though > such limit for the number of variables bound in a LET?) you might find implementations with bugs. I've certainly seen compilers with little notes in them saying "I'll fix this when someone first reports the bug". -- -- -- To be clear: * I think it's good for vendors to care about this kind of speed issue. * I think it's ok for users to care about this kind of speed issue * I think the rest of the time, users should mostly program as if Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||
Групи новин: comp.lang.lisp
Від: Kalle Olavi Niemitalo <k...@iki.fi>
Дата: 08 Jul 2001 23:40:41 +0300
Місцевий час: Нд 8 Лип 2001 23:40
Тема: Re: Recursive lambda
Kent M Pitman <pit...@world.std.com> writes:
> Kalle Olavi Niemitalo <k...@iki.fi> writes: Oh, I do use LOOP. In this situation however, I feel the > > Kent M Pitman <pit...@world.std.com> writes: > > I see. It's a bit verbose to use, though. > Learn to live with it. verbosity of LOOP outweighs the minimal speedup. Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
| ||||||||||||||