How to specify a return of an array of unknown size in Chapel - function

I tried to rely on type inference for a function with signature:
proc mode(data: [?]int)
but the compiler said it could not resolve the return type (which is a warning in in itself I guess given there are only two return statements). I tried:
proc mode(data: [?]int): [?]int
but the compiler then said there was an internal error:
internal error: CAL0057 chpl Version 1.13.1.518d486
What is the correct way of specifying that the length of an array returned by a function can only be known at run time?

If the domain/size of the array being returned cannot be described directly in the function prototype, I believe your best bet at present is to omit any description of the return type and lean on Chapel's type inference machinery to determine that you're returning an array (as you attempted). For instance, here is a procedure that reads in an array of previously unknown size and returns it:
proc readArrFromConsole() {
var len = stdin.read(int);
var X: [1..len] real;
for x in X do
x = stdin.read(real);
return X;
}
var A = readArrFromConsole();
writeln(A);
Running it and typing this at the console:
3 1.2 3.4 5.6
Generates:
1.2 3.4 5.6
Your question mentions multiple return statements, which opens up the question about how aggressively Chapel unifies types across distinct arrays. A simple example with multiple arrays of the same type (each with a unique domain, size, and bounds) seems to work:
proc createArr() {
var len = stdin.read(int);
if (len > 0) {
var X: [1..len] real;
return X;
} else {
var Y: [-1..1] real;
return Y;
}
}
var A = createArr();
writeln(A);
To understand why the compiler couldn't resolve the return type in your example may require more information about what your procedure body / return statements contained.

I've come across this from time to time in recursive functions, in situations where omitting the return type fails; in this case I create a record which is an array with its domain, e.g.:
record stringarray {
var D: domain(1);
var strs : [D] string;
}
and then define the recursive array to return one of those records:
proc repeats() : stringarray {
var reps: stringarray;
//...
for child in children do {
childreps = child.repeats();
for childrep in childreps do
reps.push_back(childrep);
}
//...
return reps;
}

Related

Error while passing values using peekpoketester

I am trying to pass some random integers (which I have stored in an array) to my hardware as an Input through the poke method in peekpoketester. But I am getting this error:
chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
What could be the reason? I don't think I need a module wrap here as this is not hardware.
class TesterSimple (dut: DeviceUnderTest)(parameter1 : Int)(parameter2 : Int) extends
PeekPokeTester (dut) {
var x = Array[Int](parameter1)
var y = Array[Int](parameter2)
var z = 1
poke(dut.io.IP1, z.asUInt)
for(i <- 0 until parameter1){poke(dut.io.IP2(i), x(i).asUInt)}
for(j <- 0 until parameter2){poke(dut.io.IP3(j), y(j).asUInt)}
}
object TesterSimple extends App {
implicit val parameter1 = 2
implicit val parameter2 = 2
chisel3.iotesters.Driver (() => DeviceUnderTest(parameter1 :Int, parameter2 :Int)) { c =>
new TesterSimple (c)(parameter1, parameter2)}
}
I'd suggest a couple of things.
Main problem, I think you are not initializing your arrays properly
Try using Array.fill or Array.tabulate to create and initialize arrays
val rand = scala.util.Random
var x = Array.fill(parameter1)(rand.nextInt(100))
var y = Array.fill(parameter2)(rand.nextInt(100))
You don't need the .asUInt in the poke, it accepts Ints or BigInts
When defining hardware constants, use .U instead of .asUInt, the latter is a way of casting other chisel types, it does work but it a backward compatibility thing.
It's better to not start variables or methods with capital letters
I suggest us class DutName(val parameter1: Int, val parameter2: Int) or class DutName(val parameter1: Int)(val parameter2: Int) if you prefer.
This will allow to use the dut's paremeters when you are writing your test.
E.g. for(i <- 0 until dut.parameter1){poke(dut.io.IP2(i), x(i))}
This will save you have to duplicate parameter objects on your DUT and your Tester
Good luck!
Could you also share your DUT?
I believe the most likely case is your DUT does not extend Module

How to write the type signature of a template function in Chapel

In trying to write an arithmetic mean function, it is perhaps better to write one template function rather than two type specific functions. One can write:
proc mean(data: [?] ?T): real
but how to restrict T to being int or real.
Also is it possible to define an array that can have either int or real data, i.e. is there a way of expressing union types for array contents?
To restrict the type of T to int or real types of any size you can add a where clause to the function definition:
proc mean(data: [] ?T): real where isIntType(T) || isRealType(T) { ... }
The isIntType and isRealType functions are defined in the Types module: http://chapel.cray.com/docs/latest/modules/standard/Types.html
Chapel supports safe unions and arrays of unions. Unions are described in section 17 of the Chapel language specification: http://chapel.cray.com/docs/latest/_downloads/chapelLanguageSpec.pdf
union IntOrReal {
var i: int;
var r: real;
}
var intRealArray: [1..2] IntOrReal;
intRealArray[1].i = 1;
intRealArray[2].r = 2.0;

error (Reducer: ) when attempting to do distinct reduce

I am getting an error when trying to do a DISTINCT reduce that I got from here. I have reproduced this error on the beer-sample bucket, so this should be easy to reproduce. I have not seen any errors in the mapreduce_errors.txt file, or anything that would lead me anywhere in the others. (If you would like me to search or post snippets of other files, please ask).
Running couchbase enterprise 4 beta, on Windows 2008 R2 (This also happened on the 3.0.1 community edition as well.).
Here is my map function (Using the beer-sample bucket, that ships directly with couchbase).
function(doc, meta) {
switch(doc.type) {
case "brewery":
emit(meta.id);
break;
}
}
Here is my reduce function:
function(keys, values, rereduce) {
return keys.filter(function (e, i, arr) {
return arr.lastIndexOf(e) === i;
});
}
This is the error:
reason: error (Reducer: )
Also an imgur of the view page if it helps: http://i.imgur.com/KyLutMc.png
The problem lies within your custom reduce function: you're not handling the case when it's being called as part of a re-reduce.
As per Couchbase documentation:
The base format of the reduce() function is as follows:
function(key, values, rereduce) {
...
return retval;
}
The reduce function is supplied three arguments:
key: The key is the unique key derived from the map() function and the
group_level parameter.
values: The values argument is an array of all of the values that match
a particular key. For example, if the same key is output three times,
data will be an array of three items containing, with each item
containing the value output by the emit() function.
rereduce: The rereduce indicates whether the function is being called
as part of a re-reduce, that is, the reduce function being called
again to further reduce the input data.
When rereduce is false:
The supplied key argument will be an array where the first argument is the key as emitted by the map function, and the id is the document ID that generated the key.
The values is an array of values where each element of the array matches the corresponding element within the array of keys.
When rereduce is true:
key will be null.
values will be an array of values as returned by a previous reduce() function. The function should return the reduced version
of the information by calling the return() function. The format of the
return value should match the format required for the specified key.
Bold formatting is mine, and the highlighted words are quite important: you should consider that sometimes, you'll receive the keys argument with a value of null.
According to the docs, you should handle the case when rereduce is true within your reduce() function, and you should know that in this case, keys will be null. In the case of your reduce() function, you could do something like this:
function(keys, values, rereduce) {
if (rereduce) {
var result = [];
for (var i = 0; i < values.length; i++) {
var distinct = values[i];
for (var j = 0; j < distinct.length; j++) {
result.push(distinct[j]);
}
}
return result.filter(function (e, i, arr) {
return arr.lastIndexOf(e) === i;
});
}
return keys.filter(function (e, i, arr) {
return arr.lastIndexOf(e) === i;
});
}
Here, I'm firstly handling the re-reduce phase. For this I'm flattening the array of arrays that I'm receiving in the values argument and then I'm removing the duplicates that might have appeared after the merge.
Then it comes your original code, which returns the keys argument array without duplicates.
To test that this reduce() function actually works, I've used the following map() function:
function(doc, meta) {
switch(doc.type) {
case "brewery":
emit(meta.id, null);
emit(meta.id, null);
break;
}
}
This intentionally generates duplicates, which then are removed by the reduce() function.
While this reduce works as a development view, it does not as a production view. The dataset must be too large so you have to implement the rereduce. This documentation should help http://docs.couchbase.com/admin/admin/Views/views-writing.html#reduce-functions

Scala: How to write a generic check function that evaluates any function that returns boolean?

I'm struggling a bit with this: I need a function that takes any function
of type fun(Any*) : Boolean as parameter, evaluates the function and returns true or
false, depending on the success of the function evaluation.
Essentially, what I need is a function type that allows any number and any type of parameter but the function must return Boolean.
Which would allow me to write functions like:
def checkLenght(str : String, length : Int) : Boolean ={
if (str.lenght == length)}
or
def ceckAB(a : Int, b : Int) : Boolean = {
if(a < b && a >= 23 && b < 42) }
so that, for example
eval(checkLenght(abc, 3)) //returns true
eval(ceckAB(4,1)) // returns false
I thought, a function type of:
type CheckFunction = (Any*) => Boolean
may does the trick but I struggle with writing the generic eval function.
Any advise?
Thank you
Solution:
The function requires
1) Another function of return type Boolean: "(func : => Boolean)"
2) Return type Boolean ": Boolean"
3) Returns the value of the passed function-parameter: " = func"
Altogether the function is:
def eval(func : => Boolean) : Boolean = func
It amazes me over again how simple simple things are in Scala.
As pointed out by the comments, this is a rather unusual function with no obvious
sense. Just a word about the underlying reasons.
Motivation:
There were a lot of question about the underlying motivation, so here a short
summary why such a function is needed.
Essentially, there are two reasons.
First one is about moving the failure handling away from the function itself
into a handler function. This preserves the purity of the check function and even allows
re-usage of generic checks.
Second, it's all about "pluggable failure handling". This means, the eval function only
tells if a failure happened (or not). In case of a failure, a handler is called through an interface. The implementation of the handler can be swapped using profiles as required.
Why?
Swapping profiles means, I code my checks and functions as usual but by switching the
profile, I switch the handler which means I can chose between full-stop, console print out, email alert, SNMP notification, push message... you name it. To do so, I need to decouple the check function from its evaluation and from its handling. That's the motivation for such a rather strange looking eval function.
And for the sake of completeness, I've already implemented all that stuff but was I facing the limitation of only handling trivial checks i.e. check(Boolean*) which is neat but often I would prefer to write a function to do more sophisticated checks.
Solved
The function is defined by returning the value of the passed function:
def eval(func : => Boolean) : Boolean = {func}
I can't say that I really understand your motivations for wanting to do what you want to do, but I guess that's beside the point. Maybe the eval function will check something before invoking the supplied function and not invoke that other function (like a fast fail) given some certain condition. Maybe you do some post checking after invoking the function and change the result based on something else. Either way, I suppose you could accomplish something similar to what you want with code looking like this:
def main(args: Array[String]) {
val str = "hello world"
println(eval(checkLength(str, 3)))
println(eval(intsEqual(1,1)))
}
def eval(func: => Boolean):Boolean = {
//Do whetever you want before invoking func, maybe
//not even invoke it if some other condition is present
val fres = func
//Maybe change something here before returning based on post conditions
fres
}
def checkLength(s:String, len:Int) = s.length() == len
def intsEqual(a:Int, b:Int) = a == b
If you really want the eval function to be able to support any function that takes any types of args and returns a Boolean, then using a by-name function like this, and then leveraging closure inside the by-name function to pass any params along to whatever actual function you want to invoke. A better way to demonstrate this is as follows:
def checkMyString(str:String, len:Int) = {
eval(str.length == len)
}
It's probably hard to see that the check str.length == len is not invoked unless eval decides to invoke it until you expand it to it's true form:
def checkMyString(str:String, len:Int) = {
def check = {
str.length == len
}
eval(check)
}
Here, the nested function check has access to str and len due to closure, and this will allow you to get around the requirement that eval must be able to invoke a function with any params that returns a Boolean.
This is just one way to solve your problem, and it might not even be suitable given your needs, but I just wanted to throw it out there.
If your input functions only have 2 arguments, like your two examples, you can write a semi generic function take takes all functions with two arguments of any type:
def eval[A,B](func: (A,B) => Boolean, arg1: A, arg2: B) = {
func(arg1, arg2)
}
def checkLength(str: String, length: Int) : Boolean = {
str.length == length
}
eval(checkLength, "ham", 4)
res0: Boolean = false
But if you want to support functions with more arguments, you would have to write one eval function for three arguments, four arguments, etc
Maybe there is a better way that can handle all cases?

Pass by reference or pass by value? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
When learning a new programming language, one of the possible roadblocks you might encounter is the question whether the language is, by default, pass-by-value or pass-by-reference.
So here is my question to all of you, in your favorite language, how is it actually done? And what are the possible pitfalls?
Your favorite language can, of course, be anything you have ever played with: popular, obscure, esoteric, new, old...
Here is my own contribution for the Java programming language.
first some code:
public void swap(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
calling this method will result in this:
int pi = 3;
int everything = 42;
swap(pi, everything);
System.out.println("pi: " + pi);
System.out.println("everything: " + everything);
"Output:
pi: 3
everything: 42"
even using 'real' objects will show a similar result:
public class MyObj {
private String msg;
private int number;
//getters and setters
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
//constructor
public MyObj(String msg, int number) {
setMsg(msg);
setNumber(number);
}
}
public static void swap(MyObj x, MyObj y)
{
MyObj tmp = x;
x = y;
y = tmp;
}
public static void main(String args[]) {
MyObj x = new MyObj("Hello world", 1);
MyObj y = new MyObj("Goodbye Cruel World", -1);
swap(x, y);
System.out.println(x.getMsg() + " -- "+ x.getNumber());
System.out.println(y.getMsg() + " -- "+ y.getNumber());
}
"Output:
Hello world -- 1
Goodbye Cruel World -- -1"
thus it is clear that Java passes its parameters by value, as the value for pi and everything and the MyObj objects aren't swapped.
be aware that "by value" is the only way in java to pass parameters to a method. (for example a language like c++ allows the developer to pass a parameter by reference using '&' after the parameter's type)
now the tricky part, or at least the part that will confuse most of the new java developers: (borrowed from javaworld)
Original author: Tony Sintes
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
"Output
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0"
tricky successfully changes the value of pnt1!
This would imply that Objects are passed by reference, this is not the case!
A correct statement would be: the Object references are passed by value.
more from Tony Sintes:
The method successfully alters the
value of pnt1, even though it is
passed by value; however, a swap of
pnt1 and pnt2 fails! This is the major
source of confusion. In the main()
method, pnt1 and pnt2 are nothing more
than object references. When you pass
pnt1 and pnt2 to the tricky() method,
Java passes the references by value
just like any other parameter. This
means the references passed to the
method are actually copies of the
original references. Figure 1 below
shows two references pointing to the
same object after Java passes an
object to a method.
(source: javaworld.com)
Conclusion or a long story short:
Java passes it parameters by value
"by value" is the only way in java to pass a parameter to a method
using methods from the object given as parameter will alter the object as the references point to the original objects. (if that method itself alters some values)
useful links:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
http://www.ibm.com/developerworks/java/library/j-passbyval/
http://www.ibm.com/developerworks/library/j-praxis/pr1.html
http://javadude.com/articles/passbyvalue.htm
Here is another article for the c# programming language
c# passes its arguments by value (by default)
private void swap(string a, string b) {
string tmp = a;
a = b;
b = tmp;
}
calling this version of swap will thus have no result:
string x = "foo";
string y = "bar";
swap(x, y);
"output:
x: foo
y: bar"
however, unlike java c# does give the developer the opportunity to pass parameters by reference, this is done by using the 'ref' keyword before the type of the parameter:
private void swap(ref string a, ref string b) {
string tmp = a;
a = b;
b = tmp;
}
this swap will change the value of the referenced parameter:
string x = "foo";
string y = "bar";
swap(x, y);
"output:
x: bar
y: foo"
c# also has a out keyword, and the difference between ref and out is a subtle one.
from msdn:
The caller of a method which takes an
out parameter is not required to
assign to the variable passed as the
out parameter prior to the call;
however, the callee is required to
assign to the out parameter before
returning.
and
In contrast ref parameters are
considered initially assigned by the
callee. As such, the callee is not
required to assign to the ref
parameter before use. Ref parameters
are passed both into and out of a
method.
a small pitfall is, like in java, that objects passed by value can still be changed using their inner methods
conclusion:
c# passes its parameters, by default, by value
but when needed parameters can also be passed by reference using the ref keyword
inner methods from a parameter passed by value will alter the object (if that method itself alters some values)
useful links:
http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
http://www.c-sharpcorner.com/UploadFile/saragana/Willswapwork11162005012542AM/Willswapwork.aspx
http://en.csharp-online.net/Value_vs_Reference
Python uses pass-by-value, but since all such values are object references, the net effect is something akin to pass-by-reference. However, Python programmers think more about whether an object type is mutable or immutable. Mutable objects can be changed in-place (e.g., dictionaries, lists, user-defined objects), whereas immutable objects can't (e.g., integers, strings, tuples).
The following example shows a function that is passed two arguments, an immutable string, and a mutable list.
>>> def do_something(a, b):
... a = "Red"
... b.append("Blue")
...
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']
The line a = "Red" merely creates a local name, a, for the string value "Red" and has no effect on the passed-in argument (which is now hidden, as a must refer to the local name from then on). Assignment is not an in-place operation, regardless of whether the argument is mutable or immutable.
The b parameter is a reference to a mutable list object, and the .append() method performs an in-place extension of the list, tacking on the new "Blue" string value.
(Because string objects are immutable, they don't have any methods that support in-place modifications.)
Once the function returns, the re-assignment of a has had no effect, while the extension of b clearly shows pass-by-reference style call semantics.
As mentioned before, even if the argument for a is a mutable type, the re-assignment within the function is not an in-place operation, and so there would be no change to the passed argument's value:
>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']
If you didn't want your list modified by the called function, you would instead use the immutable tuple type (identified by the parentheses in the literal form, rather than square brackets), which does not support the in-place .append() method:
>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'
Since I haven't seen a Perl answer yet, I thought I'd write one.
Under the hood, Perl works effectively as pass-by-reference. Variables as function call arguments are passed referentially, constants are passed as read-only values, and results of expressions are passed as temporaries. The usual idioms to construct argument lists by list assignment from #_, or by shift tend to hide this from the user, giving the appearance of pass-by-value:
sub incr {
my ( $x ) = #_;
$x++;
}
my $value = 1;
incr($value);
say "Value is now $value";
This will print Value is now 1 because the $x++ has incremented the lexical variable declared within the incr() function, rather than the variable passed in. This pass-by-value style is usually what is wanted most of the time, as functions that modify their arguments are rare in Perl, and the style should be avoided.
However, if for some reason this behaviour is specifically desired, it can be achieved by operating directly on elements of the #_ array, because they will be aliases for variables passed into the function.
sub incr {
$_[0]++;
}
my $value = 1;
incr($value);
say "Value is now $value";
This time it will print Value is now 2, because the $_[0]++ expression incremented the actual $value variable. The way this works is that under the hood #_ is not a real array like most other arrays (such as would be obtained by my #array), but instead its elements are built directly out of the arguments passed to a function call. This allows you to construct pass-by-reference semantics if that would be required. Function call arguments that are plain variables are inserted as-is into this array, and constants or results of more complex expressions are inserted as read-only temporaries.
It is however exceedingly rare to do this in practice, because Perl supports reference values; that is, values that refer to other variables. Normally it is far clearer to construct a function that has an obvious side-effect on a variable, by passing in a reference to that variable. This is a clear indication to the reader at the callsite, that pass-by-reference semantics are in effect.
sub incr_ref {
my ( $ref ) = #_;
$$ref++;
}
my $value = 1;
incr(\$value);
say "Value is now $value";
Here the \ operator yields a reference in much the same way as the & address-of operator in C.
There's a good explanation here for .NET.
A lot of people are surprise that reference objects are actually passed by value (in both C# and Java). It's a copy of a stack address. This prevents a method from changing where the object actually points to, but still allows a method to change the values of the object. In C# its possible to pass a reference by reference, which means you can change where an actual object points to.
Don't forget there is also pass by name, and pass by value-result.
Pass by value-result is similar to pass by value, with the added aspect that the value is set in the original variable that was passed as the parameter. It can, to some extent, avoid interference with global variables. It is apparently better in partitioned memory, where a pass by reference could cause a page fault (Reference).
Pass by name means that the values are only calculated when they are actually used, rather than at the start of the procedure. Algol used pass-by-name, but an interesting side effect is that is it very difficult to write a swap procedure (Reference). Also, the expression passed by name is re-evaluated each time it is accessed, which can also have side effects.
Whatever you say as pass-by-value or pass-by-reference must be consistent across languages. The most common and consistent definition used across languages is that with pass-by-reference, you can pass a variable to a function "normally" (i.e. without explicitly taking address or anything like that), and the function can assign to (not mutate the contents of) the parameter inside the function and it will have the same effect as assigning to the variable in the calling scope.
From this view, the languages are grouped as follows; each group having the same passing semantics. If you think that two languages should not be put in the same group, I challenge you to come up with an example that distinguishes them.
The vast majority of languages including C, Java, Python, Ruby, JavaScript, Scheme, OCaml, Standard ML, Go, Objective-C, Smalltalk, etc. are all pass-by-value only. Passing a pointer value (some languages call it a "reference") does not count as pass by reference; we are only concerned about the thing passed, the pointer, not the thing pointed to.
Languages such as C++, C#, PHP are by default pass-by-value like the languages above, but functions can explicitly declare parameters to be pass-by-reference, using & or ref.
Perl is always pass-by-reference; however, in practice people almost always copy the values after getting it, thus using it in a pass-by-value way.
by value
is slower than by reference since the system has to copy the parameter
used for input only
by reference
faster since only a pointer is passed
used for input and output
can be very dangerous if used in conjunction with global variables
Concerning J, while there is only, AFAIK, passing by value, there is a form of passing by reference which enables moving a lot of data. You simply pass something known as a locale to a verb (or function). It can be an instance of a class or just a generic container.
spaceused=: [: 7!:5 <
exectime =: 6!:2
big_chunk_of_data =. i. 1000 1000 100
passbyvalue =: 3 : 0
$ y
''
)
locale =. cocreate''
big_chunk_of_data__locale =. big_chunk_of_data
passbyreference =: 3 : 0
l =. y
$ big_chunk_of_data__l
''
)
exectime 'passbyvalue big_chunk_of_data'
0.00205586720663967
exectime 'passbyreference locale'
8.57957102144893e_6
The obvious disadvantage is that you need to know the name of your variable in some way in the called function. But this technique can move a lot of data painlessly. That's why, while technically not pass by reference, I call it "pretty much that".
PHP is also pass by value.
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
Outputs:
a b
However in PHP4 objects were treated like primitives. Which means:
<?php
$myData = new Holder('this should be replaced');
function replaceWithGreeting($holder) {
$myData->setValue('hello');
}
replaceWithGreeting($myData);
echo $myData->getValue(); // Prints out "this should be replaced"
By default, ANSI/ISO C uses either--it depends on how you declare your function and its parameters.
If you declare your function parameters as pointers then the function will be pass-by-reference, and if you declare your function parameters as not-pointer variables then the function will be pass-by-value.
void swap(int *x, int *y); //< Declared as pass-by-reference.
void swap(int x, int y); //< Declared as pass-by-value (and probably doesn't do anything useful.)
You can run into problems if you create a function that returns a pointer to a non-static variable that was created within that function. The returned value of the following code would be undefined--there is no way to know if the memory space allocated to the temporary variable created in the function was overwritten or not.
float *FtoC(float temp)
{
float c;
c = (temp-32)*9/5;
return &c;
}
You could, however, return a reference to a static variable or a pointer that was passed in the parameter list.
float *FtoC(float *temp)
{
*temp = (*temp-32)*9/5;
return temp;
}