Arc Forumnew | comments | leaders | submitlogin
4 points by cchooper 6007 days ago | link | parent

All macros in an expression are expanded before any part of the expression is executed. So (assign k (h k)) will be expanded before each is executed, and at that point k has no value, so (eval k) will fail.

So you need to move eval into the result of the macro expansion, and avoid calling it in the macro expansion itself:

  (mac assign (name expr) `(eval (list '= ',name ',expr)))


2 points by zhtw 6006 days ago | link

OK. I understood the problem. But your solution doesn't work.

  arc> (= x 'var)
  var
  arc> (assign x 20)
  20
  arc> var
  Error: "reference to undefined identifier: _var"
Indeed. What you wrote is "assign a value to the given name". I meant "to assign a value to a variable which name is stored in the given variable".

My original example was just attempt to copy the table into the current environment:

  (= h (obj name0 0 name1 1 name2 2))
  (each x (keys h)
    (assign x (h x)))

-----

3 points by almkglor 6006 days ago | link

Then use 'eval :

  (ontable k v h
    (eval `(= ,k ,v)))
Note that this does not copy to the current environment, just the global environment. So if you're doing something like this:

  (let foo 42
    (= h (table 'foo 1)) ; Anarki only
    (ontable k v h
      (eval `(= ,k ,v)))
    foo)
Then the 'foo you access is the local one, but the one written by 'eval is the global.

-----

3 points by absz 6006 days ago | link

Careful! You're evaluating the value of v here, which can break:

  arc> (ontable k v (table 'var 'a)
         (eval `(= ,k ,v)))
  Error: "reference to undefined identifier: __a"
You need to quote the value of v here to prevent it from being evaluated; when you do so, you get

  arc> (ontable k v (table 'var 'a)
         (eval `(= ,k ',v)))
  #hash((var . a))
  arc> var
  a
And then the body of he loop is the same as the body of my assign function from http://arclanguage.org/item?id=6918.

-----

1 point by almkglor 6006 days ago | link

This is correct ^^

-----

2 points by zhtw 6006 days ago | link

> Note that this does not copy to the current environment, just the global environment.

Yeah, I'm aware of that. But it's a good point anyway, thanks.

-----

2 points by stefano 6006 days ago | link

You don't really need to use eval:

  (mac assign (name expr)
    `(= ,name ,expr))
then (assign k 3) will be expanded to (= k 3).

-----

2 points by zhtw 6006 days ago | link

No. You didn't understand. I meant exactly what I wrote. I want to assign a value to variable which name is stored in the variable "name".

-----