1. pbr vs multiple returns

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

new topic     » topic index » view message » categorize

2. Re: pbr vs multiple returns

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.

new topic     » goto parent     » topic index » view message » categorize

3. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

6. Re: pbr vs multiple returns

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.

new topic     » goto parent     » topic index » view message » categorize

7. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

8. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

9. Re: pbr vs multiple returns

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. smile

--
"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.

new topic     » goto parent     » topic index » view message » categorize

10. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

11. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

12. Re: pbr vs multiple returns

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.

new topic     » goto parent     » topic index » view message » categorize

13. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

14. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

15. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

16. Re: pbr vs multiple returns

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 smile !

--
"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.

new topic     » goto parent     » topic index » view message » categorize

17. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

18. Re: pbr vs multiple returns

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.

new topic     » goto parent     » topic index » view message » categorize

19. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

20. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

21. Re: pbr vs multiple returns

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.

new topic     » goto parent     » topic index » view message » categorize

22. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

23. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

24. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

25. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

26. Re: pbr vs multiple returns

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu