tutorials

D

Dik T. Winter

>
> The key points you've made, IMO, are:
>
> 1. The arguments are expressions
> 2. The arguments are evaluated before the function is called
> 3. The results of the argument evaluation are assigned to the parameters

I think it is confusing when a beginning programmer finds different
terminology in different languages. And the description above does
*not* fit call by name or call by value-return, only call by reference
and call by value.
 
N

Nick Keighley

...
 > The distinction between "parameter" and "argument" is one that has
 > indeed been blurred over time, and it's unfortunate because
 > maintaining a clear distinction does have clear exegetic benefits.

I think that distinguishing them is more recent than blurring them.  I have
a Fortran reference from about 1977 where the disctinction is between
"actual argument" and "formal argument".  And in the Algol 60 reference
(1964) they are called "actual parameter" and "formal parameter".

darn! beat me to it
wiki has this to say "In maths and other subjects an argument can be a
parameter"
 
N

Nick Keighley

I don't remember this confusing me.
"The value of the argument x" doesn't sound right either. The argument is
the value of x, not x. This is where you can get tied up in knots. Best to
change the example to use different names for the formal parameter and the
local variables of the caller.

I will admit that googling for ""keyword arguments"" gets more than double
the number of hits than ""keyword parameters"", but I also admit I've never
really thought about it up to now, using mainly "parameter" for both.
Either: context will tell you whether formal or actual parameters or
arguments are being talked about, or "formal"/"actual" qualifiers can be
used.

And this common example:

 int main(int argc, char *argv[]) { ... }

does suggest argument/parameters are interchangeable; inside the function
argc and argv should be parameters, not arguments.

I must admit I hadn't thought about it much before. (Which reinforces
my argument that it isn't that important). Thinking about it I'm
pretty
sure I always use parameter and never argument

int frog (int x)
{
x++; /* increment the x parameter */
}

int mouse (int y)
{
frog (y); /* pass y to frog() */
}

now I'm not so sure... I suppose I might say things like
"then you have to call frog with a parameter of y"

If it's a more complicated expression
"call frog with the sum of the differences of the third quadrile"

avoiding them both!

big_frog (x, y + z + x);

"call big_frog with the first parameter set to one axis and the
second
two the sum of the axes"

I'm still pretty sure I hardly ever use argument in this conext.

[I was weaned on formal and actual parameters so maybe it stuck]
 
N

Nick Keighley

Richard Heathfield   said:
it may be helpful [...] to refer to arguments as ARGUMENT EXPRESSIONS,
as the word "expression" helps us to remember that we're not passing
objects to the function - we're just passing the results of evaluating
expressions.

I really like this approach, moreso than my example demonstration of
passing a constant and a variable with a different name than the
parameter.  And then combining it with the idea of assignment into
parameters helps hammer it home:

the parameters are *initialised* with the values of the arguments

The key points you've made, IMO, are:

1. The arguments are expressions
2. The arguments are evaluated before the function is called
3. The results of the argument evaluation are assigned to the parameters

Keith described the most confusing situation earlier when the argument
name is the same as that of the parameter, and I think what you have is
a good approach to sidestepping that issue.  (It's a false issue--it
shouldn't exist when described in the right light.  The fact that it
persists shows how difficult it is to obtain that "right light"!)

The casual use of the word "passed" is probably also confusing to
beginners.  They understand assignment--but is this something else like
some kind of magical reference passing?  One sentence could clarify
that.


It being perceived as harsh is entirely a bonus...? ;)

I don't remember parameter passing being a difficult concept.
Familiarity with mathematical functions maybe?
I'm not convinced that assignment *is* the right model.
Can you assign to a const? How does recursion work?


--
Nick Keighley

'And, Of course, I must give you the standard warning about
metaphoric
deformations.'
`All right,' Marvin said. `I'd like to hear about it.'
`I just gave it,' Blanders said. `But I will give it again. Watch out
or metaphoric deformations.'
(Robert Sheckly, Mindswap)
 
B

Ben Bacarisse

Nick Keighley said:
Richard Heathfield   said:
it may be helpful [...] to refer to arguments as ARGUMENT EXPRESSIONS,
as the word "expression" helps us to remember that we're not passing
objects to the function - we're just passing the results of evaluating
expressions.

I really like this approach, moreso than my example demonstration of
passing a constant and a variable with a different name than the
parameter.  And then combining it with the idea of assignment into
parameters helps hammer it home:

the parameters are *initialised* with the values of the arguments

Except that they are not! At least that is not the language used in
the standard. The reason is that initialisation is an odd beast in C.
It uses its own syntax and it can be applied to things that can't
assigned (like arrays). As a result, the standard references
assignment as the model for function calls:

6.5.2.2 Function calls

Constraints
[...]
2 If the expression that denotes the called function has a type that
includes a prototype, the number of arguments shall agree with the
number of parameters. Each argument shall have a type such that
its value may be assigned to an object with the unqualified
version of the type of its corresponding parameter.

Semantics
[...]
4 An argument may be an expression of any object type. In preparing
for the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument.

I don't remember parameter passing being a difficult concept.
Familiarity with mathematical functions maybe?
I'm not convinced that assignment *is* the right model.

Agreed. I'd prefer it to be initialisation but the boat has sailed on
that one.
Can you assign to a const? How does recursion work?

All that is need for const to work is the phrase "unqualified version
of" in the part I quoted. Recursion is a non-problem since assignment
to local variables is entirely consistent with it, so is defining
parameter passing in terms of assignment. [Equally the argument could
be flipped -- whatever problem you see for assignment and recursion is
likely to remain if parameters are initialised.]
 
B

Beej Jorgensen

Nick Keighley said:
the parameters are *initialised* with the values of the arguments

Yes, but, at risk of being further corrected, I present this evidence on
my behalf:

C99 6.5.2.2p4:
# An argument may be an expression of any object type. In preparing for
# the call to a function, the arguments are evaluated, and each
# parameter is assigned the value of the corresponding argument.

C99 6.5.2.2p7:
# If the expression that denotes the called function has a type that
# does include a prototype, the arguments are implicitly converted, as
# if by assignment, to the types of the corresponding parameters, taking
# the type of each parameter to be the unqualified version of its
# declared type.
I don't remember parameter passing being a difficult concept.

I don't, either, though I do remember trying to bend what I knew about
Pascal at the time ("var" in particular). And so many modern languages,
especially those used by beginners like Java or Python, pass references
around.
I'm not convinced that assignment *is* the right model. Can you assign
to a const?

That might be confusing, I admit. But I think maybe they can cross that
bridge when they come to it.
How does recursion work?

I don't see the conflict here--would you elaborate? The expressions are
evaluated and the parameters initialized with the results, just as
always.

What I'm generally thinking here is that perhaps over-stressing the
notion that there is an expression evaluation and assignment can help
with clarity not only in the simple cases (argument "x", parameter also
"x"), but also lay the proper groundwork for more advanced cases
(recursion, pointer arguments.)

1. "When the function is called, its arguments are passed to it."

2. "When the function is called, its arguments are evaluated, then
assigned into its parameters."

While I think (1) is fine for casual conversation, it might not be the
most secure foundation for a beginner unclear on the mechanism. And (2)
(along the lines of what RH was saying) is written in terms of
evaluation and assignment, both ideas that a newbie should be familiar
with by the time s/he learns how to write functions.

And here I'm more than willing to admit that using the proper
terminology would be very useful. :)

-Beej
 
J

jameskuyper

Richard said:
superpollo said:


No idea. Try asking its author.

I think that what he obviously meant by that question was "What
features does it posses that make it seem unreadable to you?". The
author doesn't know the answer to that question; only you do.
Misinterpreting his question the way that you did is reasonable only
as a joke.

I checked that web site. The font was readable, the language was
English, the spelling, grammar, and writing style did not seem
unusually poor, so I too am at a loss to understand the basis for your
evaluation of it as "unreadable". If you had said that it was
inaccurate, I can't claim to have looked at it closely enough to
confirm or deny that assessment; but you said it was unreadable.
 
B

Ben Bacarisse

Beej Jorgensen said:
1. "When the function is called, its arguments are passed to it."

2. "When the function is called, its arguments are evaluated, then
assigned into its parameters."

[Aside: I don't like the first "its" in either (1) or (2) the
arguments don't belong to the function but to the call. Yes, a small
point but why not just say "the" and avoid the association.]
While I think (1) is fine for casual conversation, it might not be the
most secure foundation for a beginner unclear on the mechanism. And (2)
(along the lines of what RH was saying) is written in terms of
evaluation and assignment, both ideas that a newbie should be familiar
with by the time s/he learns how to write functions.

And here I'm more than willing to admit that using the proper
terminology would be very useful. :)

For what it's worth, the phrasing I prefer is the entirely
non-standard: "the function's parameters are initialised, as if by
assignment, using the values of the corresponding argument
expressions".
 
B

Beej Jorgensen

Ben Bacarisse said:
[Aside: I don't like the first "its" in either (1) or (2) the
arguments don't belong to the function but to the call. Yes, a small
point but why not just say "the" and avoid the association.]

That's a good point. The way I had written it could lead to
argument/parameter confusion all over again, albeit indirectly.
For what it's worth, the phrasing I prefer is the entirely
non-standard: "the function's parameters are initialised, as if by
assignment, using the values of the corresponding argument
expressions".

That sounds reasonable to me.

-Beej
 
P

Phil Carmody

Keith Thompson said:
I absolutely disagree. A beginner's tutorial is exactly where it's
most important to make a clear distinction. You don't have to use the
terms "argument" and "parameter"; you can use "actual parameter" and
"formal parameter" if you like. But since the C standard uses the
terms "argument" and "parameter", using the same terms in a tutorial
is easier and less likely to lead to future confusion.

Concur.

I like to keep 'formal' in the receiving side (and strongly prefer
'parameter'.) To me, 'formal' has a kind of 'template', or 'mould'
feel to it - I don't care what you try and stick there, contrive
all you want, I'm going to refer to it as [parameter name].
Here's an example I posted earlier in this thread:

#include <stdio.h>

void func(int x)
{
printf("x = %d\n", x);
x ++;
}

int main(void)
{
int x = 42;
func(x);
printf("x = %d\n", x);
return 0;
}

How do you distinguish between the x that appears as a subexpression
in the function call and the x declared in func? How would you
explain the distinction to a beginner if you use the same term for
both? "The value of the parameter x is copied to the parameter x"?

int bar(int x, int d);
int foo(int x, int d)
{
return d>0?bar(x, d-1):x;
}
int bar(int x, int d)
{
return d>0?foo(x, d-1):x;
}

How would you distinguish between the x that appears in the function
call to foo and the and the x declared in foo? And how about the x
that appears in the function call to bar, and the x declared in foo?
Of course, the parameter is an argument in this case, there's nothing
preventing that, which is why one can contrive all one wants.

Phil
 
P

Phil Carmody

Beej Jorgensen said:
No one likes informality more than I do, but this is a case where one
can be exact with no particular loss. There's no gain here in playing
fast-and-loose, especially when so many people already think of the
terms interchangeably--you might as well say "parameter" when that's
what you mean.

I do, however, agree that simply stressing that "these are arguments,
and these are parameters" is not particular useful or vital information
on its own, and fixating on the details of the definitions can be
counter-productive. It's the behavior that's important, and it would
not surprise me one bit to find C programmers who are 100% clear on the
distinction between arguments and parameters without knowing the
difference between the two terms.

I work in a company, or an office, where I hear "can you borrow me
your B3 proto, please?" almost daily. Such usage doesn't make the
distinction between lending and borrowing, which perturbs most of
my workmates not one jot, but yes, I do find that distinction
important.

Phil
 
N

Nick Keighley

On 16 July, 23:05, Phil Carmody <[email protected]>
wrote:

I work in a company, or an office, where I hear "can you borrow me
your B3 proto, please?" almost daily. Such usage doesn't make the
distinction between lending and borrowing, which perturbs most of
my workmates not one jot, but yes, I do find that distinction
important.

Derbyshire?
 
N

Nick Keighley

Yes, but, at risk of being further corrected, I present this evidence on
my behalf:

nope, I was simply wrong. It was "obvious" to me that this was
initialisation
rather than assignment. But I confess I didn't check.

C99 6.5.2.2p4:
# An argument may be an expression of any object type. In preparing for
# the call to a function, the arguments are evaluated, and each
# parameter is assigned the value of the corresponding argument.

C99 6.5.2.2p7:
# If the expression that denotes the called function has a type that
# does include a prototype, the arguments are implicitly converted, as
# if by assignment, to the types of the corresponding parameters, taking
# the type of each parameter to be the unqualified version of its
# declared type.


I don't, either, though I do remember trying to bend what I knew about
Pascal at the time ("var" in particular).  And so many modern languages,
especially those used by beginners like Java or Python, pass references
around.

I was trying to recall my first programming language. Were parameters
difficult to understand then? I don't think so.

I don't see the conflict here--would you elaborate?  The expressions are
evaluated and the parameters initialized with the results, just as
always.

I dunno. I do remmber having trouble with recursion. I think I thought
because variables local to a function (and I included parameters in
the
class of variables local to a function) only appeared in the code once
textually (lexically) speaking- then there was only a single instance
of
them. But why initialisation rather tha assignment would fix this
conceptual
error I'm not sure. I suppose I was thinking (this is the current me
not
the historical one) "initialise the variable" true attention to the
fact
that a brand new variable was being created.

Trying to think like a new programmer is hard! I'm sure the set of
possible
misconceptions is gigantic. I used not to put blank lines to save disk
space
(I assumed a blank line took a whole line's worth of characters (80 I
suppose))

<snip>
 
B

Ben Bacarisse

I dunno. I do remmber having trouble with recursion. I think I
thought because variables local to a function (and I included
parameters in the class of variables local to a function) only
appeared in the code once textually (lexically) speaking- then there
was only a single instance of them.

Did you start with FORTRAN? In early FORTRAN (hence the caps) this
was the case (or it was permitted to be the case). Compilers could
reserve a fix block of memory for a subroutine's local data since
there was no recursion. If that is the model you know, recursion
looks very odd at first.
Trying to think like a new programmer is hard! I'm sure the set of
possible misconceptions is gigantic. I used not to put blank lines
to save disk space (I assumed a blank line took a whole line's worth
of characters (80 I suppose))

But it did! On the same FORTRAN system if you were permitted to store
your card deck to the disk system, a blank card used up 80 precious
bytes.
 
B

Beej Jorgensen

Nick Keighley said:
I was trying to recall my first programming language. Were parameters
difficult to understand then? I don't think so.

I don't think they're particularly difficult, but I remember working in
the lab at school and answering lots of questions which were the result
of basic misunderstandings of how parameters and arguments worked.
Clarification didn't take long, and 99% of people would "get" it, but
I've wondered where the confusion came from in the first place.

My background before C was BASIC, Assembly, and Pascal. (Assembly
before C was awesome; in a perfect world, I think I'd like to teach
people computer science from the ground up. In a money-driven world, we
start with Java or Python. :)

With Pascal, you could use the "var" keyword in your parameter list to
affect the argument from within the function (a "reference"? I don't
know the exact mechanism) and there was no corresponding simple way to
do that in C.

If my background had included Java or Python before C, I might find C
more confusing, but I'm not sure. More investigation is probably
warranted to see if this is true.
I think I thought because variables local to a function (and I included
parameters in the class of variables local to a function) only appeared
in the code once textually (lexically) speaking- then there was only a
single instance of them.

Hmmm! I think this is an excellent observation. And the simple 1-2-3 I
had posted earlier doesn't really suggest that a new copy of the
parameters is made each call. (A reader might question, "When you call
it again, what happens to the parameters? Do they get overwritten?")
But why initialisation rather tha assignment would fix this conceptual
error I'm not sure. I suppose I was thinking (this is the current me
not the historical one) "initialise the variable" true attention to the
fact that a brand new variable was being created.

I know the spec doesn't say anything about a stack. But it does say:

* Recursive calls are permitted (C99 6.5.2.2p11)

* Parameters are effectively declared at the top of the function body
block (C99 6.9.1p9)

* If a block containing an object is entered recursively, a new instance
of the object is created each time (C99 6.2.4p5-6)

It seems like there should be a way to present it very concisely in a
way a beginner would fully comprehend.
Trying to think like a new programmer is hard!

Yeah it is. When I mentioned teaching CSCI from the ground up earlier,
part of my reasoning is that people would get a foundation on
which to attach new knowledge. When they start with Java, it's just
like starting in free-floating space. Above the new programmers is all
kinds of stuff they don't know, and below them is all kinds of stuff
they don't know, and I worry that lack of context impedes their
learning. The mysterious stuff all around them can sometimes make for
strange assumptions.
When I was a a I'm sure the set of possible misconceptions is gigantic.

At least as large as the set of proper conceptions. :)
I used not to put blank lines to save disk space (I assumed a blank
line took a whole line's worth of characters (80 I suppose))

When I was a kid first starting with BASIC, I remember wondering what
all these "REM" statements were. I speculated that they didn't have an
effect, but in order to be sure, I put a new REM statement in my code
that ordered my spaceship to fly sideways instead of upward. It didn't
work. :) I felt sheepish. I still feel sheepish. :)

But these are the sorts of actual amazing misconceptions people can
have!

-Beej
 
R

Richard Bos

Dik T. Winter said:
I think it is confusing when a beginning programmer finds different
terminology in different languages.

True, but it is even more confusing when he finds a tutorial that
doesn't use any specific terminology consistently. It is inevitable that
different language Standards, and therefore different language texts,
use different terminology; but any single text should choose a single,
distinctive set of terms, and apply it consistently.

Richard
 
A

Antoninus Twink

It is easy for a C aficionado to pick tiny holes in the tutorial,
but that would be uncharitable and I don't plan to do it here.

How's that glass house you're living in, you unpleasant little worm?
here are three medium-to-large mistakes instead

In 1.3.2, the tutorial confuses "argument" and "parameter". [snip]
I was trying to avoid objecting to the claim that main() is always
the entry point, on the grounds that it is not that unreasonable to
expect the user to be concerned primarily with a hosted
implementation. But in 1.4.2.1
[snip]

"Medium-to-large"? What's it like living on Planet Heathfield? You
really need a sense of proportion.

Or as it says in the book that you and your fundamentalist friends claim
to live by, try removing the plank from your own eye before taking the
splinter out of your neighbor's.
 
A

Antoninus Twink

Unlike you, I welcome corrections.

This is a lie.

It is a matter of public record on this newsgroup that you refused to
acknowledge several bug reports from Han from China, even when you were
made aware of them by third parties while pretending to have killfiled
Han.
 
A

Antoninus Twink

One cannot help but wonder about the code quality of a man who is so
determined not to admit error.

Said without the slightest trace of irony. Amazing.
For example, on yesterday's reading I noticed that stddef.h is
referred to as a "file", which it can be but need not be, but I didn't
bother to mention this one.

Heathfield, you are beyond parody. It's no wonder the forger gave up
trying to outdo the real thing in absurdity.
Here's a curiosity: "The absence of a zero byte in a string is fatal
for any C program." But that's nonsense, because the absence of a zero
byte in a string is *impossible*.

Can you really not see that this absurd pedantry is the enemy of
pedagogy? No, I guess not.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
DewittMill
Top