1. Pass by address

This is the first of a short series of msgs I intend to post to the
mailing list hoping to generate some discussion about features I'd
like to see added to Euphoria.

The first item I'd like to see added is parameter passing by address
for subroutines.

Currently all subroutines accept passed parameters by value.  Any
changes made to the data passed as arguments are not reflected in
the original variables unless the updated variables are returned from
a function or assigned to some other global variable.

Robert has noted in the documentation for Euphoria that in actuallity
he has only passed a reference which points to the variables being
passed into the subroutine so that there is very little overhead in
subroutine calls.  Furthermore, since the same logic should apply to
returning results, it should be highly efficient to return updated
variables.  This is a good thing and I'm generally grateful that I
don't have to worry about this.

However, in those same notes Robert mentions that if a complex structure
is updated which is currently pointed to by two (or more, presumably)
variables, then a copy of that complex structure will be made.  As I
understand it, this copy would only be of the logical "top level" of
the sequence structure, as the addresses of the complex sequences
which comprise each element of the top-level sequence would still point
to the individual instances of those sub-sequences and would be shared
by both copies (the original structure and the new, updated copy).

I've been working on a series of functions and procedures for manipulating
key-value sequences (kvseq) which are designed to be as general purpose
as I can make them.  Each kvseq would consist of a sequence where each
element of the sequence is a two element sequence, the first being the
key and the second being the value.  Each of these elements, the key and
the value, can be any object in Euphoria.  I use the compare function to
keep them sorted and do binary searches of the structure so that I can
check for the existence of a key, retrieve the value associated with a
key, insert or update key/value pairs, append to the value associated
with a key, prepend to the value associated with a key, or delete a k/v
pair.  Each function which modifies the kvseq is passed the kvseq which
is to be updated and returns the updated version.  The passing in of the
argument and the return of the result are probably quite effecient
operations per the earlier discussion.  However, in the course of
updating the sequence, especially when inserting or deleting a k/v pair,
the code could wind up causing a complete copy of the kvseq's top level
to be made.  If these kvseq's grow to any significant length then this
could be a significant overhead.  If I could indicate that this parameter
is being passed "by address" then the update process of the interpreter
could recognize that there really is only one variable that identifies
this sequence and thus it would not have to make a copy of that potentially
large sequence.  I would convert the current functions into procedures
which would also save the (minimal) time of returning the updated value.

To my mind this enhancement to the language would be similar to having
the ability to use the "x+=1" assignment instead of having to use "x=x+1".
This would only require a minimal adjustment to the syntax of declaring
subroutines to allow parameters to have a property of "by address", how
ever Robert wanted to implement it.

I hope that this suggestion will generate some discussion of other
enhancements Euphoria users might like to see.

   -J. Kenneth Riviere (JoKeR)

new topic     » topic index » view message » categorize

2. Re: Pass by address

On passing vars by address:

#1

I'm glad someone mentioned this.  I've been giving this some thought
recently and i see the problem with passing vars in Eu by address is that
it then requires complete knowledge of the structure of the data being
passed.  Worst case, ever try to pass a complex sequence to another exe
program?  If you like to peek and poke you got it made, but this takes some
overhead time, VERY undesirable with a large data structure.
One possible way around this could be something like:

   sequence x
   global atom x_Address
   x="this sequence"
   x_Address=var_base_address("x") --similar to "routine_id()"

which of course could return the address of the Eu variable, making it
accessable to other parts of a program as well as other programs, but it
would have to return the address of the structure (not id), such that
another new Eu function in another file or program could use it such as:

   sequence y
   use_base_address(y, x_Address)
   --now y is a sequence whos values are exactly the same as x's, and
   --modifications made to y are also made to x as well.
   --x_Address could be passed to other programs too on the command line!

If var_base_address{) returns an id instead of an actual address, that will
again make passing to another program difficult as with routine_id().

#2

Currently Eu's routine_id() seems to be limited to passing within
the same program, so I'd also like to see routine_id() return an address
instead of an id. This change would be backward compatible with the current
routine_id() as well as to allow passing of routines to other programs! Of
course this would make Euphoria plug-ins a reality also.

I dont see these changes being much of a challenge for the designers of
the Eu language, i'm sure the base addresses are internally available
anyway.  This wouldnt complicate the language any more then routine_id()
did either.

Any more ideas on this subject out there?

  -- Al Getz

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

3. Re: Pass by address

>
> On passing vars by address:
>
> #1
>
> I'm glad someone mentioned this.  I've been giving this some thought
> recently and i see the problem with passing vars in Eu by
> address is that
> it then requires complete knowledge of the structure of the data being
> passed.

Although, if, instead of 'by address', we say, 'by reference', there might
be a way around this.  The interpreter could copy the pointer to the passed
variable, but rather than copying it when it's changed, simply make the
changes.  That way, the 'address' would still be hidden from the user, but
would have the important functionality of 'passing by address'.  Granted, I
don't know how this would affect performance, etc., but since Eu already
does copy pointers to variables, and seems to be able to keep track of them,
it might actually speed some things up, since you avoid having to copy the
stucture/data to somewhere else.  It might make some parts of the C
translation a bit easier/faster, too.

To argue against it, I think this makes the code less readable in some
cases(it's not as clear, to ME at least, when you're returning values this
way vs. using functions), but would probably simplify things in the other.

<snip>

> #2
>
> Currently Eu's routine_id() seems to be limited to passing within
> the same program, so I'd also like to see routine_id() return
> an address
> instead of an id. This change would be backward compatible
> with the current
> routine_id() as well as to allow passing of routines to other
> programs! Of
> course this would make Euphoria plug-ins a reality also.
>

This part is already done.  Use call_back(), which takes a routine_id as
it's argument, and returns the address an external process should call--the
equivalent of a pointer to a function in C.  That's how Eu is able to
function in Windows.

Matt Lewis

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

4. Re: Pass by address

Thanks thats nice, but i'm currently working with Euphoria v2.0 public
domain release.  As you might recall, that version only has one
"call_back()" per program.  I hope to be able to get the newest verion soon.

As for the readability argument, i dont believe that stands:
Any program which provides a high degree of functionality is inherently
"unreadable".  Any program which provides a small amount of functionaliy is
inherently readable in any language.  Thats why i think the "readability"
arguments are a crock.  I dont have a problem "reading" C++ code and that's
a far more advanced language--but as the functionality grows, so does the
readability diminish--an inverse relationship of sorts--you have to read
and understand an ever increasingly large chunk of code in order to get a
really good understanding of the program.
  If adding a variables address lookup function to the language breaks the
poor readabiliy camel's back i guess its time to hang up the keyboard.

Good languages grow.  They grow in search of more functionality coupled
with a concern for the needs expressed by programmers who use the language.
Languages that dont grow die out.  Case in point: QBasic.
In case you dont believe its dead, you havent tried Euphoria hee hee!
I'm all for increasing the functionality of the language to make the
programming task easier.

On the lighter side...

 "Romeo, oh Romeo, what makes thy programming task so difficult, Romeo?"
 "Not having that, which having, makes it easier."

  hee hee

  --Al Getz

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

5. Re: Pass by address

Al Getz writes:
> I dont have a problem "reading" C++ code

Then read this...

#define c n*n>x?p:((m=*(b+1)),N))
#define e (2<<6*sizeof(int))
#define o (8<<5*sizeof(int))
#define N ((b=t+1),x+=2,x>e?exit():o
#define p (a-t<o?*(a++)=x:47),printf("%d ",x),N)
main(){
int x=3,n,m=2,*t,*a,*b=0;
c:x%n?(int)b++:N);
}

What does this program do?  smile

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

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

6. Re: Pass by address

On Wed, 16 Aug 2000, Al Getz wrote:
....
> As for the readability argument, i dont believe that stands:
> Any program which provides a high degree of functionality is inherently
> "unreadable".  Any program which provides a small amount of functionaliy is
> inherently readable in any language.

I take it you haven't seen Intercal, then?

Irv

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

7. Re: Pass by address

C'mon. If you're going to try and challenge him, at least use something
difficult. I knew what this program did even before you posted it.

> Al Getz writes:
> > I dont have a problem "reading" C++ code
>
> Then read this...
>
> #define c n*n>x?p:((m=*(b+1)),N))
> #define e (2<<6*sizeof(int))
> #define o (8<<5*sizeof(int))
> #define N ((b=t+1),x+=2,x>e?exit():o
> #define p (a-t<o?*(a++)=x:47),printf("%d ",x),N)
> main(){
> int x=3,n,m=2,*t,*a,*b=0;
> while(b?o:((*(t=b=(int*)malloc(o))=2),a=t+1,o))n=*b,n>=m?
> c:x%n?(int)b++:N);
> }
>
> What does this program do?  smile

Okay, to be honest: I don't know.

Can you now translate it into EUPHORIA! That would be interesting.


__________________________________________________
Do You Yahoo!?
Talk to your friends online with Yahoo! Messenger.
http://im.yahoo.com

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

8. Re: Pass by address

Robert Craig writes:

> Then read this...
>
> #define c n*n>x?p:((m=*(b+1)),N))
> #define e (2<<6*sizeof(int))
> #define o (8<<5*sizeof(int))
> #define N ((b=t+1),x+=2,x>e?exit():o
> #define p (a-t<o?*(a++)=x:47),printf("%d ",x),N)
> main(){
> int x=3,n,m=2,*t,*a,*b=0;
> while(b?o:((*(t=b=(int*)malloc(o))=2),a=t+1,o))n=*b,n>=m?
> c:x%n?(int)b++:N);
> }
>
> What does this program do?  smile

I don't know, but it's a definite contender for the Obfuscated C/C++ Code
Contest.

It seems once a language reaches a certain point of maturity, someone comes
along and devises a competition to make code completely unreadable.  Some
Perl purists insist than unless you can place in the Obfuscated Perl
Contest, you're not a Perl coder. =)

> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    http://www.RapidEuphoria.com

Regards,
Greg Phillips

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

9. Re: Pass by address

Ouch!  That C++ code hurts smile

On the pass by address thread...

Maybe I'm being simplistic here (and I'm all for the easy life - it's why I
like Euphoria so much) but am I hitting the nail on the head re: pass by
address when I say:

"The problem is that a function can take multiple arguments but can only
return one value?"

If we had a function that could return multiple values would we then not
need pass by address?  Something like:

==== code snippit begins ====

function experiment(sequence a , sequence b)

  -- some sort of computation in here that
  -- modifes a and b in some way

  return a , b

end function

-- main code

sequence x
sequence y

[x , y] = experiment(x, y)

==== code snippit ends ====

I've just "invented" the [x , y] assignment syntax.  Something better must
be possible but I hope you get the idea.

Before anyone shouts "that will be inefficient" I'd argue that's a job for
the compiler / interpreter writer to worry about and not the programmer -
opinions on this, no doubt, will differ.

So is the problem simply that a function can only return one value?

Regards,

Andy Cranston.

-----Original Message-----
From: Robert Craig [mailto:rds at ATTCANADA.NET]
Sent: 17 August 2000 05:07
To: EUPHORIA at LISTSERV.MUOHIO.EDU
Subject: Re: Pass by address


Al Getz writes:
> I dont have a problem "reading" C++ code

Then read this...

#define c n*n>x?p:((m=*(b+1)),N))
#define e (2<<6*sizeof(int))
#define o (8<<5*sizeof(int))
#define N ((b=t+1),x+=2,x>e?exit():o
#define p (a-t<o?*(a++)=x:47),printf("%d ",x),N)
main(){
int x=3,n,m=2,*t,*a,*b=0;
c:x%n?(int)b++:N);
}

What does this program do?  smile

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

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

10. Re: Pass by address

Andy Cranston wrote:

> "The problem is that a function can take multiple
> arguments but can only return one value?"

There's also a problem if you want to alter a parameter of something you
passed to a routine. For example, let's say that I have a 'window' object
that I want to position in the center of the screen:

   window[x] = (screen[width]/2) - (window[width]/2)
   window[y] = (screen[height]/2) - (window[height]/2)

All fine and good, now you want to clean up your code by putting it in a
routine:

   procedure center_window( sequence w )
      w[x] = (screen[width]/2) - (w[width]/2)
      w[y] = (screen[height]/2) - (w[height]/2)
   end procedure

The problem with this is that a *copy* of the window is centered. If you
want to center the window, you have to write a function:

   function center_window( sequence w )
      w[x] = (screen[width]/2) - (w[width]/2)
      w[y] = (screen[height]/2) - (w[height]/2)
      return w
   end function

and then call it like this:

   window = center_window( window )

I'm cringing just writing that code. *bleah* After coding in C, QBasic and
Java, this just feels unnatural.

When you pass an object (in the class sense, not the Euphoria data type
sense), you *typically* want operations on that object, not on a copy of the
object. That's why languages like Java pass all complex data types as
pointers by default. (Well, that and it's computationally much cheaper to
pass a pointer than to clone an object.) If you want a copy of an object in
one of those languages, you have to explicitly ask for one.

But passing by reference isn't all blue skies and oysters. The problem with
this sort of thing is you have to remember if you are dealing with a real
object, a pointer, a clone... Soon you get into writing C-style code:

   &foo = *bar++;

One solution would be to emulate pointers with a large sequence, and pass
indexes. For example, in most of my OOP libraries, I define a global
sequence called 'the' or 'my'. The center_window routine would look like
this:

   procedure center_window( integer window )
      my[window][x] = (screen[width]/2) - (my[window][width]/2)
      my[window][y] = (screen[height]/2) - (my[window][height]/2)
   end procedure

This results in a lot more typing, and because of the extra index, the code
is slower. So I'd actually code is as:

   procedure center_window( integer window )
      sequence w
      w = my[window]
      w[x] = (screen[width]/2) - (w[width]/2)
      w[y] = (screen[height]/2) - (w[height]/2)
      my[window] = w
   end procedure

which is truely horrible code. This kind of stuff is no fun to code, and it
looks ugly!

Rather than pass by reference, Euphoria allow a sort of dot notation. Most
of the time, you're only passing one object to be altered. So:

   a.bar( b, c )

would be shorthand for:

   a = bar( a, b, c )

if bar was a function, and shorthand for:

   bar( a, b, c )

if bar was a procedure. That way, you could write:

   window.center_window()

and it would behave *properly*, as if it were a reference, without actually
introducing reference passing to the language. No special keywords, no
question about if a variable is a value or a reference. The syntax is
natural:

   myWindow.make_visible()
   myPoint.add_point( 12, 32 )
   myAccount.debit( 5000.00 )
   myShape.draw()

It looks like it's OOP, but it's not. It's just syntactic sugar. I've
actually written up a pre-processor that implements this notation and posted
it some time back. I recoded a large chunk of my code using it, and I was
able to write things like this:

   foo.plus( 12 )

long before Robert introduced the += construct to Euphoria. And the code
looked great (and was less filling). I think it's a fine solution to passing
by reference, but of course I'm biased. smile

-- David Cuny

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

11. Re: Pass by address

David Cuny wrote (and not in this order):

<SNIP>
>Rather than pass by reference, Euphoria allow a sort of dot notation. Most
>of the time, you're only passing one object to be altered. So:
>
>   a.bar( b, c )
>
>would be shorthand for:
>
>   a = bar( a, b, c )
>
>if bar was a function, and shorthand for:
>
>   bar( a, b, c )
>
>if bar was a procedure. That way, you could write:
>
>   window.center_window()
>
>and it would behave *properly*, as if it were a reference, without actually
>introducing reference passing to the language. No special keywords, no
>question about if a variable is a value or a reference. The syntax is
>natural:
>
>   myWindow.make_visible()
>   myPoint.add_point( 12, 32 )
>   myAccount.debit( 5000.00 )
>   myShape.draw()
>
>It looks like it's OOP, but it's not. It's just syntactic sugar.
<SNIP>

That's a very elegant proposal and applicable to alot of procedural
languages that have assignment and functions - not just Euphoria.  Full
marks!

<SNIP>
and then call it like this:

   window = center_window( window )

I'm cringing just writing that code. *bleah* After coding in C, QBasic and
Java, this just feels unnatural.
<SNIP>

As code like this has such an adverse effect on you (re: *bleah* smile I'll
have to make a mental note not to show you any of my code smile  It's littered
with this sort of stuff.  Can you believe that most of my C programs have
things like:

   var = var + 1

!!!  Maybe I just like torturing myself sad

Actually my coding style (if it can be called a style!) is on the "baby"
side.  I heard the term "baby programming" a few years back and liked it
because it described my programming style very well.  One look at any of my
code and other programmers instantly react with things like "it's better if
you do it like this - less code, more elegant, etc. etc.".  The point is
that although the code is longer than it needs to be, might not exploit
handy features of the language and what not the code is instantly readable
(well almost).  The fact than another programmer can take one look at my
code and immediately grasp what I trying to do and come up with more succint
and elegant ways to do it is, for me, actually a compliment.  I've written
something that is understandable - maybe pretty ugly but understandable
never the less.

Of course I'd never get away with this if I coded for a living - I'd starve
for a start.  But for my requirements right now I'll continue with the "baby
programming".

Regards,

Andy Cranston.

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

12. Re: Pass by address

On Thu, 17 Aug 2000, you wrote:
> Ouch!  That C++ code hurts smile
>
> On the pass by address thread...
>
> Maybe I'm being simplistic here (and I'm all for the easy life - it's why I
> like Euphoria so much) but am I hitting the nail on the head re: pass by
> address when I say:
>
> "The problem is that a function can take multiple arguments but can only
> return one value?"
>
> If we had a function that could return multiple values would we then not
> need pass by address?  Something like:
>
 snippit

>
> [x , y] = experiment(x, y)
>

I certainly agree that it would add some balance, perhaps even elegance, to
Euphoria if you could specify a "list" of targets which accept a function
return.  However, the idea that a function can only return one value is
misleading. I routinely wriite functions which return anywhere from 2 to 100 or
more "values". e.g. pass the function "age_account" a sequence containing
a customer record (name, address.... 30,60,90 day balances, current
transactions) and return an  updated record with balances adjusted.

Regards,
Irv

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

13. Re: Pass by address

Greg Philips writes:
> I don't know, but it's a definite contender for the
> Obfuscated C/C++ Code Contest.

That's where I got it.
It won for best short program in 1994.

http://www.ioccc.org/years.html

It prints the prime numbers up to 33554432.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

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

14. Re: Pass by address

On C syntax:
Looks to me like line #4 generates a syntax error, but
your point is well taken i can assure you.  I could also
pose an interesting dilemma in Euphoria that raises some
questions also, but ill save that for another time.
Im sure there are exceptions in every language to some
extent if we look hard enough.

On passing by address:
Initially i should have just stated my original coding
problem: passing large and complex data structures in
the form of sequence to another exe program.  The most
impressive part of Euphoria in my opinion is the sequence.
Id love to see a Euphoria class for C++ come into being.
The interface is already there.
  At present though, the best part of the language cant be
passed to another program. You cant pass a variable name
to another program because the namespace isnt system wide
as with the Windows OS.
Thats why i got drawn into this thread because i thought,
gee, if you could pass the address to another program that
could use that address to lookup the sequence then that would
solve the problem elegantly. The second program could use
and or modify the data (without excessive peeks and pokes).
The same cant be achieved with a handle or id unless its
also system wide, possibly allocating with the WinAPI.
I would prefer the address eliminating the middle man.

On readabiliy:
Also, if routine_id() returned an address, wouldnt that
eliminate the need for call_back() and simplify the
"readabiliy" of the language?  If someone needed to enumerate
the returned "id's" they could certainly store the addresses
one by one in a sequence.
Also, as someone else had mentioned, if procedure forward
referencing was an option that would make readability much
simpler in my opinion.  You arnt going to tell me

  global atom FIRST_ROUTINE
  FIRST_ROUTINE=routine_id("FirstRoutine")
  retv=c_func(FIRST_ROUTINE,{arg1,arg2,arg3})

is more readable then

  retv=FirstRoutine(arg1,arg2,arg3)

are you now? smile

Then i started reading the threads on here and saw the ideas
about allowing left sided multi-variable assignments in the
language syntax--something even a language like C cant
boast.  Gotta love it!  Would of course raise the syntax
complexity of the language possibly pushing it through
another semi-instabiliy phase.  Gotta hate that!

Take care for now and good programming!

--Al Getz

ps. would like to hear more on passing by address

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

15. Re: Pass by address

Holy smoke, Rob, what are you trying to do, give the listserv readers an
aneurysm? :)

David Gay

----- Original Message -----
From: "Robert Craig" <rds at ATTCANADA.NET>
To: <EUPHORIA at LISTSERV.MUOHIO.EDU>
Sent: Thursday, August 17, 2000 12:07 AM
Subject: Re: Pass by address


> Al Getz writes:
> > I dont have a problem "reading" C++ code
>
> Then read this...
>
> #define c n*n>x?p:((m=*(b+1)),N))
> #define e (2<<6*sizeof(int))
> #define o (8<<5*sizeof(int))
> #define N ((b=t+1),x+=2,x>e?exit():o
> #define p (a-t<o?*(a++)=x:47),printf("%d ",x),N)
> main(){
> int x=3,n,m=2,*t,*a,*b=0;
> while(b?o:((*(t=b=(int*)malloc(o))=2),a=t+1,o))n=*b,n>=m?
> c:x%n?(int)b++:N);
> }
>
> What does this program do?  smile
>
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    http://www.RapidEuphoria.com
>

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

16. Re: Pass by address

On Fri, 18 Aug 2000 00:02:18 -0400, Andy Cranston
<Andy.Cranston at EUPHONY.CO.UK> wrote:

>Ouch!  That C++ code hurts smile

>On the pass by address thread...

>Maybe I'm being simplistic here (and I'm all for the easy life - it's why I
>like Euphoria so much) but am I hitting the nail on the head re: pass by
>address when I say:

>"The problem is that a function can take multiple arguments but can only
>return one value?"

>If we had a function that could return multiple values would we then not
>need pass by address?  Something like:

You can always return a sequence with (n) elements, (n) being the number of
values that you want to return.  I believe the standard Euphoria library
function 'get()' does this.

--
Jeff Zeitlin
jzeitlin at cyburban.com

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

Search



Quick Links

User menu

Not signed in.

Misc Menu