Re: copy & set statements
Re: copy & set statements
- Subject: Re: copy & set statements
- From: email@hidden
- Date: Tue, 23 Oct 2001 23:19:37 -0400
On Wed, 24 Oct 2001 11:14:26 +1000, From: Timothy Bates <email@hidden>
>
Here you said
>
"Unless you pass a reference to a function, AppleScript functions are pure
>
functions: they don't mess with their arguments."
>
>
But earlier you noted
>
>
"Actually, everything is passed as a pointer"
>
>
So Iam confused. The fact seems to be that everything is passed as a
>
reference (pointer) but that quite often dereferencing (copy to) is invoked
>
without our needing to worry about it.
Sorry to be confusing. Basically, my first statement is wrong when it comes to
lists, records, and script objects. But I'm such a hater of function
side-effects, I never try to make a handler change its arguments. For
everything but lists, records, and script objects, you can't mess with the
contents of the actual parameter. But you can mess with the internals of a list
and the properties of a record or script object.
Also, there is a difference between an AppleScript reference and a pointer.
They are not the same thing. I'll discuss that later.
>
But that is not the same as "AppleScript functions don't mess with their
>
arguments." What did you mean by the latter? Especially the quote below is
>
hard to implement as a scripter, because as you noted, AS indeed passes
>
references to functions
I think the way AppleScript works internally (based on no inside knowledge but
some very old second-hand information from Cal and I think Chris Nebel on how
parameters are passed to handlers) is like this: The actual parameter to a
function is passed in as a pointer. (Actually, probably as one of those Mac
two-hop "handles". But its conceptually just like a pointer.) The formal
parameter gets a copy of this pointer.
on myHandler(x)
-- x is the "Formal parameter"
end myHandler
set a to {1,2,3,4}
myHandler(a) -- a is the "actual parameter"
When you are in the handler, here's how the pointers look
myHandler's x ----
|
-------\
{1,2,3,4}
-------/
|
script's a--------
When you do "set x to 32", x gets changed to point to a '32' integer.
But when you do "set end of x to 32", AppleScript chases down the existing
pointer to the list, and adds the 32 to the end.
It makes perfect sense to the implementer, but confuses the heck out of
scripters.
I think a AppleScript "reference" is fundimentally different than a pointer.
You can pass a reference so that a handler can change the value of any type of
variable, so there is some similarity in function. But a reference is really
sort of a deferred evaluation, like an Algol "call by name" parameter. If you
say,
set L to {1,2,3,4}
set r to a reference to item -2 of L
set end of L to 5
contents of r
--> result: 4
The reference is quite literally "item -2 of L", and the items of L don't get
their positional numbers until the "contents of" is executed.
Here's a weird situation:
set L to {1,2,3,4}
set Lcount to a reference to the count of L
set Llength to a reference to the length of L
set end of L to 5
{Lcount, Llength, contents of Llength}
--> result: {4, length of {1,2,3,4,5}, 5}
The results are different because "length" is a property, while "count" is an
AppleScript command. So "a reference to the count of L" is simple "a reference
to 4", while "a reference to the length of L" doesn't get the length until you
ask for the contents of the reference.
In general, I try to avoid writing code that uses or is troubled by these odd
and counterintuitive behaviors. Its too easy to forget, or overlook, or screw
up, the funny interactions. And even if I get it right, six months from now,
I'll have to re-research the rules to figure out what a piece of code is doing.
--
Scott Norton Phone: +1-703-299-1656
DTI Associates, Inc. Fax: +1-703-706-0476
2920 South Glebe Road Internet: email@hidden
Arlington, VA 22206-2768 or email@hidden