Not fully evaluating in module? - wolfram-mathematica

How do I force evaluation of all symbols in a module?
vout[vin_] = Module[{x=vin,y},
y = 200000*(1.2 - x);
Print[y];
y
];
Print[vout[0]];
I'm expecting this to print the same thing (240000) twice, but instead I'm getting this:
200000*(1.2 - vin)
240000.
Any idea what to do here to be able to get the expanded value (240000) while within the module?
Edit: Print[Evaluate[y]]; will not work either in this case

you should type ":=" instead of "=", so that your function is recomputed correctly each time.
This works fine
vout[vin_] := Module[{x=vin,y},
y = 200000*(1.2 - x);
Print[y];
y
];
Print[vout[0]];

Related

Compound Boolean Expr: Void Value Expression

def success?
return #fhosts.empty? and #khosts.empty? and #shosts.any?
end
When I run that instance method, I get an error:
/home/fandingo/code/management/lib/ht.rb:37: void value expression
return #fhosts.empty? and #khosts.empty? and #shosts.any?
I'm confused by what's happening since this works
def success?
#fhosts.empty? and #khosts.empty? and #shosts.any?
# This also works
# r = #fhosts.empty? and #khosts.empty? and #shosts.any?
# return r
end
I'm coming from a Python background, and I don't want anything to do with implicit returns. Programming has plenty of landmines as it is.
If we have an arbitrary expression, E, that consists of boolean operations and and or together, here are some operations we could perform:
if E -- works
E -- works
* v = E -- works
return E -- broken
Why doesn't the last case work?
Edit: Actually v = E doesn't work. Only
v = Ei
is evaluated. Ei+1...k are ignored.
This is likely due to the very weak binding of and which causes it to parse out differently than you expect:
return x and y
This actually means:
(return x) and y
Since you're returning immediately it doesn't have a chance to evaluate the remainder of the expression.
Your version without return is correct:
x and y
This doesn't have a binding issue and is more idiomatic Ruby. Remember you only need to put an explicit return if you're trying to force an exit before the last line of the method. Being opposed to implicit returns is going to make your code look heavily non-Ruby. They're one of the reasons Ruby is so clean and simple, and how things like a.map { |v| v * 2 } works.
The When in Rome principle applies here. If you want to write Python-style Ruby you're going to be going against the grain. It's like saying "I don't like how you say X in your spoken language, so I'll just ignore that and do it my way."
This should also work:
return x && y
The && method is very strongly bound so return is the last thing evaluated here.
Or if you really want to use and for whatever reason:
return (x and y)

How to I set a ruby variable based on an if-then decision tree

I want to write the following:
variable = if x
a
else
if y
b
else
c
end
end
Where if x is true, variable equals a. If x is false and y is true, variable equals b. If x and y are both false, variable equals c.
I thought this was valid ruby syntax but when I try it, the variable is always set to nil. Why is this and how do I set it correctly?
I am using ruby 1.9.3 btw
Edit: FALSE ALARM. In my example, c was set to nil which I thought was erroneous. My original syntax worked fine. I'm not sure of the StackOverflow etiquette on whether I should delete this question, advise is welcome.
Thanks for the quick responses.
Do not make it complicated! There is nothing wrong with writing
variable =
if x then a
elsif y then b
else c
end
No one will look at this code and not figure out what has happend.
There two main variants:
With a if-else-end tree:
variable =
if x
a
else
if y
b
else
c
end
end
and as a logical boolean algebra expression:
variable = x && a || ( y && b || c )
That is the same as:
variable = x && a || y && b || c
The first variant is usually preferred, then you are using complex code or calculation inside the if-else-end blocks. The second, when the simple read/logical constructions is used.
If you have an error or get an invalid result in your expression, just check your logical expression.

Why isn't `method=` treated the same as any other method?

Consider the following code snippet:
class Example
def my_attr=(value)
#_my_attr = value
#_my_attr * 3
end
end
I expect the expression Example.new.my_attr = 5 to return 15, but that turns out to be wrong. The original return value is always returned, even when I call the = method explicitly:
Example.new.my_attr = 5 # => 5
Example.new.my_attr=(5) # => 5
How and why does Ruby do this? Does Ruby treat methods that end in = specially, or is it some other mechanism? I guess this precludes chaining on return values of = methods, right? Is there a way to make Ruby behave differently, or is this just how it is?
Update: Credit to #jeffgran for this:
Example.new.send(:my_attr=, 5) # => 15
This is a workaround, but on another level even more perplexing, since that would mean send is clearly not always equivalent in behavior to calling a method directly.
This is how assignment works; the return value is ignored, and the result of an assignment expression is always the right-hand value. This is a fundamental feature of Ruby's grammar. left-hand side = right-hand side will always evaluate to right-hand side, regardless of whether left hand side is a variable (x), a method (object.x), a constant (X) or any expression.
Source: Programming Languages | Ruby
IPA Ruby Standardization WG Draft, 11.4.2.2.5, Single method assignments
Consider chaining of assignments, x = y = 3.
For this to work correctly, the result of y = 3 must be 3, regardless of the actual value returned by the y= method. x = y = 3 is meant to read as y = 3; x = 3, not as y = 3; x = y which is what would be implied if the return value from y= was treated as the result of y = 3.
Or consider all the other places assignment can be used. Sometimes, instead of this...
obj.x = getExpensiveThing()
if obj.x
...
... we write this ...
if obj.x = getExpensiveThing()
This couldn't work if the result of obj.x = ... could be any arbitrary thing, but we know it will work because the result of obj.x = y is always y.
Update
A comment on the question states:
Interesting, I wasn't aware of this scenario. It seems that method= returns whatever input is given...
No, it's an important distinction to make. This has nothing to do with the return value of method assignment, and it definitely does not "return whatever input is given", it returns whatever you tell it to return.
The whole point is that the return value is ignored by the grammar of the language; assignment doesn't evaluate to the return value of the attr= method, but the return value still exists as evidenced by the question itself: Example.new.send(:my_attr=, 5) # => 15. This works because it is not assignment. You're side-stepping that part of the Ruby language.
Update again
To be clear: x and y in my examples shouldn't be interpreted as literal Ruby variables, they are place holders for any valid left-hand side of an assignment. x or y could be any expression: a, obj.a, CONSTANT_A, Something::a, #instance_a, it's all the same. The value of assignment is always the right-hand side.

Local variable and Block usage

I wrote code that executes a function it receives from the (future) client, in a loop with some parameters. will call it func(name it).
Inside the function the client usually generate expression in the same variables(by GetUncertainty - each variable must be cleared before use). To do so , the simple idea is to use Block. Later , a code is executed that handles di and i outside the function.So, di and i must be globals(there could be more, it is flexible).
BTW, I know it is not efficient, but efficiency is not an issue.
func[v_, a_, r_] :=
(V = v; A = a; R = r;
Block[{V, A, R},i = V A + A 10 + R 100; di = GetUncertainty[i, {V, A, R}];] ;
Print[di])
The problem is that the client must reset the vars by hand. That means that the function parameters can't be V_,A_,R_ , otherwise The vars in the block will be replace by the values. I didn't manage to overcome this in any other way.
Another question in a similar issue. if I have
vars = {V,A,R,DR} , then
Block[vars , ..code.. ] , throws error that it is not a list.whereas Block[ {V,A,R,DR},..code..] works. How to overcome this?
Thanks.
its hard to unravel what you are trying to do, but the best approach may be to simply never assign values to symbols that need to be used as pure symbols in some context. Then you don't even need the Block[].
func[v_, a_, r_] := (
i = V A + A 10 + R 100;
di = GetUncertainty[i, {V, A, R}];
Print[di /. {V->v,A->a,R->r])
starting your own symbol names with Caps is frowned upon by the way as you risk conflict with built in symbols.
Note also there is a dedicated site mathematica.stackexchange.com
If I understand your application what you need are Formal Symbols. These are a set of Symbols with the Attribute Protected so that they cannot accidentally be assigned a value. They may be entered with e.g. Esc$AEsc for Formal Capital A. You can then use ReplaceAll (short form /.) as george showed to substitute your desired values.
Your code would be something like this:
func[v_, a_, r_] :=
Module[{i, di},
i = \[FormalCapitalV] \[FormalCapitalA] + \[FormalCapitalA] 10 + \[FormalCapitalR] 100;
di = GetUncertainty[i, {\[FormalCapitalV], \[FormalCapitalA], \[FormalCapitalR]}];
di /. {\[FormalCapitalV] -> v, \[FormalCapitalA] -> a, \[FormalCapitalR] -> r}
]
That looks horrible here but in a Notebook it looks like this:
I included Module to show how you should properly localize utility Symbols such as i and di but this particuarly simple function could also be written without them:
Your second question regarding "vars = {V,A,R,DR} then Block[vars , ..code.. ]" is answered here: How to set Block local variables by code?
Dedicated StackExchange site:

Is it safe to make a Module inside another using the same local symbols?

I find it useful sometimes to be able to make a local module (inside a parent module) with its own local symbols, which does a small task to be used only by the parent module. This is useful when the module becomes large, and there is no good reason to make smaller helper functions OUTSIDE the module as those helper functions are really needed and used by only that one parent module.
Here is a silly example with one module, and a helper module inside it to something
foo[x_] := Module[{r},
r = Module[{y, sol},
sol = First#Solve[y^2 + 3 y + 2 == 0];
y /. sol
];
x^r
]
But the problem in the above, is that the local variables for the inner module, could conflict with local variables with the parent module, because M notebook makes the inner module local variables red when I do the following, which tells me I am doing something I am not supposed to do: (I do not want to worry all the time with checking if I am using a unique local symbol for the inner module which is different from one used as local symbols for the parent Module, after all, it is supposed to be local. And also having to come up with a different symbol name when this is the case)
foo[x_] := Module[{r, y=0},
r = Module[{y, sol},
sol = First#Solve[y^2 + 3 y + 2 == 0];
y /. sol
];
x^r
]
Notice the red coloring, which according to the help, it is local scope conflict or shadowing in multiple contexts.
(M needs to use better colors, hard to make a difference between many colors, all shades of red).
(I think it is a shadowing warniong) Either way, it tells me I am not supposed to do this, even though I did not see any problem with such construct when I used it.
Value of parent module local variable 'y' in this example did not get over-written by the call to the inner module 'r' which is good.
Again, I did not want to make a function outside foo, because this small task is only used by foo[] and no need to move it to the Global context.
Ofcourse, I could always just write:
foo[x_] := Module[{r, y, sol},
sol = First#Solve[y^2 + 3 y + 2 == 0];
r = y /. sol;
x^r
]
But I am just giving an example, and this is for large module, where it helps to break the tasks inside the module itself into even few smaller tasks. Internal functions, inside functions is something I used before in other languages such as Ada/Pascal and such which has this construct and can be useful for large programs.
My question is: Just want to check with the experts here if it is safe for me to use the above, even though M gives me this red coloring warning? and if there is something I need to worry about doing this
thanks,
Yes, it is safe to use the same variable in nested Modules as long as you don't lose track of them. Mathematica treats each variable defined in a Module as local to that module. Local variables are Temporary, and are numbered as variable$ModuleNumber. You can check this for yourself with the following example:
Module[{x = 1},
Print[HoldForm#x, " = ", x]
Module[{x = 2},
Print[HoldForm#x, " = ", x]
Module[{x = 3},
Print[HoldForm#x, " = ", x]
];
Print[HoldForm#x, " = ", x]
];
Print[HoldForm#x, " = ", x]
]
(*Output
x$4576 = 1
x$4577 = 2
x$4578 = 3
x$4577 = 2
x$4576 = 1
*)
To the best of my knowledge this is a small issue with the detection.

Resources