In C ,
every variable denotes a reference, and we can get the reference from a variable by operator &. e.g. if int x=1, then &x is the reference denoted by variable x.
every variable is evaluated to the value referred to the reference. e.g. x is evaluated to 1.
In SML,
does every variable denotes a reference? E.g. If val y = ref(3), then y denotes a reference which refers to 3. if let val x = 4, what does x denote: 4 or a reference which refers to 4? Can we get the reference denoted by variable x, similarly to & in C?
y is evaluated to reference ref 3, and x is evaluated to 4.
Thanks.
A variable binding in SML does not introduce a reference. You cannot get a reference to the x in your example. All references have to be created explicitly, and are first-class values. And only such references are mutable, bindings are not.
In other words, bindings and references are completely independent features in SML.
Related
I'm new to Haskell, so please forgive if this question is dumb.
Imagine that we have two data structures bound to the names x and y.
x is mutable.
y is not.
As a matter or principle, does x necessarily have a different type than y?
Short answer: yes.
In Haskell, all variables are technically immutable. Unlike in, say, JavaScript, once you've defined a new variable in Haskell and bound it to an initial value:
let x = expression1 in body1
that's its value forever. Everywhere that x is used in body1, its value is guaranteed to be the (fixed) value of expression1. (Well, technically, you can define a brand new immutable variable x with the same name in body1 and then some of the xs in body might refer to that new variable, but that's a whole different matter.)
Haskell does have mutable data structures. We use them by creating a new mutable structure and binding that to an immutable variable:
do ...
xref <- newIORef (15 :: Int)
...
Here, the value of xref itself is not the integer 15. Rather, xref is assigned an immutable, undisplayable value that identifies a "container" whose contents are currently 15. To use this container, we need to explicitly pull values out of it, which we can assign to immutable variables:
value_of_x_right_now <- readIORef xref
and explicitly put values into it:
writeIORef xref (value_of_x_right_now + 15)
There's obviously much more that can be said about these values, and the way in which they generally need to be accessed via monadic operations in IO or another monad.
But, even setting that aside, it should be clear that the integer 15 and a "container whose contents are initialized to the integer 15" are objects with necessarily different types. In this case, the types are Int and IORef Int respectively.
So, the mutability of data structures will necessarily be reflected at the type level, simply by virtue of the fact that mutability in Haskell is implemented via these sorts of "containers", and the type of a value is not the same as the type of a container containing that value.
I have the below code.
a = 10
def f(x):
return x + a
a = 3
f(1)
If we print(f1) the result is 4. It seems that the second assignment of a is used here (a=3). Could someone explain to me if there is a particular reason or rule for not using the first assignment (a=10)?
Thank you,
Dimitrios
a and x are resolved each time return x + a is executed. You reassign a before calling f. f knows that a is not a local variable so looks up "a" in its enclosing scope. That "a" has a 3 in it, and that is what is used.
As a general rule, it would be very bad for f to use the original assignment when its executed. That would mean that functions couldn't take advange of global variables changing. It would also require that global variables be assigned before the function is even defined, which is not particularly useful for a dynamic language.
You can hack it, though. If you define a parameter with a default value, it will be assigned when the function is defined and you get what you want.
a = 10
def f(x, a=a):
return x + a
a = 3
print(f(1))
You see, you've defined a before you defined f(x). But your call to f(1) was after you assigned the value 3 to "a".
f(x) will always use the current value of "a" when it its called, not when it is defined. If you want a constant value for "a" inside f(x), you should declare it inside the function, something like:
def f(x):
a = 10
return x + a
So I got the following code:
def foo(a, b, c):
try:
a = [0]
b[0] = 1
c[0] = 2
w[0] = 3
except:
pass
return z
x, y, z = [None], [None], [None]
w = z[:]
foo(x,y,z)
print(x,y,z,w)
The last line of the code print(x,y,z,w) prints [None] [1] [2] [3], however
I don't quite get it. Why are x,y,z are being changed from within the funciton? and if w changes - and it points to z, why doesnt z change accordingly?
In Python objects are passed by reference to functions.
This line makes a copy of z
w = z[:]
so changes to z don't affect w and vice versa. In the line
a = [0]
you change the reference to point to a new object, so you don't mutate x (which is what a was initially bound to). In the following lines
b[0] = 1
c[0] = 2
you mutate the objects that you got references to (y and z in global scope), so the objects in the outside scope change. In the line
w[0] = 3
you mutate the global object w since the name w is not a parameter of the function, nor is it bound in the body of the function.
What everyone else says is correct, but I want to add my way of thinking that may be helpful if you have experience with a language like C or C++.
Every variable in Python is a pointer (well, the technical term is a "reference", but I find that more difficult to visualize than "pointer"). You know how in C/C++ you can get a function to output multiple values by passing in pointers? Your code is doing essentially the same thing.
Of course, you may be wondering, if that is the case, why don't you see the same thing happening to ints, strs or whatnot? The reason is that those things are immutable, which means you cannot directly change the value of an int or a str at all. When you "change an integer", like i = 1, you are really changing the variable, pointing it to a different int object. Similarly, s += 'abc' creates a new str object with the value s + 'abc', then assigns it to s. (This is why s += 'abc' can be inefficient when s is long, compared to appending to a list!)
Notice that when you do a = [0], you are changing a in the second way --- changing the pointer instead of the object pointed to. This is why this line doesn't modify x.
Finally, as the others has said, w = z[:] makes a copy. This might be a little confusing, because for some other objects (like numpy arrays), this syntax makes a view instead of a copy, which means that it acts like the same object when it comes to changing elements. Remember that [] is just an operator, and every type of object can choose to give it a different semantical meaning. Just like % is mod for ints, and formatting for strs --- you sometimes just need to get familiar with the peculiarities of different types.
As I know, & is called 'reference operator' which means 'address of'. So, its role is storing address in any variable. For example, 'a=&b;'. But I know another meaning which is 'references'. As you know, references is a alias of a variable. So, in my result, & has two meaning according to position. If 'a=&b;', & means 'address of b'. If 'int &a = b;', & means 'alias of another variable'.
As I know, * is called 'dereference operator'. But It is like &, It has two meaning according to position. If 'int *a = &b', * means 'pointer variable'. If 'a=*b', * means 'dereference variable'.
Are they right????
P.S. I'm foriegner. So I'm poor at English. Sorry... my poor English.
Hi as I understand you are having confusion with the concepts of pointers and references. Let me try and break it down for you :
When we use either of these in a variable declaration, think of it as specifying the datatype of that variable.
For example,
int *a; creates a pointer variable 'a', which can hold the address of(in other words, point to) another integer variable.
Similarly int & a = b; creates a reference variable 'a' which refers to b(in other words 'a' is simply an alias to integer b).
Now it might look as they are same, infact they both serve similar functionality, but here are some differences:
A pointer has memory allocated for it to hold the address of another variable to which it points, whereas references don't actually store the address of the variable they are referencing.
Another difference would be that a pointer need not be initialized when it is declared, but a reference must be initialized when it is declared, otherwise it throws an error. ie; int * a; is ok whereas int & a; throws error.
Now for the operators, try and see them not at all associated with pointers or references(Although thats where we use them the most).
Reference operator(&) simply returns you the address of its operand variable. Whereas a dereferencing operator(*) simply assumes that the value of its argument is an address, and returns the value stored at that address.
Hope this helped you. Here are some useful references(no pun intended):
https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html
How does a C++ reference look, memory-wise?
I'm puzzled as to how arguments are passed into a cppFunction when we use Rcpp. In particular, I wonder if someone can explain the result of the following code.
library(Rcpp)
cppFunction("void test(double &x, NumericVector y) {
x = 2016;
y[0] = 2016;
}")
a = 1L
b = 1L
c = 1
d = 1
test(a,b)
test(c,d)
cat(a,b,c,d) #this prints "1 1 1 2016"
As stated before in other areas, Rcpp establishes convenient classes around R's SEXP objects.
For the first parameter, the double type does not have a default SEXP object. This is because within R, there is no such thing as a scalar. Thus, new memory is allocate making the & reference incompatible. Hence, the variable scope for the modification is limited to the function and there is never an update to the result. As a result, for both test cases, you will see 1.
For the second case, there is a mismatch between object classes. Within the first call object supplied is of type integer due to the L appended on the end, which conflicts with the C++ function expected type of numeric. The issue is resolved once the L is dropped as the object is instantiated as a numeric. Therefore, an intermediary memory location does not need to be created that is of the correct type to receive the value. Hence, the modification in the second case is able to propagate back to R.
e.g.
a = 1L
class(a)
# "integer"
a = 1
class(a)
# "numeric"