Веб Зображення Новини Групи Блоги Перекладач Gmail Ще »
Групи, які ви переглядали нещодавно | Довідка | Увійти
Головна сторінка Груп Google
Remembering information during compilation
Занадто багато тем, що мають бути показані першими. Для того, щоб показати тему першою, зніміть цю опцію з іншої теми.
Під час обробки вашого запиту сталася помилка. Будь ласка, повторіть вашу спробу пізніше.
флаг
  Повідомлення 1 - 25 з 43 - Згорнути всі  -  Перекласти все вказаною мовою: Перекладено (переглянути всі оригінали)   Новіші >
Група, до якої ви додаєте допис, - група Usenet. Відтак, будь-хто в Інтернеті бачитиме вашу електронну адресу.
Вашу відповідь не було надіслано.
Ваш допис надіслано
 
Від:
Кому:
Копія:
Продолжить:
Додати копію: | Додати продовження: | Редагувати тему
Тема:
Підтвердження:
З метою підтвердження введіть символи, наведені на зображенні нижче, або числа, які чуєте, натиснувши значок доступу. Прослухайте і введіть цифри, що чуєте
 
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 20:18
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Sat, 07 Nov 2009 18:18:19 GMT
Місцевий час: Сб 7 Лис 2009 20:18
Тема: Remembering information during compilation
I'm trying to construct a macro called memory. The syntax is
memory (&rest body) and doing  (memory form) should expand to

(SYMBOL-MACROLET ((CELL XXX))
   form)

where XXX should be replaced by the number of surrounding memory
invocations. So for example

(memory
  (format t "CELL has value ~a~%" cell)
  (memory  (format t "CELL has value ~a~%" cell))
  (format t "CELL has value ~a~%" cell))

should expand to

(SYMBOL-MACROLET ((CELL 1))
  (FORMAT T "CELL has value ~a~%" CELL)
  (SYMBOL-MACROLET ((CELL 2))
     (FORMAT T "CELL has value ~a~%" CELL))
  (FORMAT T "CELL has value ~a~%" CELL))

and produce
    CELL has value 1
    CELL has value 2
    CELL has value 1

Note how in the second invocation of memory, CELL is assigned the form
2 because it is inside 2 nested invocations of memory. No matter how
deeply nested (within reason) the invocations of memory are CELL should
get the correct value. Below are my efforts but they have not met with
success.

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         `(symbol-macrolet ((cell ,a))
             ,@body)
         (decf a))))

With the test I gave above it produces
    CELL has value 1
    CELL has value 1
    CELL has value 1

So the second invocation of memory in the test does not increase by 1
the value of CELL.

The second attempt wouldn't be completely satisfactory even if it
worked because it exposes to the outside world an internal part of the
implementation , the variable B. But it doesn't work.

(defparameter b 0)

(defmacro memory2 (&rest body)            
  (prog2
     (defparameter b (+ b 1))
     `(symbol-macrolet ((cell ,b))
         ,@body)
     (defparameter b (- b 1))))

Once again doing

(memory2
  (format t "CELL has value ~a~%" cell)
  (memory2  (format t "CELL has value ~a~%" cell))
  (format t "CELL has value ~a~%" cell))

produces
    CELL has value 1
    CELL has value 1
    CELL has value 1

I tried some variations of the above but no luck. So first why do my
attempts above not work ? I assume that by the time the code generated
from the macro expansion gets compiled the statement (decf a) has
already been executed. Am I right ?

It would be convenient if Lisp had some kind of minimal-compile
function so that you could do  (minimal-compile form)  and it would
return what results after minimal compilation of the form. With
such a thing one could define memory as

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         (minimal-compile
            `(symbol-macrolet ((cell ,a))
                ,@body))
         (decf a))))

Does anyone know an implementation with such a facility ? Any other
solutions to the problem ?

--
Shakespeare also predicted structured programming:
"Go to, go to, thou are a foolish fellow. Let me be clear of thee."
Twelfth Night, Act IV, Scene 1.

from http://www.iidb.org/vbb/showthread.php?p=3352214#post3352214


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal J. Bourguignon  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 20:41
Групи новин: comp.lang.lisp
Від: p...@informatimago.com (Pascal J. Bourguignon)
Дата: Sat, 07 Nov 2009 19:41:47 +0100
Місцевий час: Сб 7 Лис 2009 20:41
Тема: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> I'm trying to construct a macro called memory.

(defparameter *cell* 0)
(define-symbol-macro cell *cell*)
(defmacro memory (&rest body)
  `(let ((*cell* (1+ *cell*)))
     ,@body)))

C/USER[100]> (memory
              (format t "CELL has value ~a~%" cell)
              (memory  (format t "CELL has value ~a~%" cell))
              (format t "CELL has value ~a~%" cell))
CELL has value 1
CELL has value 2
CELL has value 1
NIL

--
__Pascal Bourguignon__


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Kaz Kylheku  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 20:44
Групи новин: comp.lang.lisp
Від: Kaz Kylheku <kkylh...@gmail.com>
Дата: Sat, 7 Nov 2009 18:44:28 +0000 (UTC)
Місцевий час: Сб 7 Лис 2009 20:44
Тема: Re: Remembering information during compilation
On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:

> It would be convenient if Lisp had some kind of minimal-compile
> function ...

Indeed, it would help a certain troll in another thread to have a fraction of a
valid point.

Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Kaz Kylheku  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 20:53
Групи новин: comp.lang.lisp
Від: Kaz Kylheku <kkylh...@gmail.com>
Дата: Sat, 7 Nov 2009 18:53:49 +0000 (UTC)
Місцевий час: Сб 7 Лис 2009 20:53
Тема: Re: Remembering information during compilation
On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:

Why does cell have to be a symbol macro? How about simply generating:

(let ((cell (1+ cell)) ...)

Take advantage of the LET scoping rule which allows you to shadow an outer
variable, but use its avlue to initialize the shadowing one.

You just need to bootstrap this somehow for the outermost invocation.  Here is
where a symbol macro comes in: a global one made with define-symbol-macro,
to avoid introducing cell as a dynamic variable.


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal Costanza  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 21:04
Групи новин: comp.lang.lisp
Від: Pascal Costanza <p...@p-cos.net>
Дата: Sat, 07 Nov 2009 20:04:32 +0100
Місцевий час: Сб 7 Лис 2009 21:04
Тема: Re: Remembering information during compilation

What do you want the following to evaluate to?

(setq f (memory
           (lambda ()
             (memory (print cell)))))

(funcall f)

If you want this to evaluate to 1, the other Pascal's solution is fine.

IF you want this to evaluate to 2, here is another solution:

(define-symbol-macro cell 0)

(defmacro memory (&body body &environment env)
   (let ((new-cell-value (1+ (macroexpand 'cell env))))
     `(symbol-macrolet ((cell ,new-cell-value))
        ,@body)))

One important thing to keep in mind: Don't use side effects in macro
definitions. In both your solutions, you tried to achieve the result by
assigning to a local or global variable as part of the macroexpansion
process. However, you cannot predict whether or when, and how often, a
particular macro will be invoked. For example, development environments
may offer users to expand macros on demand, compilers may expand macros
several times for analysis, higher-order macros may expand inner macro
for analysis as well, etc., etc. So make sure that your macros are
always side-effect-free (unless you really know what you're doing).

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Vassil Nikolov  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 7 Лис, 21:55
Групи новин: comp.lang.lisp
Від: Vassil Nikolov <vniko...@pobox.com>
Дата: Sat, 07 Nov 2009 14:55:07 -0500
Місцевий час: Сб 7 Лис 2009 21:55
Тема: Re: Remembering information during compilation

On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> I'm trying to construct a macro called memory. The syntax is
> memory (&rest body) and doing  (memory form) should expand to
> (SYMBOL-MACROLET ((CELL XXX))
>    form)
> where XXX should be replaced by the number of surrounding memory
> invocations.

  Surrounding how?  Lexically or dynamically?

  ---Vassil.

--
"Even when the muse is posting on Usenet, Alexander Sergeevich?"


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 8 Лис, 00:06
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Sat, 7 Nov 2009 14:06:40 -0800 (PST)
Місцевий час: Нд 8 Лис 2009 00:06
Тема: Re: Remembering information during compilation

On 7 Nov, 18:41, p...@informatimago.com (Pascal J. Bourguignon) wrote:

> Spiros Bousbouras <spi...@gmail.com> writes:
> > I'm trying to construct a macro called memory.

> (defparameter *cell* 0)
> (define-symbol-macro cell *cell*)
> (defmacro memory (&rest body)
>   `(let ((*cell* (1+ *cell*)))
>      ,@body)))

This is a good approximation to what I asked for. The following is
even better:

(defparameter b 0)
(defmacro memory (&rest body)
   `(let ((b (1+ b)))
      (symbol-macrolet ((cell b))
        ,@body)))

It makes cell only available within body not everywhere. A difference
from my vision is that in the code above cell expands to a variable
instead of a numerical constant but that's fairly unimportant.  I'm a
bit more annoyed by the fact that your solution also exposes an
implementation detail to the world. I would prefer a 100% clean
solution like what we would have if memory were a function when we
would use closures.

--
Who's your mama ?


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 8 Лис, 00:20
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Sat, 7 Nov 2009 14:20:42 -0800 (PST)
Місцевий час: Нд 8 Лис 2009 00:20
Тема: Re: Remembering information during compilation

On 7 Nov, 18:53, Kaz Kylheku <kkylh...@gmail.com> wrote:

> Why does cell have to be a symbol macro? How about simply generating:

> (let ((cell (1+ cell)) ...)

> Take advantage of the LET scoping rule which allows you to shadow an outer
> variable, but use its avlue to initialize the shadowing one.

It doesn't have to be a symbol macro. The point of the exercise is to
investigate methods by which different invocations of the same macro
can share information. Many of the technical details are unimportant.
Having said that , it would be nice to have a way for this sharing of
information to happen through objects only the macro knows about.

> You just need to bootstrap this somehow for the outermost invocation.  Here is
> where a symbol macro comes in: a global one made with define-symbol-macro,
> to avoid introducing cell as a dynamic variable.

It would be good if this bootstrapping could be done through the
macro
definition itself.

--
To have absolutely if l' this large Mister is loved!
Translation on 2-11-2009 by
http://uk.babelfish.yahoo.com/translate_txt of
"A posséder absolument si l'on aime ce grand monsieur!


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 8 Лис, 00:23
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Sat, 7 Nov 2009 14:23:36 -0800 (PST)
Місцевий час: Нд 8 Лис 2009 00:23
Тема: Re: Remembering information during compilation
On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:

> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> > I'm trying to construct a macro called memory. The syntax is
> > memory (&rest body) and doing  (memory form) should expand to
> > (SYMBOL-MACROLET ((CELL XXX))
> >    form)
> > where XXX should be replaced by the number of surrounding memory
> > invocations.

>   Surrounding how?  Lexically or dynamically?

Lexically. See the examples above. I'm not even sure what a
dynamic surrounding would be.

Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
* Kaz Kylheku <20091107104314....@gmail.com> :
Wrote on Sat, 7 Nov 2009 18:44:28 +0000 (UTC):

| On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote:
|> It would be convenient if Lisp had some kind of minimal-compile
|> function ...
|
| Indeed, it would help a certain troll in another thread to have a
| fraction of a valid point.

Assuming you are baiting me here by calling me a troll, I think you are
rather sore for pointing out you had no clue what minimal compilation
was and its implications to symbol macro-expansion

--
Madhu


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Barry Margolin  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 8 Лис, 07:50
Групи новин: comp.lang.lisp
Від: Barry Margolin <bar...@alum.mit.edu>
Дата: Sun, 08 Nov 2009 00:50:47 -0500
Місцевий час: Нд 8 Лис 2009 07:50
Тема: Re: Remembering information during compilation
In article
<52b2c0f6-8c87-498c-a716-11efaf7a0...@o10g2000yqa.googlegroups.com>,
 Spiros Bousbouras <spi...@gmail.com> wrote:

> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:
> > On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

> > > I'm trying to construct a macro called memory. The syntax is
> > > memory (&rest body) and doing  (memory form) should expand to
> > > (SYMBOL-MACROLET ((CELL XXX))
> > >    form)
> > > where XXX should be replaced by the number of surrounding memory
> > > invocations.

> >   Surrounding how?  Lexically or dynamically?

> Lexically. See the examples above. I'm not even sure what a
> dynamic surrounding would be.

(defun fun1 ()
  (memory
     (print cell)
     (fun2)
     (print cell)))

(defun fun2
  (memory
    (print cell)))

When PRINT in FUN2 is called, there's one lexical surrounding
invocation, two dynamic ones.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Vassil Nikolov  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 8 Лис, 18:08
Групи новин: comp.lang.lisp
Від: Vassil Nikolov <vniko...@pobox.com>
Дата: Sun, 08 Nov 2009 11:08:07 -0500
Місцевий час: Нд 8 Лис 2009 18:08
Тема: Re: Remembering information during compilation

On Sat, 7 Nov 2009 14:23:36 -0800 (PST), Spiros Bousbouras <spi...@gmail.com> said:

> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:
>> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:

>> > I'm trying to construct a macro called memory. The syntax is
>> > memory (&rest body) and doing  (memory form) should expand to
>> > (SYMBOL-MACROLET ((CELL XXX))
>> >    form)
>> > where XXX should be replaced by the number of surrounding memory
>> > invocations.

>> Surrounding how?  Lexically or dynamically?
> Lexically.

  Then a solution cannot be based on a special variable (at least not
  a naïve solution; and even if a complicated solution could, I don't
  think it would be worth the candles).

  ---Vassil.

--
"Even when the muse is posting on Usenet, Alexander Sergeevich?"


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 9 Лис, 23:36
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Mon, 9 Nov 2009 13:36:37 -0800 (PST)
Місцевий час: Пн 9 Лис 2009 23:36
Тема: Re: Remembering information during compilation
On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

> What do you want the following to evaluate to?

No preference , the question was for educational purposes.

This is interesting. I did some experiments trying to understand why
it behaves the way it does. Let's also define

(defmacro memory2 (&body body)
   (let ((new-cell-value (1+ (macroexpand 'cell))))
     `(symbol-macrolet ((cell ,new-cell-value))
        ,@body)))

(let ((f1
         (memory
           (lambda ()
             (memory (format t "Calling f1 gives ~a~%" cell)))))
      (f2
         (memory2
           (lambda ()
             (memory2 (format t "Calling f2 gives ~a~%" cell))))))
   (funcall f1)
   (funcall f2)
    '|                            |)

I get
Calling f1 gives 2
Calling f2 gives 1

Let me see if I understand the reason for the difference between
memory and memory2. The first call to the two macros expands to the
same thing and places what follows in the scope of (after expansions)
(symbol-macrolet ((cell 1))
The difference lies in the behaviour of the line
(let ((new-cell-value (1+ (macroexpand 'cell env))))
   vs
(let ((new-cell-value (1+ (macroexpand 'cell))))
in the second call to the macros. There
(macroexpand 'cell env) evaluates to 1 whereas
(macroexpand 'cell) evaluates to 0.
The reason is the following excerpt in the macroexpand page in
the HS:

    In addition to macro definitions in the global environment,
    any local macro definitions established within env by
    macrolet or symbol-macrolet are considered. If only form is
    supplied as an argument, then the environment is effectively
    null, and only global macro definitions as established by
    defmacro are considered.

I assume the last line should actually read "defmacro or
define-symbol-macro are considered".

Is my understanding correct ?

--
<Khassaki> HI EVERYBODY!!!!!!!!!!
<Judge-Mental> try pressing the the Caps Lock key
<Khassaki> O THANKS!!! ITS SO MUCH EASIER TO WRITE NOW!!!!!!!
<Judge-Mental> fuck me
   http://www.bash.org/?835030


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 9 Лис, 23:50
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Mon, 9 Nov 2009 13:50:16 -0800 (PST)
Місцевий час: Пн 9 Лис 2009 23:50
Тема: Re: Remembering information during compilation
On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

> One important thing to keep in mind: Don't use side effects in macro
> definitions. In both your solutions, you tried to achieve the result by
> assigning to a local or global variable as part of the macroexpansion
> process. However, you cannot predict whether or when, and how often, a
> particular macro will be invoked. For example, development environments
> may offer users to expand macros on demand, compilers may expand macros
> several times for analysis, higher-order macros may expand inner macro
> for analysis as well, etc., etc. So make sure that your macros are
> always side-effect-free (unless you really know what you're doing).

So you're saying that setq (or setf) should not appear in the code of
the macroexpansion function ? Why , what could go wrong ?

--
Who's your mama ?


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal J. Bourguignon  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 10 Лис, 03:40
Групи новин: comp.lang.lisp
Від: p...@informatimago.com (Pascal J. Bourguignon)
Дата: Tue, 10 Nov 2009 02:40:18 +0100
Місцевий час: Вт 10 Лис 2009 03:40
Тема: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:

>> One important thing to keep in mind: Don't use side effects in macro
>> definitions. In both your solutions, you tried to achieve the result by
>> assigning to a local or global variable as part of the macroexpansion
>> process. However, you cannot predict whether or when, and how often, a
>> particular macro will be invoked. For example, development environments
>> may offer users to expand macros on demand, compilers may expand macros
>> several times for analysis, higher-order macros may expand inner macro
>> for analysis as well, etc., etc. So make sure that your macros are
>> always side-effect-free (unless you really know what you're doing).

> So you're saying that setq (or setf) should not appear in the code of
> the macroexpansion function ? Why , what could go wrong ?

(defvar *c* 0)

(defmacro  m ()
   (incf *c*)
   `',*c*)

(defun f ()
   (list (m) (m)))

(f) --> (1 2) ; or
    --> (42 87) ; or anything else.

(f) --> (1 2) ; or
    --> (3 4) ; or
    --> (36 99) ; or anything else.

For example, here is what you get with clisp:

C/USER[5]> (f) ; interpreted
(1 2)
C/USER[6]> (f) ; minimal compilation is cached.
(1 2)
C/USER[7]> (compile 'f) ; execute minimal compilation once again
F ;
NIL ;
NIL
C/USER[8]> (f) ; hence the new result
(3 4)
C/USER[9]> (f)
(3 4)

--
__Pascal Bourguignon__
http://www.informatimago.com


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal Costanza  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 10 Лис, 11:04
Групи новин: comp.lang.lisp
Від: Pascal Costanza <p...@p-cos.net>
Дата: Tue, 10 Nov 2009 10:04:52 +0100
Місцевий час: Вт 10 Лис 2009 11:04
Тема: Re: Remembering information during compilation

Yes, this is correct. The Common Lisp environment objects effectively
give you a first-class representation of (compile-time) lexical
environments.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal Costanza  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 10 Лис, 11:10
Групи новин: comp.lang.lisp
Від: Pascal Costanza <p...@p-cos.net>
Дата: Tue, 10 Nov 2009 10:10:03 +0100
Місцевий час: Вт 10 Лис 2009 11:10
Тема: Re: Remembering information during compilation

Spiros Bousbouras wrote:
> On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:
>> One important thing to keep in mind: Don't use side effects in macro
>> definitions. In both your solutions, you tried to achieve the result by
>> assigning to a local or global variable as part of the macroexpansion
>> process. However, you cannot predict whether or when, and how often, a
>> particular macro will be invoked. For example, development environments
>> may offer users to expand macros on demand, compilers may expand macros
>> several times for analysis, higher-order macros may expand inner macro
>> for analysis as well, etc., etc. So make sure that your macros are
>> always side-effect-free (unless you really know what you're doing).

> So you're saying that setq (or setf) should not appear in the code of
> the macroexpansion function ? Why , what could go wrong ?

As I said, a macro may be expanded more than once. For example, in the
LispWorks IDE (and others), I can right-click on an s-expression and
macroexpand it, to see what the result of macroexpansion will be. This
will trigger any side effects the macro definition may produce.

Here is another example: Assume you have a 'with-locked macro that
supposedly takes a lock on an object and then executes some code. Since
taking locks is expensive, it may want to avoid doing so. So it does
something like this:

(defmacro with-lock (object &body body &environment env)
   (if (contains object (walk body env))
     `(call-with-locked-object ,object (lambda () ,@body))
     `(progn ,@body)))

(defun contains (object expanded-body)
   ... some form of membership test ...)

(defun walk (code env)
   ... something that repeatedly calls
       (macroexpand code env)
       to expand all macros in code
   ...)

> Who's your mama ?

I don't know why that would be relevant in this thread.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 10 Лис, 23:36
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Tue, 10 Nov 2009 13:36:42 -0800 (PST)
Місцевий час: Вт 10 Лис 2009 23:36
Тема: Re: Remembering information during compilation
On 10 Nov, 01:40, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

If that's what Pascal meant I'm not surprised. But he referred to the
code in my first post, for example

(let ((a 0))
   (defmacro memory (&rest body)
      (prog2
         (incf a)
         `(symbol-macrolet ((cell ,a))
             ,@body)
         (decf a))))

His phrasing above and the example gave me the impression that he was
saying that all assignments are dangerous even if the effects of the
assignment do not persist after the macroexpansion function has
finished executing. If that's what he meant then I do find it
surprising. For example I don't see what could go wrong with my code
above regardless of how many times the macro gets expanded.

In any case, it seems that if one wants to have macros share
information (apart from trivial cases perhaps) then this cannot be
achieved behind the scenes so to speak. What I mean behind the scenes
is the way you would do it with functions:

(let ((a))
   (defun foo ...
   (defun bar ...)

Any changes to a one function makes the other knows about but the
rest of the code is ignorant about a.  With macros however one has to
put any changes to the shared information in the code the macro
produces thereby leaking what ought to be internal implementation. I
consider this a blemish in Lisp.

--
Capitalization is the difference between "I had to help my uncle Jack
off a horse.." and "I had to help my uncle jack off a horse.."
    http://www.bash.org/?367896


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pascal Costanza  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 11 Лис, 02:40
Групи новин: comp.lang.lisp
Від: Pascal Costanza <p...@p-cos.net>
Дата: Wed, 11 Nov 2009 01:40:58 +0100
Місцевий час: Ср 11 Лис 2009 02:40
Тема: Re: Remembering information during compilation

I didn't read your code carefully enough, so I indeed didn't notice that
  the side effect didn't persist. However, this code could still create
problems, for example when a user tries to macroexpand some particular
form while some other code is compiled in a background thread, and two
invocations of 'memory are thus expanded at the same time. You would
either need to synchronize the accesses to the 'a variable, for example
by using locks or STM (har :P ), or you should just use local bindings
for 'a.

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:

> (let ((a))
>    (defun foo ...
>    (defun bar ...)

> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.  With macros however one has to
> put any changes to the shared information in the code the macro
> produces thereby leaking what ought to be internal implementation. I
> consider this a blemish in Lisp.

You can hide the shared information in a package.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Thomas A. Russ  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 11 Лис, 03:51
Групи новин: comp.lang.lisp
Від: t...@sevak.isi.edu (Thomas A. Russ)
Дата: 10 Nov 2009 17:51:34 -0800
Місцевий час: Ср 11 Лис 2009 03:51
Тема: Re: Remembering information during compilation

Well, I'm not convinced that this has to work the way you may wish it
to.  In particular, the expansion of macros inside BODY doesn't have to
occur in the dynamic scope of the expansion of MEMORY.

So, for example, it seems to me it is perfectly permissible, and in fact
the most likely implementation, that when macros are being expanded the
following happens:

The macro MEMORY is encountered by the code walker or compiler.  It is
expanded, and given the BODY contents.  The BODY contents are not
evaluated, but merely returned inside the SYMBOL-MACROLET form.  The
macroexpansion function for MEMORY returns the new form.

This new form is now walked by the code walker, so if there is any
macros in the newly returned form, they will also be properly expanded.
But since the macro-expansion function has already returned, the value
of variable A has been restored.  So the next expansion doesn't see any
dynamic change.

In fact, I'm pretty sure it has to work this way, since otherwise macros
that expand into code headed by other macros would not work properly.
There will not be any invocation of macro-expansion functions during the
invocation of a macro-expansion function.

You could probably observe this by tracing the macro-expansion function
that corresponds to your macro.  I would expect to see it return before
any other macro expansion occurs.

--
Thomas A. Russ,  USC/Information Sciences Institute


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Tobias C. Rittweiler  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 11 Лис, 10:31
Групи новин: comp.lang.lisp
Від: "Tobias C. Rittweiler" <t...@freebits.de.invalid>
Дата: Wed, 11 Nov 2009 09:31:58 +0100
Місцевий час: Ср 11 Лис 2009 10:31
Тема: Re: Remembering information during compilation

Spiros Bousbouras <spi...@gmail.com> writes:
> (let ((a 0))
>    (defmacro memory (&rest body)
>       (prog2
>          (incf a)
>          `(symbol-macrolet ((cell ,a))
>              ,@body)
>          (decf a))))

(Mind Thoms Russ' response!)

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:

> (let ((a))
>    (defun foo ...
>    (defun bar ...)

> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.  With macros however one has to
> put any changes to the shared information in the code the macro
> produces thereby leaking what ought to be internal implementation.

Where is it leaking? Because you can introspectively look at a macro's
expansion? Do you consider reflection to be "blemish" in general?

> I consider this a blemish in Lisp.

Impenetrable encapsulation is only longed for by the timid. :-)

  -T.


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 17 Лис, 16:34
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Tue, 17 Nov 2009 06:34:46 -0800 (PST)
Місцевий час: Вт 17 Лис 2009 16:34
Тема: Re: Remembering information during compilation
On 11 Nov, 00:40, Pascal Costanza <p...@p-cos.net> wrote:

Is there any established way for how such parallel
expansion/compilation is supposed to work ? Intuitively it seems to
me that in the scenario you're describing the implementation ought to
create one copy of a for the compilation and another for any
expansions which are not part of the compilation. If it doesn't do
that what makes you think that even your code will work correctly ?
There may be clashes with the use of new-cell-value.

You can but still I find it kludgy. You already have the datum in a
variable i.e. in memory but in order to share it with a different
invocation of the macro you have to "print" it and then read it back
in again. Very ugly.  Apart from aesthetics there's another issue :
"Practical Common Lisp" says in footnote 4 of chapter 4 : "Not all
Lisp objects can be written out in a way that can be read back in".
What if it is such an object you want to share ?

--
Never attribute to conspiracy what can adequately be explained by
shared attitudes.


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pillsy  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 17 Лис, 16:48
Групи новин: comp.lang.lisp
Від: Pillsy <pillsb...@gmail.com>
Дата: Tue, 17 Nov 2009 06:48:30 -0800 (PST)
Місцевий час: Вт 17 Лис 2009 16:48
Тема: Re: Remembering information during compilation
On Nov 10, 4:36 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
[...]

> In any case, it seems that if one wants to have macros share
> information (apart from trivial cases perhaps) then this cannot be
> achieved behind the scenes so to speak. What I mean behind the scenes
> is the way you would do it with functions:
> (let ((a))
>    (defun foo ...
>    (defun bar ...)
> Any changes to a one function makes the other knows about but the
> rest of the code is ignorant about a.

This is a trick I've used once or twice in the past, and I'm just
submitting it as an idea in part because I'd like to see if there are
problems with it that I haven't considered up until now. It's hardly
something I do every day, and I know this corner of macrology is
generally riddled with pitfalls.

The idea is that you have easy access to uninterned symbols, and those
symbols not only have their value cells, but also function cells and
property lists to play with. You could do something like this:

(let ((closed (closed "BACKING-")))
   (defmacro foo (name &rest args)
      (setf (get closed name) (stuff-from-foo-args args))
      (generate-foo-expansion name args closed))
   (defmacro bar (name &rest args)
      (setf (get closed name) (stuff-from-bar-args args))
      (generate-bar-expansion name args closed)))

Is there something horribly wrong with this approach?

Cheers,
Pillsy


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Spiros Bousbouras  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 17 Лис, 17:16
Групи новин: comp.lang.lisp
Від: Spiros Bousbouras <spi...@gmail.com>
Дата: Tue, 17 Nov 2009 07:16:49 -0800 (PST)
Місцевий час: Вт 17 Лис 2009 17:16
Тема: Re: Remembering information during compilation
On 11 Nov, 01:51, t...@sevak.isi.edu (Thomas A. Russ) wrote:

I would be surprised if you or anyone else were convinced since I
already said in my opening post that I tested it and it doesn't work.

> The macro MEMORY is encountered by the code walker or compiler.  It is
> expanded, and given the BODY contents.  The BODY contents are not
> evaluated, but merely returned inside the SYMBOL-MACROLET form.  The
> macroexpansion function for MEMORY returns the new form.

> This new form is now walked by the code walker, so if there is any
> macros in the newly returned form, they will also be properly expanded.
> But since the macro-expansion function has already returned, the value
> of variable A has been restored.  So the next expansion doesn't see any
> dynamic change.

Or as I said in my OP : "I assume that by the time the code generated
from the macro expansion gets compiled the statement (decf a) has
already been executed."

--
The worst part of living on the West Coast is having to remember to
say "no mayonnaise" when ordering a burger.
  tinyurl.com/mayo-quote


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Pillsy  
Переглянути профіль   Перекласти вказаною мовою: Перекладено (переглянути оригінал)
 Більше налаштувань 17 Лис, 18:25
Групи новин: comp.lang.lisp
Від: Pillsy <pillsb...@gmail.com>
Дата: Tue, 17 Nov 2009 08:25:36 -0800 (PST)
Місцевий час: Вт 17 Лис 2009 18:25
Тема: Re: Remembering information during compilation
On Nov 17, 9:48 am, Pillsy <pillsb...@gmail.com> wrote:
[...]

> (let ((closed (closed "BACKING-")))
>    (defmacro foo (name &rest args)
>       (setf (get closed name) (stuff-from-foo-args args))
>       (generate-foo-expansion name args closed))
>    (defmacro bar (name &rest args)
>       (setf (get closed name) (stuff-from-bar-args args))
>       (generate-bar-expansion name args closed)))
> Is there something horribly wrong with this approach?

Well, one thing that's potentially horribly wrong with the approach is
its dependence on compile-time side-effects. This problem seems pretty
avoidable if all you want to do is establish a private chanell that
can be accessed by your expansions; that may not be enough for your
purposes. But if it is, there's always

(let ((closed (gensym "CLOSED-")))
  (defmacro foo (name &rest stuff)
    `(progn
        (setf (get ',closed ',name) ,(mangle-foo-args args))
        ,(foo-expand name args closed)))
  (defmacro bar (name &rest stuff)
    `(progn
        (setf (get ',closed ',name) ,(mangle-bar-args args))
        ,(foo-expand name args closed))))

Cheers,
Pillsy


Ви мусите увійти перед публікацією повідомлень.
Аби надіслати допис, будь ласка, спочатку приєднайтеся до цієї групи.
Будь ласка, поновіть своє прізвисько на сторінці налаштування передплати перед тим, як надіслати свій допис.
У вас немає права надсилання дописів до цієї групи.
Повідомлення 1 - 25 з 43   Новіші >
« Повернутися до обговорень « Новіша тема     Старіша тема »

Створити групу - Групи Google - Домашня сторінка Google - Правила користування послугою - Заява про конфіденційність і нерозголошення інформації
©2009 Google