Newbie question about scoping rules



Thanks to Richard I think I now understand what goes on. The definition

g(s) := arrayapply(s, [4]);

seems to work correctly in all cases.

Explanation(?):  s is protected inside g but not s[4] (if s[4] has a 
global meaning then it is evaluated immediately before subsituting
the parameter s with the argument to g).

Using arrayapply(s, [4]) is a trick(?) to avoid using s[4] directly.

====

As explained above gg(s):=s[4]; does not work. s[4] is evaluated 
immediately before any parameter subsitutions take place.

====

ggg(s):=block([],local(s),s[4]);

does not work since now ggg(s) returns s_4 (unevaluated). Explanation: 
since s is now local to ggg, s[4] is protected but unfortunately ggg 
also does no longer know the global meaning of s_4.

Note however that ggg(t) does work! After replacing the parameter s by t 
the result is t_4 but since t is not defined as local, maxima can look 
up the definition of t_4 in the global environment and evaluate it further.

======

Wouldn't is be more natural if things like s[4] were automatically
protected inside a function body if s is a parameter?
It seems to me this is the way other languages behave.

Michel