1. pbr vs multiple returns
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 10, 2007
- 613 views
cchris005 wrote: > > > Subject: Re: Digest for EUforum at topica.com, issue 6333 > > > > > > posted by: Pete Lomax <petelomax at blueyonder.co.uk> > > > > CChris wrote: > > > }}} <eucode> > > > function pop(byref sequence stack) > > > object top > > > top=stack[$] > > > stack=stack[1..$-1] > > > return top > > > end function > > > </eucode> {{{ > > > > > Currently, you need to return both the modified stack and the former top > > > element, which is awkward. > > > > FWIW, I plan something like: > > }}} <eucode> > > function[2] pop(sequence stack) > > return stack[$], stack[1..$-1] > > end function > > > > {nextitem,stack}=pop(stack) > > </eucode> {{{ > > > > > More generally, PBR enables to transform an object, rather to return a > > > modified object which you have to copy onto the original - waste of CPU. > > Technically, I plan an "unnecessary" dword move which "true" pbr > > wouldn't; but that is trivial overhead compared to existing cow semantics > > (in fact so trivial I very much doubt it would ever show on any timing > > test). > > > > Would that "dword move" also work when transforming a subscripted > quantity, like (3]? Hopefully, I'll know more when I start implementing it, see below. > > And, by the way, would you really expect to get the modified stack in > the returned value? I probably programmed too much in asm, but I find > this a bit confusing. And you have to perform an extra s1=s[1] to get > the value you need. You seem to be confusing
return stack[$],stack[1..$-1]
with
return {stack[$],stack[1..$-1]}
So, no, I don't expect to get the modified stack "in" "the" return value, I expect to get the modified stack as the second return value. Internally, I plan to implement eg:
function[2] pop(sequence stack) return stack[$], stack[1..$-1] end function {nextitem,stack}=pop(stack)
as something similar to (pseudocode):
object fres1,fres2 -- virtual, of course sequence popstack -- scoped to pop, "" pop: fres1=popstack[$] fres2=popstack[1..$-1] ret popstack=stack stack=<no value> call pop top=fres1 stack=fres2
When I said "mov dword" I was referring to the last two statements, a neglible and insignificant cost for avoiding cow overheads. Going back to a[i]=update(a[i]), I expect that to be frighteningly difficult to fully optimise with this multiple returns approach and may need real pbr. But anyway, I think multiple returns are a pretty neat feature in their own right, albeit not quite as flexible as true pbr. > Your proposal doesn't look very good to me. Maybe not. Let me just add that it seems Rob has gone to great lengths to optimise say x=append(x,...) and I feel that optimisation should be generalised so it applies to user code, not just a handful of builtins. > > > > > > Eu has function pointers, using call_back(routine_id(rt_name)). What > > > confuses me is why I can't do it with variables. Am I the only one? > > > > Firstly, as background, a routine_id is *utterly meaningless* to any > > other than call_func, call_proc, and call_back. Agreed? > > > > True. What is the issue? I think I was trying to say that you'd never pass a routine_id to a c func, unless you intend to have it passed back to Eu code, as C code cannot do anything with it. Likewise variable_id would be no use to C code. I was just trying to set the scene and make it clear I was not talking about var_id but raw_address(var_id). > Did you ever try to allow an external dll/piece of code to access an Eu > variable? And do you think this is not right? I've always used raw blocks of memory when dealing with C code. > Using a get_this_var()/set_this_var(typeof_this_var x) pair for every > such variable looks really like a bad idea to me. That's how we wind up > doing it unfortunately. Well it seems to me that call_back(get_var) and call_back(set_var) would be the only way you could possibly manipulate Eu vars from C code. Very tricky but at least possible. See below. > > Admittedly, you an also alloocate an address (isn't this a raw pointer?) Yes but it is not an Eu variable. > and use this for interfacing. Only problem is that peek/poke are so darn > slow... Separate issue. > > But indeed, my primary point was: there's a routine_id, why is a > variable_id() any more complicated? Hence why is it not implemented? It is a shed load more complicated. You don't modify routines. They don't move about. If you do x=append(x,x) then almost always x will have been shifted somewhere else in memory. Consider string s="text". In assembly this goes something like: dd 4 ; length dd 0x82000001 ; type and refcount data db "text",0 align 4 s dd (data+1) ror 2 (see execute.h for Eu implementation, which shifts 3 and uses different high bits, etc) So, say we get the actual address of s and pass it to a C function. Is it goiing to know what to do with it? Does it understand the types? Will it honour the refcounts and clone things when needed? Will it maintain length (and base and postfill)? When the C code craps on things, is the Eu backend going to cope/give intelligible error messages? Will it promise not to make circular references? Will it typecheck things it modifies? And so on. Open this up and you completely destabalise the backend. If you get to a point in some C code where you want to modify some Eu vars, you are far better off invoking a call_back and doing it in Eu, imo. The same is probably true if you just want to subscript an Eu var in C. Regards, Pete
2. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 10, 2007
- 573 views
I don't understand linking two separate concepts (pass by reference and multiple returns). Can you explain a little better how they are related? -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
3. Re: pbr vs multiple returns
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> Jan 10, 2007
- 583 views
Pete Lomax wrote: > > cchris005 wrote: > > > > > Subject: Re: Digest for EUforum at topica.com, issue 6333 > > > > > > > > > posted by: Pete Lomax <petelomax at blueyonder.co.uk> > > > > > > CChris wrote: > > > > }}} <eucode> > > > > function pop(byref sequence stack) > > > > object top > > > > top=stack[$] > > > > stack=stack[1..$-1] > > > > return top > > > > end function > > > > </eucode> {{{ > > > > > > > Currently, you need to return both the modified stack and the former top > > > > > > > > element, which is awkward. > > > > > > FWIW, I plan something like: > > > }}} <eucode> > > > function[2] pop(sequence stack) > > > return stack[$], stack[1..$-1] > > > end function > > > > > > {nextitem,stack}=pop(stack) > > > </eucode> {{{ > > > > > > > More generally, PBR enables to transform an object, rather to return a > > > > modified object which you have to copy onto the original - waste of CPU. > > > Technically, I plan an "unnecessary" dword move which "true" pbr > > > wouldn't; but that is trivial overhead compared to existing cow semantics > > > (in fact so trivial I very much doubt it would ever show on any timing > > > test). > > > > > > > Would that "dword move" also work when transforming a subscripted > > quantity, like (3]? > Hopefully, I'll know more when I start implementing it, see below. > > > > > And, by the way, would you really expect to get the modified stack in > > the returned value? I probably programmed too much in asm, but I find > > this a bit confusing. And you have to perform an extra s1=s[1] to get > > the value you need. > You seem to be confusing > }}} <eucode> > return stack[$],stack[1..$-1] > </eucode> {{{ > with > }}} <eucode> > return {stack[$],stack[1..$-1]} > </eucode> {{{ > > So, no, I don't expect to get the modified stack "in" "the" return value, > I expect to get the modified stack as the second return value. > All right. But I would have used multiple return for other stuff rather. I fully understand why Jason is confused. > Internally, I plan to implement eg: > }}} <eucode> > function[2] pop(sequence stack) > return stack[$], stack[1..$-1] > end function > > {nextitem,stack}=pop(stack) > </eucode> {{{ > as something similar to (pseudocode): > }}} <eucode> > object fres1,fres2 -- virtual, of course > sequence popstack -- scoped to pop, "" > pop: > fres1=popstack[$] > fres2=popstack[1..$-1] > ret > > popstack=stack > stack=<no value> > call pop > top=fres1 > stack=fres2 > </eucode> {{{ > When I said "mov dword" I was referring to the last two statements, a neglible > and insignificant cost for avoiding cow overheads. > > Going back to a[i]=update(a[i]), I expect that to be frighteningly difficult > to fully optimise with this multiple returns approach and may need real pbr. > So why confuse the matter by taking multiple return in, since they would be a partial solution to the problem at best? If you see the same IL code repeated in the way you'd have with s[i]=update(s[i]), it doesn't look frigteningly difficult to replace the part that repeats left_sym with left_sym itself. Not trivial (you have to keep track of which sequence of IL translates which assignable or expression), but not awful I'd think. > But anyway, I think multiple returns are a pretty neat feature in their own > right, albeit not quite as flexible as true pbr. > > > Your proposal doesn't look very good to me. > Maybe not. Let me just add that it seems Rob has gone to great lengths to > optimise > say x=append(x,...) and I feel that optimisation should be generalised so it > applies to user code, not just a handful of builtins. > > > > > > > Eu has function pointers, using call_back(routine_id(rt_name)). What > > > > confuses me is why I can't do it with variables. Am I the only one? > > > > > > Firstly, as background, a routine_id is *utterly meaningless* to any > > > other than call_func, call_proc, and call_back. Agreed? > > > > > > > True. What is the issue? > I think I was trying to say that you'd never pass a routine_id to a c func, > unless you intend to have it passed back to Eu code, as C code cannot do > anything > with it. Likewise variable_id would be no use to C code. I was just trying to > set the scene and make it clear I was not talking about var_id but > raw_address(var_id). > Oh I see. And I didn't get that point because I wasn' talking yet about raw_pointer(). > > Did you ever try to allow an external dll/piece of code to access an Eu > > variable? And do you think this is not right? > I've always used raw blocks of memory when dealing with C code. > > > Using a get_this_var()/set_this_var(typeof_this_var x) pair for every > > such variable looks really like a bad idea to me. That's how we wind up > > doing it unfortunately. > Well it seems to me that call_back(get_var) and call_back(set_var) would be > the only way you could possibly manipulate Eu vars from C code. Very tricky > but at least possible. See below. > > > > Admittedly, you an also alloocate an address (isn't this a raw pointer?) > Yes but it is not an Eu variable. > > and use this for interfacing. Only problem is that peek/poke are so darn > > slow... > Separate issue. No. If it were reasonably fast (not more than 5-6 tests and mov's), then there would be no need for a more efficient way to hand raw pointers to external code. And you'd have no need for raw_pointer() altogether. > > > > But indeed, my primary point was: there's a routine_id, why is a > > variable_id() any more complicated? Hence why is it not implemented? > It is a shed load more complicated. > You don't modify routines. > They don't move about. > If you do x=append(x,x) then almost always x will have been shifted somewhere > else in memory. I was referring to handles in my previous posts. var_id would be a purely Eu handle to a roaming memory location. Must be "volatile" as your example shows, ie be evaluated every tilme it is invoked. routine_id's are _identical_: the only difference is that they are not volatile - they don't move. > > Consider string s="text". > In assembly this goes something like: > dd 4 ; length > dd 0x82000001 ; type and refcount > data db "text",0 > align 4 > > s dd (data+1) ror 2 > (see execute.h for Eu implementation, which shifts 3 and uses different high > bits, etc) > > So, say we get the actual address of s and pass it to a C function. Is it > goiing > to know what to do with it? Does it understand the types? Will it honour the > refcounts and clone things when needed? Will it maintain length (and base and > postfill)? When the C code craps on things, is the Eu backend going to > cope/give > intelligible error messages? Will it promise not to make circular references? > Will it typecheck things it modifies? And so on. > Wait. If you open accass to a dword or *float, nothing of this happens. > Open this up and you completely destabalise the backend. > > If you get to a point in some C code where you want to modify some Eu vars, > you are far better off invoking a call_back and doing it in Eu, imo. > The same is probably true if you just want to subscript an Eu var in C. > C doesn't know about sequences, only homogeneous arrays. Hence, you won't be passing an Eu sequence to a C routine, except if it is a sequence of integers or floats. The logical thing to do then would be to poke the sequence in memory getting an array of machine/C type, pass that to externa;l code and then peek back. Problem is, we usually want to do this to take advantage of raw speed in external code, but the overhead of the back and forth copy process offsets the benefits. To sum up that multi-topic thread: * multiple returns are nice and desirable; * they don't substitute for PBR, which is also desirable; * faster peek/poke is probably a goal to achieve; it's so fast in asm; * var_id() returns a handle to be used only by get_var(), set_var(), get_var_type(), is_initialised() and friends. Raw var_id's are as useless to external code as raw routine_id's. * An equivalent of call_back() for variables would be far trickier than call_back(), and hardly needed if peek/poke worked as efficiently as one would expect. Further comments may have to go to separate threads perhaps. Regards. CChris > Regards, > Pete
4. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 10, 2007
- 570 views
CChris wrote: > > I was referring to handles in my previous posts. var_id would be a purely > Eu handle to a roaming memory location. Must be "volatile" as your example > shows, ie be evaluated every tilme it is invoked. routine_id's are > _identical_: the only difference is that they are not volatile - they don't > move. Well, technically, it wouldn't really move either, because you'd pass a pointer to SymTab[xx].obj. And that value might be either an integer or a pointer to an atom or a sequence. /pedant > > > Open this up and you completely destabalise the backend. > > > > If you get to a point in some C code where you want to modify some Eu vars, > > you are far better off invoking a call_back and doing it in Eu, imo. > > The same is probably true if you just want to subscript an Eu var in C. > > > > C doesn't know about sequences, only homogeneous arrays. Hence, you won't > be passing an Eu sequence to a C routine, except if it is a sequence of > integers or floats. The logical thing to do then would be to poke the sequence > in memory getting an array of machine/C type, pass that to externa;l code and > then peek back. Problem is, we usually want to do this to take advantage of > raw speed in external code, but the overhead of the back and forth copy > process offsets the benefits. But you might write some C code that uses the Eu-headers, and manipulates eu data directly. I'm planning on doing that with the next version of wxEuphoria. Matt
5. Re: pbr vs multiple returns
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 10, 2007
- 572 views
- Last edited Jan 11, 2007
Jason Gade wrote: > > I don't understand linking two separate concepts (pass by reference and > multiple returns). Can you explain a little better how they are related? Just two different techniques that can both be used to implement a generic pop function that does two things, ie get top and modify stack. Is that any clearer? I have a gut feeling that multiple returns will prove much easier to implement than pbr, and now I think of it, there seems little to stop
top=pop(*stack)
from being nothing more than syntactic sugar for
{top,stack}=pop(stack)
Regards, Pete
6. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 10, 2007
- 591 views
- Last edited Jan 11, 2007
Pete Lomax wrote: > > Jason Gade wrote: > > > > I don't understand linking two separate concepts (pass by reference and > > multiple returns). Can you explain a little better how they are related? > > Just two different techniques that can both be used to implement a generic pop > function that does two things, ie get top and modify stack. > > Is that any clearer? > > I have a gut feeling that multiple returns will prove much easier to implement > than pbr, and now I think of it, there seems little to stop > }}} <eucode> > top=pop(*stack) > </eucode> {{{ > from being nothing more than syntactic sugar for > }}} <eucode> > {top,stack}=pop(stack) > </eucode> {{{ > > Regards, > Pete So it's just for this specific application? I can see the argument for multiple returns in some cases but I would rather use PBR in this particular case. Using ooeu syntax:
function pop( sequence * stack ) object tos -- why have a stack that only holds numbers? tos = stack[$] stack = stack[1..$-1] -- Matt, does this make a copy or not? return tos end function ... top = pop(my_stack) -- my_stack is actually modified by the pop() function
This makes the most sense to me. -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
7. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 10, 2007
- 576 views
- Last edited Jan 11, 2007
Jason Gade wrote: > > > I can see the argument for multiple returns in some cases but I would rather > use PBR in this particular case. > > Using ooeu syntax:
function pop( sequence * stack ) object tos -- why have a stack that only holds numbers? tos = stack[$] stack = stack[1..$-1] -- Matt, does this make a copy or not? return tos end function ... top = pop(my_stack) -- my_stack is actually modified by the pop() function
> > This makes the most sense to me. No, it would *not* make a copy with ooeu, which can be a big benefit if stack is large, and/or you pop a lot. Just because, if I wanted to do this in eu (i.e., have a generic pop function) I'd pass an id to pop, and have that be an index into a sequence that kept all the stacks. Usage is just as easy (although you couldn't do funky things to the stack--which might or might not be a good thing--because it'd be hidden from the users) but you wouldn't be as fast. That might or might not be an issue in this case. Matt
8. Re: pbr vs multiple returns
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 11, 2007
- 594 views
Jason Gade wrote: > So it's just for this specific application? NO OF COURSE NOT!!! Surely you can think of plenty of uses for multiple returns! value() for example (for which pbr makes no sense btw). > top = pop(my_stack) > > This makes the most sense to me. That would be the worst of all for me. The big danger is that my_stack may be modified when I am not expecting it to be. Obviously this pop *example* is sufficiently trivial you might not see what I mean, but on a more complex use of pbr, in some big 3rd party library you are just starting to learn, or one recently modified with pbr, it could be really confusing. At the very least make it top=pop(&stack) or similar. Also, what if you don't want to modify stack? With mr it is just
{top,}=pop(stack)
Obviously in this case it might be easier to write a get_top() function, and/or the "{,}" would be optional, but with a more complex routine it might easily be such a pain to duplicate/hack that you happily trade unnecessary slice or two for less code) Sorry to bang on about this, course it's ok for you to prefer pbr, but no way could I not answer that first question, and once I start... Regards, Pete
9. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 11, 2007
- 585 views
Pete Lomax wrote: > > Jason Gade wrote: > > So it's just for this specific application? > > NO OF COURSE NOT!!! > Surely you can think of plenty of uses for multiple returns! > value() for example (for which pbr makes no sense btw). Okay. I thought I had said that I could see some usefulness in multiple returns I just don't link the two ideas together the same way that you do. > > top = pop(my_stack) > > > > This makes the most sense to me. > That would be the worst of all for me. The big danger is that my_stack may be > modified when I am not expecting it to be. Obviously this pop *example* is > sufficiently > trivial you might not see what I mean, but on a more complex use of pbr, in > some big 3rd party library you are just starting to learn, > or one recently modified with pbr, it could be really confusing. At the very > least > make it top=pop(&stack) or similar. The routine specification tells the user whether the parameter is modified or not. Nothing should be "unexpected". However most routines would not be written to use PBR and probably even fewer library routines. > Also, what if you don't want to modify stack? With mr it is just > }}} <eucode> > {top,}=pop(stack) > </eucode> {{{ > Obviously in this case it might be easier to write a get_top() function, > and/or > the "{,}" would be optional, but with a more complex routine it might easily > be such a pain to duplicate/hack that you happily trade unnecessary slice or > two for less code) > > Sorry to bang on about this, course it's ok for you to prefer pbr, but no way > could I not answer that first question, and once I start... > > Regards, > Pete No problem, I think we just disagree. And between the two of us I'm not the one who has written a large Euphoria project (Edita) so take my comments with a grain of salt. -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
10. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 11, 2007
- 568 views
Jason Gade wrote: > > The routine specification tells the user whether the parameter is modified or > not. Nothing should be "unexpected". However most routines would not be > written > to use PBR and probably even fewer library routines. It might even make sense to make the caller specify pbr, so that both the caller and the callee have to agree. That way it's explicit that you're allowing and expecting it to change. Matt
11. Re: pbr vs multiple returns
- Posted by Chris Bensler <bensler at nt.net> Jan 11, 2007
- 569 views
Matt Lewis wrote: > > Jason Gade wrote: > > > > The routine specification tells the user whether the parameter is modified > > or > > not. Nothing should be "unexpected". However most routines would not be > > written > > to use PBR and probably even fewer library routines. > > It might even make sense to make the caller specify pbr, so that both > the caller and the callee have to agree. That way it's explicit that > you're allowing and expecting it to change. > > Matt I would definitely agree that PBR shoud be defined by both the callee and caller. I'm not very convinced that PBR is nessecary though. Other than convenience and a slight improvement to readability (which is debatable IMO), can someone please explain how PBR would be useful compared to multiple return values? It aint clicking for me. Optimization? Also, regarding multiple return values. What is the purpose of providing an alternate syntax for multiple return values? I don't see the purpose of introducing a new syntax to declare that a function returns multiple values. We can already do that by returning a sequence. All we need is a syntax for how to assign the members of a returned sequence to multiple variables. {err,val} = get("3.14") Shouldn't that be a viable statement without having to modify how get() works? In anycase, I would whole heartedly agree with the syntax I demonstrated for multiple return values. I would rather not be required to use a special syntax to declared that a function returns multiple values. I don't see much point in it other than to force the caller to assign the result to multiple variables, instead of to a sequence if they wanted. Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
12. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 11, 2007
- 554 views
Chris Bensler wrote: > > Matt Lewis wrote: > > > > Jason Gade wrote: > > > > > > The routine specification tells the user whether the parameter is modified > > > or > > > not. Nothing should be "unexpected". However most routines would not be > > > written > > > to use PBR and probably even fewer library routines. > > > > It might even make sense to make the caller specify pbr, so that both > > the caller and the callee have to agree. That way it's explicit that > > you're allowing and expecting it to change. > > > > Matt > > I would definitely agree that PBR shoud be defined by both the callee and > caller. > I'm not very convinced that PBR is nessecary though. > > Other than convenience and a slight improvement to readability (which is > debatable > IMO), can someone please explain how PBR would be useful compared to multiple > return values? It aint clicking for me. Optimization? Yes, for optimization. If you have medium to large-size sequences (or structures if we get them) that you have to manipulate it is better to modify them directly instead of constantly making copies. Right now the only workaround is to use a global sequence and that is probably just as bad. -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
13. Re: pbr vs multiple returns
- Posted by Tommy Carlier <tommy.carlier at telenet.be> Jan 11, 2007
- 584 views
Chris Bensler wrote: > I would definitely agree that PBR shoud be defined by both the callee and > caller. > I'm not very convinced that PBR is nessecary though. > > Other than convenience and a slight improvement to readability (which is > debatable > IMO), can someone please explain how PBR would be useful compared to multiple > return values? It aint clicking for me. Optimization? > > Also, regarding multiple return values. What is the purpose of providing an > alternate syntax for multiple return values? > I don't see the purpose of introducing a new syntax to declare that a function > returns multiple values. We can already do that by returning a sequence. All > we need is a syntax for how to assign the members of a returned sequence to > multiple variables. > > {err,val} = get("3.14") > > Shouldn't that be a viable statement without having to modify how get() works? > > In anycase, I would whole heartedly agree with the syntax I demonstrated for > multiple return values. I would rather not be required to use a special syntax > to declared that a function returns multiple values. I don't see much point > in it other than to force the caller to assign the result to multiple > variables, > instead of to a sequence if they wanted. I also think the assignment of multiple values would be great. It would make Euphoria more functional. The stack code could look like this:
-- pushes o onto stack, and returns stack function push(sequence stack, object o) return append(stack, o) end function -- pops an object from the stack, and returns {stack, popped_object} function pop(sequence stack) return { stack[1..$-1], stack[$] } end function sequence s object o s = {} for i = 1 to 10 do s = push(s, i) end for for i = 1 to 10 do {s, o} = pop(s) end for
That said, I also like the idea of PBR. I agree with Matt, that both the caller and callee have to specify the passing by reference. I don't really like the * notation of C/C++ (and OOEU?). I quite like the way it's done in C#, via the 'ref' keyword. In Euphoria, it could look like this:
procedure swap(ref object o1, ref object o2) object o o = o1 o1 = o2 o2 = o end procedure integer a, b a = 1 b = 2 swap(ref a, ref b)
The stack code could look like this, with PBR:
procedure push(ref sequence s, object o) s = append(s, o) end procedure function pop(ref sequence s) object o o = s[$] s = s[1..$-1] return o end function sequence s object o s = {} for i = 1 to 10 do push(ref s, o) end for for i = 1 to 10 do o = pop(ref s) end for
To be honest, I actually like this PBR -- The Internet combines the excitement of typing with the reliability of anonymous hearsay. tommy online: http://users.telenet.be/tommycarlier tommy.blog: http://tommycarlier.blogspot.com
14. Re: pbr vs multiple returns
- Posted by Chris Bensler <bensler at nt.net> Jan 11, 2007
- 572 views
Tommy Carlier wrote: > > I also think the assignment of multiple values would be great. It would make > Euphoria > more functional. The stack code could look like this: > }}} <eucode> > -- pushes o onto stack, and returns stack > function push(sequence stack, object o) > return append(stack, o) > end function > > -- pops an object from the stack, and returns {stack, popped_object} > function pop(sequence stack) > return { stack[1..$-1], stack[$] } > end function > > sequence s > object o > s = {} > for i = 1 to 10 do > s = push(s, i) > end for > > for i = 1 to 10 do > {s, o} = pop(s) > end for > </eucode> {{{ > That said, I also like the idea of PBR. I agree with Matt, that > both the caller and callee have to specify the passing by reference. > I don't really like the * notation of C/C++ (and OOEU?). I quite like the > way it's done in C#, via the 'ref' keyword. In Euphoria, it could look like > this: > }}} <eucode> > procedure swap(ref object o1, ref object o2) > object o > o = o1 > o1 = o2 > o2 = o > end procedure > > integer a, b > a = 1 > b = 2 > swap(ref a, ref b) > </eucode> {{{ > The stack code could look like this, with PBR: > }}} <eucode> > procedure push(ref sequence s, object o) > s = append(s, o) > end procedure > > function pop(ref sequence s) > object o > o = s[$] > s = s[1..$-1] > return o > end function > > sequence s > object o > s = {} > for i = 1 to 10 do > push(ref s, o) > end for > > for i = 1 to 10 do > o = pop(ref s) > end for > </eucode> {{{ > To be honest, I actually like this PBR I agree with Tommy's suggestions 100% A keyword is better than a symbol. Either 'ref' or 'pbr'. 'pbr' might be less likely to be confused with an actual parameter name. Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
15. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 11, 2007
- 561 views
- Last edited Jan 12, 2007
Chris Bensler wrote: > > > I agree with Tommy's suggestions 100% > A keyword is better than a symbol. Either 'ref' or 'pbr'. 'pbr' might be less > likely to be confused with an actual parameter name. I think you guys are probably right. I went with the asterisk because it absolutely wouldn't break any code, and because it's fairly well known from C. It should be fairly trivial to switch to 'ref' or 'pbr' in the code. The significant coding will be in making the caller specify pbr. Matt
16. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 11, 2007
- 549 views
- Last edited Jan 12, 2007
Matt Lewis wrote: > > Chris Bensler wrote: > > > > > > I agree with Tommy's suggestions 100% > > A keyword is better than a symbol. Either 'ref' or 'pbr'. 'pbr' might be > > less > > likely to be confused with an actual parameter name. > > I think you guys are probably right. I went with the asterisk because it > absolutely wouldn't break any code, and because it's fairly well known > from C. It should be fairly trivial to switch to 'ref' or 'pbr' in the > code. The significant coding will be in making the caller specify pbr. > > Matt Just throwing my two cents in for "ref". "pbr" isn't as clear. You might have people start thinking "Pabst Blue Ribbon" or something ! -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
17. Re: pbr vs multiple returns
- Posted by CChris <christian.cuvier at agriculture.gouv.fr> Jan 11, 2007
- 580 views
- Last edited Jan 12, 2007
Chris Bensler wrote: > > Matt Lewis wrote: > > > > Jason Gade wrote: > > > > > > The routine specification tells the user whether the parameter is modified > > > or > > > not. Nothing should be "unexpected". However most routines would not be > > > written > > > to use PBR and probably even fewer library routines. > > > > It might even make sense to make the caller specify pbr, so that both > > the caller and the callee have to agree. That way it's explicit that > > you're allowing and expecting it to change. > > > > Matt > > I would definitely agree that PBR shoud be defined by both the callee and > caller. Please explain why. It means redundant coding: not only the routine declaration states which argument is by value and which argument is by reference, but you want every coder to supply the same information every time he uses the routine. What will happen if the sequence of refs and non refs used by the caller is different from the one the callee supplied at declaration time? Throw out an error? Issue a warning? This would make the code more error prone, not less, and without any added functionality. I don't mind if Eu defines optional keywords to flag arguments as ref or vals at call time, as long as I'm not forced to type them in. > I'm not very convinced that PBR is nessecary though. > > Other than convenience and a slight improvement to readability (which is > debatable > IMO), can someone please explain how PBR would be useful compared to multiple > return values? It aint clicking for me. Optimization? In another post, you mentioned the append() function. While s2=append(s1,x) must remain a valid call and has some uses, you are probably aware that, most of the time, what you want is to add an element to s1. Since this is really what you want, you should be able to code it as append_self(s1,x), with s1 being passed by ref. What is the point to create a new copy of s1 whose destiny is to be very soon overwritten? Using multiple return values for this purpose is as much as a hack as using global variables as we now have to do. > > Also, regarding multiple return values. What is the purpose of providing an > alternate syntax for multiple return values? > I don't see the purpose of introducing a new syntax to declare that a function > returns multiple values. We can already do that by returning a sequence. All > we need is a syntax for how to assign the members of a returned sequence to > multiple variables. > > {err,val} = get("3.14") > > Shouldn't that be a viable statement without having to modify how get() works? > > In anycase, I would whole heartedly agree with the syntax I demonstrated for > multiple return values. I would rather not be required to use a special syntax > to declared that a function returns multiple values. I don't see much point > in it other than to force the caller to assign the result to multiple > variables, > instead of to a sequence if they wanted. > > Chris Bensler > ~ The difference between ordinary and extraordinary is that little extra ~ > <a href="http://empire.iwireweb.com">http://empire.iwireweb.com</a> - Empire > for Euphoria I have nothing against multiple return values. As already pointed out, if you can assign to a sequence of variables leaving some of them alone at your discretion (this uses PBR actually), then MRV may not have any use at all. We seem to agree on this particular point. CChris
18. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 11, 2007
- 563 views
- Last edited Jan 12, 2007
Matt Lewis wrote: > > Chris Bensler wrote: > > > > > > I agree with Tommy's suggestions 100% > > A keyword is better than a symbol. Either 'ref' or 'pbr'. 'pbr' might be > > less > > likely to be confused with an actual parameter name. > > I think you guys are probably right. I went with the asterisk because it > absolutely wouldn't break any code, and because it's fairly well known > from C. It should be fairly trivial to switch to 'ref' or 'pbr' in the > code. The significant coding will be in making the caller specify pbr. > > Matt I'm not too sure about the challenges in making the caller specify pbr but could it just be a mechanism like typechecking? Unless typechecking is turned off then when the function is called the interpreter makes sure both the definition and the call itself has the 'ref' keyword. Another thought, though, is that whatever word is used for 'ref' instead of an asterisk is going to break any programs that might use that same word as a variable name. Usually I prefer words to symbols but right now I'm not so sure... -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
19. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 11, 2007
- 587 views
- Last edited Jan 12, 2007
Jason Gade wrote: > > > I'm not too sure about the challenges in making the caller specify pbr but > could > it just be a mechanism like typechecking? Unless typechecking is turned off > then when the function is called the interpreter makes sure both the > definition > and the call itself has the 'ref' keyword. The challenge is that I have to rework the parser to be aware of when it's parsing arguments for a routine call, so that if it finds the PBR token, it can remember that. Also, if it finds that token anywhere else, it should cause an error. > Another thought, though, is that whatever word is used for 'ref' instead of > an asterisk is going to break any programs that might use that same word as > a variable name. Usually I prefer words to symbols but right now I'm not so > sure... Yeah, that was the dilemma I faced initially, and why I went with the asterisk. Matt
20. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 11, 2007
- 571 views
- Last edited Jan 12, 2007
CChris wrote: > > Chris Bensler wrote: > > > > I would definitely agree that PBR shoud be defined by both the callee and > > caller. > > Please explain why. The choice is between making people type a little bit more, and possibly causing bugs when they get unexpected side effects of variables changing because they forgot that they were passing something by reference. This is the art part of language design that Rob mentioned. > I have nothing against multiple return values. As already pointed out, if > you can assign to a sequence of variables leaving some of them alone at your > discretion (this uses PBR actually), then MRV may not have any use at all. > We seem to agree on this particular point. While there is an overlap between the two, they ultimately do deal with different issues. I think that we should stop comparing them, and deal with each on its own merits. Matt
21. Re: pbr vs multiple returns
- Posted by Jason Gade <jaygade at yahoo.com> Jan 11, 2007
- 563 views
- Last edited Jan 12, 2007
Matt Lewis wrote: > > Jason Gade wrote: > > > > > > I'm not too sure about the challenges in making the caller specify pbr but > > could > > it just be a mechanism like typechecking? Unless typechecking is turned off > > then when the function is called the interpreter makes sure both the > > definition > > and the call itself has the 'ref' keyword. > > The challenge is that I have to rework the parser to be aware of when it's > parsing arguments for a routine call, so that if it finds the PBR token, > it can remember that. Also, if it finds that token anywhere else, it > should cause an error. Sorry, I didn't mean that to imply that there were no challenges but rather that I myself am not familiar with all of the specifics that have to be changed. I had the general idea though... I'm reworking the Shootout program "reverse-complement" and I kind of wish that I had pass-by-reference. However not having it is making me think a little harder about how to write the program in a Euphoria way instead of just copying the C straight over (as well as the other couple of languages that I'm looking at...) -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
22. Re: pbr vs multiple returns
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 11, 2007
- 575 views
- Last edited Jan 12, 2007
Chris Bensler wrote: My apologies for the recent (part 4) post. > Also, regarding multiple return values. What is the purpose of providing an > alternate syntax for multiple return values? > I don't see the purpose of introducing a new syntax to declare that a > function returns multiple values. We can already do that by returning a > sequence. You are quite right. After considering this a bit more, I think I was trying to avoid creating the "wrapper" sequence for the return values but actually if the last time I returned {x,y} it put x in one variable and y in another, the previous "{,}" should still be sitting there with a refcount of 1 ready for re-use anyway. > All > we need is a syntax for how to assign the members of a returned sequence to > multiple variables. > > {err,val} = get("3.14") > > Shouldn't that be a viable statement without having to modify how get() > works? Yep. While this means we no longer need #=, as a separate and lesser issue you might still want @= (pronounced all equal), so that:
{x,y}@="chris"
sets both x and y to "chris" rather than x to 'c' and y to 'h'. Same deal of course with {x,y} at =get_name(). Regards, Pete
23. Re: pbr vs multiple returns
- Posted by Chris Bensler <bensler at nt.net> Jan 11, 2007
- 568 views
- Last edited Jan 12, 2007
Pete Lomax wrote: > > Chris Bensler wrote: > > My apologies for the recent (part 4) post. No offense taken. I'm just very frustrated with trying to justify myself to everyone. Personally I'd like to know where Euphoria wants to go, so I can either start making it happen or get on with my own things instead. This limbo is good for nobody. Everybody has a wishlist and it's always religious war. We should not be trying to dictate what should be in Eu, we should be listening to what Eu needs. As I said before, maybe Eu is perfect for what it's supposed to be already and we are all bashing heads for nothing. We need to recognize the separation of varying opinions and perspectives on priority and find a comprimise before we can begin to determine what is practical to implement. > > Also, regarding multiple return values. What is the purpose of providing an > > alternate syntax for multiple return values? > > I don't see the purpose of introducing a new syntax to declare that a > > function returns multiple values. We can already do that by returning a > > sequence. > You are quite right. After considering this a bit more, I think I was trying > to avoid creating the "wrapper" sequence for the return values but actually > if the last time I returned {x,y} it put x in one variable and y in another, > the previous "{,}" should still be sitting there with a refcount of 1 ready > for re-use anyway. > > > All > > we need is a syntax for how to assign the members of a returned sequence to > > multiple variables. > > > > {err,val} = get("3.14") > > > > Shouldn't that be a viable statement without having to modify how get() > > works? > Yep. While this means we no longer need #=, as a separate and lesser issue you > might still want @= (pronounced all equal), so that: > }}} <eucode> > {x,y}@="chris" > </eucode> {{{ > sets both x and y to "chris" rather than x to 'c' and y to 'h'. Same deal of > course with {x,y} at =get_name(). > > Regards, > Pete What's wrong with repeat() ? Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
24. Re: pbr vs multiple returns
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jan 11, 2007
- 567 views
- Last edited Jan 12, 2007
Chris Bensler wrote: > > Pete Lomax wrote: > > > > Chris Bensler wrote: > > > > My apologies for the recent (part 4) post. > > No offense taken. I'm just very frustrated with trying to justify myself to > everyone. > > Personally I'd like to know where Euphoria wants to go, so I can either start > making it happen or get on with my own things instead. This limbo is good for > nobody. > > Everybody has a wishlist and it's always religious war. We should not be > trying > to dictate what should be in Eu, we should be listening to what Eu needs. As > I said before, maybe Eu is perfect for what it's supposed to be already and > we are all bashing heads for nothing. > > We need to recognize the separation of varying opinions and perspectives on > priority and find a comprimise before we can begin to determine what is > practical > to implement. I thought that's what we were doing. Seriously, though, on one hand, I understand (and to an extent, share) your frustration--dammit, why can't they all just see that I'm right?!? :) > > }}} <eucode> > > {x,y}@="chris" > > </eucode> {{{ > > sets both x and y to "chris" rather than x to 'c' and y to 'h'. Same deal of > > course with {x,y} at =get_name(). > > What's wrong with repeat() ? I think what Pete is talking about is kinda the complement (reverse? whatever) of repeat(). He's taking one thing and assigning it to several things with a single statement. It's just syntactic sugar, compressing things into a single statement. Personally, I don't see that it adds very much, and would vote to keep it out at this point. Matt
25. Re: pbr vs multiple returns
- Posted by Chris Bensler <bensler at nt.net> Jan 12, 2007
- 558 views
Matt Lewis wrote: > > Chris Bensler wrote: > > > > Pete Lomax wrote: > > > > > > Chris Bensler wrote: > > > > > > My apologies for the recent (part 4) post. > > > > No offense taken. I'm just very frustrated with trying to justify myself to > > everyone. > > > > Personally I'd like to know where Euphoria wants to go, so I can either > > start > > making it happen or get on with my own things instead. This limbo is good > > for > > nobody. > > > > Everybody has a wishlist and it's always religious war. We should not be > > trying > > to dictate what should be in Eu, we should be listening to what Eu needs. As > > I said before, maybe Eu is perfect for what it's supposed to be already and > > we are all bashing heads for nothing. > > > > We need to recognize the separation of varying opinions and perspectives on > > priority and find a comprimise before we can begin to determine what is > > practical > > to implement. > > I thought that's what we were doing. Seriously, though, on one hand, I > understand (and to an extent, share) your frustration--dammit, why can't > they all just see that I'm right?!? :) I know what you mean about the frustration and yes, I feel that too, but that has more to do with differences in opinion, not being right or wrong. We need to know what Eu's opinion is, not 5 or 6 adamant peoples. > > > }}} <eucode> > > > {x,y}@="chris" > > > </eucode> {{{ > > > sets both x and y to "chris" rather than x to 'c' and y to 'h'. Same deal > > > of > > > course with {x,y} at =get_name(). > > > > > What's wrong with repeat() ? > > I think what Pete is talking about is kinda the complement (reverse? > whatever) of repeat(). He's taking one thing and assigning it to several > things with a single statement. It's just syntactic sugar, compressing > things into a single statement. Personally, I don't see that it adds > very much, and would vote to keep it out at this point. > > Matt {x,y} = repeat("chris",2) Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
26. Re: pbr vs multiple returns
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jan 12, 2007
- 561 views
Matt Lewis wrote: > > Chris Bensler wrote: > > > }}} <eucode> > > > {x,y}@="chris" > > > </eucode> {{{ > > > > What's wrong with repeat() ? Good catch. > > I think what Pete is talking about is kinda the complement (reverse? > whatever) of repeat(). He's taking one thing and assigning it to several > things with a single statement. It's just syntactic sugar, compressing > things into a single statement. Personally, I don't see that it adds > very much, and would vote to keep it out at this point. > Agreed. More than anything else I was, erm, reserving the "@=" notation. Still something for much later, but I agree with Chris that repeat would be fine for the same reasons as returning a sequence of multiple results, and could even be recognised by the parser, so the repeat statement need never actually be performed. Regards, Pete