home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.tcl:1792 comp.lang.perl:6936 comp.lang.scheme:2571
- Path: sparky!uunet!destroyer!sol.ctr.columbia.edu!news.cs.columbia.edu!mail
- Newsgroups: comp.lang.tcl,comp.lang.perl,comp.lang.scheme
- Date: Wed, 11 Nov 92 00:21:57 EST
- From: thayer@cs.columbia.edu (Charles Thayer)
- Message-ID: <9211110521.AA01343@cs.columbia.edu>
- Subject: Closures, Object-Oriented Equivalence, New version of Perl and TCL
- Lines: 599
-
- [Back to the discussion of making TCL object-oriented...]
-
- david@twg.com to comp.lang.TCL:
- dh> So, thinks I, why not create a way for multiple
- dh> interpreters to be active each of which thinking it owns
- dh> `.' ...
- dh> Since then I've realized this same stuff can be used to
- dh> create modules with a hidden implementation and public
- dh> interface. It depends on using a separate interpretor to
- dh> hold the implementation, and puts tiny procedures into
- dh> each interpretor which wants to import the public
- dh> interface.
-
- thayer@cs.columbia.edu to comp.lang.TCL,comp.OBJECT:
- me> You could implement the rest of an object oriented system by using
- me> interpreters as objects once you've built the glue to talk
- me> to all of them.
-
- [continuing with my thought...] This applies to almost all languages.
- That is to say that if you can create a new instance of the current
- language execution (or environment) you have a metaphor for an object.
- In Perl (or ADA :) this would be supported with `package'. In Scheme
- it is a built-in concept. [and I haven't even mentioned dictionaries
- in forth or postscript.] Having a new interpretOR that acts like a
- normal run of the system is just like providing Perl's `package'
- mechanism. In fact, David Herron says at the top of his source for
- the multiple-interpretOR: "An attempt at providing a `package' concept
- in TCL".
-
- Grady Booch [Object-Oriented Design with Applications] describes an
- object as having state, behavior, and identity. By creating an
- individual TCL-interpretOR, you set aside a symbol table for holding
- that object's state (eg. its variables.) You also can create proc's
- (procedures and subroutines) that can act upon that local state to
- define that object's behavior. And lastly, you have given that object
- identity, by naming its TCL-interpretOR, and this identity can allow
- you to uniquely access it later.
-
- This however, only gives you an object, or more precisely a data
- abstraction that includes local state and methods. It doesn't give one
- an object-oriented system.
-
- Grady Booch describes object-oriented as having objects, classes, and
- inheritance. In order to extend the simple `package' model of objects
- to form an object-oriented system, you'd want a way to distinguish
- classes of objects (eg. a class state and interface that provide
- functions on the class itself, such as new) and a way to inherit
- between classes. To support this through a `package' mechanism it is
- important to be able to chain the packaged environments to control the
- closure of an object.
-
- For example, in Scheme, a 'define' saves the current environment and
- leaves the ability to reach the enclosing (dynamic) environment:
-
- ;; code from Scheme and the Art of Programming
- (define (adder x) (lambda (y) (+ x y)))
- (define add8 (adder 8))
- (add8 3)
- ==> 11
-
- Here add8 has it's y bound to 8 in the symbol table with x bound as a
- free symbol; Whereas adder has x and y bound as free symbols. By saying
- the function is free, all I mean is that it is undefined in the
- environment of that particular object. When the free symbol needs to
- be resolved the enclosing environment is checked. In this case one
- could view '+ as being free in adder and add8, but bound in the top-level
- environment (therefore not an error).
-
- In an object-oriented system this is a metaphor for inheritance. An
- enclosing environment can create a new sub-environment that could be
- said to inherit the enclosing environment's state and behavior:
-
- (begin
- (define (echo h . t)
- (if h (begin (display h) (echo t)) (newline)))
- (echo "Running")
- (define (ClassA)
- (define (p) (echo "class a"))
- (p)
- (define (ClassB)
- (p))
- (define (ClassC)
- (define (p) (echo "class c"))
- (p))
-
- (ClassB)
- (ClassC))
- (ClassA))
- Running
- class a
- class a
- class c
- ;No value
-
- Here classB inherits from classA. And classC inherits from classA,
- but creates a new definition for p. [Unfortunately, this simple
- example is a bit contrived to avoid fun macros and evals. Besides,
- plenty of people have already written object systems in scheme :) ]
-
- Likewise, perl has packages that have their own individuals stabs,
- (aka symbol tables.) However these don't nest (well).
-
- #!/bin/perl
- package main;
- @package=('main');
- sub moo { print "main'moo\n"; }
- &main'msg(moo);
-
- package A; @package=('A', 'main'); # just pretend this is inheritance :)
- &main'msg(moo);
-
- package B; @package=('B', 'main');
- sub moo { print "B'moo\n"; }
- &main'msg(moo);
-
- [But since these environments don't nest, I kinda went and changed the
- usual calling semantics to a message based one]
-
- sub msg {
- local($sub,@args)=@_;
- local($package,$filename,$line)=caller;
- local(@search)=eval "@$package" . "'package";
- local($context);
- while($context=shift @search) {
- eval "&$context" . "'$sub(@args)";
- return if (!$@);
- }
- }
-
- As one can quickly tell, it takes some doing before scheme or perl
- would nest their environments in a way that particularly supports
- inheritance. In David Herron's interpretOR the problem of extending
- the system to be object-oriented is identical to the one in perl, in
- that environments are named at the global level. One solution, hinted
- at in the above perl code, is to have an environment to manage all
- other environments (eg main and msg, tcl and interp.) But this
- quickly becomes tiresome to do by hand, and begs for a built-in
- system.
-
- As it stands, tcl is more well-behaved that Perl, but slightly less
- than scheme. Here is the same program (yet again) in tcl. You should
- note that variables nest in a very purposeful manner.
-
- [thayer:0] BashER> tcl
- tcl>cat object.tcl
- #!/usr/local/bin/tcl
-
- proc classA {} {
- set str a
- proc p {} { upvar str s; echo classA $s }
- p
- proc classB {} {
- uplevel p
- }
- proc classC {} {
- eval set tmp { [info body p] }
- proc p {} { echo classC }
- p
- eval { proc p {} } { $tmp }
- }
- classB
- classC
- p
- }
- classA
-
- tcl>source object.tcl
- classA a
- classA a
- classC
- classA a
-
- Oddly, tcl gives you full access to enclosing evironments with upvar/uplevel,
- but is more prejudiced about making all procs global. However,
- because of the thoughtful design of tcl, I can just shove aside the p
- proc temporarily to emulate the desired behavior. Tcl could also be
- used to do as perl does, except you'd want to save procs as strings
- (another cumbersome system.)
-
- David Herron's interpretOR (from my limited knowledge of its current
- state) would be more nicely behaved and might look like:
-
- interp new classA
- interp new classB
- interp new classC
- interp eval classA {
- set str a
- proc p {} { upvar str s; echo [interp whoami] $s }
- }
- interp eval classB {
- proc p {} { interp eval classA { p } }
- }
- interp eval classC {
- proc p {} { echo [interp whoami] }
- }
- interp eval classA { p }
- interp eval classB { p }
- interp eval classC { p }
-
- Here his closures handle partitioning of procs in a much better way
- than writing a messaging system, in a way that is more compatible with
- existing code. However, one still yearns for a real object-system.
-
- thayer@cs.columbia.edu to comp.lang.TCL,comp.OBJECT:
- me> This is very interesting. It would appear that you've got
- me> yourself a simple closure mechanism. And it has been said
- me> that "Objects are a poor-man's closures."
-
- pdc@dcs.ed.ac.uk to comp.OBJECT:
- pc> I think this is an excellent and thought-provoking analogy.
-
- I found it to be interesting too. It's a proverb attributed to Norman
- Adams, which I read in a recent article in "AI Expert" by Kenneth Dickey,
- called "Scheming with Objects" [kend@data.rain.com].
-
- throopw@sheol.UUCP to comp.OBJECT:
- tw> The *interesting* relationship is that the
- tw> essentially-syntactic sucrose making up the object(while)
- tw> captures an interesting subcase of the closure(goto), which
- tw> aids software developers in reasoning about a program's
- tw> behavior.
-
- Absolutely. Which is why one would rather have objects than closures if
- the language syntax can't be changed by the user. However, it seems
- that there is almost never a reason to not provide both.
-
- Yet this begs the the two questions
-
- (a) "what is the exact definition of a closure in a language?" so that
- we can know how to provide them. I can tell you about closures in
- mathematical systems, or explain why certain movies have good closure,
- or point to lambda in some dialect of lisp and say closure, but I
- don't know of any good discussions about them in milieu of programming
- language construction --I imagine this is my own fault since I am more
- interested in objects. It seems to me that the closest thing to a
- formal discussion of the operations on closures in a programming
- languages is object-oriented-design 8-?
-
- (b) "what is the exact definition of an object oriented system?" so
- that we can know how to build one. I can easily say "take objects,
- group them by class, and add inheritance" but so many issues exist
- about what language features make a system usuable for a programmer
- that any one implementation is doomed to exclude many such features.
- How should one take a system supporting closures and build a usable
- object system?
-
- In fact, some would undoubtedly say that closures themselves are a
- subset of continuations anyway (you know who you are :) and before we
- know it, we are back to working with turing machines and electrons :(
-
- What I would seek out of all this is the simplest most straight-
- forward way to provide an object-oriented system (maybe BOB is the
- answer --Doctor Dobbs.) I see TCL or SIOD as lightweight enough to
- provide object-oriented systems to other programming languages such as
- Perl. The idea being that a very efficient tiny object-system in tcl
- or siod, with the right hooks in the parent language, could function
- to make the parent language object-oriented (where wanted).
-
- Objective-C did a good job of extending C in a straight-forward
- manner. C++ did a good job of extending C in a not-so
- straight-forward, but efficient, manner. I seek something that could
- be used to extend all languages that don't directly generate
- executable code, and that could be used as callable libraries in those
- that do. Something that could be embedded in everything from awk
- to common lisp, cheaply.
-
- My motivation/interest in this is a bit bizarre. I would like to see
- tcl in almost everything as the new meta-tool. Under Unix, pipelines,
- regexps, and tcp sockets have done a lot for allowing free and liberal
- tooling. An open-tcl-interface on applications and toolkits could
- provide a new realm of intra-application communication and floating
- toolkits. For a description of what I mean see the end of this post.
- [or search for the string "intra-application"]
-
- bevan@cs.man.ac.uk to comp.OBJECT:
- bv> You could always use a language which has closure(goto) and
- bv> lets you the _user_ add the syntax necessary to represent
- bv> object(while) when and if they want it. One example of
- bv> this would be Scheme using its (hygenic) macro system.
-
- Absolutely. [it is hygenic isn't it..never thought of it that way]
- However, I often find myself (whether the language is scheme, perl, or
- tcl) eval'ing something for the third or fourth time, and saying to
- myself "enough's enough." Scheme is good language for writing other
- programming systems such as Prolog, LOOP, Ski, expert shells. [I
- don't know anything about LOOP or Ski, but Stephen Bevan wrote these
- in scheme.] Other languages such as Perl or Tcl, however, don't
- provide such facilities in the language. To change the syntax you
- have to change the language. (roughly speaking.)
-
- Besides, who wants to sit down at common lisp and write an
- object-system when there is already CLOS. Who wants to add networking
- code to TCL when there is Perl. Who wants to write for X using the
- Athena Widget Set when there is WAFE. Likewise, nobody wants to write
- while from a goto, when they sit down to work in a language.
-
- throopw@sheol.UUCP to comp.OBJECT:
- tw> But it has been discussed many times on comp.object, so if
- tw> I'm overlooking a FAQ, or pummeling a deceased equine,
- tw> please treat me gently.
-
- ``I would call you a sado-masochistic-equestrian-necrofeliac, but
- that would be beating a dead horse'' --anonymous
-
- I see it's 3:36am here in New York, so I'm going to get back coding.
- Here's a small present for those that read all the way to this point:
-
- #!/bin/perl
-
- # Prints a profile of most used words. The actual work in progress
- # is yet another mail pre-sifter.
-
- $garbage='[ \t\n,.<>\[\]{}!@&^|]';
- while(<>) {
- /$garbage*(.*)/; $_ = $1;
- @wordlist = split(/$garbage/);
- $wc{$word}++ while($word = shift wordlist);
- }
- unshift(@prof, "$wc{$word}:$word") while($word = shift @keys);
- sub bynumber { $b <=> $a; }
- @nwc = sort bynumber @prof;
- print "$word\n" while ($word = shift @nwc);
-
-
- /charles
- ==============================================================================
- Charles Thayer, Columbia University, Dept. CS, Tech-staff... my words only.
- ==============================================================================
- PS. Gee, so much writing and only the tip of the iceburg, drat.
-
- PPS. Please forgive my cross posting. This has relevance to the various
- requests for an "Object-Oriented Perl" [c.l.perl], the discussion of
- "Multiple Interpreters in TCL / Spawning" [c.l.tcl], "objects and
- closures" [c.object], and more scheme code than I intended
- [c.l.scheme].
-
- PPPS. Here is what I meant about intra-application communication and
- open-ended toolkits:
-
- Imagine the following scenario where I am writing an nfs-client
- filesystem that will allow users to safely have mail delivered to
- their home directory. Here's what I would be running:
- ------------------------------------------------------------
- X
- tvtwm or your favorite window manager
- editor on my source
- debugger on the programmer
- xterm to recompile and test the program
- latex to format the documentation
- xdvi to view the documentation in a pretty window
- editor on the documentation
- xclock to point out how behind I am
- mega-biff that tells me if I have mail or if any new netnews has come in
- trn to look for info on nfs-bugs
- archie to find other example nfs-clients
- ftp to grab example source
- xnetload reports the load on machines around the network
- xcpustate tells me that I need twice as much memory
- xwafeping gives me the thumbs down if a machine goes off the net
- xwafenetmate gives the number of users on machines around the network
- editor to read my mail
- xterm on another host to test the nfs-client remotely
- vmstat in an xterm to tells that I am about to blow my lid
- ------------------------------------------------------------
-
- Now imagine that these all had dinky little tcl front-ends that spoke
- some IPC or TCP. Imagine these tools written in tcl with procs to
- interface to all the underlying utility:
-
- ============================================================
- systat - daemon that has interface to load, vmstat, users and all the
- fun system things like disk writes and reads, each as a tcl proc.
-
- term-manager - lets you control multiple terminals as a group of windows
- on as many displays as you like. If one terminal overlaps another it
- could automatically move to fit in a programmed way.
-
- editor - lets you bring up as many windows and buffers as you, with
- multiple font support, and cross talking between buffers. (just like
- lucid emacs :)
-
- ftp-er - supports a little progress window to many ftp sites, and
- remembers what ftp sites you've been to and what software you got, and
- where you put it.
-
- rfc-822 - a bunch of functions to process rfc-compliant mail
-
- trn-manager - like trn but now you can apply brutal regexps to kill
- off threads, and has nice bookmarking so that you can save messages
- more easily.
-
- xdvi - same as it ever was but reprogrammable, so now you have a that
- print button you always wanted.
-
- gdb-engine - follows a process here or there.
-
- tcl-latex - same as tex or latex, but tells you where the current
- token is in the parser.
- ============================================================
-
- Okay, now imagine that all of these work together with a send command.
- The send command allows processA to execute TCL-code in processB.
-
- c-mode in my editor brings up a bunch of buttons on the top of my
- buffer. I hit the one marked compile and another window comes into
- the foreground with make running on my file (the editor has just
- executed "send buffer *compile* restart".) The compile fails and the
- whole compile screen turns red, and my source buffer now highlights
- a miscreant line in my makefile (the editor has just executed "send
- buffer-set *source* error on line 234 Makefile".)
-
- I fix the Makefile and the compile works. Now I hit the run button on
- the top of my c-code buffer, and gdb comes to the foreground running
- my program and highlighting the line currently being executed in my
- c-code. The run of the program is actually being displayed in a window
- run by the term-manager, and simultaneous on a read-only window on
- a friends xterminal. The friend is a project partner, for whom I
- granted access to certain xwindows.
-
- A piece of mail arrives for my account and a window pops up. This
- is because I have told my mega-biff to pipe my incoming mail through
- the rfc-822 server then check for certain fields. I "set from-match
- '*[Uu]rgent*'" in my mega-biff.rc file so that the window would pop
- up and beep a few times. Incidentally, I have also put the following
- in my mega-biff.rc file:
-
- proc pop-up {
- send loudly editor pop-to-buffer *in-mail* from [extract msg $last msg]
- send editor send buffer *in-mail* { beep; beep; display-time }
- }
-
- The mega-biff doesn't know how to pop-up incoming mail, but I have
- taught it to send it to my editor if it noticed an interesting from
- line.
-
- Interestingly, although there are three or four users on the machine,
- there is only one rfc-822 running. Every new connection is assigned
- it's own "interp new rcf-822.$port.$user.$host" so that multiple users
- share the same code, but not data.
-
- I read the mail, it is from my project partner who says "joe has heard
- of a package called hlfsd that implements an nfs-client." So I go to
- my archie screen, where I am foolishly executing "prog nfs", and hit
- the button "new interp". This brings up a new archie client (also
- David Herron's interpretOR) where I type "prog { hlfsd* } on { prep
- cs.columbia barkley.berk } do { pop-found-list }". As you can imagine
- "pop-found-list" sends the results of a search to my editor, or if I
- have no editor running, I have programmed it to just send me mail.
-
- This goes on for hours...of course.
-
- Every now and then my mega-biff notices a new news posting with the
- word closure in the subject line and pops up (via the term-manager) a
- terminal session running trn, and doubles the size of my xclock so
- that I don't loose track of time.
-
- Every now and again my xdvi window pops up, when my friend sends
- his latex output to both of our xdvi's to show me a new page of
- our documentation.
-
- I get bored of working on the code at hand, so I write a simple
- network monitor shell script. It allows me to add or delete hosts to
- watch and it brings up an xwafeclock inside itself when a host goes
- down to point out the time of death, otherwise it queries the remote
- systat "send host moose.cs.columbia.edu tcl-agent systat load-5;
- load-10; load-15" and draws a graph of load with the results.
-
- ETC...Etc...etc...
-
- PS. I would want to write the "backends" to these things in perl if perl
- had a good open-interface to things like tcl.
-
- For those who read this far here is another small perl present, and
- another work in progress. It generates tvtwm menus from dns and yp
- information.
-
- begin 444 tvtwmrc.pl
- M'YV0(T*\$)/&S0LX9>2P4:!@!(@S9=PD#$.G#(@V>4#0L4/G3ALY8T"$J4/G
- M31N*:<:$8<,F#PL0=>:4F0."B),I+_/ >?FB#)TQ+\BDF4/'3!HV,T6Z(=-0
- M(QJ+;-*LL5CR8<2)%4$4K"AG)IV"9RY&C"F2I$F4*EGF<<%P#)HW<%"0('.V
- M8 \P PL&K>O&39@V9<"DV*$ ;D04-G&*>$L41 LVCNF 0%/0S!L0<_F"X",B
- MQ68^"D"(!B'4HH@A;^JP(>/FA&2(DAE+KGS9LAS,=$\6%$'8L!L43ZI082'"
- MAXN-'3^.<3&R)$2)<BB6(=.9L$RD8^@ %SY8 0D^/6(0;DKE*6F*8<2$D0GB
- MC9G);QK3EG/RZQLW6FF*J7-4,ID\?K61TDHM@6"&'":1YL8<"MQ!&5(H\)"8
- M#Y[M$=IH;L%%V&@@L/%&6G*Q(1L+)%#FAF4DSI'''"3&ET(/<\ 1E78O@/ "
- MB5]TQZ&'()(PAVPOQC@C"B]PX<*-)(@8'QTZCC;7@E^H.,<>/LK61P\^KKBA
- MDZS-\45\5/ZXY)4DQ$=8'PJ,X2%[B8WGD!1EA$&&4Q85! =)2LVY54)P="59
- MC&6,D<9*((QATDE+,>C@465$2$005 1!(0@6<NC0% @)2F@8V:5Q7WX:A3$5
- M?FF\%T:'!5DD1AEG%$13&$N!$!$9--V1!AUH@ #$A:(Y="I""A5Z**QZTF0;
- M8'KBAZM%EK'TAJUNA'5'&'GHP"L(#@%A:!N(SAF&'&?$(!*X,H#@PKGCGN'$
- MKI:"8,*VW:*0;@PO?7N"^=ZT*]X#H!0I.BE0H"D5X @8(+*Z0 ! DO5*A
- M CRN)!>\Q+( A+US!"GCK43:2&(,W4'\H<0DC$&4'&"]*(())0^[E+R\/1PQ
- M&W+1T08<05)FAF07@SL'80F4?#)8/8@@-!TH1XN9S7#$G,"B$)+ -(PZ\XQQ
- MA9B9C#311FN=]!DO27TS;R"@&;377!_]];\[<.&&TV7803+:T7K&!Q\@3"L'
- M?B((4<41.F0]=+0Q<]B'K&RP9V$"#B5A*JH2@>K&&Y*=2G&LMX(:Z%O3/=SG
- M5IA]L:5H:*)9!AZ9P^ F"$V(FM2I@+E1AZQN()V1;2#(44=?8"D% AY<M:'
- M''6(\7OPE%[KT++IUA$[':]VE3NKIQO[QFTC@B!E16UHI%,9]<8:G_<(73NS
- M7/6Y]47V)*2/1I0KDNC^EQGW (3H38WV>>T@B. 0$V]XPQIZASL>M(\BZAO1
- M 7_R/BG)#X'OBX\/W%:XT9P/"%-949"N)YD,S@$%)>@2_0#6H9'1K$1+(B'4
- M+"(7V5"M5-K!8!DTZ+ $" P%1I.-"'K@!Z/-3X<UW)$)Y>(B+(D03"@D2A^
- MQJ$;&BT^.^SA M4'Q1J*K$=2>M&3O"0E*ED):#9\#PZS-(<H^A""\"NC%3ED
- M N E1$!^.2&0P'BX,B3.(A8:00(2P*']2<9_VEL1:=+ &M=<!((&NAX(#*C
- M^*1H11-\&QT?9CC$*:XA>_1C_QPR/J$44C+N2^1M&+FD%LTADDXSW,/J>,?D
- MZ;&/2?NC0V0SR$\>DH&B7&02Z8!*H*%)E1P2CP+0-+SB@2 /R*N4!8=(@C,@
- MJ XXLQ_^'**_6&Z23@]Y)AQ U4QM4G!T)>Q15(CR(C#H))3=3,TV)4('9ZH3
- M#(2AIF@T"<AQSH8F21H*';YIOB$"P9X;E(-VA,2Q%VP!!%S8IQNZL (D ;0[
- M\@0!/1UB3U#]4Y_\%&*/YGBM%0YLER_<&0HN2LX:MC%X!2$91X$Y&F$2DWC&
- MRX-*DMG/'K'3G=!\T?W .5%LXG2;0\',3;TIR6OY!@59@ )Q=#)3H?KDIYPA
- MX04!"LX51BBID]I#H=X"AQW 9$%5&ZD]<328LEV+I'2 $0=U9<]XPA)T]=2G
- M1>WY30[55*4IK.J#6 C2'\%0K/I,00W/5Z44PFAC-#(2DCB:@).^,:4G%!,Y
- MP?G+EIZ)(3 =)%%.0I2$)*^)8FS!;430DY\$19]&08H:DY< WPA%#HA)PA2H
- M8(0D,*$(BBDM4(1"E-3.I#HR\^=K =J#KLCIM;&=;6UO.X60X0X%<^#@2(<;
- MV" N$XM .NR0BG2DD&F49&:( VNT*%G)N $)W#!"<R%&[XP<30W)$%X62.K
- M.(3.BHZE#V3E4E[OCL9L9E-3?*:3!M@20;:TM2UN0R;,2MI1<:HK'6:-Z4;]
- MQO&SU\4K.:7)4VN*@ LY7!*($QH"$%>X>RV8 V1B (,6.V8.QFL!?G;I&"I@
- MAI8M,!X-'','$.RX!6W0#QOJ8)$5X*D%%E'(&UHU8]FX(#.ZP8\)1ES48%ZV
- MF,8CGAN^$+O9*5,TA)72%V37!IWB[ZW\$T&7$2H"DVEO=Y@1,YFIO >W@7@(
- M4P#!%';7 AJ\@(QC=MZ(BW*<6R&E@J+);QMPZ (5B. E(MBS&_K\9SD[[]']
- MJX(;TH 'X*+YCWVP<U%?:LP E8'+8\$PF)DY/U.;N<-P73.(W:QES+3Z+V6@
- MLYU/DV=)VQJ-IAZT&0I-AT.#4]$X],(6IO@^4W>AT9B.-)_]#&U(:YK3GJXF
- M7$/M!GX2\PM?*((3B !N\E"&)D%MSEF^DI8"/0<KG7,(:DZ4AC/4(3KVP8]O
- M<XD<C["E*06YU:"BH@>4W(=!J/'0;18GA.N1(2$)5Z0(Q, &3JU!! ]+@J'<
- MT#J_0$0.2*@W&J)R!C3\D>)$%@&E^H<'.,B)1Q?O7U>H8U9B-N$^'T(#@@##
- MVH;+X>%RB/AHA5#Q,5Q\F QQPANH8&@\[M$A=&G-G][2XZ\4NPSJD8/U;K,L
- M]D"++G=@4 )$@ </R0GC8\>#@(V.=K(3Q QF:#L>9OC;AY$=47(?PYV((IVV
- MEP0.#>\TXWZ'J!/4JB!@MSL>9.(3G==![NPT.W7L_O YK.'O&.]# I+^AI"7
- MG.0F9^UI#OZ&0P]^X]%%2MX0_ZQ<IH8.=Y+,?5JB>,;C2G=YA[G<)0]YG_!>
- M\70O(](5H/'[=#P,'R?"?>@P!:J+7NVZ5_SOTQ[Y-YP=^'FH>]K?'G?%NYP,
- MT1\[%):4!#HHO2*9WSSQ-W[\CQMA^?VS 1Y8+(+!3^$D+-'*Q@_I\82PA>E7
- M]WYI)G_T9W_X!QE6IWI9-P=L$01F 2<5]Q5V4 9P,@=IH =E,'A1P!]&-ST6
- MB(%Y\Q3X$09R<Q3I@11L(07$8A)04'1E\#Q/!P),X!/8]'6MARC(YUDRPBD6
- M$09PL#$SY2D+PA;%MVEFD ="D >:UCH_"!:#%Q-481XI\2EB\ 9X0!C-]RQ%
- MV'X)$8.\M8,9P3Q3B!\;1P=AD"IRL'[&!RLY* ='4 8FX1-RD!$BP&(P@ <R
- MT&(M ,K /UYQ .DA!ULG\X^'$/\08ST1!7\"UP, 3W%EUR$(-M\ 836"B/
- MJ$A588,]%@8[XUD/-X:ED@=@H0!$4 9F,!)L0 =&L#N=\BG#MBIE <*, 5Q
- M0&1E@($ B!0Q*"8"I1%-!P(+J !0 "O0\89Q:#O]LX<M8(<89P4%1@=UL!*E
- M:'E_US\Q@ <T@''#V!<),05FF!4B,#GTL1(8EX5WX(P"%8ULX 2XQB#>F!)K
- MD!&+(P)4< 5- )%R#IL^'&Y]R%'1TP.L1]T4!(+PA !21($"0(] (>E "!
- M4X:G(QF!8P:LF&\*( 0(>1_BLI .F3L!1 <=.6QK%FDS88$'AW$8.9#W42X]
- MT)$(0CDAZ0(C204><06L%W8HF9%N, ,*Z9(?&9,C:9-+T7JKZ :MN" 8=Y$Z
- MR9(=.89MX$P@,)$NX"%WD!!*J9([V9.!XY10*944:93YUC\/)UIG*!,R]@8M
- M8!EC$!-)F9($N9$@T)0;%Y.@>(1729 \V9);.9=2.8D3R!!NJ9$*R2&B$3@)
- M:!%1:2 N$!U#84?/8I6!Z08L29B)>9B%J9A4"9DZF9>4:9B_F)@B28EE )@Z
- M"9<TP2&!HXF7.6R,*1-WN9*#>9JCD9HWN9HRF6HB()1@!P)%>93"%YF<*9N7
- MJ9J@Z0)UF0>DB96FV9D>23FV.9)-,!1CD)-8.9G">9DO*1G%.9))<"+74Q]"
- M2)UX&9O,F9W/B9M3L"+<DY0BH'QW\#8)H)<BP1(Q.0=C@" L 79NH B4 5-
- M$Y\=22#U>9^E-V2R* )($(?U)Y\"*I7VB9]* A@,(0)&$ ,+&J#TZ: $FG\B
- MT(=]B'$4*@,7&C@-JI@/6J#]XZ$6RI]&, ,C.I]L,* 0FJ)\**(LFHT 2J(9
- M:J(;"AD=RH<NRJ(U\*(E.FPGRJ$>FHTL:@-$NJ-&VJ,TN@)#RJ(WT*0QJJ$S
- M^J,KP*0LB@-6*J,HJJ55:I!B(3O:$R@6J0"]&98B,):M609GF98?PI8*\&6*
- M^8D;%XK7PIIE.9H1-6QJ&1/#MZ9"*'-]*F-RNI;"9Z=\VIA[Z@*!RB#$-))3
- M4))"N*BA(0(W]P:5.@<FB90),&R'F:EXIF=PE@10@ 7U)Y*X26MP5@-^2*J]
- M!F<V, -^&*JW::9M1A.U5JNQVC^E*FFO(@;3B:LCZ:HC2*P8!ZRSNB"D88JK
- MFJNSLZMOAA\/UWW,:JK.6G)I$*W'RJMPQJW+RFO:2A-JL 9LX*VM"J[X<:[I
- M*JOE>A&3HZZZBJSR^@;C&JR[0Q-P$ =R0*_3:J_]^J_P*JS: XT VS_V2A2/
- M5[#["@)V@ =YH <)2ZVU%K$3FZ]YA@104$;&NJZ3 0?"EZTW1Q"J5;%N%F2>
- MJK$@D%0R(0<3J'4H2Q,ZP;)$H$\GD! >RZKU2A.\10?C&@1C(%OU][&ZRBE!
- M)1LC.WH+4GIE4'\A0';(DV(KUF(PX!CX,6^I9Q$M8&-:Z[0O%F-BT&,_%F3
- M.&1<>V2@&!(M, 3N@G$.08]E<'D(LFDF [52^T8O5K4N)F,@0 5SBS3WD1(T
- MT;5_&[AU2[AAZQ@ZYAAFBW)<2[:.80;XD0/S9P/J01-&)ADM(!DF,*XG!@(R
- M@*-1&[I4"P)V>+6&2P)(\ 2S];:9&KHU4*4)4+I3JV*H:[4UAAFM^[J?VQ0B
- M( 5/\ 0V-@5(4 1,P 1X:[JXF[I8"P+"2[P+LP>]2P6'8[C12P736[W7"V.,
- MZV..*V1$QF/@FY:5>[F9.[G20AE9D6-A07$6YQC,,CLM,#L(4A6_&[=&$ 2S
- M)03#2P7+>[M\>[4D0+VN:[V[N[_]^[_;>\#=*[;E^[AH2[X_1KD@8+DQ@+GK
- MH;XA>"M<*P;O6W1K(+\&0K_V2SF7H5LO<(I$487.^;O$! 1:AFIF"JN[(L.[
- M0\.SXZLW;&HZ+!+$VL.X]L/7*L2 \</<:L2GMF;NJL0_W :3X\1K-K!2G&H,
- M6\5FBK%ZL"L*\*TABZGDRK$[2VQ(H0! $+HB &W]P[$MD -6BS JUY^;UFF[
- M,JD@J[)@7*HERR@@D*!$,<:C"@3(I+>["F2>6D9US!!>7+-URI^EZK()$;.
- MW'1F+%/201_]HQ,O*\DBD,A=#+(_BW$60JXW2Q0Y*[.X&L@_RUE<X<DCB;0T
- MH;2B[,AU, 8JT<=+,LE71ZJ[PVE&$,!Z>[K.Z[=#4 5.D 188 2[6\S'G,R+
- MFV,1++Z1"[Z;R\%B@"#O2<)*QF26.,?O\;L*V\MX$ 3 C,G"K+M^NY9S?"J&
- MJ\Z<QL[>"\UE*\T4+!K5+%IV$+X=W+Y)YB'<[,YX<"K@W&;B+ 3EC&+-B\YD
- M*,XQ9F, '6/QW+B&?+;CVP*2"P+W#+/ZO"C\G#O^7!#=S&G&,] 700'O;>Y
- MV[<+/<=<Z]#BS+41'<T4/<T[AM%'IM$3S=%<V\]+!M( ;1$#+02ZLR"VPG:U
- MF[?FG- J'=)X,"?M+,Y.'=/S/-/U;-.<B]-FJ]/:_-$KS6ES$M2P4G#=>M3,
- M.\#/JQYN(-:[*P2PH@5G^,P2+<$5?=$9G<\YS;X[[=$]C1]HK=8PK,@@6VMA
- M\!BS3*X&&P0MH+RI3,EGC#PBH&R#S0;/YFC](VEJ+,?8YLJ!#6=MT (4V\B&
- M_;!-T ):$*V!C,;*UMEZ,-EQ;-F4C=ET/'Q>+,N@7:I^##VF3<F92A=U< 85
- MM[)D+< IK;K6FAJ^O1Z%:V.\?=R>"M<R#;GU7-<;C==;O=>D8=R_31,#'16K
- M(E!Y<-+GO-3<G1!TD!&&.][>[=Q3#=T63<TW;==93=U(IM?<C-[E#;O]TP:J
- MT=US"-Y*3=P7L=\),8>[J]]LP-_F+=7ZS-Z2*]UW[<'5S<T&CN#XW69/012R
- M [3!'<S__;QNX149OKL?CN%'IN 3S>#N?=7P72ORS=/_?.%T$.(#+11V,!3A
- MN>%);=9^2^,V_BF&R^.?JMX+/L'MO6,.'M\0/M_;#-) 7J@#C09U0"OWX=\Z
- MCA]0+N7X8;A7'EU9;N)R3=-6[1A8S>))[N(@O>6?,M"V<7%[9+L<7N6B-,*&
- MN^9"?N)$+KGF&^;X/-UE3M\@3>=__<FZJIM$69&76MB$WF.$>I*+O<O!:XI=
- M\2,@$ 3)6[2L">DS@0;\"2<'DNF6[@+0TA6=_B/\N8W0\>DNQXUIJ*FB6;3&
- M*IJ;/A,7^+1[=.D?.)K!VZ>NWJBN*0( 5)7_ND>XFIFK7H2A^.G'R9^E:.Q'
- M^.EX.KAV2:%S2A.?DNC1&JDL.NWM@1]2\)&?OCO8+@):$$!ML.LNH ?DSJ*J
- MP0;C;A*?3I$L@>XF$>M\)U"?'NEF*%#\V0+\WN_^_N_1.CD'N@2VI=BU[@*5
- M)[C(*0)14 5) ,#"/FRU>"NRC9[J^8*%G9Z=5>X'/ZJ:ZCP41^MD#7.PJZF<
- M8B)087W4T>9D)WF. 4UD(!T@4 ,OEA86P9._*P).X!-W<#TCS'LLCP?5)R<E
- M/P104 5Z]HTB7[IZ%Q-*[Q@0<8P$O@(QL(PP("XY#P4)808W!Y]D#2QF,(E2
- M!J)8, 8G\9]!;_8^6/)EKWMI3_*!#IW26=C1:9]V5'$2D1H>V^AE+ )%D'U[
- M3];!!_5P"!C(& .V.G\MM@*V"@/+6/*EN!]GP(]!3P9B@ >$+_4940,T8+DX
- M< ,VX*&J:\$8/ .9F_-#L!)K&8'74[1,K_HECP2GD_IL4*Q'_11J!_M9OR2W
- MXOID!P>\S[ES8-?Q;,$$>+5QCYO=>2P&]S:@O?S?V?R?[O$=IXX2E8-[7[J(
- 4DOF&3^"(?X=VN (T0 ..C_69IP#=
-
- end
-