> > > At some level every argument passing mechanism ever invented is "call by > > > value" because it consists of copying some bits from an arbitrary place > > > in the caller to some place that the callee knows to look for them.
> > This is not true.
> Yes it is.
> > In a call-by-reference language the bits that are passed to the > > callee are *not* a copy of the caller's bits but the address of the > > caller's bits.
> The caller either already has those bits stored explicitly in a register > or in the current stack frame, or else has those bits implicitly > available and regenerates them each time using something such as a > LEA/PEA (load/push effective address) instruction.
You are stretching the definition of `copying' rather far. In all cases of function calling, except tail-recursive calls that pass no arguments, there is transmission of information, and this occurs via bits in a digital computer. No argument there. But LEA isn't a copy operation.
If you told me to `copy this paper and give it to Smith' and instead of using the Xerox machine I told Smith that the original was in your office and he should feel free to do whatever he wanted to it, you'd be justifiably upset, and I don't think I could argue that conceptually a copy of *something* was transmitted to Smith, so your request was satisfied.
You are also stretching the definition of `place'. An LEA instruction does *not* work by ``copying some bits from an arbitrary place in the caller to some place that the callee knows to look for them''. It works by computing an offset (usually from the frame base).
"Takehiko Abe" <k...@ma.ccom> wrote in message news:keke-0505020053180001@solg4.keke.org... > In article <fosn59mdgp....@blume-pcmh.research.bell-labs.com>, Matthias Blume <matth...@shimizu-blume.com> wrote:
> > > Common Lisp doesn't copy its parameter, which is different from C.
> > Of course it does. If I write
> > (defvar x <something>) > > (defun f (y) (setq y <something else>)) > > (f x)
> > then f receives a copy of the contents of x.
> No, it doesn't. f receives the contents of x, not a copy of it. If that > <something> is mutable, you can modifiy it in f.
If F did not receive a copy of the contents of x, then it wouldn't be in X anymore. When F is running, there are two variables of interest, x and y. Both contain the same thing, yet they are not the same location. How could this be without something being copied?
> > The assignment to y will not affect x.
> Of course not.
It doesn't seem to be that obvious. In some languages assignment to Y *would* affect X (and vice versa). The have a name for this. It is `call-by-reference'.
>>>>Harbison & Steele states "C provides only call-by-value parameter >>>>passing. This means that the value of the actual parameters are >>>>conceptually copied into a storage area local to the called function." >>>><Sec 9.5>.
>>>So far you are correct.
>>>>This behavior is different from that of Common Lisp.
>>>They don't say that. And it would be wrong.
>>Common Lisp doesn't copy its parameter, which is different from C.
>>>PARAMETER PASSING IN LISP IS CALL-BY-VALUE.
>>Whatever. but Harbison & Steele clearly indicates in the above >>that call-by-value implies parameter copying. And that is what >>many people expect. so I think "call-by-identity" has merits.
> As I understand it, what Matthias Blume is saying is that all objects in > Lisp are, effectively, pointers. And so the pointer is being copied.
> At the surface level, it is pointless and a distraction to teach it this > way. All objects in Lisp are pointers, yes, but saying so causes people > who know about pointers to expect a certain set of things to be available; > for example, they expect addition on a pointer to mean something different > than it does. They are confused that x+1 does not add one to the pointer > x getting a pointer to the next thing; C has no equivalent function, > _certainly_ not as an infix operator, that dereferences a pointer, adds > 1, mallocs a new result, and yields a pointer result.
I disagree, because if the "pointer" was passed by reference, then it could be changed, but it can not be. What it point to can be changed, but not the pointer itself.
I would say however that it would perhaps be pointless if the "pointer" was immutable.
I actually do not (and never have) expect to be able to do pointer arithmetic on anything that "points" be it pointers, references or symbols.
> I don't agree with teaching a language by appeal to datatypes that are > below the level of abstraction that the language was created to indulge.
I agree with this, but I do not think the current discussion is in such a context. It might have started out in that context, but that have changed.
> > you can return multiple values by returning multiple values > > instead of having an "argument" be a return value, etc.
> I see two benefits in returning multiple values via parameters as > in C, compared to multiple values in Lisp:
> 1. The names of the parameters can describe the values. In Lisp, > you can get a similar effect with a documentation string.
> 2. By giving a C function a null pointer as a parameter, you can > instruct it not to store the corresponding value. (The > function must explicitly support this; strtol() does.) > The function may even be able to completely avoid computing > the value. I am not aware of such an idiom in Lisp.
> I think I would prefer crossing these features with keyword > arguments, so that new return values could be added to functions > without affecting existing callers. A function call would > specify which values it wants. Functions would normally provide > all available values and Lisp would discard the unused ones, but > there would also be a way for functions to check which values are > needed and compute only those.
> Has this already been implemented in some language? > If so, how does the syntax look?
matlab has that. all input and output parameters are "optional". nargin and nargout are variables telling how many input and output parameters are really set.
for example here is a sketch of a matlab function doing that.
function [x,y,z] = foo(a,b,c) %FOO % [x,y,z] = foo(a,b,c) % this function provides some kind of example
% manually provide input arg value if nargin < 1, b = 1; end x = a+b; if nargin < 2, y = a+c; else y = a/b; end % don't compute stuff not used if nargout > 2, z = expensive_function(c) end
it's reasonably easy to understand but kind of tedious at times. matlab has no sense of keyword type named parameters.
> ... For the last time: cbv (or cbr, or cbn) describes the semantic > relationship between the *name* that is the formal parameter and the > *expression* that is the actual argument.
right; i think those who doubt matthias should probably consult some reference texts. i include a few here as examples:
aho/sethi/ullman, pp. 424: (compilers) "the actual parameters are evaluated and their r-values are passed to the called procedure."
allen: pp 100: (lisp) "the evaluation scheme, CBV which we chose is called call-by-value. It is called applicative order evaluation or inside-out style of evaluation, meaning that we evaluate the subexpressions before evaluating the main expression. [...] Informally, call-by-value says: evaluate the arguments to a function before you apply the function definition to the arguments."
stoy: pp 177: (language theory) "we are referring to call by value. in this mode of evaluation, the operator and the operand of an application is evaluated /before/ the application itself is performed."
i don't have any really good recent references, so if these are no longer useful definitions, i cannot tell.
oz -- don't count your chickens in glass houses until the cows come home. -- david vestal
Matthias Blume <matth...@shimizu-blume.com> writes: > > This is not about technicalities. This is about pedagogy.
> Exactly. I hate the kind of teaching where the teacher tells gentle > lies because the students are supposedly not ready to hear the real > truth.
if you model learning as "exposure" then yes, but if you model learning as "process of understanding", then obliqueness has its place (turning the student so that they can see the real truth more easily).
the bigger question is: who determines when the student is ready?
Matthias Blume <matth...@shimizu-blume.com> writes: > (and have been long before I first said anything, so it was not my > communication problem that got them confused in the first place), > maybe, just maybe, the problem is with them. Would you not at least > accept this as a possibility?
so, when you're debugging some code, and you realize the problem, does your editor understand "wrong var and OBOE" or do you have to tell it things like:
do you worry about the general class of "wrong var and OBOE" bugs, or do you care about fixing the problem w/ this particular program, or both (and in what order)?
k...@ma.ccom (Takehiko Abe) writes: > That contradicts what you wrote earlier:
> > In C, pass-by-value implies that a copy is made of the value > > passed,
> Nonsense!! In C, as in Lisp, no copy is made.
> good night.
You should be reading the whole thread, including the followups. Matthias corrected this statement by explaining what he meant.
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
Erik Naggum <e...@naggum.net> writes: > * k...@ma.ccom (Takehiko Abe) > | > > > PARAMETER PASSING IN LISP IS CALL-BY-VALUE. > | > > > | > > Whatever. but Harbison & Steele clearly indicates in the above > | > > that call-by-value implies parameter copying. > | > > | > Indeed. > | > | That contradicts what you wrote earlier: > | > | > In C, pass-by-value implies that a copy is made of the value > | > passed, > | > | Nonsense!! In C, as in Lisp, no copy is made. > | > | good night.
> Look, guys, am I the only one here with a computer science education? > (Besides Matthias Blume, obviously.)
Probably not, but perhaps fewer than you might suspect. Many of us older codgers got into computer science coming from a different route than from a computer science degree. It's always a good idea to assume the worst in that respect, and point us to the proper educational information when possible. I went out to the net and searched quite a bit, and found many references to the three definitions you cite, in various wordings. It is interesting, in fact, that there are _so_ many of these sets of definitions, all worded slightly differently (some name a few other calling styles, as well). I don't know how many of them are posted for the sake of CS graduates (or undergraduates, as course material), but perhaps the lack of the single location for these definitions suggests that indeed it is a confusing subject for many.
> I have no idea how people get so > screwd up -- if I had, I would make a comet carreer in psychiatry from > watching all the nutjobs on USENET for so many years -- but call by value > or reference or name refers to the information passed from the caller to > the callee about how the arguments (actual parameters) to a function were > specified. Let me take the standard three, again:
> 1 Call by value -- no information is passed from the caller to the callee > about the origin of the argument, only its value is available. So when > the formal parameter is used, it refers to a local binding of that value.
> 2 Call by reference -- information is passed that makes the callee to > reference the actual argument, to which the formal parameter refers, so > when the formal parameter is used, it indirectly refers to the caller's > binding of that value.
> 3 Call by name -- information is passed that makes the actual argument as > it was specified in the call available to the caller, including any > bindings that an expression closes over, such that using the formal > argument (acts as if the system) evaluates the expression each time.
> This call-by-foo things is _so_ not about what the values of arguments > might be. This is _only_ about how much the callee gets to know about > the arguments it receives. I marvel at the lack of education or other > exposure to these terms in the literature that could have produced such a > horrible confusion. This is an extremely clear-cut differentiation of > argument passing semantics that leaves no room for confusion. If you > cannot access the _binding_ that was used as an actual argument in the > callee, you do _not_ have call-by- reference semantics regardless of how > much you may modify the contents of any composite object you are passed.
I've seen so many people make the mistake of trying to describe Lisp as call-by-reference, that I tried to go outside the CS box (which I am already outside of, anyway) to explain the problem and to help people to understand what it is that Lisp does, precisely. I invented a term, "pass-by-LispVal", in parallel with Kent Pitman, who apparently perceived the same kind of problem I did and invented his own term, "pass-by-identity". I suppose that you could classify these two terms as similar to or specializations on call-by-value/pass-by-value.
The problem with the terms call-by-value/pass-by-value is not that they are not well-defined. The problem is that these terms are confusing because people don't understand what a "value" is. Values are different things in different languages. In C, a struct is a value but an array is not. In Lisp, neither structs nor arrays are values. Because of these different definitions of "value", confusion creeps in.
In order to reduce the confusion, I think it would be helpful to add such definitions into appropriate FAQs. Nobody that I know of defines what a value is in Lisp, although it is trivial, and although I have described several times what a LispVal is, not only here but also in comp.arch.
Does such a definition exist for C? I looked at the ANSI C docs and various reference material, and could find nothing. If such a description does exist, then it would be useful for a Lisp FAQ entry such as "Is Lisp pass-by-value, pass-by-reference, or pass-by-name?" could be answered, (e.g. "pass-by-value, with appropriate understanding of what a value is") along with that appropriate definition of what a Lisp Value is. Also, a link could be made to the C definitions for Value, for contrast. Such a FAQ entry could go a long way to reducing the confusion on this subject.
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
In article <3229526943281...@naggum.net>, Erik Naggum <e...@naggum.net> wrote: > This is an extremely clear-cut differentiation of > argument passing semantics that leaves no room for confusion. If you > cannot access the _binding_ that was used as an actual argument in the > callee, you do _not_ have call-by- reference semantics regardless of how > much you may modify the contents of any composite object you are passed.
Please note that I am not arguing that Lisp has call-by-reference semantics.
I had read your previous post about 'the standard three' and I thought I got them right. I have a mental model of Lisp's argument passing, which seems very natural and intuitive. However, my understanding was that it's different from C's argument possing model which involves 'copying' of an argument.
Thanks for your patience.
-- "What we hear constantly is that after September 11th, everything changed. There is a good rule of thumb: if something is repeated over and over as obvious, the chances are that it is obviously false." -- Chomsky <http://www.zmag.org/content/ForeignPolicy/chomsky_march26.cfm>
In article <dvXA8.66989$%s3.26566...@typhoon.ne.ipsvc.net>, "Joe Marshall" <prunesqual...@attbi.com> wrote:
> > > > Common Lisp doesn't copy its parameter, which is different from C.
> > > Of course it does. If I write
> > > (defvar x <something>) > > > (defun f (y) (setq y <something else>)) > > > (f x)
> > > then f receives a copy of the contents of x.
> > No, it doesn't. f receives the contents of x, not a copy of it. If that > > <something> is mutable, you can modifiy it in f.
> If F did not receive a copy of the contents of x, then it wouldn't > be in X anymore.
My understanding is that F receives the location of the contents, so both X and Y can share it.
> When F is running, there are two variables of > interest, x and y. Both contain the same thing, yet they are not > the same location.
This is where I lost track. I think they hold the same location.
-- "What we hear constantly is that after September 11th, everything changed. There is a good rule of thumb: if something is repeated over and over as obvious, the chances are that it is obviously false." -- Chomsky <http://www.zmag.org/content/ForeignPolicy/chomsky_march26.cfm>
> BUT UNDER CALL-BY-REFERENCE SEMANTICS IT WOULD!!!!
Of course it would.
-- "What we hear constantly is that after September 11th, everything changed. There is a good rule of thumb: if something is repeated over and over as obvious, the chances are that it is obviously false." -- Chomsky <http://www.zmag.org/content/ForeignPolicy/chomsky_march26.cfm>
> > What you're wrong about is your apparent belief that it is reasonable to > > expect a C programmer to obtain an accurate understanding of how Lisp > > function parameters work by saying simply, "It's call-by-value, just as in > > C" and leaving it at that.
> Could you, please, quote me saying this.
Sure. In your very first posting in this thread you wrote:
> Lisp is "call by value". Period.
...
> > Yes, you are technically correct, but it doesn't help a C > > programmer understand why when he passes a struct by value he gets a > > copy of the struct, but when he passes a list by value he doesn't > > get a copy of the list.
> Indeed, it does not help. It helps even less to explain this > phenomenon with the wrong explanation. The correct answer is that a > Lisp list is not at all like a C struct.
True, but it's not nearly as clear that a cons cell is not at all like a C struct. In fact, to explain the behavior of passing a cons cell you have to hypothesize that you're really passing a pointer to the cons cell as the "value", but this hypothetical pointer is nowhere to be found in the language specification. You have to invent it. IMO that's no more reasonable than inventing a new term to describe what's going on.
> > This is not about technicalities. This is about pedagogy.
> Exactly. I hate the kind of teaching where the teacher tells gentle > lies because the students are supposedly not ready to hear the real > truth.
But there is no "real truth". All this stuff is just metaphor, stories that we tell to describe the behavior of complex systems, and its all approximation to the truth to varying degrees. There are no functions, there are just machine instructions. There are no machine instructions, there are just bits. There are no bits, there are just voltages. There are no voltages, there are just quantum wave functions. Lisp is call-by-value for some value of "value". It depends on what the meaning of the word "is" is. (Bill Clinton got a lot of flack for saying that, but it really *does* depend on what the meaning of the word "is" is. But Bill made the same mistake you are making: it depends on what your *audience* thinks the meaning of the word "is" is, not what you think it is. Both you and Bill are right and wrong in exactly the same way.)
>>>>>Common Lisp doesn't copy its parameter, which is different from C.
>>>>Of course it does. If I write
>>>> (defvar x <something>) >>>> (defun f (y) (setq y <something else>)) >>>> (f x)
>>>>then f receives a copy of the contents of x.
>>>No, it doesn't. f receives the contents of x, not a copy of it. If that >>><something> is mutable, you can modifiy it in f.
>>If F did not receive a copy of the contents of x, then it wouldn't >>be in X anymore.
> My understanding is that F receives the location of the contents, so > both X and Y can share it.
>>When F is running, there are two variables of >>interest, x and y. Both contain the same thing, yet they are not >>the same location.
> This is where I lost track. I think they hold the same location.
They hold the same location, but are different themselves. If they were passed by reference then changing the location y holds also changes the locayion x holds.
I think of it this way:
- pass by value passes the value of the variable. The value might be a pointer of course.
- pass by reference takes the variable, finds the address of that variable and passes that (as opposed to the address that variable points to).
In article <gat-0505020039060...@192.168.1.50>, g...@jpl.nasa.gov (Erann Gat) wrote:
> True, but it's not nearly as clear that a cons cell is not at all like a C > struct. In fact, to explain the behavior of passing a cons cell you have > to hypothesize that you're really passing a pointer to the cons cell as > the "value", but this hypothetical pointer is nowhere to be found in the > language specification. You have to invent it. IMO that's no more > reasonable than inventing a new term to describe what's going on.
The word "pointer" is perhaps not found in the language specification, but if a C programmer just mentally substitutes the word "pointer" every place it says "binding" then they'll understand it perfectly well.
In some ways a C++ reference is a better analogy, but in other ways worse. It is a better analogy, for example, in terms of the implicit dereferencing, and also in that experienced C++ programmers know that the compiler will often optomize away references (such as in calling inline functions). It is worse, in that assignment to a C++ reference variable changes the contents of the value referred to, while asignment in Lisp makes the binding point to a different value.
In article <3229526943281...@naggum.net>, Erik Naggum <e...@naggum.net> wrote: > Look, guys, am I the only one here with a computer science education? > (Besides Matthias Blume, obviously.) I have no idea how people get so > screwd up
I'll tell you exactly how they get screwed up: they read the wrong books. They read K&R and Stroustrup or C++ for Dummies, and as a result they have no idea what a binding is. And it's not their fault. It's very hard to find a good definition of the word "binding" (as a noun) in published works. If you don't believe me, time yourself to see how long it takes you to find one (not including the Hyperspec, of course).
"Joe Marshall" <prunesqual...@attbi.com> writes a very interesting post demonstrating the difference between call-by-value and call-by-reference.
I am not an assembly language programmer [it's on the list of things to do], so I have a few quick questions regarding the assembled output listed below:
> ff 75 e4 pushl [ebp-28] ; push contents of X
> FF 75 F8 pushl [ebp-08h] ; push contents of X
> 8B 45 FC movel eax, [ebp-4] ; contents of X is EAX
> ff 75 fc pushl [ebp-08h] ; push contents of X
> 8d 7d fc lea -4(%ebp),%edi ; compute address of X > 57 push %edi ; push it
So the first 4 lines [3 from CL implementations, 1 from C] I quoted involve copying the "value" of X onto the stack before calling function bar. What happens if the "value" of X does not fit in a long-word?
The second question is how does the last LEA instruction work to compute the address? Is this an x86 architecture?
-jon -- ------------------ Jon Allen Boone ipmon...@delamancha.org
* Duane Rettig <du...@franz.com> | The problem with the terms call-by-value/pass-by-value is not that | they are not well-defined. The problem is that these terms are | confusing because people don't understand what a "value" is.
I believe it is entirely clear in the context of all three conventions.
I also think there is a difference between call _by_ value/reference and call _with_ value/reference that is somehow conflated here. That is, somehow, people confuse what the argument _is_ and _how_ it is passed.
| Values are different things in different languages. In C, a struct is a | value but an array is not. In Lisp, neither structs nor arrays are | values. Because of these different definitions of "value", confusion | creeps in.
This is a classic case of equivocation. Just because there are different kinds of values and references in the language, does not mean that the _same_ meaning of "value" and "reference" exists in a technical term that relates to the relationship between actual and formal parameter in a call.
| If such a description does exist, then it would be useful for a Lisp FAQ | entry such as "Is Lisp pass-by-value, pass-by-reference, or | pass-by-name?" could be answered, (e.g. "pass-by-value, with appropriate | understanding of what a value is") along with that appropriate definition | of what a Lisp Value is.
I answered Frode with what I think is a fresh start. Let me repeat it here in case it got lost:
Argument passing in Common Lisp is conceptually equivalent to building a list of the results of evaluating each of the argument forms to the function and passing that list to the function, which conceptually unpacks it into the formal parameters. All knowledge of the source of the values is lost by that time.
The conceptual equivalence to a list is used to lay the ground for apply, &rest, &key, etc, and also neatly captures the order of evaluation so an explanation of this rule will fall out naturally from the description.
| Also, a link could be made to the C definitions for Value, for contrast.
But it has nothing to do with what a _value_ is. This has to do with whether you pass whatever-a-value-is or wherever-whatever-is-a-value-is whenever you pass an argument to a function. (Call it the Shakira theory. :) -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
70 percent of American adults do not understand the scientific process.
* Takehiko Abe | I had read your previous post about 'the standard three' and I thought I | got them right. I have a mental model of Lisp's argument passing, which | seems very natural and intuitive. However, my understanding was that it's | different from C's argument possing model which involves 'copying' of an | argument.
Well, no, C's does not involve copying, it just passes all struct members as individual arguments, as in destructuring. I guess a destructured pass by value looks a lot like a copy, and I guess this whole messy argument passing thing in C has confused a lot of people, what with arrays being passed by value but as references, with pointers being passed by value but being references, and struct being passed by value but as values.
| Thanks for your patience.
You're welcome. I hear this not nearly enough. :) -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
70 percent of American adults do not understand the scientific process.
* Erann Gat | I'll tell you exactly how they get screwed up: they read the wrong books.
So we push the problem one step back and have not answered the question but have to ask ourselves how the authors got screwed up, instead.
| They read K&R and Stroustrup or C++ for Dummies, and as a result they | have no idea what a binding is. And it's not their fault. It's very | hard to find a good definition of the word "binding" (as a noun) in | published works. If you don't believe me, time yourself to see how long | it takes you to find one (not including the Hyperspec, of course).
H.P.Barendregt: The Lambda Calculus, Its Syntax and Semantics. 1 second. (It is within reach from where I sit.) He discusses variables in an appendix and refers to Frege and Pierce for defining the nature of free and bound variables. The term "binding" is mathematical in nature and comes from the concept of free and bound variables. H.P.Barendregt has also been published in Handbook of Logic in Computer Science, vol 2, Background: Computational Structures and in Handbook of Theoretical Computer Science, vol B, Formal Methods and Semantics, where he also writes about lambda calculus. Lambda calculus was my first guess.
Then I went back to my undergrad CS texts, just to see if there were any useful references. I found H.R.Lewis, C.H.Papadimitriou: Elements of the Theory of Computation and C.Ghezzi, M.Jazayeri: Programming Language Concepts both to explain it briefly but accurately. A.V.Aho, J.D.Ullman: Foundations of Computer Science also covers free and bound variables under predicate logic. Of course, SICP covers binding, but slightly better in the first edition than the second.
My third choice of literature to search for this would be in compiler literature. The seminal work of A.V.Aho, R.Sethi, J.D.Ullman: Compilers; Principles, Techniques, and Tools, covered binding accurately and well. D.Grune, H.E.Bal, C.J.H.Jacobs, K.G.Langendoen: Modern Compiler Design covers it in Logic Programming, where they refer to bound and unbound variables. Most other compiler books cover the problem of binding without calling it binding.
My fourth guess was that the O'Reilly books on Perl and Python ought to say something about this, but Perl only uses it in relation to the tie operator and Python does not mention it at all. So I checked Programming Ruby, which I recalled have a binding operator, and true enough, we find that it explains the variable bindings of a block very well and supports access to these bindings.
By this time, I had spent 20 minutes pulling some 30 books out of my 1100-volume strong personal library and had found 12 hot hits. So not only did I know roughly where to look, it was where I thought I would find it. If any the other books also have a description of binding, I do not know, but I am not at all unhappy with the hit rate.
Of course, I excluded all Lisp books. Anatomy of Lisp, Lisp in Small Pieces, Common Lisp the Language, etc, all cover bindings excellently. I also excluded all Java, Ada, and C++ books because I cannot recall that any of them have ever mentioned bindings by that name.
I believe that if you grasp free and bound variables in mathematics (i.e. calculus), predicate logic, and lambda calulus and figure out things like scope, then lexical environments, and you read just a little bit about compilers, the idea of a binding will emerge without serious mental effort. The fact that Common Lisp exposes what in other languages are gone by the time the compiler has finished with it and so not available in the runtime environment tends to obscure and hide these issues from their users. The lack of binding capture in closures (because they simply do not exist) tends to make it unnecessary to know about them. -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
70 percent of American adults do not understand the scientific process.
> > True, but it's not nearly as clear that a cons cell is not at all like a C > > struct. In fact, to explain the behavior of passing a cons cell you have > > to hypothesize that you're really passing a pointer to the cons cell as > > the "value", but this hypothetical pointer is nowhere to be found in the > > language specification. You have to invent it. IMO that's no more > > reasonable than inventing a new term to describe what's going on.
> The word "pointer" is perhaps not found in the language specification, > but if a C programmer just mentally substitutes the word "pointer" every > place it says "binding" then they'll understand it perfectly well.
Perhaps, but that still doesn't justify saying "It's call by value. Period." At best, "It's call by value, and all the values are pointers that are automatically dereferenced every time you refer to them." But even that isn't entirely true because...
> In some ways a C++ reference is a better analogy, but in other ways > worse. It is a better analogy, for example, in terms of the implicit > dereferencing, and also in that experienced C++ programmers know that > the compiler will often optomize away references (such as in calling > inline functions). It is worse, in that assignment to a C++ reference > variable changes the contents of the value referred to, while asignment > in Lisp makes the binding point to a different value.
Right. There is no simple way to explain how Lisp values work to a C programmer so that they will reliably "understand it perfectly well." Hell, there's not even any simple way to explain it to *Lisp* programemrs so that they will reliably understand it perfectly well, as the length of this thread amply demonstrates.
* Erann Gat | Perhaps, but that still doesn't justify saying "It's call by value. | Period." At best, "It's call by value, and all the values are pointers | that are automatically dereferenced every time you refer to them." But | even that isn't entirely true because...
Please listen. Call _by_ value is different from call _with_ value. The meaning of "value" is irrelevant. The fact that you cannot access the _binding_ of the value is the clue. In call _by_ reference, you do not pass _some_ references to objects, you pass references to _bindings_. -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
70 percent of American adults do not understand the scientific process.
> > > True, but it's not nearly as clear that a cons cell is not at all like a C > > > struct. In fact, to explain the behavior of passing a cons cell you have > > > to hypothesize that you're really passing a pointer to the cons cell as > > > the "value", but this hypothetical pointer is nowhere to be found in the > > > language specification. You have to invent it. IMO that's no more > > > reasonable than inventing a new term to describe what's going on.
> > The word "pointer" is perhaps not found in the language specification, > > but if a C programmer just mentally substitutes the word "pointer" every > > place it says "binding" then they'll understand it perfectly well.
> Perhaps, but that still doesn't justify saying "It's call by value. > Period." At best, "It's call by value, and all the values are pointers > that are automatically dereferenced every time you refer to them."
Yes, I agree.
> But even that isn't entirely true because...
> > In some ways a C++ reference is a better analogy, but in other ways > > worse. It is a better analogy, for example, in terms of the implicit > > dereferencing, and also in that experienced C++ programmers know that > > the compiler will often optomize away references (such as in calling > > inline functions). It is worse, in that assignment to a C++ reference > > variable changes the contents of the value referred to, while asignment > > in Lisp makes the binding point to a different value.
> Right. There is no simple way to explain how Lisp values work to a C > programmer so that they will reliably "understand it perfectly well."
I didn't say that there was a simple way. In particular, I didn't say that telling someone that a Lisp binding is a pointer and then handing them a compiler is sufficient. But I think that saying "Read the Lisp spec and everywhere it ways 'binding' think to yourself 'C pointer'" will work prety well for those who already understand C (or machine language) pointers.
> Hell, there's not even any simple way to explain it to *Lisp* programemrs > so that they will reliably understand it perfectly well, as the length of > this thread amply demonstrates.
I'm convinced it's more a terminology problem than an actual understanding problem.
One big obstacle, I think, is that at the time the terms "call by value", "call by reference", and "call by name" were invented, pretty much all variables in all languages were statically typed, of known and fixed size, and either statically allocated at absolute addresses or at a fixed offset from some base register.
Yes, Lisp arguments are "call by value", but that is not at all enough to understand them because all the values are pointers (which Lisp calls "bindings") and the things that Lisp calls "values" are the heap objects pointed to by those pointers.
Bruce Hoult <br...@hoult.org> writes: > One big obstacle, I think, is that at the time the terms "call by > value", "call by reference", and "call by name" were invented, pretty > much all variables in all languages were statically typed, of known and > fixed size, and either statically allocated at absolute addresses or at > a fixed offset from some base register.
This is nonsense. Lisp is the second oldest computer language still in common use and call-by-value, call-by-reference and call-by-name are decades old concepts and terms. As Matthias Blume has already pointed out, people in and around the lisp community were those who initially developed these ideas and terminology. Lisp was the canonical example of cbv and Algol-60 was (and still is) the canonical example of cbn.
Typing issues are completely orthogonal to cbv parameter passing, and so are allocation and stack frame details. One big obstacle, I think, is the insular nature of the lisp community.