1. Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at ?o?gar.com> Apr 30, 2008
- 844 views
I create a db.e file that defines the word close. I then:
include db.e as d --- do things f = open(filename, "w") -- later close(f)
It called the database's close function, not the internal. So, even if you use a namespace, your included files cannot define functions by the same name as an internal and you expect to continue to use an internal function? -- Jeremy Cowgar http://jeremy.cowgar.com
2. Re: Namespace clobbering internals
- Posted by Mike <vulcan at w?n.?o.nz> Apr 30, 2008
- 789 views
Jeremy Cowgar wrote: > > I create a db.e file that defines the word close. I then: > > }}} <eucode> > include db.e as d > > --- do things > f = open(filename, "w") > > -- later > close(f) > </eucode> {{{ > > It called the database's close function, not the internal. So, even if you use > a namespace, your included files cannot define functions by the same name as > an internal and you expect to continue to use an internal function? > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> Jeremy, As far as I can tell, builtin routines are automatically in a global namespace. Anything that goes there is immediately available to every bit of the rest of the program being parsed. At the end of parsing that namespace must be chock full. A program may define a routine with the same name as that of a builtin. If the routine is also specified as 'global' it will replace the original one and so we end up with the problem you encountered here. I solve this in orac in 2 ways: 1) Anything defined as 'global' will only reach to the next level and cannot exceed that range unless propagated further. If there could be said to be global namespace in Orac, it is superbly clean. 2) Use the prefix 'builtin' and the compiler will know that you only refer to the builtin symbol. In the code fragment above, the only change Orac needs for it to work correctly is to drop the "as d" part. Your global "close" will override the builtin "close" until the end of that file, at which, time the builtin "close" will reassert itself. If you ever needed to access the builtin "close" inside that file then it is just a case of.. builtin: close() Well, I'm not sure that this actually helps you unless you convert to Orac (Welcome to the Dark Side, brother, hehehe...). No, seriously, since you've got work to do NOW, what I would do is just use my_close. regards, Mike
3. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at cowgar?com> Apr 30, 2008
- 778 views
Would it make sense that if a function/variable is called with no namespace qualifier that exists as a built-in and user defined inside a namespace that the built-in be used? That would seem like the logical answer. The user knew there would be a conflict, thus, he/she included the file w/the conflict with a namespace to prevent that conflict. Now. If you include a file w/no namespace and now you have a built-in and user defined function of the same name, no namespace qualifier and called it with no namespace qualifier, then I would think the application should err out as it does now. Matt, what do you think?
include pgsql.e as db db:close() --- we know it's calling pgsql.e's close function f = open(...) close(f) --- no namespace given, use the built-in
... another example
include pgsql.e close() --- hm, Euphoria cannot tell if they want built-in --- or pgsql.e's close(), therefore crash Euphoria with --- the namespace qualifier error it currently uses
-- Jeremy Cowgar http://jeremy.cowgar.com
4. Re: Namespace clobbering internals
- Posted by Matt Lewis <matthewwalkerlewis at g?ai?.com> Apr 30, 2008
- 756 views
Jeremy Cowgar wrote: > > It called the database's close function, not the internal. So, even if you > use a namespace, your included files cannot define functions by the same > name as an internal and you expect to continue to use an internal function? Yes, euphoria namespaces work differently than in, say, C++. They don't hide anything, they just serve to disambiguate. Matt
5. Re: Namespace clobbering internals
- Posted by Matt Lewis <matthewwalkerlewis at gmai?.c?m> Apr 30, 2008
- 791 views
Jeremy Cowgar wrote: > > Would it make sense that if a function/variable is called with no namespace > qualifier that exists as a built-in and user defined inside a namespace > that the built-in be used? That would seem like the logical answer. > > The user knew there would be a conflict, thus, he/she included the file > w/the conflict with a namespace to prevent that conflict. > > Now. If you include a file w/no namespace and now you have a built-in and > user defined function of the same name, no namespace qualifier and called > it with no namespace qualifier, then I would think the application should > err out as it does now. This will break code. One of my favorite things to do is to overload things like print. Of course, that could be fixed by using namespaces, but it sort of defeats the purpose of overriding something like this. It can make debugging easier by inserting an override that logs, or does something different, or whatever. Also, what if you want to use the overload in the same file as it is declared? I suppose you could have the file include itself, but as CChris would certainly tell us, that would just be silly. A better solution might be to reserve a namespace for built-ins. Maybe something like, "eu". So your example might become:
include pgsql.e as pg include mysql.e as my pg:close() -- pgsql.e's close function my:close() -- mysql.e's close function eu:close() -- reserved built-in namespace, use the built-in close() -- error, multiple definitions
Matt
6. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at cowga?.c?m> Apr 30, 2008
- 751 views
Matt Lewis wrote: > > A better solution might > be to reserve a namespace for built-ins. Maybe something like, "eu". > > So your example might become: > }}} <eucode> > include pgsql.e as pg > include mysql.e as my > pg:close() -- pgsql.e's close function > my:close() -- mysql.e's close function > eu:close() -- reserved built-in namespace, use the built-in > close() -- error, multiple definitions > </eucode> {{{ Yes, that's a good solution. I tried to follow the internals about how namespaces work and have failed to have it click yet. Can we make this change? All internals have a reserved namespace, eu, that can optionally be used if the programmer sees the need. As you pointed about about my solution, it will break code and take away some of the benefit, but adding a namespace to internals should not break anything and only solve problems. What would it take to do this? If you want to do it, or maybe give me a few pointers then I can play with doing it. Your call. -- Jeremy Cowgar http://jeremy.cowgar.com
7. Re: Namespace clobbering internals
- Posted by Shawn Pringle <shawn.pringle at ??ail.com> Apr 30, 2008
- 766 views
This is what I tried to explain in the chat room. We would like to put included modules into a namespace exclusively so that a function such as close could ONLY be referenced through its name space: d:close() but not close(). You see when functions are included by namespace you set a name for they also go into a global local namespace. Right now: include db.e -- includes into the global name space include db.e as d -- includes into global namespace and namespace 'd'. -- no way to put include db.e into a namespace 'd' exclusively. Perhaps you could use existing keywords in a new way: include db.e as d, without global -- includes db.e into d but close() will call the builtin. -- Even if there is a function called insert in db.e, calling insert() will fail, -- you must type d:insert(). Jeremy Cowgar wrote: > > I create a db.e file that defines the word close. I then: > > }}} <eucode> > include db.e as d > > --- do things > f = open(filename, "w") > > -- later > close(f) > </eucode> {{{ > > It called the database's close function, not the internal. So, even if you use > a namespace, your included files cannot define functions by the same name as > an internal and you expect to continue to use an internal function? > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
8. Re: Namespace clobbering internals
- Posted by Arthur Crump <arthur.crump at ntlwo?l?.com> Apr 30, 2008
- 784 views
- Last edited May 01, 2008
"include db.e as d, without global" in a module looks more like a syntax to prevent a program which called this module from receiving db.e, rather than this module not receiving it without its namespace; an option I would like to see, incidentally. Perhaps: "include db.e as d only" might be sufficient. However, Jeremy Cowgar's suggestion of a standard namespace such as eu for builtin routines is equally good. Arthur Crump, in Cheshire, England. Shawn Pringle wrote: > > This is what I tried to explain in the chat room. We would like to put > included modules into a namespace exclusively so that a function such as > close could ONLY be referenced through its name space: d:close() but not > close(). You see when functions are included by namespace you set a name > for they also go into a global local namespace. > > Right now: > include db.e -- includes into the global name space > > include db.e as d -- includes into global namespace and namespace 'd'. > > -- no way to put include db.e into a namespace 'd' exclusively. > > > Perhaps you could use existing keywords in a new way: > > include db.e as d, without global > -- includes db.e into d but close() will call the builtin. > -- Even if there is a function called insert in db.e, calling insert() will > fail, > -- you must type d:insert(). > > Jeremy Cowgar wrote: > > > > I create a db.e file that defines the word close. I then: > > > > }}} <eucode> > > include db.e as d > > > > --- do things > > f = open(filename, "w") > > > > -- later > > close(f) > > </eucode> {{{ > > > > It called the database's close function, not the internal. So, even if you > > use > > a namespace, your included files cannot define functions by the same name as > > an internal and you expect to continue to use an internal function? > > > > -- > > Jeremy Cowgar > > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
9. Re: Namespace clobbering internals
- Posted by Shawn Pringle <shawn.pringle at ?mail.c?m> May 01, 2008
- 797 views
I saw the idea of keeping symbols out of the global scope necessary for porting existing EUPHORIA applications and libraries to the new standard library. Imagine you have 12,000 lines of code and you wish to use this new standard library. Can you imagine having to do a search and replace for every builtin to include an eu: namespace qualifier? Perhaps it is just better to avoid the names of builtins in the first place unless you really want to override them. Instead of open and close, the same kind of thing could be called connect() and disconnect(). Shawn Pringle Arthur Crump wrote: > > > "include db.e as d, without global" > in a module looks more like a syntax to prevent a program which called > this module from receiving db.e, rather than this module not receiving > it without its namespace; an option I would like to see, incidentally. > > Perhaps: > "include db.e as d only" > might be sufficient. > > However, Jeremy Cowgar's suggestion of a standard namespace such as eu > for builtin routines is equally good. > > Arthur Crump, in Cheshire, England. > > Shawn Pringle wrote: > > > > This is what I tried to explain in the chat room. We would like to put > > included modules into a namespace exclusively so that a function such as > > close could ONLY be referenced through its name space: d:close() but not > > close(). You see when functions are included by namespace you set a name > > for they also go into a global local namespace. > > > > Right now: > > include db.e -- includes into the global name space > > > > include db.e as d -- includes into global namespace and namespace 'd'. > > > > -- no way to put include db.e into a namespace 'd' exclusively. > > > > > > Perhaps you could use existing keywords in a new way: > > > > include db.e as d, without global > > -- includes db.e into d but close() will call the builtin. > > -- Even if there is a function called insert in db.e, calling insert() will > > fail, > > -- you must type d:insert(). > > > > Jeremy Cowgar wrote: > > > > > > I create a db.e file that defines the word close. I then: > > > > > > }}} <eucode> > > > include db.e as d > > > > > > --- do things > > > f = open(filename, "w") > > > > > > -- later > > > close(f) > > > </eucode> {{{ > > > > > > It called the database's close function, not the internal. So, even if you > > > use > > > a namespace, your included files cannot define functions by the same name > > > as > > > an internal and you expect to continue to use an internal function? > > > > > > -- > > > Jeremy Cowgar > > > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a>
10. Re: Namespace clobbering internals
- Posted by Jason Gade <jaygade at yah?o.co?> May 01, 2008
- 757 views
Shawn Pringle wrote: > > I saw the idea of keeping symbols out of the global scope necessary for > porting existing EUPHORIA applications and libraries to the new standard > library. > Imagine you have 12,000 lines of code and you wish to use this new standard > > library. Can you imagine having to do a search and replace for every builtin > > to include an eu: namespace qualifier? > > Perhaps it is just better to avoid the names of builtins in the first place > unless > you really want to override them. Instead of open and close, the same kind > of > thing could be called connect() and disconnect(). > > Shawn Pringle But you wouldn't have to do that really (although automation certainly eases the task). You would only have to add a namespace qualifier to symbols that clashed. And if a namespace keyword was adopted as has been suggested then I think that conflicts would be far easier to fix. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
11. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at co?g?r.com> May 01, 2008
- 763 views
Jason Gade wrote: > > Shawn Pringle wrote: > > > > I saw the idea of keeping symbols out of the global scope necessary for > > porting existing EUPHORIA applications and libraries to the new standard > > library. > > Imagine you have 12,000 lines of code and you wish to use this new standard > > > > library. Can you imagine having to do a search and replace for every > > builtin > > > > to include an eu: namespace qualifier? > > > > But you wouldn't have to do that really (although automation certainly eases > the task). You would only have to add a namespace qualifier to symbols that > clashed. > I think Shawn is right. Say, you have your program that uses the function close() many times to close a file. Then you include, say, my pgsql.e file which also defines close(). Now, everywhere in his code that contains close() (as referring to the built-in close()), would require a prefix of eu: added. Otherwise, it would call the close() defined in pgsql.e, even though pgsql.e included inside of a namespace. I think I am back to my original thoughts on this: http://www.openeuphoria.org/EUforum/m20234.html Now, Matt replied that it would break existing code, as people who have over-ridden built-in's intentionally to have their own version of printf() for use while debugging or something. Depending on how many people do that, it may just be better to realize that as soon as anyone anywhere defines a function by the name of an internal, then you've lost the ability to use that internal (as soon as you include that file in your code that is). That doesn't seem quite right, but that is how things are looking right now? -- Jeremy Cowgar http://jeremy.cowgar.com
12. Re: Namespace clobbering internals
- Posted by Shawn Pringle <shawn.pringle at gma?l.?om> May 01, 2008
- 781 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > Shawn Pringle wrote: > > > > > > I saw the idea of keeping symbols out of the global scope necessary for > > > porting existing EUPHORIA applications and libraries to the new standard > > > library. > > > Imagine you have 12,000 lines of code and you wish to use this new > > > standard > > > > > > library. Can you imagine having to do a search and replace for every > > > builtin > > > > > > to include an eu: namespace qualifier? > > > > > > > But you wouldn't have to do that really (although automation certainly eases > > the task). You would only have to add a namespace qualifier to symbols that > > clashed. > > > > I think Shawn is right. Say, you have your program that uses the function > close() > many times to close a file. Then you include, say, my pgsql.e file which also > defines close(). > > Now, everywhere in his code that contains close() (as referring to the > built-in > close()), would require a prefix of eu: added. Otherwise, it would call the > close() defined in pgsql.e, even though pgsql.e included inside of a > namespace. > > I think I am back to my original thoughts on this: > > <a > href="http://www.openeuphoria.org/EUforum/m20234.html">http://www.openeuphoria.org/EUforum/m20234.html</a> > > Now, Matt replied that it would break existing code, as people who have > over-ridden > built-in's intentionally to have their own version of printf() for use while > debugging or something. > > Depending on how many people do that, it may just be better to realize that > as soon as anyone anywhere defines a function by the name of an internal, then > you've lost the ability to use that internal (as soon as you include that file > in your code that is). That doesn't seem quite right, but that is how things > are looking right now? > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> Consider this: (eu.e:) global procedure old_close( integer fd ) close( fd ) end procedure global procedure close( integer fd ) close( fd ) end procedure global function open( sequence filename, sequence access ) open( filename, access ) end function ---- main.ex include eu.e as eu include db.e as db integer fd object line fd = eu:open( "c:\autoexec.bat", "r" ) line = gets(fd) while sequence(line) ? line line = gets(fd) end while old_close( fd ) You see you can setup a builtin namespace without touching the backend source. You can still access the builtin but you have to alter how you access it. This would break any large project: win32lib.ew, ide.exw and thus inhibit the standard library's acceptance to large existing projects. This is what we did for redefining printf(). Often the new printf would need to call the old printf you needed to give the old printf another name: old_printf. Shawn
13. Re: Namespace clobbering internals
- Posted by Matt Lewis <matthewwalkerlewis at gma?l.?om> May 01, 2008
- 750 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > Shawn Pringle wrote: > > > > > > I saw the idea of keeping symbols out of the global scope necessary for > > > porting existing EUPHORIA applications and libraries to the new > > > standard library. Imagine you have 12,000 lines of code and you wish > > > to use this new standard library. Can you imagine having to do a > > > search and replace for every builtin to include an eu: namespace > > > qualifier? > > > > But you wouldn't have to do that really (although automation certainly > > eases the task). You would only have to add a namespace qualifier to > > symbols that clashed. > > > > I think Shawn is right. Say, you have your program that uses the function > close() many times to close a file. Then you include, say, my pgsql.e file > which also defines close(). > > Now, everywhere in his code that contains close() (as referring to the > built-in close()), would require a prefix of eu: added. Otherwise, it > would call the close() defined in pgsql.e, even though pgsql.e included > inside of a namespace. Well, remember, this is only if he wants to do add something new to his existing 12KLOC. If he keeps using the libraries he has, nothing changes. How many built-ins are we talking about overriding? > I think I am back to my original thoughts on this: > > http://www.openeuphoria.org/EUforum/m20234.html > > Now, Matt replied that it would break existing code, as people who have > over-ridden built-in's intentionally to have their own version of printf() > for use while debugging or something. Yes. But also consider your hypothetical pgsql.e. It couldn't use its own close() function, unless it defines a namespace for itself. This fails the principle of least surprise. > Depending on how many people do that, it may just be better to realize > that as soon as anyone anywhere defines a function by the name of an > internal, then you've lost the ability to use that internal (as soon as > you include that file in your code that is). That doesn't seem quite right, > but that is how things are looking right now? I remain unconvinced that refactoring your code to accommodate a new library is too much of a burden. Matt
14. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at co?gar.?om> May 01, 2008
- 802 views
Matt Lewis wrote: > > How many built-ins are we talking about overriding? > Here are some common ones that would make libraries easier if we can override them. The reason I say this, is why come up with 20 creative names for the same task just to prevent collisions. Now, if I want to delete a record from a database I have to use delete, then to remove something from a map, I have to use vanish, then to delete an item in a sequence I have to remove, etc... If diff libs could all use remove or delete to remove or delete something, then it makes things easier. append, prepend, remove, length, compare, equal, find, match, sort, open, close. That's just real quick off the top of my head. Again, being able to use these function names makes programming libraries and using libraries simpler. map:length() for instance. Instead of coming up with map:size(), map:length_of(), map:mass(), map:volume(), map:extent(), map:porpotion(), etc... or... map:remove() instead of map:delete(), map:take(), map:take_off(), map:withdraw(), etc... Again, this creates a simpler API. One problem with programming in Forth is the requirement of every single word has to be a new name, so when programming anything sizeable in forth you wind up becoming an English scholar and your dictionary becomes your greatest tool in programming. You then come up with names that are so very similar that later you even question what it does. > > Yes. But also consider your hypothetical pgsql.e. It couldn't use its > own close() function, unless it defines a namespace for itself. This > fails the principle of least surprise. > Yes, that's a problem. I wonder if in addition to a eu: namespace if we should borrow a good idea from the OO people (not to make Euphoria OO, and not to suggest that I like Java better than Euphoria, but why not learn from other languages? To not learn from other languages is not very smart), self:, this:, current:, me: or something like that. Just more thinking about the subject. Matt, I think the eu: namespace is a critical addition, even if we do or do not use it to solve some of these problems we are speaking of right now. What it will do is give, in example, the pgsql.e file the ability to call the built-in close() or it's own close(). I do not think anyone will complain if we add the eu: namespace as it will not break a thing and will only help in situations. Can you give me a pointer or direction in implementing this? -- Jeremy Cowgar http://jeremy.cowgar.com
15. Re: Namespace clobbering internals
- Posted by CChris <christian.cuvier at agricul?ure.gouv.f?> May 01, 2008
- 786 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > Shawn Pringle wrote: > > > > > > I saw the idea of keeping symbols out of the global scope necessary for > > > porting existing EUPHORIA applications and libraries to the new standard > > > library. > > > Imagine you have 12,000 lines of code and you wish to use this new > > > standard > > > > > > library. Can you imagine having to do a search and replace for every > > > builtin > > > > > > to include an eu: namespace qualifier? > > > > > > > But you wouldn't have to do that really (although automation certainly eases > > the task). You would only have to add a namespace qualifier to symbols that > > clashed. > > > > I think Shawn is right. Say, you have your program that uses the function > close() > many times to close a file. Then you include, say, my pgsql.e file which also > defines close(). > > Now, everywhere in his code that contains close() (as referring to the > built-in > close()), would require a prefix of eu: added. Otherwise, it would call the > close() defined in pgsql.e, even though pgsql.e included inside of a > namespace. > > I think I am back to my original thoughts on this: > > <a > href="http://www.openeuphoria.org/EUforum/m20234.html">http://www.openeuphoria.org/EUforum/m20234.html</a> > > Now, Matt replied that it would break existing code, as people who have > over-ridden > built-in's intentionally to have their own version of printf() for use while > debugging or something. > > Depending on how many people do that, it may just be better to realize that > as soon as anyone anywhere defines a function by the name of an internal, then > you've lost the ability to use that internal (as soon as you include that file > in your code that is). That doesn't seem quite right, but that is how things > are looking right now? > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> If someone somewhere overrides a builtin, I guess that the purpose is to extend the builtin without changing its normal processing. This way, the user can take advantage of the enhancements without bothering to use yet another name[space]. Then, what is the point of insisting on calling the builtin? For the sake of peace of mind, something easy can be done. Usually, extending a builtin takes the following form:
procedure print_wrapped(whatever) -- wrap builtin as a regular routine, because builtins have no routine_id print(whatever) end procedure -- now we have an alternate way of calling print() constant print_id=routine_id("print_wrapped") -- now redefine the builtin, while elying on it if the extensions are not -- needed on some call. global procedure print(whatever) -- Very, very unfortunately, the signature cannot be changed. if my_own_procesing() then my_smecial_code() else call_proc(print_id,{whatever}) end if end procedure
Extending a builtin otherwise would have to be discouraged. Notice that, if print_id is made global, then you can call the vintage print() again. Some piece of (good) kludgy ol' Eu. In most languages, the proecess is very straightforward. CChris
16. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at ?o?gar.com> May 01, 2008
- 778 views
CChris wrote: > > If someone somewhere overrides a builtin, I guess that the purpose is to > extend > the builtin without changing its normal processing. This is not the case, Please see my post: http://www.openeuphoria.org/EUforum/m20279.html -- Jeremy Cowgar http://jeremy.cowgar.com
17. Re: Namespace clobbering internals
- Posted by Jason Gade <jaygade at y??oo.com> May 01, 2008
- 762 views
Jeremy Cowgar wrote: > > CChris wrote: > > > > If someone somewhere overrides a builtin, I guess that the purpose is to > > extend > > the builtin without changing its normal processing. > > This is not the case, Please see my post: > > <a > href="http://www.openeuphoria.org/EUforum/m20279.html">http://www.openeuphoria.org/EUforum/m20279.html</a> > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> What you describe isn't overriding, it's overloading. The namespace proposals so far (default namespace in include, eu namespace for builtins) should enable overloading. Unless I'm missing something in the conversation. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
18. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at cowg?r.?om> May 01, 2008
- 767 views
Jason Gade wrote: > > > What you describe isn't overriding, it's overloading. > Yes, but the original problem is that there is no way to overload, it is overriding. > The namespace proposals so far (default namespace in include, eu namespace for > builtins) should enable overloading. Except that it will force people to use eu: in their code even when they include map.e as map ... Let's say map overload's the find() function (may be a dumb example, but an example).
include map.e as map map:map m m = map:new() m = map:put(m, "name", "Jason") m = map:find(m, "Jason") sequence e e = {1,2,3} ? find(3, e)
So, the lower part dealing with the sequence was code that existed already in programmer Joe's code. Now Joe makes use of the new map. Well, his find() for the sequence e is now broke. He has to go back and prefix find() with eu: Now, as Matt said, it may not be that big of a conversion path for people to do that. My original thinking was in the above example, find() exists in both the built-in namespace and the map namespace. If there is a conflict and no namespace is given, then Euphoria should chose the built-in function, however, that would take away the ability to override a built-in (again as Matt pointed out to me). -- Jeremy Cowgar http://jeremy.cowgar.com
19. Re: Namespace clobbering internals
- Posted by CChris <christian.cuvier at a?r?culture.gouv.fr> May 01, 2008
- 802 views
Jeremy Cowgar wrote: > > CChris wrote: > > > > If someone somewhere overrides a builtin, I guess that the purpose is to > > extend > > the builtin without changing its normal processing. > > This is not the case, Please see my post: > > <a > href="http://www.openeuphoria.org/EUforum/m20279.html">http://www.openeuphoria.org/EUforum/m20279.html</a> > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> I see. The overloading of a single routine name to perform similar actions on different sorts of objects has been consistently fought off on this list. Of course, as a user of some OO languages (mostly Eiffel and less Delphi), I think that overloading would make the language much easier to learn and use. I'd be delighted if we could at last come back from this nonsense of "if it does something else, give it another name". Nevertheless, extensions in the way I described are also useful, and should be made posible *as well*. CChris
20. Re: Namespace clobbering internals
- Posted by CChris <christian.cuvier at ?griculture.gou?.fr> May 01, 2008
- 773 views
Jason Gade wrote: > > Jeremy Cowgar wrote: > > > > CChris wrote: > > > > > > If someone somewhere overrides a builtin, I guess that the purpose is to > > > extend > > > the builtin without changing its normal processing. > > > > This is not the case, Please see my post: > > > > <a > > href="http://www.openeuphoria.org/EUforum/m20279.html">http://www.openeuphoria.org/EUforum/m20279.html</a> > > > > -- > > Jeremy Cowgar > > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> > > What you describe isn't overriding, it's overloading. > > The namespace proposals so far (default namespace in include, eu namespace for > builtins) should enable overloading. > > Unless I'm missing something in the conversation. > > -- > A complex system that works is invariably found to have evolved from a simple > system that works. > --John Gall's 15th law of Systemantics. > > "Premature optimization is the root of all evil in programming." > --C.A.R. Hoare > > j. Yes, they would. CChris
21. Re: Namespace clobbering internals
- Posted by Jason Gade <jaygade at yaho??com> May 01, 2008
- 761 views
Jeremy Cowgar wrote: > > Jason Gade wrote: > > > > > > What you describe isn't overriding, it's overloading. > > > > Yes, but the original problem is that there is no way to overload, it is > overriding. > > > The namespace proposals so far (default namespace in include, eu namespace > > for > > builtins) should enable overloading. > > Except that it will force people to use eu: in their code even when they > include > map.e as map ... Let's say map overload's the find() function (may be a dumb > example, but an example). > > }}} <eucode> > include map.e as map > > map:map m > m = map:new() > m = map:put(m, "name", "Jason") > m = map:find(m, "Jason") > > sequence e > e = {1,2,3} > ? find(3, e) > </eucode> {{{ > > So, the lower part dealing with the sequence was code that existed already in > programmer Joe's code. Now Joe makes use of the new map. Well, his find() for > the sequence e is now broke. He has to go back and prefix find() with eu: > > Now, as Matt said, it may not be that big of a conversion path for people to > do that. My original thinking was in the above example, find() exists in both > the built-in namespace and the map namespace. If there is a conflict and no > namespace is given, then Euphoria should chose the built-in function, however, > that would take away the ability to override a built-in (again as Matt pointed > out to me). > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> I understand the problem a bit better now. A proper solution requires some thought I think... -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
22. Re: Namespace clobbering internals
- Posted by Shawn Pringle <shawn.pringle at ?mail.c?m> May 02, 2008
- 788 views
If you set builtins as always being the one used when a namespace is not specified you will break overloading. If you leave the interpreter the way it is, your new library's use of functions with the same names as builtins will break much more code than what's in print.e. A third alternative is to introduce some kind of hiding into a namespace. A fourth alternative involves avoiding any builtin names. When I say, hiding objects into a namespace. I would like you to suppose that insert() is a routine defined in db.e. 'include db.e' means you can only access db.e's insert() function as insert(). 'include db.e as db' means you can access db.e's insert() function as both insert() and db:insert(). You could hack the backend such that that allows you can get access to insert() as db:insert() but not as insert(). I don't like the idea of modifying the backend, though. The fourth alternative is, you can use the same method names over and over if you ensure they are not builtins. All new libraries can use routines names over and over so long as the name doesn't appear twice in the same file. So, you may need to find synonyms for some builtin names but you only need to find one synonym for each one. There is no modifying the backend and you wont break any existing code. The fourth alternative, I have to say is less bug proned than the third alternative since you are not modifying the interpreter C-source itself. You don't need to put the builtins into their own namespace because you purposely avoid using builtins. This means that large programs like Judith's IDE could use it without renaming or namespaceing other things. The third alternative has appeal to me. I think it would be neat to do a kind of overloading only for things inside a namespace. You might introduce bugs into the EU interpreter but large programs could then use this library without renaming or namespacing other things. The first two ideas are well understood by anyone who reads Matt's posts so I will not talk more about them here. :) Shawn
23. Re: Namespace clobbering internals
- Posted by jiri babor <jbabor at p?radi?e.net.nz> May 02, 2008
- 785 views
I must admit I have not followed your discussion from the start, but one simpler solution seems to me rather obvious: instead of adding ever more convoluted namespace rules, introduce a special, restricted type of global identifiers, which will have to be *always* preceded by a context specifier. A single new keyword will be required, say 'export' instead of 'global'. Using example similar to Jason's: -- map.e export type map(... export function new(... export function put(... export function find(... -- myprog.ex include map.e as map integer index map:map m m = map:new() m = map:put(m, "name", "Jason") index = map:find(m, "Jason") sequence e e = {1,2,3} ? find(3, e) -- system function not clobbered! The globals can stay as they are, but they should be used for important, system-wide identifiers only. Their wholesale use should be strongly discouraged. This approach will leave the global space uncluttered, programs more understandable, and not much, if any legacy code will be broken. jiri
24. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at co??ar.com> May 02, 2008
- 795 views
jiri babor wrote: > > > keyword will be required, say 'export' instead of 'global'. > I wonder if the inverse might be helpful? override ... for instance, say you want to override the print function:
override function close(...) --- code end function
Now, those that wish to override internals can, and those that just want to make their own close() function for a database, or a PDF writer, or who knows what, they can. -- Jeremy Cowgar http://jeremy.cowgar.com
25. Re: Namespace clobbering internals
- Posted by Matt Lewis <matthewwalkerlewis at gmai?.co?> May 02, 2008
- 772 views
jiri babor wrote: > > I must admit I have not followed your discussion from the start, but one > simpler solution seems to me rather obvious: instead of adding ever more > convoluted namespace rules, introduce a special, restricted type of global > identifiers, which will have to be *always* preceded by a context specifier. > A single new keyword will be required, say 'export' instead of 'global'. Of *course* it's obvious to you, Jiri. Seriously, though, it's good to hear from you again. <snip> > The globals can stay as they are, but they should be used for important, > system-wide identifiers only. Their wholesale use should be strongly > discouraged. > > This approach will leave the global space uncluttered, programs more > understandable, and not much, if any legacy code will be broken. Yes, this gets into the 'packaging' topic that has been discussed a bit. I think this is very similar to what I've proposed in that arena. I'd add a little to this idea, to say that you have to use the namespace that is specific to that file, because a namespace also can apply to the globals included by the file given the namespace.
-- app.ex include foo.e as foo include bar.e as bar foo:baz() -- ok bar:bar() -- ok foo:bar() -- error! -- foo.e include bar.e as bar ... bar:bar() -- bar.e export procedure bar() end procedure global procedure baz() end procedure
I like this because no matter where bar.e goes, the behavior stays the same, and it's scope is obvious. I'm contrasting this to CChris' packaging proposal, where we would have to add some additional packaging information in other files. This would allow library writers to spread out among multiple files (making their lives easier) but without exposing the internals to library users, who can possibly come to rely on something meant to be internal, and subject to change without notice. Matt
26. Re: Namespace clobbering internals
- Posted by Jeremy Cowgar <jeremy at cowgar??om> May 02, 2008
- 796 views
I don't know if anyone else is, but I'm having troubles following all the suggestions, the pros/cons, etc... I wonder if we should create a wiki page for a Namespace plan or something? Seems kind of hard to act on any of this because it seems we've made no decision and it's hard to even decide what choices there are to make a decision about, or for that matter, what the problem actually is any more -- Jeremy Cowgar http://jeremy.cowgar.com
27. Re: Namespace clobbering internals
- Posted by Matt Lewis <matthewwalkerlewis at ?mail.c?m> May 02, 2008
- 807 views
Jeremy Cowgar wrote: > > I don't know if anyone else is, but I'm having troubles following all the > suggestions, > the pros/cons, etc... I wonder if we should create a wiki page for a Namespace > plan or > something? Seems kind of hard to act on any of this because it seems we've > made no decision > and it's hard to even decide what choices there are to make a decision about, > or for > that matter, what the problem actually is any more In fact, there already is one, although it's out of date now, as it describes stuff already implemented: http://rapideuphoria.wiki.sourceforge.net/Namespace_Resolution Matt
28. Re: Namespace clobbering internals
- Posted by Jason Gade <jaygade at ?ah?o.com> May 03, 2008
- 785 views
Jeremy Cowgar wrote: > > jiri babor wrote: > > > > > > keyword will be required, say 'export' instead of 'global'. > > > > I wonder if the inverse might be helpful? override ... for instance, say you > want to override the print function: > > }}} <eucode> > override function close(...) > --- code > end function > </eucode> {{{ > > Now, those that wish to override internals can, and those that just want to > make their own close() function for a database, or a PDF writer, or who knows > what, they can. > > -- > Jeremy Cowgar > <a href="http://jeremy.cowgar.com">http://jeremy.cowgar.com</a> You know, I was reading some Python docs last night, for no particular reason, and one of their standards and practices for naming routines that might clash with a built-in is to append an underscore to the identifier:
function open_(sequence name) -- Do stuff here end function
Not a permanent solution because we really do need to decide how scopes and namespaces should work better, but maybe a good temporary solution since we never seem to be able to come to a consensus. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.