(def-junk some-label
:f1 ...
:f2 ( :key1 #'some-function
:key2 ...
...
:keyn))
Where :f2 contains keyword values which should be passed to
a particular method in the event that that method is called.
I need each of the values within :f2 to be evaluated, or for example
#'some-function will be passed as the cons (function some-function),
and not be funcallable down the road without explicitly eval-ing
it (AFAIK). The length of :f2 may vary.
After much shedding of tears and knashing of teeth, I finally
just gave up and wrote something like this:
(defmacro def-junk (label &key f1 f2)
`(def-junct-fct ,label
...
:f2 (mapcar #'(lambda(x)
(eval x))
,(push 'list f2)))
Which works, but which calls #'eval. For reasons I've read about
and thought I understood at the time but have yet to experience
viscerally, I 'know' that calling eval is evil, and introduces
strange side-effects into your program.
Two questions:
1) Am I going to hell?
2) Is there a way to do this without calling eval?
Thanks for your help!
- Eric
>
> I'm trying to implement a macro which [...] contains keyword values
> which should be passed to a particular method in the event that that
> method is called.
>
> I need each of the values within :f2 to be evaluated, or for example
> #'some-function will be passed as the cons (function some-function),
> and not be funcallable down the road without explicitly eval-ing
> it (AFAIK).
Well, if your only concern was to name a function, you could just use
the symbol. Symbols are funcallable. However, if you want to allow
arbitrary evaluation, explicit use of EVAL is a no-no here. The
compilation environment won't have the appropriate lexical environment
for a correct evaluation. Calling EVAL is not evil, it's just often
the wrong thing. And it is definitely wrong here. Strange side-effects
have nothing to do with it. It has to do with the fact that you're doing
the side-effects in the wrong place. It's like having a self-inflating
tent and deciding to make it do its inflation thing in the car on the
way to the forest instead of when you get to the forest in order to
save some time. It may indeed save some time, but when you get done,
your tent is set up inside your car instead of at the park where you
wanted it.
Just do
(defmacro def-junk (label &key f1 f2)
`(setup-junk ',label
:f1 ...whatever...
:f2 (list ,@f2)))
so that
(def-junk foo :f2 (:foo #'foo :bar #'bar))
expands into
(setup-junk 'foo :f2 (list :foo #'foo :bar #'bar))
> Two questions:
>
> 1) Am I going to hell?
Do not think about programming as a religion. Religious dogma has
no place in programming decisions.
> 2) Is there a way to do this without calling eval?
The normal rule of thumb for a macro is "put the form to in a place
in the expansion where it will be naturally evaluated without an
explicit call to eval".
> Thanks for your help!
Good luck.
* Kent M Pitman
| Do not think about programming as a religion. Religious dogma has no
| place in programming decisions.
I object. "good", "evil", "heaven", and "hell" are perfectly legitimate
programming terms. it's a pity that the early programmers of humans made
it appear they are religious terms. "good" is when what you have done
leads to less work (even though it may be a lot of work). "evil" is when
what you have done leads to more work (especially when it is very little
work at first). "heaven" is when your program behaves well, your users
are content, and every change you make has fully predictable consequences
and changes only what it should change: the result of "good" programming.
"hell" is when your program fails, your users despair, and every change
you make is not only wrong, but can not be predicted in how and where the
wrongness will manifest itself: the result of "evil" programming.
e.g., C++ is virtually pure evil. Bill Gates and his entire company is
in hell because of evil programming in BASIC and C++, and all kinds of
evil monsters are hoisted upon users from this hell: viruses, general
protection failures, blue screens, licenses and patents, forced upgrades,
backward incompatibility disservice packs, DLL interdependencies -- the
list goes on and on. a number of these are _literally_ from hell, it's
not just a feeling anymore.
once in hell there is no salvation, save to stop programming and using
evil computers and software from hell. if you are engaging in evil
programming practices, you do not necessarily go to hell, but you have to
absolve yourself through purifying punishment, like reading the manual.
and when the lambda opened the seventh seal, silence covered the sky.
hey, this could work. help make this religious dogma for humans in
general, and _then_ maybe we can get rid of C++ and all of Microsoft's
evil software! (nothing short of a new religion will, I'm afraid.)
#:Erik
--
@1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century
Kent M Pitman wrote:
> > 1) Am I going to hell?
>
> Do not think about programming as a religion. Religious dogma has
> no place in programming decisions.
Newsgroups should have sprinkler systems to extinguish stuff like this.
<g>
Me, I'm a Taoist when it comes to programming.
kt
> * Eric Scott
> | 1) Am I going to hell?
>
> * Kent M Pitman
> | Do not think about programming as a religion. Religious dogma has no
> | place in programming decisions.
>
> I object. "good", "evil", "heaven", and "hell" are perfectly legitimate
> programming terms.
You're just trying to get me to say such terms are evil, aren't you? ;-)
> it's a pity that the early programmers of humans made
> it appear they are religious terms. "good" is when what you have done
> leads to less work (even though it may be a lot of work). "evil" is when
> what you have done leads to more work (especially when it is very little
> work at first). [...etc.]
My objection is not with the use of such characterizations in proper
context, but rather to the dissociation of such judgments from context.
Every decision has good and bad potential, depending on the goal. To
say that an operator or style is "just good" or "just bad" seems to me
to miss the point (that is, my point, though maybe not everyone's) that
people should be assessing their choices on the basis of their goals,
not on the basis of a universally constant value system which requires
no understanding of goals. It's not that I don't think that some paths
lead frequently to problems, so much as that I encourage everyone to
still go through the exercise of listing out their goals and assessing
options in that context. I think the so-called "good" things will stand
up to such a treatment and the so-called "bad" things won't. But often
we get so used to discarding some solutions as bad that we sometimes
forget they had good purposes.
I think encouraging people to re-examine the obvious at routine
intervals would overall help Lisp. One reason they don't end up trying
it so much is that they get it compiled into their head (usually while
writing "hello_world") that C is "better" than Lisp and they forget to
reevaluate this later (e.g., when they have a real application in mind
or when their application has grown a lot). If they were encouraged to
reexamine the obvious, we might make some converts.
But generally, times change and people change and technology changes,
and I think it's wise to attach reasons/context/etc. to virtually any
"rule of thumb" we make so we know when to reconsider it.