Is it possible to pass parameters by reference in Rebol? - rebol3

Here, I have attempted to set the value of a global variable from inside a function, but the value has not changed:
setGlobalScope: func [theVar1] [
theVar1: 10
]
theVar: 1
setGlobalScope theVar
print theVar
"This prints 1 instead of 10. The value of theVar has not changed."
Is it possible to modify the value of a function's parameter from inside the function itself, so that the value is modified within the global scope instead of the function's scope?

You passed an integer value, not a word. Within the function, the word theVar1 is assigned the value of that integer. Reassigning it doesn't change it, because values like integers and dates and decimal numbers aren't "pointers" under the hood.
Hence, the answer from #sqlab where you can get around this by various ways of getting the word itself. The difference between function ['x] [code] and function [:x] [code] may interest you as an aside...
Why doesn't Rebol 3 honor quoted function parameters that are parenthesized?
But note that series values in Rebol do have modifying functions that affect the target, vs. just reassignment of where the word points. Consider:
setGlobalScope: func [theVar1 [string!]] [
clear theVar1
insert theVar1 "Modification"
]
theVar: "Original"
setGlobalScope theVar
print theVar
That prints Modification.
If you need to pass non-series values by reference, you need to put them in a series and use series modification operations instead of assignment. Because an assignment would just overwrite the "pointer" you have to the block or whatever. Worst case scenario you can wrap a single value in a block--if you must. But Rebol has a lot of "wait, look at it this other way..." where dialecting comes to the rescue in creating a better interface than that thing you were trying to clone from another less cool language. :-)
Mitigating the complexity of passing by reference is Rebol's simplicity at handling multiple return results:
foo: function [value1 value2] [
return reduce [
value1 + 7
value2 + 16
]
]
set [a b] foo 03 04
print a
print b
That outputs 10 and 20.

By using a combination of lit-word and get-word there is more than one way.
e.g
>> setGlobalScope: func ['theVar1] [set :theVar1 10]
>> theVar: 1
== 1
>>
>> setGlobalScope theVar
== 10
>>
>> print theVar
10
and
>> setGlobalScope: func [theVar1] [set :theVar1 10]
>> theVar: 1
== 1
>> setGlobalScope 'theVar
== 10
>> print theVar
10

I think you can just modify your variable theVar directly in your setGlobalScope funct.

Related

I am not getting the desired output with my python code

<code>def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = number/10
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList, i)
if answer == 1:
print(i)
else:
continue`</code>
I am a beginner at programming and I was trying to write a code to print all the possible combinations of a number. If user enters a 3 digit number the program will check all the three digit numbers to find possible combinations but instead it gives all the numbers as output. For example if user enters 12 then the output should be 12 21 but instead it shows every number from 10 to 99.
As far as I know everything is working fine but the results are not as I expect.
This is a pass-by-reference vs pass-by-value problem. What that means is when you pass a list to a function in python you are not passing the values in that list, you are passing the list itself, or rather its location in memory. So when you are modifying MyList in your CheckNumber function you are actually modifying the MyList variable globally. This is not true for primitive types which is why modifying number does not change i in the for loop. Quick example:
def foo(my_list):
my_list.append('world')
print(my_list)
a = []
foo(a) # this will print out 'world'
print(a) # this will print out 'world'
b = 'hello'
foo(b.copy()) # This will print out 'hello world'
print(b) # Here we have not passed b directly into foo,
# but instead passed a copy, so this will just print out 'hello' as b
# has not been modified
To summarize variable are stored in a specific location in memory. When you pass-by-reference you are passing a long that location in memory so you variable will be mutated. If you pass-by-value, you function will create a new variable and store a copy of the data so you will not mutate your outer variable. In other languages you can specify which way to pass in a variable but afaik you cannot in python.
With that out of the way this is a very easy fix. You don't want to modify your original MyList so just make a copy of it and pass that into the function. You also forgot to cast number/10 to int in the CheckNumber function. The working code should look like this:
def CheckNumber(MyList, number):
counter=0
while number!=0:
for i,element in enumerate(MyList):
if number%10==element:
del MyList[i]
else:
continue
number = int(number/10)
if len(MyList)==0:
return 1
else:
return 2
print("Program to print all the possible combinations of a number")
MyNumber = int(input("Enter the number: "))
MyList = []
while MyNumber!=0:
MyList.append(MyNumber%10)
MyNumber=int(MyNumber/10)
MyLimit = 10**(len(MyList)-1)
for i in range(MyLimit, MyLimit*10):
answer = CheckNumber(MyList.copy(), i)
if answer == 1:
print(i)
else:
continue
More info on pass-by-reference:
What's the difference between passing by reference vs. passing by value?
https://blog.penjee.com/passing-by-value-vs-by-reference-java-graphical/
https://courses.washington.edu/css342/zander/css332/passby.html

"for var = 1, 2" in Lua

What does this kind of loop do in Lua?
for count = 1, 2 do
-- do stuff
end
The variable count isn't used in the body of the loop.
It executes the body of the loop twice.
There's no need to refer to count inside the loop unless you need to know its current value.
for count = 1,5 do
print("Hello")
end
prints
Hello
Hello
Hello
Hello
Hello
In this case count is "dummy variable" - "dummy" in that a variable is used fulfill a certain construct even though the variable is not used. (Another common name for such a usage is _, although count arguably adds a little more semantic intent.)
Such a dummy variable is used because LUA loops require a variable / assignment in the grammar construct. However, there is no requirement that the variable is used - hence a "dummy".
.. A numeric for [loop] has the following syntax:
for var=exp1,exp2,exp3 do
something
end
That loop will execute something for each value of var from exp1 to exp2, using exp3 as the step to increment var. This third expression [exp3] is optional; when absent, Lua assumes one [1] as the step value.

For loops LUA Different Types

I wanted to learn more about for loops, as far as I know there are different types?
For instance,
for i = 1, 5 do
print("hello")
end
^ I know about this one, it's going to print hello 5 times, but there are others like the one below which I do not understand, specifically the index bit (does that mean it is number 1?) and what is the ipairs for
for index, 5 in ipairs(x) do
print("hello")
end
If there are any other types please let me know, I want to learn all of them and if you can provide any further reading I'd be more than greatful to check them out
As you can read in the Lua reference manual
3.3.5 For Statement
The for statement has two forms: one numerical and one generic.
The numerical for loop repeats a block of code while a control
variable runs through an arithmetic progression. It has the following
syntax:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
Example:
for i = 1, 3 do
print(i)
end
Will output
1
2
3
You seem familiar with that one. Read the reference manual section for more details.
The generic for statement works over functions, called iterators. On
each iteration, the iterator function is called to produce a new
value, stopping when this new value is nil. The generic for loop has
the following syntax:
stat ::= for namelist in explist do block end namelist ::= Name {‘,’
Name}
Example:
local myTable = {"a", "b", "c"}
for i, v in ipairs(myTable) do
print(i, v)
end
Will ouput
1 a
2 b
3 c
ipairs is one of those iterator functions mentioned:
Returns three values (an iterator function, the table t, and 0) so
that the construction
for i,v in ipairs(t) do body end will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first nil value.
Read more about ipairs and pairs here:
https://www.lua.org/manual/5.3/manual.html#pdf-pairs
https://www.lua.org/manual/5.3/manual.html#pdf-ipairs
Of course you can implement your own iterator functions!
Make sure you also read:
Programming in Lua: 7 Iterators and the Generic for
Yes, It will print hello 5 times
According to this answer on Difference between pairs, ipairs, and next?
ipairs does the exact same thing as pairs, but with a slight twist to it.
ipairs runs through the table, until it finds a nil value, or a value that is non-existent, if that makes sense. So, if you ran the script I showed you for pairs, but just replaced pairs with ipairs, it would do the exact same thing

Why do tabulate or summarize not take into account missing values when implemented inside a program?

As an illustrative example, suppose this is your dataset:
cat sex age
1 1 13
1 0 14
1 1 .
2 1 23
2 1 45
2 1 15
If you want to create a table of frequencies between cat and sex, you tabulate these two variables and you get the following result:
tab cat sex
| sex
cat | 0 1 | Total
-----------+----------------------+----------
1 | 1 2 | 3
2 | 0 3 | 3
-----------+----------------------+----------
Total | 1 5 | 6
I am writing a Stata program where the three variables are involved, i.e. cat, sex and age. Getting the matrix of frequencies for the first two variables is just an intermediate step that I need for further computation.
cap program drop myexample
program def myexample, rclass byable(recall) sortpreserve
version 14
syntax varlist [aweight iweight fweight] [if] [in] [ , AGgregate ]
args var1 var2 var3
tempname F
marksample touse
set more off
if "`aggregate'" == "" {
local var1: word 1 of `varlist'
local var2: word 2 of `varlist'
local var3: word 3 of `varlist'
qui: tab `var1' `var2' [`weight' `exp'] if `touse', matcell(`F') label matcol(`var2')
mat list `F'
}
end
However, when I run:
myexample cat sex age
I get this result which is not what I expected:
__000001[2,2]
c1 c2
r1 1 1
r2 0 3
That is, given that age contains a missing value, even if it is not directly involved in the tabulation, the program ignores the missing value and does not take into account that observation. I need to get the result of the first tabulation. I have tried using summarize instead, but the same problem arises. When implemented inside the program, missing values are not counted.
You are complaining about behaviour which you built into your own program. The responsibility and the explanation are in your hands.
The effect of
marksample touse
followed by calling up a command with the qualifier
if `touse'
is to ignore missing values. marksample by default marks as "to use" those observations in which all variables specified have non-missing values; the other observations are marked as to be ignored. It also takes account of any if or in qualifiers and any zero weights.
It's also true, as #Noobie explains, that omitting missing values from a tabulation is default for tabulate in any case.
So, to get the result you want you'd need to modify your marksample call to
marksample touse, novarlist
and to call up tabulate with the missing option (if it's compulsory) or to allow users to specify a missing option which you then pass to tabulate.
You also ask about summarize. By design that command ignores missing values. I don't know what you would expect summarize to do about them. It could report a count of missing values. If you want that, several other commands will oblige, such as codebook or missings (Stata Journal). You can always include a report on missings in your program, such as using count to count the missings and display the result.
I understand your program to be very much work in progress, so won't comment on details you don't ask about.
This is caused by marksample. Rule 5 in help mark states
The marker variable is set to 0 in observations for which any of the
numeric variables in varlist contain a numeric missing value.
You should use the novarlist option. According to the help file,
novarlist is for use with marksample. It specifies that missing values
among variables in varlist not cause the marker variable to be set to 0.
if I understand well you want tab to include missing values? If so, you just have to ask for it
tab myvar1 myvar2, mi
from the documentation
missing : treat missing values like other values

Change variable passed in a method [duplicate]

This question already has answers here:
'pass parameter by reference' in Ruby?
(6 answers)
Closed 8 years ago.
How can I change the contents of a variable using a method? Maybe I'm not saying this correctly. What is a way to get the reference to a variable like in C? Example:
// main stuff
int gorilla = 29;
makeMeABanana(&gorilla);
void makeMeABanana(int *gorilla) { }
How can I do something like this in Ruby?
You should not do this - you're just porting techniques that are fully appropriate to C to Ruby, where they are no longer appropriate. There are several fancy ways around this (eg using a Proc closed over your calling namespace, or eval) but they are usually inappropriate in Ruby unless you know precisely what you're doing.
Recently on the ruby-talk mailing list, someone asked about writing a swap function where swap(a,b) would swap the values of the variables "a" and "b". Normally this cannot be done in Ruby because the swap function would have no reference to the binding of the calling function.
However, if we explictly pass in the binding, then it is possible to write a swap-like function. Here is a simple attempt:
def swap(var_a, var_b, vars)
old_a = eval var_a, vars
old_b = eval var_b, vars
eval "#{var_a} = #{old_b}", vars
eval "#{var_b} = #{old_a}", vars
end
a = 22
b = 33
swap ("a", "b", binding)
p a # => 33
p b # => 22
This actually works! But it has one big drawback. The old values of "a" and "b" are interpolated into a string. As long as the old values are simple literals (e.g. integers or strings), then the last two eval statements will look like: eval "a = 33", vars". But if the old values are complex objects, then the eval would look like eval "a = #", vars. Oops, this will fail for any value that can not survive a round trip to a string and back.
Referred from : http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc
Integers are objects, with an id, like everything else in Ruby. They are implemented like this:
p (0..10).map{|n| n.object_id}
#=>[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
All other objects have even object_id numbers. There is no way to change 7 (object_id 15) into something else.

Resources