Pointers and references: Difference between revisions

(→‎{{header|PL/I}}: Section added)
Line 937:
 
To the first approximation, Perl 6 programmers do not think about references much; since everything is a reference, and value semantics are emulated by assign and other mutating operators, the ubiquitous references are largely transparent to the Perl 6 programmer most of the time.
 
=={{header|Phix}}==
Phix does not have pointers, other than for playing with raw allocated memory, typically for interfacing with another language pre-compiled into a dll/so, although for that builtins/cffi.e offers a more grown-up mechanism with seamless 32/64 bit portability. There is no pointer math beyond sizes in bytes.
<lang Phix>atom addr = allocate(8) -- (assumes 32 bit)
poke4(addr,{NULL,SOME_CONSTANT})
c_proc(xSome_External_Routine,{addr,addr+4})
?peek4s({addr,2}) -- prints {x,y}
free(addr)</lang>
There are in fact 5 variants of poke: poke1, poke2, poke4, poke8, and pokeN which allows the size to be dynamically specified.
Likewise there are 9 versions of peek: peek1s, peek2s, peek4s, peek8s, peek1u, peek2u, peek4u, peek8u, and peekNS, and again the
latter allows the size and signed flag to be dynamically specified. All variants can peek/poke a single byte/word/dword/qword or
a specified number of consecutive such from the specified address. Note that floating point values need to go via atom_to_float32
or float32_to_atom, where 32 could also be 64 or 80.
 
You can, of course use pointers via inline assembly (but only as a last resort/if you are mental enough):
<lang Phix>atom mypi
#ilASM{
fldpi
[32]
lea edi,[mypi]
[64]
lea rdi,[mypi]
[]
call :%pStoreFlt }</lang>
or
<lang Phix>string mystring = "mystring"
#ilASM{
[32]
mov esi,[mystring]
lea esi,[ebx+esi*4] -- byte[esi] is 'm'
[64]
mov rsi,[mystring]
lea rsi,[rbx+rsi*4] -- byte[rsi] is 'm'
[]
}</lang>
Of course in a reference counted language like Phix, playing directly with the innards like that may have dire unexpected side effects.
Phix does not have references, however everything is passed by reference, with copy-on-write semantics. Unless the source and destination are the same, and it is local, so it cannot possibly be referenced elsewhere, in which case automatic pass-by-reference is used, which for Phix means skipping the reference counting. For example:
<lang Phix>sequence s
s = myfunc(s)</lang>
It is a general optimisation, applied by the complier whenever and wherever it can, without the programmer having to do anything special.
Several of the builtins, for instance s = append(s,thing) have a similar optimisation, as long as s occurs on both the rhs and lhs, and less any need for it to be local (since the builtins are non-recursive leaf routines).
 
Phix takes the view that there should be as few as possible unintended side effects. If you see a line of code such as s = myfunc(...) then you have the full list of all [local] variables it will modify on the lhs, without needing to pick through the parameter list, though of course it might trample on a few external global or static variables. Personally I find that approach often helps me narrow down all the places where a bug might lurk much quicker, and that is certainly worth an occasional bit of extra typing on the lhs.
 
There is an extreme example in the interpreter. For performance, symtab names are left as a meaningless ternary tree index, until an error
occurs. At which point pEmit2.e/rebuild_callback() deliberately fudges the reference counting, so that it can replace all said indexes in
the symtab with string names, in situ, before repairing the reference count and continuing. It ain't pretty but it works well.
 
=={{header|PHP}}==
7,820

edits