1. Pass by address
- Posted by "J. Kenneth Riviere" <kriviere at MINDSPRING.COM> Aug 16, 2000
- 576 views
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)
2. Re: Pass by address
- Posted by Al Getz <xaxo at AOL.COM> Aug 16, 2000
- 524 views
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
3. Re: Pass by address
- Posted by Matthew Lewis <MatthewL at KAPCOUSA.COM> Aug 16, 2000
- 506 views
> > 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
4. Re: Pass by address
- Posted by Al Getz <xaxo at AOL.COM> Aug 16, 2000
- 508 views
- Last edited Aug 17, 2000
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
5. Re: Pass by address
- Posted by Robert Craig <rds at ATTCANADA.NET> Aug 17, 2000
- 490 views
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? Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
6. Re: Pass by address
- Posted by Irv Mullins <irv at ELLIJAY.COM> Aug 17, 2000
- 483 views
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
7. Re: Pass by address
- Posted by ck lester <cklester at YAHOO.COM> Aug 17, 2000
- 506 views
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? 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
8. Re: Pass by address
- Posted by Greg Phillips <i.shoot at rednecks.com> Aug 17, 2000
- 491 views
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? 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
9. Re: Pass by address
- Posted by Andy Cranston <Andy.Cranston at EUPHONY.CO.UK> Aug 17, 2000
- 521 views
Ouch! That C++ code hurts 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? Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
10. Re: Pass by address
- Posted by David Cuny <dcuny at LANSET.COM> Aug 17, 2000
- 532 views
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. -- David Cuny
11. Re: Pass by address
- Posted by Andy Cranston <Andy.Cranston at EUPHONY.CO.UK> Aug 17, 2000
- 528 views
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* I'll have to make a mental note not to show you any of my code 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 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.
12. Re: Pass by address
- Posted by Irv Mullins <irv at ELLIJAY.COM> Aug 17, 2000
- 490 views
On Thu, 17 Aug 2000, you wrote: > Ouch! That C++ code hurts > > 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
13. Re: Pass by address
- Posted by Robert Craig <rds at ATTCANADA.NET> Aug 17, 2000
- 492 views
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
14. Re: Pass by address
- Posted by Al Getz <xaxo at AOL.COM> Aug 17, 2000
- 505 views
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? 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
15. Re: Pass by address
- Posted by David Alan Gay <moggie at INTERLOG.COM> Aug 17, 2000
- 497 views
- Last edited Aug 18, 2000
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? > > Regards, > Rob Craig > Rapid Deployment Software > http://www.RapidEuphoria.com >
16. Re: Pass by address
- Posted by Jeff Zeitlin <jzeitlin at CYBURBAN.COM> Aug 18, 2000
- 505 views
On Fri, 18 Aug 2000 00:02:18 -0400, Andy Cranston <Andy.Cranston at EUPHONY.CO.UK> wrote: >Ouch! That C++ code hurts >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