Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[ A world of words ] naming convention, namespace, namespace pollution,

 [1/15] from: rebol::meurrens::org at: 28-May-2003 11:40


Hello, [ A world of words ] naming convention, namespace, namespace pollution, good practises, coding styles + multiple inheritance in the example As things are going on, I feel the necessity to organize a little bit the names I use. I mean, as well, names for script *files* and names for *words* used to store my values. I did not find on the web or by reading existing scripts something like a "convention", a "tradition" { tradition may be incompatible with rebolution -:) ??? } The need arises from several reasons --- avoid clashes, namespace pollution, etc in my own works --- avoid clashes in a cooperative/collaborative process as permitted by REBOL do http://rebol.my-friend.net/his-her-script.r --- readability/documentation/sharing knowledge --- deal with "no private/public in REBOL objects" (as for PHP, etc) { I allways prefix all private things with "_" (underscore) } --- deal with "no object strong typing in REBOL" (as for PHP, etc) --- deal with "no return type in function signature" --- deal with "case insensitive in REBOL" {no camelBack convention, but we may still decide to use it on a voluntary basis} {no ALL_UPPER_CASE convention, but we may still decide to use it on a voluntary basis} --- existing scripts show an extensive use of "-" (minus) but not "_" (underscore) Any reason ??? --- availability in the names of "special" characters such as "?" "!" "#" that have/should have/receive a "universal conventional" meaning. Below are some of my current ideas/practises. Together with a short example. But before deciding/publishing/re-inventing the wheel/etc, I'll like to know if there exists already some "good practises". ?????????? When do you use *.r or *.reb or even *.rebol ??? (*.rip is for archives) Do you use some other extensions ??? (a part of *.exe for Win32 executables of course) e.g. to store images converted to REBOL binaries, etc, etc ??? as %rebol-logo_83x31.jpg.r Do you use prefixes for your script names ??? such as %i-my-script.r ;;; defines a unique value : i-my-script , an interface definition block %o-my-script.r ;;; defines a unique value : o-my-script , an implementation definition block %my-script.r ;;; defines a set of values %v-my-script.r ;;; a so-called events driven "application" using REBOL/VIEW %c-my-script.r ;;; a so-called "application" using REBOL/CORE my-script.exe ;;; compilation of %v-my-script.r for WIN32 Special names for files holding data ??? preferences ??? configurations ??? a part from the well known %user.r %preferences.r something like ??? %my-script.ini.r How do you define an "application" ??? How do you define a "reblet" ??? Do you have conventions to let know that a given file is just a set of values, or is a "reblet" ??? an application ??? Do you use special conventions for naming your words ??? such as ?my-object ;;; help function ?my-object-my-value ;;; help function my-word? ;;; returns a logic (boolean) what about other special characters, such as "# " and "!" ??? when used as the first letter??? as the last??? Is there a consensus in the community on how/when to use them ??? Do you use something like an hungarian prefix ??? such as in the following script { demonstrating also so-called "multiple inheritance" and the " interface v. body" pattern we initially developped for JAVA in an anterior and still parallel life } Do you use "multiple inheritance" ??? (does not replace "composition"...!) Do you use upper/lower cases for documentation purposes ??? such as A_NOT_SO_GOOD_PI: 3.14 ;; constant Do you use indentation conventions and some other coding syles ??? === REBOL[] ;;;; in file i-browser.r ;;; just to show interface v. implementation + show multiple inheritance i-browser: [ ?browser: function [/all][][ print "smart browser" if found? all [ ?browser-run ?browser-msg-bye ] ] ; ?browser-run: does [ help browser-run ] browser-run: function ["browse an url" u [url!]][][ browse u ] ; default implementation ?browser-msg-bye: does [ print "browser-msg-bye: ; message displayed when leaving the application"] browser-msg-bye: "bye bye" ] ;;;; in file o-browser.r ;;; just for the fun; not very smart indeed o-browser: [ browser-run: function ["browse an url" u [url!]][][ either connected? [ alert browser-msg-bye browse u ] [ alert "you are not connected to internet" ] ] ] ;;;; in file i-pretty-script.r i-pretty-script: [ ?pretty-script: function [/all][][ print "a funny example" if found? all [ ?pretty-script-run ?pretty-script-col-black ?pretty-script-col-white ] ] ; existence of ?pretty-script is also a way to test if an object "IS" a i-pretty-script ?pretty-script-col-black: does [ print "pretty-col-black: ; black is beautifull"] pretty-col-black: 10.10.10 ; nearly black ?pretty-script-col-white: does [ print "pretty-col-white: ; white is never really white"] pretty-col-white: 245.245.245 ; nearly white ?pretty-script-run: does [ help pretty-run ] pretty-run: function ["just try it"][][] ; dummy here ; to ovrdn ] ;;;; in file o-pretty-script.r ;;;; dependencies : i-pretty-script.r i-browser o-pretty-script: [ pretty-col-black: does [ random 20.20.20 ] ; ovrdn as a function, just for the fun. _pretty-col-marc: 33.66.99 ; the blue used in this implementation _pretty-laydef-1: [ style sty-but button 80x20 bold _pretty-1-but-black: sty-but pretty-col-black "black" [ alert join "nearly black " face/color ] sty-but _pretty-col-marc "home" [ browser-run http://www.meurrens.org/ ] sty-but pretty-col-white "close" [ unview ] sty-but _pretty-col-marc "quit" [ quit ] ] pretty-run: function ["just try it"][][ view layout _pretty-laydef-1 ] ] ;;;; in my applic file random/seed now my-specific: [ pretty-col-black: random 255.0.0 ; black becomes red pretty-col-white: request-color/color 233.234.235 ; let the user choices the white browser-msg-bye: {Ce n'est qu'un "Au Revoir", mes fr=E8res} ?: does [ print "===" ?browser/all print "===" ?pretty-script/all print "===" ] ] my-obj: make make make make make object! ; 5 make's expect 5 def's : i-pretty-script i-browser o-pretty-script o-browser my-specific ; open the console... my-obj/? ; do some job... my-obj/pretty-run my-obj/browser-run http://www.rebol.com/ ==== As you see, there are many questions and I certainly forgot a lot... I'll appreciate your feedback. Regards </marc> Prof. Ir Marc Meurrens, Brussels (be) TEL: +32 (0)2 537 2812 FAX: +32 (0)2 537 7645 EMAIL: [marc--meurrens--org] URL: http://www.meurrens.org/ REB: http://rebol.mksa.net/ PGPKEY: http://www.meurrens.org/pgp/ Please don't mail me attached files, instead, use my 'exchange area' : EXCHANGE AREA: http://www.meurrens.org/exchange/ (HTTP/FTP upload/download of temporary/persistent files)

 [2/15] from: gchiu:compkarori at: 28-May-2003 23:16

Re: [ A world of words ] naming convention, namespace, namespace pollut


On Wed, 28 May 2003 11:40:31 +0200 Marc Meurrens <[rebol--meurrens--org]> wrote:
>As you see, there are many questions and I certainly >forgot a lot... > >I'll appreciate your feedback.
Marc, Please read the official style guide: http://www.rebol.com/docs/core23/rebolcore-5.html#sect5. which may answer some of your questions -- Graham Chiu http://www.compkarori.com/vanilla/ Rebol Encyclopaedia Project

 [3/15] from: ptretter:charter at: 28-May-2003 7:34


I would just add that I really don't think that anything is needed beyond the style guide. I think the freedom of expression within the code is not a problem. Most REBOLers can distinguish the code without need of certain conventions. REBOL should stay easy to learn like it was for me when I started out. Paul Tretter ----- Original Message ----- From: "Graham Chiu" <[gchiu--compkarori--co--nz]> To: <[rebol-list--rebol--com]> Sent: Wednesday, May 28, 2003 6:16 AM Subject: [REBOL] Re: [ A world of words ] naming convention, namespace, namespace pollution, good practises, coding styles

 [4/15] from: nitsch-lists:netcologne at: 28-May-2003 14:41


Marc Meurrens wrote:
> Hello, > [ A world of words ]
<<quoted lines omitted: 9>>
> something like a "convention", a "tradition" > { tradition may be incompatible with rebolution -:) ??? }
http://www.rebol.com/docs/core23/rebolcore-5.html Eventually get an IOS-account, there are some original rt-style-apps.
> > The need arises from several reasons > --- avoid clashes, namespace pollution, etc in my own works > --- avoid clashes in a cooperative/collaborative process as permitted > by REBOL > do http://rebol.my-friend.net/his-her-script.r
my-module: context[ .. ] you have to take care you made all words local. Either by function-locals or by having them as set-words in the top-level. means, here 'a is local, but 'b is global. : ctx: context[ a: 123 do [b: 234] ] because the context-builder did not look in the inner block. a good way to check if you made something global: query/clear system/words do %script.r probe query system/words
> --- readability/documentation/sharing knowledge > --- deal with "no private/public in REBOL objects" (as for PHP, etc) > { I allways prefix all private things with "_" (underscore) }
with series, 'find and all the inbuild stuff i rarely need a lot of fields. public/private or deep object-hierarchies are waste of time with typical script-sizes IMHO. stuff like files: [%file1.r as-text %file2.r as-binary] foreach [file mode][either 'as-text = mode[..][..] ] saves some declarations :)
> --- deal with "no object strong typing in REBOL" (as for PHP, etc) > --- deal with "no return type in function signature"
keep a console open. often you can try the function and look at its result. rebol needs not much initialisation, so trying out is often as fast as switching to help-window.
> --- deal with "case insensitive in REBOL" > {no camelBack convention, but we may still decide to use it on a > voluntary basis} > {no ALL_UPPER_CASE convention, but we may still decide to use it > on a voluntary basis}
personally, dealing with camelBack is harder ;)
> --- existing scripts show an extensive use of "-" (minus) but not "_" > (underscore) > Any reason ???
rebol does it. and it saves shift-keys :)
> --- availability in the names of "special" characters such as "?" "!" "#" > that have/should have/receive a "universal conventional" meaning.
length? something. inbuild datatypes are marked integer!
> Below are some of my current ideas/practises. > Together with a short example.
<<quoted lines omitted: 8>>
> as > %rebol-logo_83x31.jpg.r
*.r for files which can be loaded, *.txt for texts. RT uses *.rcb for rebol-compressed binary (~zip) and some other extensions.
> Do you use prefixes for your script names ??? > such as
<<quoted lines omitted: 7>>
> %c-my-script.r ;;; a so-called "application" using REBOL/CORE > my-script.exe ;;; compilation of %v-my-script.r for WIN32
with lots of files i prefer %module-name-type.r . file-requestors sort by module, and *-type.r selects the file-type. IOS prefers simple names and subdirectories.
> Special names for files holding data ??? preferences ??? > configurations ???
<<quoted lines omitted: 3>>
> something like ??? > %my-script.ini.r
on IOS a lot %prefs.r . And variable-style filenames.
> > How do you define an "application" ??? > How do you define a "reblet" ??? > Do you have conventions to let know that a given file > is just a set of values, or is a "reblet" ??? an application ???
reblets have larger headers :) I use "reblet" to interface a server and demos on rebsites. application means standalone.
> Do you use special conventions for naming your words ??? > such as > ?my-object ;;; help function > ?my-object-my-value ;;; help function > my-word? ;;; returns a logic (boolean)
my-word? for others i would use a word instead of "?", about-my-object or something. btw, console has tab-completion, so abo^tab is not to much typing ;) And help with a string shows all words with the string inside, like help read
> what about other special characters, such as "# " and "!" ??? > when used as the first letter??? as the last??? > Is there a consensus in the community on how/when to use them ???
i guess consensus is, not as first letter.
> Do you use something like an hungarian prefix ??? > such as in the following script
when using /view, i often have the same name for a variable and its face, so i call the face f-variable-name. sometimes i use hungarian postfix (variable-face).
> { demonstrating also so-called "multiple inheritance" > and the " interface v. body" pattern > we initially developped for JAVA in an anterior and still parallel life } > > Do you use "multiple inheritance" ??? > (does not replace "composition"...!)
not conscious.
> Do you use upper/lower cases for documentation purposes ??? > such as > A_NOT_SO_GOOD_PI: 3.14 ;; constant
loong ago there was the preprocessor, and it was handy and smart and did not know nothing about lexical scopes. So peoples wrote BE_WARNED in very big letters. Also it says: this is an integer which wants to be an enumeration. here we use if 'as-text = mode [] no need to bring the integer-step in, no need for warning. So with Rebol, why? :)
> Do you use indentation conventions > and some other coding syles ???
%clean-script.r, open brackets are the last on the line, closing brackets have their own line. 'any / 'all instead of 'if, when possible. func[a /local b] instead of function[a][b]

 [5/15] from: greggirwin:mindspring at: 28-May-2003 12:20


Hi Marc, Lots of good questions here. Others have given you good advice, so I'll just add a few opinions from my perspective. Bear in mind that I've only been REBOLing for a couple years; I'm still adjusting my mindset and still trying new things. MM> --- avoid clashes, namespace pollution, etc in my own works Yes, Meyer's thoughts on Linnaean naming conventions are very applicable to REBOL I think. MM> --- readability/documentation/sharing knowledge This is most important of all to me. MM> --- deal with "no private/public in REBOL objects" (as for PHP, etc) MM> { I allways prefix all private things with "_" (underscore) } You *can* actually create private words, with a USE block, but I haven't used this technique much myself in real applications. o: make object! [ get-a: set-a: get-b: set-b: none use [_a _b] [ _a: _b: none get-a: does [_a] set-a: func [value] [_a: value] get-b: does [_b] set-b: func [value] [_b: value] ] ] It adds a lot of code compared to: o: make object! [a: b: none] I keep thinking that I'll use it for larger things, or where I explicitly want to protect private items, but only time will tell. MM> --- deal with "case insensitive in REBOL" MM> {no camelBack convention, but we may still decide to use it on a MM> voluntary basis} MM> {no ALL_UPPER_CASE convention, but we may still decide to use it on a MM> voluntary basis} I go for readability first. I came from a VB - which is case insensitive - and I've *never* understood the appeal of case sensitive languages. I'm particularly confused by the Smalltalk/Ruby rule about the *first* letter's case defining the scope. Very strange to me. In Ruby it's a language rule, in Smalltalk it's just a convention IIRC. In any case, I've moved away from CamelBack, using dashes to separate words in REBOL. MM> --- existing scripts show an extensive use of "-" (minus) but not "_" MM> (underscore) MM> Any reason ??? I think it's easier to type and more natural looking. Other languages don't allow it or they would probably have used it too. :) MM> When do you use *.r or *.reb or even *.rebol ??? .r for REBOL files, .txt for most other things (using make-doc formatting for most things). I'm still playing with what to do about files that are really data, compressed or otherwise, but are also valid REBOL code. It's fuzzy sometimes so it's hard to say if something is treated more like data than code or vice-versa. MM> Do you use prefixes for your script names ??? No, but I've never done that. Under VB I used a modified Hungarian notation, but I use *very* little of it under REBOL; just for words that refer to VID faces at this point, and still playing with it. MM> Special names for files holding data ??? preferences ??? configurations ??? MM> a part from the well known MM> %user.r MM> %preferences.r MM> something like ??? MM> %my-script.ini.r I avoid names with multiple dots in them (e.g. xxx.ini.r) because you never know when something might get tripped up over it. For some archive versions of files, I've included the version in the file name and, while I like using dots in that case, I haven't decided if it's worth the risk. MM> How do you define an "application" ??? MM> How do you define a "reblet" ??? MM> Do you have conventions to let know that a given file MM> is just a set of values, or is a "reblet" ??? an application ??? I'll often put a "tail" on file names that tells me what they are. E.g. my-app.r my-app-lib.r my-app-test.r my-app-defs.r Other types of files get a prefix. E.g. build-my-app.r All my Windows library modules (for API defs and interfaces) start with "win-". Ultimately, I try to make the names read well, so they match how I would say them. MM> Do you use special conventions for naming your words ??? ... MM> what about other special characters, such as "# " and "!" ??? MM> when used as the first letter??? as the last??? MM> Is there a consensus in the community on how/when to use them ??? There is no consensus AFAIK. I use a trailing "?" for logic values. You can't use "#". I use * or ! sometimes, to denote a special word that is, for example, a (duplicate) reference to a value that gets modified. I usually prepend !, so it isn't confused with datatype values. MM> Do you use something like an hungarian prefix ??? Not much, as I said above. REBOL is meant to be readable, and Hungarian isn't. :) There are places I'm still playing with it, like using "ctx" for objects/contexts which may not be referenced directly in much code. MM> { demonstrating also so-called "multiple inheritance" MM> and the " interface v. body" pattern MM> we initially developped for JAVA in an anterior and still parallel life } ... MM> Do you use "multiple inheritance" ??? MM> (does not replace "composition"...!) I've only toyed with the concept in REBOL. It's a different mindset because it doesn't have to be set at design time. You could easily aggregate them at runtime. Makes for interesting possibilities. MM> Do you use upper/lower cases for documentation purposes ??? MM> such as MM> A_NOT_SO_GOOD_PI: 3.14 ;; constant I've gotten away from that convention as a general rule. I tend to treat it like underlined text now. It's only appropriate occasionally, and it's disruptive when you're reading. -- Gregg

 [6/15] from: greggirwin::mindspring::com at: 28-May-2003 15:47


Hi Marc, MM> --- availability in the names of "special" characters such as "?" "!" "#" I forgot another thing I use them for! If I have a code template that I want to LOAD, and it contains replaceable parameters, I will use those special characters to give them names that stand out, but still allow the code to be LOADed by REBOL. E.g. display-item: func [ {Load the screen with the data from the given item.} item ][ !!!display-item!!! id-list/picked: append clear id-list/picked item/id show main-lay ] Sometimes it's still easier just to use strings, but having lexically correct data can be useful at times. -- Gregg

 [7/15] from: rebol:meurrens at: 2-Jun-2003 11:19


Hello Greg, At 12:20 28/05/2003 -0600, you wrote:
>You *can* actually create private words, with a USE block, but I >haven't used this technique much myself in real applications.
<<quoted lines omitted: 10>>
> ] > ]
The miscellaneous methods proposed on this list (and, to me, by private mail from other rebollers) to create PRIVATE things .... ;;;;;;;;;;;;;;;;;;;; REBOL [] use [ priv1 ] [ o1: make object! [ priv1: 1 =pri: does [ priv1 ] ] ] ;;; priv1 remains a *PUBLIC* INSTANCE WORD use [ priv2 ] [ priv2: 2 o2: make object! [ =pri: does [ priv2 ] pri=: func[a][priv2: a] ] ] ;;; priv2 is a PRIVATE STATIC WORD o3: make object! [ =pri: none use [priv3] [ priv3: 3 =pri: does [ priv3 ] ] ] ;;; priv3 is a PRIVATE STATIC WORD o4: make object! [ a:41 use [] [ b: 42 ] ] ;;; a INSTANCE WORD ;;; b GLOBAL WORD o22: make o2 [] ;;;;;;;;;;;;;;;;;;;;;;;; ... only apply for so-called "static variables" { ; =pri ; pronounce "get pri" ; pri= ; pronounce "set pri" } Just run the above mini script and, then, try : priv1 ; error priv2 ; error priv3 ; error o1/priv1 ; 1 ; !!!!!!!!!!!!! PUBLIC o2/priv2 ; error o22/priv2 ; error o3/priv3 ; error o1/=pri ; 1 o2/=pri ; 2 o22/=pri ; 2 o3/=pri ; 3 o22/pri= 22 ; 22 o22/=pri ; 22 o2/=pri ; 22 ; !!!!!!!!!!!! STATIC Of course, it does not make difference as far as you only create underived singletons (o1, o3) (objects with just ONE instance). But in ordinary situations (o2, o22, ...), it means that, AFAIK (????? I hope I am wrong...), there is no way to create PRIVATE INSTANCE WORDS :-( My own convention is to prefix their name with an "underscore" and to destroy with energy any script that would contain a "/" followed by a "_" Something very easy to detect automatically :-) HTH </marc>
>-- Gregg
Prof. Ir Marc Meurrens, Brussels (be) TEL: +32 (0)2 537 2812 FAX: +32 (0)2 537 7645 EMAIL: [marc--meurrens--org] URL: http://www.meurrens.org/ REB: http://rebol.mksa.net/ PGPKEY: http://www.meurrens.org/pgp/ Please don't mail me attached files, instead, use my 'exchange area' : EXCHANGE AREA: http://www.meurrens.org/exchange/ (HTTP/FTP upload/download of temporary/persistent files)

 [8/15] from: nitsch-lists::netcologne::de at: 2-Jun-2003 14:04

Re: [ A world of words ] naming convention, namespace, namespace pollu


Marc, why do you need privates? protection against malicious scripts is hard, because functions do not clear their arguments after call.
>> context[ _pri: 123 set 'pri does[_pri]] >> pri
== 123
>> second :pri ; the function-body
== [_pri]
>> get first second :pri ; the word in the body references the hidden '_pri
== 123 for informal privates a convention should do. real protection makes debugging harder. -Volker Marc Meurrens wrote:

 [9/15] from: greggirwin:mindspring at: 3-Jun-2003 10:02


Hi Volker, VN> Marc, why do you need privates? ... VN> for informal privates a convention should do. real protection makes VN> debugging harder. A convention is good. As a lot of us know from working with VID, you don't have any idea what is supposed to be private, or what the "true" public interfaces are in many cases. Also, while I agree that private data can make debugging harder, it can also be said that the lack of a protection mechanism can also make debugging harder because there is no way to guarantee encapsulation, which means any piece of code can change things so you can't rule anything out. In any case, I think REBOL gives us the tools we need to do things in lots of different ways. I went through much the same process Marc is when I found REBOL (trying to find ways to do things I've done in other languages). Now I don't try to make REBOL work like other languages, I try to look at how to design and build things in the context of how REBOL works. -- Gregg

 [10/15] from: greggirwin:mindspring at: 3-Jun-2003 9:56


Hi Marc, MM> But in ordinary situations (o2, o22, ...), it means that, MM> AFAIK (????? I hope I am wrong...), MM> there is no way to create PRIVATE INSTANCE WORDS I'm not sure of what distinction you want to make between private *instance* words and private *static* words, as shown in your o3 example. I modded it here to provide a set accessor function. o3: make object! [ =pri: pri=: none use [priv3] [ priv3: 3 =pri: does [ priv3 ] pri=: func [a] [priv3: a] ] ] ;;; priv3 is a PRIVATE STATIC WORD
>> o33: make o3 [] >> o3/=pri
== 3
>> o3/pri=: 33
== 33
>> o3/=pri
== 3
>> o33/=pri
== 3 I would hazard a guess that you can acheive what you want (once we know exactly what that is). MM> My own convention is to prefix their name with an "underscore" MM> and to destroy with energy any script that would contain MM> a "/" followed by a "_" MM> Something very easy to detect automatically :-) I've done the same thing myself in a number of places. Of course, then I found one place where I wanted to actually use a leading underscore with words in an object, so I'm still considering what the best approach or convention is for this kind of thing. -- Gregg

 [11/15] from: rebol:meurrens at: 4-Jun-2003 0:54

Re: [ A world of words ] naming convention, namespace, namespace pollut


Hi Gregg, Thank you for your interest in this matter. I was surprised (and very happy) by your result. Unfortunately there is a small mistyping (the ":")
>> o3/pri=: 33 >== 33
You did not use the "set method" ; you just replaced it by 33 .... :-( Anyway, here is the example completely rewritten for all the readers who did not follow this thread since the beginning. This makes clear, for those not aware of our OO vocabulary, what we mean by "static" and by "instance". A more pedagogical example (the "tank") still come later in this message together with "what I want". REBOL [ ] use [ y z ] [ z: 3 ; PRIVATE STATIC WORD (thanks 'use) obj: make object! [ =z: does [ z ] z=: func [ a ] [ z: a ] =x: x=: none use [ x ] [ x: 1 ; PRIVATE STATIC WORD (not instance) =x: does [ x ] x=: func [ a ] [ x: a ] ] y: 2 ; PUBLIC INSTANCE WORD (despite 'use) =y: does [ y ] y=: func [ a ] [ y: a ] w: 4 ; PUBLIC INSTANCE WORD =w: does [ w ] w=: func [ a ] [ w: a ] ] ] other: make obj [ ]; another instance ; x is PRIVATE : obj/x ===> error ; x is STATIC ... obj/x= 11 other/=x ; ===> 11 ; y is PUBLIC : obj/y ; ===> 2 ; y is INSTANCE ... obj/y= 22 other/=y ; ===> 2 (unchanged) ; z is PRIVATE : obj/z ===> error ; z is STATIC ... obj/z= 33 other/=z ; ===> 33 I would hazard a guess that you can acheive what you want (once we
>know exactly what that is).
This would be nice. Let us discuss of the "tank" example. It's a very simple example I often use to illustrate OO, and how OO can be implemented in some language. If you, or another reboller, has a solution to this "school case" this would be marvellous.... ;;;;;;;;;;;;; WHAT I WANT... THE "TANK" EXAMPLE use [ _capacity ] [ _capacity: 100 ; max number of gallons in any tank ;;; "STATIC" tank1: make object! [ _content: 0 ; current nr of gallons in this very tank ;;; each "INSTANCE" has a different content content+: func [ add ] [ _content: max 0 min _capacity _content + max 0 add ] content-: func [ sub ] [ _content: max 0 min _capacity _content - max 0 sub ] =content: does [ _content ] =capacity: does [ _capacity ] ] ] tank2: make tank1 [ ] ; two different instances tank1/content+ 50 ; add 50 gallons in tank 1 tank2/content+ 80 ; add 80 in tank 2 tank2/content- 20 ; substract 20 from tank 2 tank1/content+ 999 ; try (!!!!!) to add 999 in tank 1 (much will go on the floor...) tank1/content- 5 ; substract 5 from tank 1 tank1/=content ; ===> 95 (try with your own car: 0 + 50 + 999 - 5 ===> 95 !!!) tank2/=content ; ===> 60 ( 0 + 80 - 20 ) ;;;;;;;;;;;;;;;; I WANT TO AVOID THAT WE MAY WRITE THIS HORRIBLE CODE: cash: -500 ; i now allow negative values for cash due to my new credit policy ; .... and 425 lines below... price: 30 ; price of gas in $ per gallon ; .... and 212 lines below... a: cash / price ; use all our money to buy gas. how much gallons may we receive? ; ... and 723 lines below... tank1/_content: a ; now the tank holds a negative number of gallons... ; later on, we'll use tank1/_content or tank1/=content ; to compute a negative distance... ; etc, etc... and somewhere else we'll crash our car on a wall... !!! ;;;;;;;;;; BY AVOIDING A DIRECT ACCESS TO _content == BY ENCAPSULATING _content (for those who are new to OO concepts/vocabulary, the '_content is encapsulated with appropriate methods; mind that there is no "set" method and that the increase and "decrease" methods carefully check argument and result)
>MM> My own convention is to prefix their name with an "underscore" >MM> and to destroy with energy any script that would contain
<<quoted lines omitted: 4>>
>with words in an object, so I'm still considering what the best >approach or convention is for this kind of thing.
;;;;; THE ONLY WAY I FOUND FOR INSTANCE VARIABLES IN REBOL ;;;;; IS THE CONVENTION "private begins with _" ;;;;; (that I also use in other languages) ;;;;; and then to detect the presence of "/" followed by "_" in scripts. ;;;;; WHY ? NOT AGAINST MALICIOUS SCRIPTS, ;;;;; BUT JUST TO PRODUCE ROBUST/READABLE/REUSABLE CODE ; a "malicious" script may decide anyway that it will not respect the convention ; a "malicious" script may anyway use 'set and access to everything, ; even things "protected" by 'use ; and even without using "/" followed by "_" ;; example: give a negative value to the _capacity :
>> probe tank1 >> make tank1 [ set first second :=capacity -999 ] >> tank2/=capacity
== -999 See also Volker's "malicious" example in message 29138 of this thread. Regards, </marc>
>-- Gregg >
Prof. Ir Marc Meurrens, Brussels (be) TEL: +32 (0)2 537 2812 FAX: +32 (0)2 537 7645 EMAIL: [marc--meurrens--org] URL: http://www.meurrens.org/ REB: http://rebol.mksa.net/ PGPKEY: http://www.meurrens.org/pgp/ Please don't mail me attached files, instead, use my 'exchange area' : EXCHANGE AREA: http://www.meurrens.org/exchange/ (HTTP/FTP upload/download of temporary/persistent files)

 [12/15] from: dockimbel:free at: 4-Jun-2003 11:06

Re: [ A world of words ] naming convention, namespace, namespace poll


Hi Marc, En réponse à Marc Meurrens <[rebol--meurrens--org]>: [...]
> ;;;;;;;;;;;;; WHAT I WANT... THE "TANK" EXAMPLE > use [ _capacity ] [
<<quoted lines omitted: 11>>
> ] > ]
[...] If you use private contexts, keep in mind that you may loose some REBOL important features like : - reflection :
>> first tank1 ; get all words defined in object tank1
== [self _content content+ content- =content =capacity] You cannot see '_capacity anymore. A function using reflection to process your object will miss this word. - serialization :
>> tank1: load mold tank1 >> tank1/=capacity >> _capacity
** Script Error: _capacity has no value ** Near: _capacity Same issue when saving then reloading your object with save & load or when sending it over a tcp connection. HTH, -DocKimbel

 [13/15] from: greggirwin:mindspring at: 4-Jun-2003 12:33


Hi Doc, dff> If you use private contexts, keep in mind that you may loose some REBOL dff> important features like : dff> - reflection : dff> - serialization : Excellent points Doc! -- Gregg

 [14/15] from: greggirwin::mindspring::com at: 4-Jun-2003 14:49


Hi Marc, MM> Unfortunately there is a small mistyping (the ":") Thanks for catching that! I'm not always as careful as I should be when responding to ML items; I go too fast and think too little. :) Thanks also for your detailed response. Now I can see clearly the issue we're up against, with the USE context being shared between instances. I thought about it for a little bit, and didn't come up with any brilliant solutions. While it might be possible to cook one up, it would likely obscure the main point and cause confusion if used as a teaching tool. So, I started on my real work for the day, but it nagged me, and then an idea began to grow in my mind. Given that REBOLs approach to OO concepts is different from the norm, should we really try to force fit standard examples into it? Maybe not. If students need to learn Java, C++, or .NET rules about how OO works in those enivirons, how valuable is it to see examples in REBOL. In other words, the OO concepts can be pure, but the implementations are not. In that light, how valuable is it to be able to see those concepts in action? I place a high value on that kind of thing myself, but there is a mismatch. If you create an articfical environment for demonstrating OO concepts, it doesn't really matter how it works behind the scenes, or if the language used is useful for other things (i.e. in the real world) versus being used *only* to explain and demonstrate OO concepts. What I'm talking about, of course, is building a dialect in REBOL which would be used to explain and demonstrate OO concepts as clearly as possible, without any particular regard for practicality. But I digress... MM> ;;;;;;;;;;;;; WHAT I WANT... THE "TANK" EXAMPLE Rather than taking a traditional approach which, as I said, would probably end up being less than attractive, I decided to look at it in a different way; a REBOLish way. What we want, is to use abstraction and information hiding to our advantage. Where REBOL differs is how strict it is about enforcing some of these things. In your scenario of the horrible code we *may* write, REBOL doesn't offer us much protection in how it implements OOP concepts. So how do we elegantly provide encapsulation and abstraction? How about with a dialect? Using your comments as a guide, I put together a dialect based approach to the tank problem. I started out simple, but kept getting ideas and decided to play with them a bit. (code at end of message) This approach doesn't solve the problem of completely preventing people from doing bad things if they have access to the code and data structures used internally, but it does show that you can provide a public interface that only allows certain things to be done. The way results are returned is...different. As I worked, I wanted a way to see the results of a command in context, then I started thinking about messaging in a remote or asynchronus enivronment, and *real* messaging as opposed to just RPC. I'll have to play with the idea more, and think about how the grammar needs to be bi-directional; that is, the client side may want to parse the response it gets. In any case, let me know what you think. I have to go do some real work now! :\ -- Gregg ; Code below. Watch for wrap! REBOL [] tank: make object! [content: 0 capacity: 100] tank-context: make object! [ tanks: copy [] results: copy [] ; This FORMs all results, so numeric result may not want to use it. add-result: func [item] [append results reduce [reform item]] ; Dialect Rules rules: context [ available: none ; Parsed data (using a trailing * to denote them) id*: amount*: word*: none gallons: ['gallons | 'gallon] tank-id: [ opt 'tank set id* [issue! | integer!] (id*: to issue! id*) ] make-tank: [ 'make tank-id opt [ opt ['with 'a] 'capacity opt 'of set amount* integer! opt gallons ] ( either find/skip tanks id* 2 [ add-result ["tank" id* "already exists"] ][ append tanks reduce [ id* make tank compose [ capacity: (either amount* [amount*][100]) ] ] add-result ["tank" id* "added"] ] ) ] destroy-tank: [ 'destroy tank-id ( either find/skip tanks id* 2 [ remove/part find tanks id* 2 add-result ["tank" id* "destroyed"] ][ add-result [ "tank" id* "didn't exist, so was not destroyed" ] ] ) ] add: [ 'add set amount* integer! opt gallons ['in | 'to] tank-id ( available: tanks/:id*/capacity - tanks/:id*/content tanks/:id*/content: tanks/:id*/content + min amount* available add-result [ "Tank" id* "now contains" tanks/:id*/content "gallons" ] ) ] subtract: [ ; 'remove might be a better word than 'subtract 'subtract set amount* integer! opt gallons 'from tank-id ( available: tanks/:id*/content tanks/:id*/content: tanks/:id*/content - min amount* available add-result [ "Tank" id* "now contains" tanks/:id*/content "gallons" ] ) ] get-value: [ opt 'get tank-id set word* word! ;(add-result tanks/:id*/:word*) ( add-result switch/default word* [ content [[ "tank" id* "contained" tanks/:id*/:word* "gallons" "at" now/precise ]] capacity [[ "tank" id* "can contain a maximum of" tanks/:id*/:word* "gallons" ]] ][ ["Tank" id* "doesn't have a" mold form word* "value"] ] ) ] main: [ some [ make-tank | destroy-tank | add | subtract | get-value ] to end ] ] ; End of dialect rules set 'tank-manager func [command [block!] /notify fn [function!]] [ clear results if not parse command rules/main [ add-result ["command" mold command "failed"] ] if notify [fn results] results ] ] cbk-fn: func [ "Callback function for tank-manager." results ] [ print mold results ] tc: :tank-context ; just a lazy shortcut for console fiddling tank-cmd: func [command [block!]] [ tank-manager/notify command :cbk-fn ] tank-cmd [make tank #1] tank-cmd [make tank #2] tank-cmd [make tank #3 capacity 200] tank-cmd [make tank 4 with a capacity of 500 gallons] tank-cmd [make #4 with a capacity of 500 gallons] tank-cmd [make #5 capacity of 500 gallons] print "" tank-cmd [destroy tank 4] tank-cmd [destroy tank #4] tank-cmd [desotry tank #5] tank-cmd [destroy tank 5] tank-cmd [destroy tank #3] print "" tank-cmd [add 50 gallons to tank 1] tank-cmd [add 80 in tank 2] tank-cmd [subtract 20 from tank 2] tank-cmd [add 999 to #1] tank-cmd [subtract 5 gallons from tank 1] tank-cmd [ ; two commands at once subtract 5 gallons from tank 1 add 25 gallons to #2 ] ;tank-cmd [subtract 105 gallons from tank 1] print "" tank-cmd [#1 content] tank-cmd [get #2 capacity tank 2 content] ; two commands at once tank-cmd [get #1 material]

 [15/15] from: nitsch-lists:netcologne at: 5-Jun-2003 1:04


Hi Marc, Gregg, My favorite style-example is vid. Its large, but lots smaller than comparable gui-toolkits. And Carl tries to avoid accessor-functions there. trying vid-style, i would use an interface like tank/duration: 00:00:05 tank/rate: 5 ; liters flow tank if one wants really to access tank/content directly, in vid he could. some times usefull, most time why? -Volker Gregg Irwin wrote:
>Hi Marc, >MM> Unfortunately there is a small mistyping (the ":")
<<quoted lines omitted: 104>>
> available: tanks/:id*/capacity - tanks/:id*/content > tanks/:id*/content: tanks/:id*/content + min amount*
available
> add-result [ > "Tank" id* "now contains" tanks/:id*/content "gallons"
<<quoted lines omitted: 7>>
> available: tanks/:id*/content > tanks/:id*/content: tanks/:id*/content - min amount*
available

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted