Delayed evaluation and setdefault()

any possible side-effects the call to b() might have will not
happen of a() returns true, because then b() will never be
executed.

However, if I go looking for dictionary keys like this:

then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

If b() has side-effects, this may not be what you want at all. It
would seem to me not too exotic to expect Python to have some
sort of construct or syntax for dealing with this, just as it
supports Boolean short-circuiting.

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

Advertisements

any possible side-effects the call to b() might have will not
happen of a() returns true, because then b() will never be
executed.

However, if I go looking for dictionary keys like this:

then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

If b() has side-effects, this may not be what you want at all. It
would seem to me not too exotic to expect Python to have some
sort of construct or syntax for dealing with this, just as it
supports Boolean short-circuiting.

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

Click to expand...

It's normal---setdefault is just a method and its parameters get
evaluted before the call occur. If you want this kind of lazy
evaluation, I'd suggest something like this ('foo' in d) or
(d.setdefault('foo', b()). If you want your value too, it gets even
trickier.

Actually, if you really need this kind of functionality, it might be
worth defining a function.

Advertisements

then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

Click to expand...

The setdefault method of dictionaries is just a normal method in Python;
only the builtin `and' and `or' operators have special short-circuiting
behavior. That is to say, there are no builtin functions or methods in
Python which are "special forms."

It's true that the kind of thing you want to do (lazy evaluation in some
incidental context) is common, but it would not be a good idea to start
selectively adding special forms to the language since it would greatly
complicate things. Right now if I see

this.that(something, theOther())

I can immediately tell what gets evaluated or called and when. I don't
need to know that there are special cases in some things that look like
method/function calls but actually might be special forms, and that's a
good thing.

As for your particular solution, you're much better off implementing the
lazy evaluation you want yourself, rather than wishing there were
special language support for it for that particular method (or a very
small subset of methods/functions).

any possible side-effects the call to b() might have will not
happen of a() returns true, because then b() will never be
executed.

However, if I go looking for dictionary keys like this:

then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

If b() has side-effects, this may not be what you want at all. It
would seem to me not too exotic to expect Python to have some
sort of construct or syntax for dealing with this, just as it
supports Boolean short-circuiting.

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

Click to expand...

Lazy evaluation is dangerous as the state of mutable objects may have
changed in the mean time. In your case

if "foo" not in d:
d["foo"] = b()

should do.

However, if you absolutely want it, here's a slightly more general approach:

You will still have to bother with undeferring in *many* places in your
program, so the above would go into the "or other" category. For lazy
evaluation to take off, I think it has to be build into the language. I
doubt, though, that much effort will be saved, as a human is normally lazy
enough to not calculate things until absolutely needed.

d.setdefault('foo', b())
then b() *does* get executed regardless of whether or not the
value it returns is actually used ('foo' was not found) or not
('foo' was found).

So I guess my question is twofold: one, do people think
differently, and if so why?; and two: is there any elegant (or
other) way in which I can achieve the delayed evaluation I desire
for setdefault, given a side-effect-having b()?

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Ask a Question