Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

You will be a winner today. Pick a fight with a four-year-old.


comp / comp.lang.tcl / Re: My hang-up about OOP (snit)

SubjectAuthor
* My hang-up about OOP (snit)Luc
+* Re: My hang-up about OOP (snit)Rich
|`* Re: My hang-up about OOP (snit)Luc
| +- Re: My hang-up about OOP (snit)Robert Heller
| +- Re: My hang-up about OOP (snit)Rich
| +- Re: My hang-up about OOP (snit)Rich
| `* Re: My hang-up about OOP (snit)Rich
|  +* Re: My hang-up about OOP (snit)Luc
|  |`* Re: My hang-up about OOP (snit)Rich
|  | `- Re: My hang-up about OOP (snit)Lawrence Woodman
|  `- Re: My hang-up about OOP (snit)Robert Heller
+- Re: My hang-up about OOP (snit)saito
+* Re: My hang-up about OOP (snit)Robert Heller
|`* Re: My hang-up about OOP (snit)Luc
| `* Re: My hang-up about OOP (snit)Robert Heller
|  `* Re: My hang-up about OOP (snit)Luc
|   `* Re: My hang-up about OOP (snit)Robert Heller
|    `* Re: My hang-up about OOP (snit)Luc
|     `* Re: My hang-up about OOP (snit)Robert Heller
|      `* Re: My hang-up about OOP (snit)Luc
|       `- Re: My hang-up about OOP (snit)Robert Heller
`- Re: My hang-up about OOP (snit)Luis Mendes

1
Subject: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Tue, 25 Jun 2024 21:09 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: My hang-up about OOP (snit)
Date: Tue, 25 Jun 2024 18:09:28 -0300
Organization: A noiseless patient Spider
Lines: 27
Message-ID: <20240625180928.43fcc5c1@lud1.home>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 25 Jun 2024 23:09:29 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="91916e09b13d8e03225c6dec34468415";
logging-data="1828133"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+sa1gi/AuQqQxCn+wE4JkVB0lp5wKNUwk="
Cancel-Lock: sha1:8O4rAUBQcsaGvlXKFEddUBUJh4k=
View all headers

It's hard for me to accept OOP because as hard as I try I really can't
not think that OOP is the Emperor's new clothes.

Example from snit:

snit::type dog {
method {tail wag} {} {return "Wag, wag"}
method {tail droop} {} {return "Droop, droop"}
} dog spot
puts [spot tail wag]
puts [spot tail droop]

Why exactly is that any better than this:

proc dog {args} {
if {$args == "tail wag"} {return "Wag, wag"}
if {$args == "tail droop"} {return "Droop, droop"}
} puts [dog tail wag]
puts [dog tail droop]

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Tue, 25 Jun 2024 22:29 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Tue, 25 Jun 2024 22:29:46 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 67
Message-ID: <v5fgcq$1oiln$2@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home>
Injection-Date: Wed, 26 Jun 2024 00:29:46 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f1f0464a150e143234d52dfb8b591d5a";
logging-data="1854135"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+owCW/JKZM9T+ru7rxOUd8"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:z7LOl5jpCcmLpXQpx3TVECOX3vQ=
View all headers

Luc <luc@sep.invalid> wrote:
> It's hard for me to accept OOP because as hard as I try I really can't
> not think that OOP is the Emperor's new clothes.
>
> Example from snit:
>
> snit::type dog {
> method {tail wag} {} {return "Wag, wag"}
> method {tail droop} {} {return "Droop, droop"}
> }
> dog spot
> puts [spot tail wag]
> puts [spot tail droop]
>
>
> Why exactly is that any better than this:
>
> proc dog {args} {
> if {$args == "tail wag"} {return "Wag, wag"}
> if {$args == "tail droop"} {return "Droop, droop"}
> }
> puts [dog tail wag]
> puts [dog tail droop]

If you only *ever* have one dog, either are essentially the same.

But, if at some point you want to manage spot, frank, sam, donut, and
alexa, all of which are different dogs, then you can do:

snit::type dog {
method {tail wag} {} {return "Wag, wag"}
method {tail droop} {} {return "Droop, droop"}
}

Once to create a generic "dog" framework.

And then later do, all in the same single program instance:

dog spot
dog frank
dog sam
dog donut
dog alexa

And have five, fully independent dogs (each with their own independent
"data") that you can manipulate, without having to do anything special
at the time you create them.

I.e., you can wag spot's tail, give food to sam, and label alexa with
"last vet visit was 2024-06-21" (assuming you had mentods for 'feed'
and for 'last-vet-visit' in the generic framework.

To do the same with the "proc" you have to rewrite the code to
be something like:

proc dog-spot ...
proc dog-frank ...
proc dog-sam ...

Or else you have to modify the dog proc to use a global variable to
store "different dogs" and take a parameter of "dog-name" so it knows
which dog to manipulate.

The "objects" give you that "data separation" as part of the OO
framework, without you having to build it in manually.

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Tue, 25 Jun 2024 22:57 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Tue, 25 Jun 2024 19:57:30 -0300
Organization: A noiseless patient Spider
Lines: 53
Message-ID: <20240625195730.26db3755@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<v5fgcq$1oiln$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 Jun 2024 00:57:31 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="e2607d8de2045b1f274b27019dc63914";
logging-data="1863412"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/AmYuges8ptzmHX+00EJqKGCs+g8yVtuM="
Cancel-Lock: sha1:L0jgVNAEi0V/VnWMedKpONfKTVA=
View all headers

On Tue, 25 Jun 2024 22:29:46 -0000 (UTC), Rich wrote:

>If you only *ever* have one dog, either are essentially the same.
>
>But, if at some point you want to manage spot, frank, sam, donut, and
>alexa, all of which are different dogs, then you can do:
>
> snit::type dog {
> method {tail wag} {} {return "Wag, wag"}
> method {tail droop} {} {return "Droop, droop"}
> }
>
>Once to create a generic "dog" framework.
>
>And then later do, all in the same single program instance:
>
>dog spot
>dog frank
>dog sam
>dog donut
>dog alexa
>
>And have five, fully independent dogs (each with their own independent
>"data") that you can manipulate, without having to do anything special
>at the time you create them.
>
>I.e., you can wag spot's tail, give food to sam, and label alexa with
>"last vet visit was 2024-06-21" (assuming you had mentods for 'feed'
>and for 'last-vet-visit' in the generic framework.

And how is that better than this:

proc dog {dogname args} {
if {$args == "tail wag"} {return "$dogname Wag, wag"}
if {$args == "tail droop"} {return "$dogname Droop, droop"}
if {$args == "eats food"} {return "$dogname Nom, nom"}
if {$args == "goes to vet"} {return "$dogname Tries to run"}

}
puts [dog fido tail wag]
puts [dog lucky tail droop]
puts [dog charlie eats food]
puts [dog mitts goes to vet]

That will handle multiple dogs pretty well.

One "method," one "if." It's pretty much it, isn't it?

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: saito
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Wed, 26 Jun 2024 00:35 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: saitology9@gmail.com (saito)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Tue, 25 Jun 2024 20:35:50 -0400
Organization: A noiseless patient Spider
Lines: 22
Message-ID: <v5fnp8$1ppf3$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 Jun 2024 02:35:52 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="3bb659fc895fa791760003fb2a60d4b1";
logging-data="1893859"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/iXaRXCof1tVVgWhv2BsL/"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:U1cYeyp2/3fdnDekWHeSPGhbB2w=
Content-Language: en-US
In-Reply-To: <20240625180928.43fcc5c1@lud1.home>
View all headers

On 6/25/2024 5:09 PM, Luc wrote:
> It's hard for me to accept OOP because as hard as I try I really can't
> not think that OOP is the Emperor's new clothes.
>
> Example from snit:
>

It is probably not a good idea to grok the why's of OOP from an
implementation library.

I recently came across a book in a used bookshop that is, well, kind of
mesmerizing. It is huge, full of text, and surprisingly engaging. And it
uses a language that frankly I probably didn't ever know existed.

However, I highly recommend it if you want to get a deep understanding
of the reasons, motivations, implementations, etc. Overall, it looks
like a great software engineering book in general.

I found a link to it on Amazon with some rave reviews:

https://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554/?_encoding=UTF8&pd_rd_w=H4y8U&content-id=amzn1.sym.f911c8db-3a2b-4b3e-952f-b80fdcee83f4&pf_rd_p=f911c8db-3a2b-4b3e-952f-b80fdcee83f4&pf_rd_r=143-1472743-9555525&pd_rd_wg=ZqER8&pd_rd_r=0c8a7ba5-857e-40b8-957e-b788ff6c7a63&ref_=aufs_ap_sc_dsk

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Wed, 26 Jun 2024 01:00 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-2.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-2.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Wed, 26 Jun 2024 01:00:40 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240625180928.43fcc5c1@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
Date: Wed, 26 Jun 2024 01:00:40 +0000
Lines: 111
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-5bcvKdphcBrbTUaDK8PzlVSmjhUGrPM2uVZtnHattusBsyk1X4nS0qzPVvDt1ST6mtN4LYhfApIMsye!smiQcBK/hoHfDL8j6H+l5Ti+z2MRxiFKywVhD5K01Vz3I41EpR2Ee3yvphR9vV518DIIwuywEEsF!pA8=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Tue, 25 Jun 2024 18:09:28 -0300 Luc <luc@sep.invalid> wrote:

>
> It's hard for me to accept OOP because as hard as I try I really can't
> not think that OOP is the Emperor's new clothes.
>
> Example from snit:
>
> snit::type dog {
> method {tail wag} {} {return "Wag, wag"}
> method {tail droop} {} {return "Droop, droop"}
> }
> dog spot
> puts [spot tail wag]
> puts [spot tail droop]
>
>
> Why exactly is that any better than this:
>
> proc dog {args} {
> if {$args == "tail wag"} {return "Wag, wag"}
> if {$args == "tail droop"} {return "Droop, droop"}
> }
> puts [dog tail wag]
> puts [dog tail droop]

snit::type greatdane {
component common -inherit true
constructor {args} {
install common using dog %%AUTO%%
}
method bark {} {return "WOOF!"}
}

While the dog example is a bit silly and trivial, there are real world use
cases where this inheritence (delegation) game pays off handsomly.

It is partitularly usefull for megawidgets. Tk's base widgets are already
written in an OO style. Also snit "compiles" the code to be far more efficient
than either a stack of if's (or a cascade of if ... elseif ... else ...). In
any case, something like:

snit::type foo {
method a {} {...}
method b {} {...}
method c {} {...}
method d {} {...}
method e {} {...}
method f {} {...}
method g {} {...}
method h {} {...}
method i {} {...}
method j {} {...}
}

is probably easier to read and debug than

proc foo {fun args} {
if {$fun eq "a"} {
...
} elseif {$fun eq "b"} {
...
} elseif {$fun eq "c"} {
...
} elseif {$fun eq "d"} {
...
} elseif {$fun eq "e"} {
...
} elseif {$fun eq "f"} {
...
} elseif {$fun eq "g"} {
...
} elseif {$fun eq "h"} {
...
} elseif {$fun eq "i"} {
...
} elseif {$fun eq "j"} {
...
} else {
error ...
}
}

The other thing is that the dog example has no instance variables (or options)
-- this seems to make the use of OO pointless. Once you add in instance
variables and options, and start having multiple instances of the "type" (or
more significantly, widgets), you will want to have the common "code" in one
shared place and you will want to have some way of keeping track of instance
variables / instance options and that is of course the whole point of having
reusable widgets in the first place...

Single instance classes are pretty pointless -- so are classes where all
instances are totally identical (where all of the class instances are 100%
interchangable and carry no instance specific state). That would like having
a "type" 42 (the specific integer with the specific value of 42).

There are sometimes "classes" like that: there are some specific use cases --
see "ENSEMBLE COMMANDS" in man snitfaq. I also use this to create "main"
programs where I can encapsulate "global" program data / constants /
parameters (as type variables). I don't really *need* to do this, but it keeps
things tidy and I don't need to use either '::' (global decls) all over the
place and don't have to worry about stepping on some other code's toes.

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Wed, 26 Jun 2024 01:30 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-3.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-2.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Wed, 26 Jun 2024 01:30:41 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240625195730.26db3755@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>??<v5fgcq$1oiln$2@dont-email.me>
<20240625195730.26db3755@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <tfidneWpOuHc8ub7nZ2dnZfqn_qdnZ2d@giganews.com>
Date: Wed, 26 Jun 2024 01:30:41 +0000
Lines: 80
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-NpjF7jo5qhFvncGfR80+d1qhyEM4H7xyFgkLc48ESWDfIDrlbg/+PR6XGd0TlDjrLA5qp9MFTSNWcFC!HMfDd6psOG0buKw+NbS0N1svnJaB0Z/8inksr2dDkxFgE9iBJErRgWjKWJtphZuZNnDDvLB66/u8!4Dw=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Tue, 25 Jun 2024 19:57:30 -0300 Luc <luc@sep.invalid> wrote:

>
> On Tue, 25 Jun 2024 22:29:46 -0000 (UTC), Rich wrote:
>
> >If you only *ever* have one dog, either are essentially the same.
> >
> >But, if at some point you want to manage spot, frank, sam, donut, and
> >alexa, all of which are different dogs, then you can do:
> >
> > snit::type dog {
> > method {tail wag} {} {return "Wag, wag"}
> > method {tail droop} {} {return "Droop, droop"}
> > }
> >
> >Once to create a generic "dog" framework.
> >
> >And then later do, all in the same single program instance:
> >
> >dog spot
> >dog frank
> >dog sam
> >dog donut
> >dog alexa
> >
> >And have five, fully independent dogs (each with their own independent
> >"data") that you can manipulate, without having to do anything special
> >at the time you create them.
> >
> >I.e., you can wag spot's tail, give food to sam, and label alexa with
> >"last vet visit was 2024-06-21" (assuming you had mentods for 'feed'
> >and for 'last-vet-visit' in the generic framework.
>
>
> And how is that better than this:
>
> proc dog {dogname args} {
> if {$args == "tail wag"} {return "$dogname Wag, wag"}
> if {$args == "tail droop"} {return "$dogname Droop, droop"}
> if {$args == "eats food"} {return "$dogname Nom, nom"}
> if {$args == "goes to vet"} {return "$dogname Tries to run"}
>
> }
> puts [dog fido tail wag]
> puts [dog lucky tail droop]
> puts [dog charlie eats food]
> puts [dog mitts goes to vet]
>
> That will handle multiple dogs pretty well.
>
> One "method," one "if." It's pretty much it, isn't it?

Nope. How would you handle instance variables? Options? Dog breeds (which
would be implemented with derived classes with specialized methods, instance
variables and options)? And with a large number of methods, etc., that if
very quickly becomes unweildly.

The dog example is probably a bad example to base ALL of OO on. It was only
meant as a starting point, like:

proc HelloWorld {} {
puts "Hello World"
} HelloWorld

can be trivially replaced with:

puts "Hello World"

and from that *ALONE* one could argue that "proc" is pointless, totally
ignoring all of the other reasons why one would use proc.

>

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Wed, 26 Jun 2024 04:02 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Wed, 26 Jun 2024 04:02:56 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 139
Message-ID: <v5g3tf$1vbr0$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home> <v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home>
Injection-Date: Wed, 26 Jun 2024 06:02:56 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f1f0464a150e143234d52dfb8b591d5a";
logging-data="2076512"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19BK1QjaO/Je7PSbeUrrZCu"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:oDuzB6eLn8G6xlr5aQk1tAC7B/o=
View all headers

Luc <luc@sep.invalid> wrote:
> On Tue, 25 Jun 2024 22:29:46 -0000 (UTC), Rich wrote:
>
>>If you only *ever* have one dog, either are essentially the same.
>>
>>But, if at some point you want to manage spot, frank, sam, donut, and
>>alexa, all of which are different dogs, then you can do:
>>
>> snit::type dog {
>> method {tail wag} {} {return "Wag, wag"}
>> method {tail droop} {} {return "Droop, droop"}
>> }
>>
>>Once to create a generic "dog" framework.
>>
>>And then later do, all in the same single program instance:
>>
>>dog spot
>>dog frank
>>dog sam
>>dog donut
>>dog alexa
>>
>>And have five, fully independent dogs (each with their own independent
>>"data") that you can manipulate, without having to do anything special
>>at the time you create them.
>>
>>I.e., you can wag spot's tail, give food to sam, and label alexa with
>>"last vet visit was 2024-06-21" (assuming you had mentods for 'feed'
>>and for 'last-vet-visit' in the generic framework.
>
>
> And how is that better than this:
>
> proc dog {dogname args} {
> if {$args == "tail wag"} {return "$dogname Wag, wag"}
> if {$args == "tail droop"} {return "$dogname Droop, droop"}
> if {$args == "eats food"} {return "$dogname Nom, nom"}
> if {$args == "goes to vet"} {return "$dogname Tries to run"}
>
> }
> puts [dog fido tail wag]
> puts [dog lucky tail droop]
> puts [dog charlie eats food]
> puts [dog mitts goes to vet]
>
> That will handle multiple dogs pretty well.
>
> One "method," one "if." It's pretty much it, isn't it?

Robert explained that your one 'if' is going to get pretty unweildy
very fast, esp. if you have different dogs with different behaviors.
I.e., fido can fetch, lucky refuses to fetch but will chew your
slippers, charle will roll over and fetch, but never chews your
slippers.

But, you are focused on the "call method" part of objects, and that's
not the part that makes objects actually useful. It's helpful, but the
real value is the fact that each object is an isolated little block of
data (with a set of procs that know how to access and manipulate that
data).

A better example than the "dog" one for objects and the data
encapsulation aspects is to instead think "bank accounts" (this won't
be proper snit syntax below, but hopefully you'll follow):

snit::type savings {
variable balance 0 ;# assume this initalizes 'balance' to zero when a
#new object of type 'savings' is created

method deposit {amount} {
set balance [expr {$balance + $amount]
}

method withdraw {amount} {
set balance [expr {$balance - $amount]
}

method inquire {} {
return $balance
}
}

Now we create accounts for fred and barney:

savings fred
savings barney

And we have two objects, "fred" and "barney" that both have a
"balance" variable, but... their balance variables are actually
separaate (you would not want your bank account to be "shared" with
everyone else who banks at that bank, right).

So if fred deposts 20, you can do:

fred depost 20

Then, if you 'inquire' about the balances you get:

fred inquire
20
barney inquire
0

Different answers, because each object has its own unique set of
variables (i.e., data) that is private for just it. Whatever you do to
barney's account, fred's balance remains the same.

This is where the real 'magic' of objects starts to show it's value.
You were building someing some months ago where I pointed out that
you'd accidentially worked your way into building a very simple object
by accident. IIRC you were trying to track multiple windows in a text
or on a canvas for something, and you'd created a set of namespaces or
something, one per each window, to store the variables needed for that
window apart from the others.

Had that been 'objects' from the start, you'd have created a class that
defined the variables each window needed, and the methods to act on
those variables (and update the window contents) and then you could
have just created "new" objects, one per window, and had all the
framework of separate variables and procs all taken care of by the OO
system.

And since objects can have an 'initializer', you could have had the
creation of the object also create the window associated with the
object automatically, and store away the window names in object
variables to use to manipulate the window. And a finalizer to destroy
the windows that were created when the object was destroyed. So you
could have done:

win new abc

and gotten the window created, plus all the 'procs' to do things with
the window, and then when done with it called

abc destroy

and had the windows also destroyed and all the variables deleted that
were part of the object -- all automatically.

Subject: Re: My hang-up about OOP (snit)
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Wed, 26 Jun 2024 04:09 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Wed, 26 Jun 2024 04:09:27 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 61
Message-ID: <v5g49n$1vjk4$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home> <v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home>
Injection-Date: Wed, 26 Jun 2024 06:09:27 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f1f0464a150e143234d52dfb8b591d5a";
logging-data="2084484"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19On/k2GfopXAiP4cSAN7Hw"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:drr2qzot9+cHy5urs4Fw6X6WQaM=
View all headers

Luc <luc@sep.invalid> wrote:
> On Tue, 25 Jun 2024 22:29:46 -0000 (UTC), Rich wrote:
>
>>If you only *ever* have one dog, either are essentially the same.
>>
>>But, if at some point you want to manage spot, frank, sam, donut, and
>>alexa, all of which are different dogs, then you can do:
>>
>> snit::type dog {
>> method {tail wag} {} {return "Wag, wag"}
>> method {tail droop} {} {return "Droop, droop"}
>> }
>>
>>Once to create a generic "dog" framework.
>>
>>And then later do, all in the same single program instance:
>>
>>dog spot
>>dog frank
>>dog sam
>>dog donut
>>dog alexa
>>
>>And have five, fully independent dogs (each with their own independent
>>"data") that you can manipulate, without having to do anything special
>>at the time you create them.
>>
>>I.e., you can wag spot's tail, give food to sam, and label alexa with
>>"last vet visit was 2024-06-21" (assuming you had mentods for 'feed'
>>and for 'last-vet-visit' in the generic framework.
>
>
> And how is that better than this:
>
> proc dog {dogname args} {
> if {$args == "tail wag"} {return "$dogname Wag, wag"}
> if {$args == "tail droop"} {return "$dogname Droop, droop"}
> if {$args == "eats food"} {return "$dogname Nom, nom"}
> if {$args == "goes to vet"} {return "$dogname Tries to run"}
>
> }
> puts [dog fido tail wag]
> puts [dog lucky tail droop]
> puts [dog charlie eats food]
> puts [dog mitts goes to vet]
>
> That will handle multiple dogs pretty well.
>
> One "method," one "if." It's pretty much it, isn't it?

Also, Ashok's chapter from his Tcl book that describes 8.6's OO
subsystem is available online:

https://www.magicsplat.com/articles/oo.html

You might consider carefully reading it. It is not that long, and
Ashok uses the "bank account" metaphor instead of the "dog" one, which
provides some intuitiveness into the "separate variables in each
object" aspect (you don't want your bank account data shared with
others you did not approve it to be shared with).

Subject: Re: My hang-up about OOP (snit)
From: Luis Mendes
Newsgroups: comp.lang.tcl
Organization: SunSITE.dk - Supporting Open source
Date: Wed, 26 Jun 2024 18:28 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!dotsrc.org!filter.dotsrc.org!news.dotsrc.org!not-for-mail
From: luisXXXlupeXXX@gmail.com (Luis Mendes)
Subject: Re: My hang-up about OOP (snit)
Newsgroups: comp.lang.tcl
References: <20240625180928.43fcc5c1@lud1.home>
MIME-Version: 1.0
User-Agent: Pan/0.154 (Izium; 517acf4)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Date: 26 Jun 2024 18:28:33 GMT
Lines: 43
Message-ID: <667c5dd1$0$706$14726298@news.sunsite.dk>
Organization: SunSITE.dk - Supporting Open source
NNTP-Posting-Host: f3f6c35c.news.sunsite.dk
X-Trace: 1719426513 news.sunsite.dk 706 luislupe@gmail.com/149.90.63.252:39018
X-Complaints-To: staff@sunsite.dk
View all headers

On Tue, 25 Jun 2024 18:09:28 -0300, Luc wrote:

> It's hard for me to accept OOP because as hard as I try I really can't
> not think that OOP is the Emperor's new clothes.
>
> Example from snit:
>
> snit::type dog {
> method {tail wag} {} {return "Wag, wag"} method {tail droop} {}
> {return "Droop, droop"}
> }
> dog spot puts [spot tail wag]
> puts [spot tail droop]
>
>
> Why exactly is that any better than this:
>
> proc dog {args} {
> if {$args == "tail wag"} {return "Wag, wag"}
> if {$args == "tail droop"} {return "Droop, droop"}
> }
> puts [dog tail wag]
> puts [dog tail droop]

Hi Luc,

I understand your feelings, I also don't like OO.
AFAICT, OO was first implemented in Smalltalk by Allan Kay.
But it seems that he is sort of regretful of having called it a Object
Oriented programming language, instead of a Message Passing programming
language.

Other programming languages tried to the the OO thing, but without the
luster of the rest.

I suggest you see some videos about Smalltalk, and even consider doing a
MOOC in Pharo from a french university to have the real feel of it.
https://mooc.pharo.org/

All the best,

Luís

Subject: Re: My hang-up about OOP (snit)
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Wed, 26 Jun 2024 22:32 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Wed, 26 Jun 2024 22:32:17 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 95
Message-ID: <v5i4th$2br31$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home> <v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home>
Injection-Date: Thu, 27 Jun 2024 00:32:18 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f2af626a43225667389fcf19b03236d3";
logging-data="2485345"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+i+US4Wb9ASMT8dONaVcLF"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:k862e0aKmTfg683WKBZSh1fnEqY=
View all headers

Luc <luc@sep.invalid> wrote:
> And how is that better than this:
>
> proc dog {dogname args} {
> if {$args == "tail wag"} {return "$dogname Wag, wag"}
> if {$args == "tail droop"} {return "$dogname Droop, droop"}
> if {$args == "eats food"} {return "$dogname Nom, nom"}
> if {$args == "goes to vet"} {return "$dogname Tries to run"}
>
> }
> puts [dog fido tail wag]
> puts [dog lucky tail droop]
> puts [dog charlie eats food]
> puts [dog mitts goes to vet]
>
> That will handle multiple dogs pretty well.
>
> One "method," one "if." It's pretty much it, isn't it?

The Tcl 'my' manpage provides a very simple example that should help
illuminate why the 'object' method would be better than your 'dog'
example above.

The 'class' example it gives is (modified slightly below):

% oo::class create c {
variable counter
method count {} {
puts [incr counter]
}
}
::c

This creates a class command 'c' that will create objects. So lets
create two objects, o1 and o2:

% c create o1
::o1
% c create o2
::o2

Now, what we have is two objects, that each have their own "counter"
variable. The 'counter' variable is not shared between them. Watch
this below:

Make o1 count a few times:

% o1 count
1
% o1 count
2
% o1 count
3
% o1 count
4
% o1 count
5

Now, make o2 count for the first time:

% o2 count
1

o2 returns 1, not 6, so its 'counter' variable is separate from the
'counter' variable in o1 (which is presently storing the value '5').

Now make them both count once each again:

% o1 count
6
% o2 count
2

o1 knows it was at 5, and so it returns 6, and o2 knows it was at 1, so
it returns 2.

And, note, this example got this "separation" of data automatically,
from just this little bit of 'code':

% oo::class create c {
variable counter
method count {} {
puts [incr counter]
}
}

As a thought experiment, consider how you'd make your 'dog' proc
'count' (say you have circus dogs that can 'count' ...) and imagine how
to give each of four different dogs their own, independent, counter to
store their current value into.

Then, compare the code you'd need to add to the dog proc to make a
'counting dog' proc with separate counter variables for each dog to the
code necessary to achieve the same result from the counting class
above.

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Thu, 27 Jun 2024 01:02 UTC
References: 1 2 3 4
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Wed, 26 Jun 2024 22:02:00 -0300
Organization: A noiseless patient Spider
Lines: 51
Message-ID: <20240626220200.0613ab6c@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<v5fgcq$1oiln$2@dont-email.me>
<20240625195730.26db3755@lud1.home>
<v5i4th$2br31$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 27 Jun 2024 03:02:01 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="45a762fadea9095f510d51d9df4273ce";
logging-data="2529711"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX189xHsVDDNFf1rhhuSj5l+nN+NDdu2az38="
Cancel-Lock: sha1:i+WwaAMqO/EW9IWsxdCDMm3T4R8=
View all headers

On Wed, 26 Jun 2024 22:32:17 -0000 (UTC), Rich wrote:

>As a thought experiment, consider how you'd make your 'dog' proc
>'count' (say you have circus dogs that can 'count' ...) and imagine how
>to give each of four different dogs their own, independent, counter to
>store their current value into.
>
>Then, compare the code you'd need to add to the dog proc to make a
>'counting dog' proc with separate counter variables for each dog to the
>code necessary to achieve the same result from the counting class
>above.

lassign "1 1" c_01 c_02

proc countcees {cee} {
upvar \#0 $cee _cee
incr _cee
puts $_cee
}

countcees c_01
2 countcees c_01
3 countcees c_02
2 countcees c_02
3 countcees c_01
4

In reality though, nobody needs a proc for that.

incr c_o1
1 incr c_o2
1 incr c_o2
2 incr c_o2
3 incr c_o2
4 incr c_o1
2

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Thu, 27 Jun 2024 01:09 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Wed, 26 Jun 2024 22:09:32 -0300
Organization: A noiseless patient Spider
Lines: 124
Message-ID: <20240626220932.62b9e27e@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 27 Jun 2024 03:09:33 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="45a762fadea9095f510d51d9df4273ce";
logging-data="2529711"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/fP8h3d+xm+sYvELc1jbXD4Z5K/2VPStU="
Cancel-Lock: sha1:v73rfRPE9NXNPyDFe5SXgVksXsM=
View all headers

On Wed, 26 Jun 2024 01:00:40 +0000, Robert Heller wrote:

>While the dog example is a bit silly and trivial, there are real world use
>cases where this inheritence (delegation) game pays off handsomly.
>
>It is partitularly usefull for megawidgets. Tk's base widgets are already
>written in an OO style. Also snit "compiles" the code to be far more
>efficient than either a stack of if's (or a cascade of if ... elseif ...
>else ...). In any case, something like:
>
>snit::type foo {
> method a {} {...}
> method b {} {...}
> method c {} {...}
> method d {} {...}
> method e {} {...}
> method f {} {...}
> method g {} {...}
> method h {} {...}
> method i {} {...}
> method j {} {...}
>}
>
>is probably easier to read and debug than
>
>proc foo {fun args} {
> if {$fun eq "a"} {
> ...
> } elseif {$fun eq "b"} {
> ...
> } elseif {$fun eq "c"} {
> ...
> } elseif {$fun eq "d"} {
> ...
> } elseif {$fun eq "e"} {
> ...
> } elseif {$fun eq "f"} {
> ...
> } elseif {$fun eq "g"} {
> ...
> } elseif {$fun eq "h"} {
> ...
> } elseif {$fun eq "i"} {
> ...
> } elseif {$fun eq "j"} {
> ...
> } else {
> error ...
> }
>}
>
>The other thing is that the dog example has no instance variables (or
>options) -- this seems to make the use of OO pointless. Once you add in
>instance variables and options, and start having multiple instances of the
>"type" (or more significantly, widgets), you will want to have the common
>"code" in one shared place and you will want to have some way of keeping
>track of instance variables / instance options and that is of course the
>whole point of having reusable widgets in the first place...
>
>Single instance classes are pretty pointless -- so are classes where all
>instances are totally identical (where all of the class instances are 100%
>interchangable and carry no instance specific state). That would like
>having a "type" 42 (the specific integer with the specific value of 42).
>
>There are sometimes "classes" like that: there are some specific use cases
>-- see "ENSEMBLE COMMANDS" in man snitfaq. I also use this to create "main"
>programs where I can encapsulate "global" program data / constants /
>parameters (as type variables). I don't really *need* to do this, but it
>keeps things tidy and I don't need to use either '::' (global decls) all
>over the place and don't have to worry about stepping on some other code's
>toes.

This is a really good explanation that got me interested. I've been
reading up on snit and I like what I see.

But I am stuck in this:

snit::widget TopWindow {
hulltype toplevel
delegate option * to hull
component of

constructor {args} {
wm withdraw $win
wm resizable $win 1 1
wm attributes $win -zoomed 1
wm geometry $win 60x10+0+0
wm title $win "test"
tk appname "test"
bind $win <Alt-q> {exit 0}
bind $win <Alt-Q> {exit 0}

set of [frame $self.of]
pack $of -fill both -expand 1

$self configurelist $args
puts "self is $self"
}
}

TopWindow .toplevel
puts [winfo children .]

output: .

The snit manual says:

"The body of a type constructor is executed once when the type is defined,
and never again."

So the part that defines frame $self.of should have been executed, right?
In which case, $self.of is a child of the toplevel widget, right?
Then how come puts [winfo children .] only outputs "." with no mention
of the frame?

Oh, the 'wm withdraw $win' line doesn't seem to be executed either. The
gray box still pops up.

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Thu, 27 Jun 2024 02:13 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-2.nntp.ord.giganews.com!local-1.nntp.ord.giganews.com!border-1.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-2.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Thu, 27 Jun 2024 02:13:16 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <v5i4th$2br31$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home>
<v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home>
<v5i4th$2br31$1@dont-email.me>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <_c2cndiQBp0hV-H7nZ2dnZfqnPqdnZ2d@giganews.com>
Date: Thu, 27 Jun 2024 02:13:16 +0000
Lines: 175
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-AHnf60+Kyz/D0hvHR/5kAScqli94Ppz9uoUWZXA0rxjxpbFk5G8k8A7mgQalYMe0SBCfEJIua+ELMDj!OMHfyQu7QvggD898dUbPUGP/sg6WGv5cWp9ALgsciHOozUMnO6NfgV+JgoxdAeQaowj3XIrM37MC!75w=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Wed, 26 Jun 2024 22:32:17 -0000 (UTC) Rich <rich@example.invalid> wrote:

>
> Luc <luc@sep.invalid> wrote:
> > And how is that better than this:
> >
> > proc dog {dogname args} {
> > if {$args == "tail wag"} {return "$dogname Wag, wag"}
> > if {$args == "tail droop"} {return "$dogname Droop, droop"}
> > if {$args == "eats food"} {return "$dogname Nom, nom"}
> > if {$args == "goes to vet"} {return "$dogname Tries to run"}
> >
> > }
> > puts [dog fido tail wag]
> > puts [dog lucky tail droop]
> > puts [dog charlie eats food]
> > puts [dog mitts goes to vet]
> >
> > That will handle multiple dogs pretty well.
> >
> > One "method," one "if." It's pretty much it, isn't it?
>
> The Tcl 'my' manpage provides a very simple example that should help
> illuminate why the 'object' method would be better than your 'dog'
> example above.
>
> The 'class' example it gives is (modified slightly below):
>
> % oo::class create c {
> variable counter
> method count {} {
> puts [incr counter]
> }
> }
> ::c
>
> This creates a class command 'c' that will create objects. So lets
> create two objects, o1 and o2:
>
> % c create o1
> ::o1
> % c create o2
> ::o2
>
> Now, what we have is two objects, that each have their own "counter"
> variable. The 'counter' variable is not shared between them. Watch
> this below:
>
> Make o1 count a few times:
>
> % o1 count
> 1
> % o1 count
> 2
> % o1 count
> 3
> % o1 count
> 4
> % o1 count
> 5
>
> Now, make o2 count for the first time:
>
> % o2 count
> 1
>
> o2 returns 1, not 6, so its 'counter' variable is separate from the
> 'counter' variable in o1 (which is presently storing the value '5').
>
> Now make them both count once each again:
>
> % o1 count
> 6
> % o2 count
> 2
>
> o1 knows it was at 5, and so it returns 6, and o2 knows it was at 1, so
> it returns 2.
>
> And, note, this example got this "separation" of data automatically,
> from just this little bit of 'code':
>
> % oo::class create c {
> variable counter
> method count {} {
> puts [incr counter]
> }
> }
>
> As a thought experiment, consider how you'd make your 'dog' proc
> 'count' (say you have circus dogs that can 'count' ...) and imagine how
> to give each of four different dogs their own, independent, counter to
> store their current value into.
>
> Then, compare the code you'd need to add to the dog proc to make a
> 'counting dog' proc with separate counter variables for each dog to the
> code necessary to achieve the same result from the counting class
> above.

And to totally blow Luc's mind, consider this "class":

snit::widgetadaptor ROText {
delegate method * to hull
delegate option * to hull except {-background -borderwidth -font
-foreground -highlightbackground -highlightcolor -highlightthickness
-relief -insertbackground -selectbackground -insertborderwidth
-selectborderwidth -selectforeground -padx -pady}
typeconstructor {
ttk::style configure ROText \
-background ttk::theme::default::colors(-frame) \
-borderwidth 1 \
-font TkFixedFont \
-foreground black \
-relief sunken \
-selectbackground ttk::theme::default::colors(-selectbg) \
-selectborderwidth 1 \
-selectforeground ttk::theme::default::colors(-selectfg) \
-padx 0 -pady 0
}
option -style -default ROText
method _themeUpdated {} {
#puts stderr "*** $self _themeUpdated"
foreach o {-background -borderwidth -font -foreground
-highlightbackground -highlightcolor -highlightthickness -relief
-insertbackground -selectbackground -insertborderwidth
-selectborderwidth -selectforeground -padx -pady} {
if {![catch {ttk::style lookup $options(-style) $o} ov]} {
#if {"$ov" eq ""} {continue}
#puts stderr "*** $self _themeUpdated: $o $ov"
catch {$hull configure $o $ov}
}
}
}
constructor {args} {
installhull using text
$self configurelist $args
set indx [lsearch [bindtags $win] Text]
bindtags $win [lreplace [bindtags $win] $indx $indx ROText]
bind $win <<ThemeChanged>> [mymethod _themeUpdated]
$self _themeUpdated
}
}

(A large chunk of the code is ommited -- the full file is here:
https://github.com/RobertPHeller/ModelRRSystem/blob/master/trunk/Scripts/Common/snitrotext.tcl
-- the whole laundry list of bindings are left out
)

What this deceptively simple "widgetadaptor" does is two things: It "wraps"
around the Tk "text" widget and makes it readonly (not user editable) -- great
for things like log output, etc. At the same time, it makes it themed, just
like the various ttk:: widgets. (A snit::widgetadaptor is a special case of a
snit::type intended to "wrap" around an arbitary widget.)

The only methods added are the theme related methods. It takes away the old
school styling options (-background -borderwidth -font -foreground, etc.) and
replaces them with a -style option. It also changes the bindtags to remove the
text insert key and mouse bindings (eg generic key press and paste bindings).
Otherwise it is otherwise just like a garden variety text widget. Note that
this in fact leverages the fact all of Tk's widgets are in fact functionally
OO, dispite being coded in plain C. Actually *lots* of Tcl is functionally OO,
dispite not technically being OO. SNIT can "inheirt" (delagate) to Tcl
"commands" that are not snit "types" -- all the commands have to have are a
functional structure like "<command> sub-command ..." and (optionally)
implement the configure and cget "methods" (sub-commands).

>
>

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Thu, 27 Jun 2024 02:33 UTC
References: 1 2 3 4 5
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Thu, 27 Jun 2024 02:33:58 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 48
Message-ID: <v5ij2m$2hug7$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home> <v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home> <v5i4th$2br31$1@dont-email.me> <20240626220200.0613ab6c@lud1.home>
Injection-Date: Thu, 27 Jun 2024 04:33:58 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f2af626a43225667389fcf19b03236d3";
logging-data="2685447"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18ecNApvA6HsUl9lZMtPf3H"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:le5Sv0BPJFYTWdHGro250DF9zxc=
View all headers

Luc <luc@sep.invalid> wrote:
> On Wed, 26 Jun 2024 22:32:17 -0000 (UTC), Rich wrote:
>
>>As a thought experiment, consider how you'd make your 'dog' proc
>>'count' (say you have circus dogs that can 'count' ...) and imagine
>>how to give each of four different dogs their own, independent,
>>counter to store their current value into.
>>
>>Then, compare the code you'd need to add to the dog proc to make a
>>'counting dog' proc with separate counter variables for each dog to
>>the code necessary to achieve the same result from the counting class
>>above.
>
> lassign "1 1" c_01 c_02
>
> proc countcees {cee} {
> upvar \#0 $cee _cee
> incr _cee
> puts $_cee
> }
>
> countcees c_01
> 2
> countcees c_01
> 3
> countcees c_02
> 2
> countcees c_02
> 3
> countcees c_01
> 4
>
>
> In reality though, nobody needs a proc for that.

True, but you are missing the forest for the trees.

Imagine extending your example above to 273 different "counters" (or
managing 273 different sets of complicated [more than just a single
counter] pieces of independent data) or imagine managing 15 different
windows with differing (not shared) data, in the same app.

That's the point, the "do it with a proc and a bunch of globals"
method, where you have to modify the code to extend from 14 to 15 windows
(and likely have to add a 15'th 'then' clause to 95 different 'if'
statements) vs. having the system handle the "separation" details and your code
change to go from 14 to 15 is to to just create 15 objects instead of 14.

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Thu, 27 Jun 2024 02:42 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-2.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-1.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Thu, 27 Jun 2024 02:42:35 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240626220932.62b9e27e@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>??<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
<20240626220932.62b9e27e@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>
Date: Thu, 27 Jun 2024 02:42:35 +0000
Lines: 178
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-fceja3yHXdh7J2JAb9slWo0kSo6y/OYzoha9/UtUbCiZOmNwCJ25Yac7LmASC3puMOVA2jtjs7BZ1UA!NzjRu51Y7B9Aj6ZEemhr9xi3cRrqdLXok7cdav/h+uGYePBYSksS+wjUj9AmwW3GbiweM6ItLh5L!LTM=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Wed, 26 Jun 2024 22:09:32 -0300 Luc <luc@sep.invalid> wrote:

>
> On Wed, 26 Jun 2024 01:00:40 +0000, Robert Heller wrote:
>
> >While the dog example is a bit silly and trivial, there are real world use
> >cases where this inheritence (delegation) game pays off handsomly.
> >
> >It is partitularly usefull for megawidgets. Tk's base widgets are already
> >written in an OO style. Also snit "compiles" the code to be far more
> >efficient than either a stack of if's (or a cascade of if ... elseif ...
> >else ...). In any case, something like:
> >
> >snit::type foo {
> > method a {} {...}
> > method b {} {...}
> > method c {} {...}
> > method d {} {...}
> > method e {} {...}
> > method f {} {...}
> > method g {} {...}
> > method h {} {...}
> > method i {} {...}
> > method j {} {...}
> >}
> >
> >is probably easier to read and debug than
> >
> >proc foo {fun args} {
> > if {$fun eq "a"} {
> > ...
> > } elseif {$fun eq "b"} {
> > ...
> > } elseif {$fun eq "c"} {
> > ...
> > } elseif {$fun eq "d"} {
> > ...
> > } elseif {$fun eq "e"} {
> > ...
> > } elseif {$fun eq "f"} {
> > ...
> > } elseif {$fun eq "g"} {
> > ...
> > } elseif {$fun eq "h"} {
> > ...
> > } elseif {$fun eq "i"} {
> > ...
> > } elseif {$fun eq "j"} {
> > ...
> > } else {
> > error ...
> > }
> >}
> >
> >The other thing is that the dog example has no instance variables (or
> >options) -- this seems to make the use of OO pointless. Once you add in
> >instance variables and options, and start having multiple instances of the
> >"type" (or more significantly, widgets), you will want to have the common
> >"code" in one shared place and you will want to have some way of keeping
> >track of instance variables / instance options and that is of course the
> >whole point of having reusable widgets in the first place...
> >
> >Single instance classes are pretty pointless -- so are classes where all
> >instances are totally identical (where all of the class instances are 100%
> >interchangable and carry no instance specific state). That would like
> >having a "type" 42 (the specific integer with the specific value of 42).
> >
> >There are sometimes "classes" like that: there are some specific use cases
> >-- see "ENSEMBLE COMMANDS" in man snitfaq. I also use this to create "main"
> >programs where I can encapsulate "global" program data / constants /
> >parameters (as type variables). I don't really *need* to do this, but it
> >keeps things tidy and I don't need to use either '::' (global decls) all
> >over the place and don't have to worry about stepping on some other code's
> >toes.
>
>
> This is a really good explanation that got me interested. I've been
> reading up on snit and I like what I see.
>
> But I am stuck in this:
>
> snit::widget TopWindow {
> hulltype toplevel
> delegate option * to hull
> component of
>
> constructor {args} {
> wm withdraw $win
> wm resizable $win 1 1
> wm attributes $win -zoomed 1
> wm geometry $win 60x10+0+0
> wm title $win "test"
> tk appname "test"
> bind $win <Alt-q> {exit 0}
> bind $win <Alt-Q> {exit 0}
>
> set of [frame $self.of]

The above is wrong in several ways. Widgets *never* use $self to reference the
widget's path. ($self would only be used to reference methods.) Secondly,
components are "installed" [exception: *typecomponents* are set]. So the above
should be:

install of using frame $win.of

> pack $of -fill both -expand 1
>
> $self configurelist $args
> puts "self is $self"
> }
> }
>
> TopWindow .toplevel
> puts [winfo children .]
>
> output: .
>
>
> The snit manual says:
>
> "The body of a type constructor is executed once when the type is defined,
> and never again."
>
> So the part that defines frame $self.of should have been executed, right?
> In which case, $self.of is a child of the toplevel widget, right?
> Then how come puts [winfo children .] only outputs "." with no mention
> of the frame?
>
> Oh, the 'wm withdraw $win' line doesn't seem to be executed either. The
> gray box still pops up.

The gray box is ".", but your snit::widget TopLevel is creating a *new*
toplevel called .toplevel and withdrawing it and never deiconifying it. I
explained the problem with the frame "of" above.

marchhare% tclsh
% package require snit
2.3.2
% snit::widget TopWindow {
hulltype toplevel
delegate option * to hull
component of

constructor {args} {
wm withdraw $win
wm resizable $win 1 1
wm attributes $win -zoomed 1
wm geometry $win 60x10+0+0
wm title $win "test"
tk appname "test"
bind $win <Alt-q> {exit 0}
bind $win <Alt-Q> {exit 0}

install of using frame $win.of
pack $of -fill both -expand 1

$self configurelist $args
puts "self is $self"
}
} ::TopWindow
% TopWindow .toplevel
self is .toplevel
.toplevel
% puts [winfo children .]
.toplevel
% winfo children .toplevel
.toplevel.of
%

>

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Lawrence Woodman
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Thu, 27 Jun 2024 05:56 UTC
References: 1 2 3 4 5 6
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: lorrywoodman@gmail.com (Lawrence Woodman)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Thu, 27 Jun 2024 05:56:33 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 89
Message-ID: <v5iuuh$2jicl$1@dont-email.me>
References: <20240625180928.43fcc5c1@lud1.home>
<v5fgcq$1oiln$2@dont-email.me> <20240625195730.26db3755@lud1.home>
<v5i4th$2br31$1@dont-email.me> <20240626220200.0613ab6c@lud1.home>
<v5ij2m$2hug7$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 27 Jun 2024 07:56:34 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="f740227600175dca9b796269f2810f90";
logging-data="2738581"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+TeCGCVzLXWkhGbwcPyaAEIrVxL7QOw4Y="
User-Agent: Pan/0.154 (Izium; 517acf4)
Cancel-Lock: sha1:OHg4uMciPCocUlAhlC5vyzv36UA=
View all headers

On Thu, 27 Jun 2024 02:33:58 -0000 (UTC), Rich wrote:

> Luc <luc@sep.invalid> wrote:
>> On Wed, 26 Jun 2024 22:32:17 -0000 (UTC), Rich wrote:
>>
>>>As a thought experiment, consider how you'd make your 'dog' proc
>>>'count' (say you have circus dogs that can 'count' ...) and imagine how
>>>to give each of four different dogs their own, independent, counter to
>>>store their current value into.
>>>
>>>Then, compare the code you'd need to add to the dog proc to make a
>>>'counting dog' proc with separate counter variables for each dog to the
>>>code necessary to achieve the same result from the counting class
>>>above.
>>
>> lassign "1 1" c_01 c_02
>>
>> proc countcees {cee} {
>> upvar \#0 $cee _cee incr _cee puts $_cee
>> }
>>
>> countcees c_01 2
>> countcees c_01 3
>> countcees c_02 2
>> countcees c_02 3
>> countcees c_01 4
>>
>>
>> In reality though, nobody needs a proc for that.
>
> True, but you are missing the forest for the trees.
>
> Imagine extending your example above to 273 different "counters" (or
> managing 273 different sets of complicated [more than just a single
> counter] pieces of independent data) or imagine managing 15 different
> windows with differing (not shared) data, in the same app.
>
> That's the point, the "do it with a proc and a bunch of globals"
> method, where you have to modify the code to extend from 14 to 15
> windows (and likely have to add a 15'th 'then' clause to 95 different
> 'if'
> statements) vs. having the system handle the "separation" details and
> your code change to go from 14 to 15 is to to just create 15 objects
> instead of 14.

The non OOP code used in this discussion could be better. Here's an
alternative to the OOP code, which uses a dictionary although an array
could also be used. This could easily be extended to more internal
variables and more methods on those variables. It could even be argued
that this is OOP code in some respects. The advantage this has over
normal OOP code is that you know what functions are actually being called
with the object. That is my main gripe with most OOP, at times you have
no idea what functions are actually being called on an object and you have
to dig through the code until you work out what instantiated an object and
what the methods do on that particular object.

namespace eval counter {
namespace export {[a-z]*}
namespace ensemble create
}

proc counter::new {} {
dict create count 0
}

proc counter::count {counterName} {
upvar counterName counter
dict incr counter count
puts [dict get $counter count]
}

set counter [counter new]
counter count counter
counter count counter
counter count counter
counter count counter

Best wishes

Lorry

---
Modula-2 Compilers on CP/M
https://techtinkering.com/articles/modula-2-compilers-on-cpm/

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Thu, 27 Jun 2024 21:08 UTC
References: 1 2 3 4
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Thu, 27 Jun 2024 18:08:32 -0300
Organization: A noiseless patient Spider
Lines: 29
Message-ID: <20240627180832.3c8fc106@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
<20240626220932.62b9e27e@lud1.home>
<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable
Injection-Date: Thu, 27 Jun 2024 23:08:33 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="dedb7287d57426da4d535b32db3e663d";
logging-data="3070792"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/0Ado2nXxKcijaHFXDNrqTzRWrLmjb6BA="
Cancel-Lock: sha1:Lc13VDPOhMkd70Vi61pRUZiqwBQ=
View all headers

On Thu, 27 Jun 2024 02:42:35 +0000, Robert Heller wrote:

>The above is wrong in several ways. Widgets *never* use $self to reference
>the widget's path. ($self would only be used to reference methods.)
>Secondly, components are "installed" [exception: *typecomponents* are
>set]. So the above should be:

Thanks!

But I already regret snitting the toplevel.

I mean, is there any benefit in snitting everything or should I rather
just snit the things I know there will be many of?

And apart from very personal preferences, is there any really good
reason for someone to prefer snit over TclOO?

From where I stand (about 2 inches tall so not a great view), it *seems*
that snit is easier. But it also seems that TclOO has better documentation.

I'm also wondering, is this "delegate" business really good for me?
Wouldn't it be better for me to get used to a more traditional (inheritance)
approach to OOP? Would TclOO give me the more tradiional approach?
Does it also handle widgets? Can I make megawigets with it?

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Thu, 27 Jun 2024 23:41 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-1.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-1.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Thu, 27 Jun 2024 23:41:16 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240627180832.3c8fc106@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>??<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>??<20240626220932.62b9e27e@lud1.home>??<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>
<20240627180832.3c8fc106@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <76icnV37fZoBZeD7nZ2dnZfqnPudnZ2d@giganews.com>
Date: Thu, 27 Jun 2024 23:41:16 +0000
Lines: 77
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-zBFHCBT8S30eqS4eoMl9S4przvm9gkMr7z1zOTAlJey8pd9u67uMj7/zf1BVVdoxEv5xexbYyDT1xjF!w82CgAKcRnOMMUpRRHmAclhVBkS7r+bguCGjVBfTU1+z5ZKuLr2G6IVe1UaMYELbrdwlNoAj/+uc!pGU=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Thu, 27 Jun 2024 18:08:32 -0300 Luc <luc@sep.invalid> wrote:

>
> On Thu, 27 Jun 2024 02:42:35 +0000, Robert Heller wrote:
>
> >The above is wrong in several ways. Widgets *never* use $self to reference
> >the widget's path. ($self would only be used to reference methods.)
> >Secondly, components are "installed" [exception: *typecomponents* are
> >set]. So the above should be:
>
> Thanks!
>
> But I already regret snitting the toplevel.
>
> I mean, is there any benefit in snitting everything or should I rather
> just snit the things I know there will be many of?

Any thing where you have encapsulated data or state benefits from being a
class, if only to document the encapsulated data or state, even if there is
only ever one or if it is in fact an instance-less snit::type. It is a
convenient way to gather the "global" data that is part of a logical function
block or programming unit. One major problem to many scripting languages
(including especially Tcl), is polluting the global namespace. Yes you can
simply create a namespace filled with variables and procs rather than a
snit::type, and get to the same logical situation. It is that snit takes care
of all of the "infrastructure" to implement that and "hides" some of that
infrastructure and provides some special support features (like the
typeconstructor) that are convenient.

The other benefit is creating a self-contained code library. You may only have
one toplevel in any given program, but you are likely to write many programs.
You might have a certain "style" of toplevel you like and want to reuse in
your many programs. Creating this styled toplevel and parameterizing it in a
"library" package as a snit::widget or snit::widgetadaptor is useful, because
you get reuse this code.

>
> And apart from very personal preferences, is there any really good
> reason for someone to prefer snit over TclOO?

In my case I started using snit before TclOO became available, so...

>
> From where I stand (about 2 inches tall so not a great view), it *seems*
> that snit is easier. But it also seems that TclOO has better documentation.

Snit always seemed to have good enough documentation for me. OTOH, I was
already very familiar with OO (C++, Java, etc.), so I never needed a general
OO primer. Maybe Snit might not be good for a first time OO programmer -- I
can't really say.

> I'm also wondering, is this "delegate" business really good for me?
> Wouldn't it be better for me to get used to a more traditional (inheritance)
> approach to OOP? Would TclOO give me the more tradiional approach?
> Does it also handle widgets? Can I make megawigets with it?
>

I don't know about whether TclOO handles widgets or not. The delegate business
seems really good for everything I do in Tcl -- it fits well with Tk's widget
methodology. Tradiional inheritance (ala C++ and Java) can be a bitch sometimes
(you don't want to hear my rants about Java GUI programming). I would say that
one is not "better" than the other. Just different and they solve different
problems differently -- I do a lot of C++ programming (generally NOT GUI work)
and Tcl/Tk programming (using SNIT). So I use both flavors of "inheritance"
all the time, just doing different things. I know, that is not really the sort
of answer you are looking for, but there it is. Sometimes you need a hammer
and sometimes you need a screwdriver, so you have both in your toolbox. One
is not really "better" than the other, just that hammers work better with
nails and screwdrivers work better with screws...

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Fri, 28 Jun 2024 00:27 UTC
References: 1 2 3 4 5 6
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Thu, 27 Jun 2024 21:27:04 -0300
Organization: A noiseless patient Spider
Lines: 112
Message-ID: <20240627212704.46c26379@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
<20240626220932.62b9e27e@lud1.home>
<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>
<20240627180832.3c8fc106@lud1.home>
<76icnV37fZoBZeD7nZ2dnZfqnPudnZ2d@giganews.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 28 Jun 2024 02:27:05 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="8baf39e74934074e0441f0f0115dbdac";
logging-data="3136992"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19C02iLrXR541UKza5K/pgE15Noj611ubQ="
Cancel-Lock: sha1:V1rnPMHxFabOhwUmEkvki9+JKE8=
View all headers

On Thu, 27 Jun 2024 23:41:16 +0000, Robert Heller wrote:

>Snit always seemed to have good enough documentation for me.

Of course I am not very bright (or I have no previous experience with
OOP if you want to be kind), but I am struggling with using snit at all
because of this:

The world famous snit faq says:

"For example, the following code creates a read-only text widget... "
etc. etc.

::snit::widgetadaptor rotext {

constructor {args} {
# Create the text widget; turn off its insert cursor
installhull using text -insertwidth 0

# Apply any options passed at creation time.
$self configurelist $args
}

# Disable the text widget's insert and delete methods, to
# make this readonly.
method insert {args} {}
method delete {args} {}

# Enable ins and del as synonyms, so the program can insert and
# delete.
delegate method ins to hull as insert
delegate method del to hull as delete

# Pass all other methods and options to the real text widget, so
# that the remaining behavior is as expected.
delegate method * to hull
delegate option * to hull
}

Yeah, the document has some examples.
Now, how do I call that? I did it like this:

rotext .rox

and nothing happened. Well, I got the Tk gray box.

The world famous snit faq says:

"For example, the following code creates a read-only text widget... "

Where is the text widget then?

After a lot of struggle, I fixed it by adding 'pack $win' within the
constructor. Why can't the manual tell me that? Why can't the example
code include it?

There was more struggle.

snit::widget TopWindow {
hulltype toplevel
delegate option * to hull
component of
variable of

constructor {args} {
wm withdraw .
wm resizable $win 1 1
wm attributes $win -zoomed 0
wm geometry $win 600x100+0+0
wm title $win "test"
tk appname "test"
bind $win <Alt-q> {exit 0}
bind $win <Alt-Q> {exit 0}

install of using frame $win.of
pack $of -fill both -expand 1

$self configurelist $args
}
} TopWindow .toplevel

Now, how do I add the read-only text widget to that toplevel?

Again, a lot of struggle to figure this out:

rotext .toplevel.of.rox

Why can't the manual tell me that?

And I can only do that by explicitly referencing ".toplevel"
which seems inadequate. There should be a variable that contains
that toplevel path. There probably is, but heck if I know what
that is.

I'm still struggling with other things. Anyway, my point is
the documentation has multiple examples of how to create a
type but no examples whatsoever of how to call what the code
is creating. It just assumes the reader knows because it's obvious.
But it took me a long time to guess on my own.

Thank you for your guidance once again.

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Fri, 28 Jun 2024 02:24 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-2.nntp.ord.giganews.com!border-1.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-1.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Fri, 28 Jun 2024 02:24:19 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240627212704.46c26379@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>??<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>??<20240626220932.62b9e27e@lud1.home>??<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>??<20240627180832.3c8fc106@lud1.home>??<76icnV37fZoBZeD7nZ2dnZfqnPudnZ2d@giganews.com>
<20240627212704.46c26379@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <zv6dnSg8IeFOg-P7nZ2dnZfqn_ednZ2d@giganews.com>
Date: Fri, 28 Jun 2024 02:24:19 +0000
Lines: 192
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-M8SBTkzHm6bFkbvOQYwCukjPHKksnF/AlzPuNhzDNtAvC/qhYxSyRfxq/3/WfwWN7Ph99J/FsfD9Epr!IujUikaZrlAhPB73gd+VXgqehCXxyljsyBkWk8Kxi5XNueErM5GFYxNsml5RlLY2Y5FN1aQXXVa4!fTk=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Thu, 27 Jun 2024 21:27:04 -0300 Luc <luc@sep.invalid> wrote:

>
> On Thu, 27 Jun 2024 23:41:16 +0000, Robert Heller wrote:
>
> >Snit always seemed to have good enough documentation for me.
>
>
> Of course I am not very bright (or I have no previous experience with
> OOP if you want to be kind), but I am struggling with using snit at all
> because of this:
>
> The world famous snit faq says:
>
> "For example, the following code creates a read-only text widget... "
> etc. etc.
>
> ::snit::widgetadaptor rotext {
>
> constructor {args} {
> # Create the text widget; turn off its insert cursor
> installhull using text -insertwidth 0
>
> # Apply any options passed at creation time.
> $self configurelist $args
> }
>
> # Disable the text widget's insert and delete methods, to
> # make this readonly.
> method insert {args} {}
> method delete {args} {}
>
> # Enable ins and del as synonyms, so the program can insert and
> # delete.
> delegate method ins to hull as insert
> delegate method del to hull as delete
>
> # Pass all other methods and options to the real text widget, so
> # that the remaining behavior is as expected.
> delegate method * to hull
> delegate option * to hull
> }
>
>
> Yeah, the document has some examples.
> Now, how do I call that? I did it like this:
>
> rotext .rox
>
> and nothing happened. Well, I got the Tk gray box.

The snit::widget and snit::widgetadaptor entities work *exactly* like "native"
Tk widgets.

For a regular text widget you would do:

test .t
pack .t -fill both -expand yes

so for a rotext, you would do:

rotext .rox
pack .rox -fill both -expand yes

The widget constructor doesn't 'automatically' pack the widget. Although pack
is probably the most common geometry manager, you could use grid or place, so
the choice of geometry manager (and its options) is left up to the programmer.

>
> The world famous snit faq says:
>
> "For example, the following code creates a read-only text widget... "
>
> Where is the text widget then?
>
> After a lot of struggle, I fixed it by adding 'pack $win' within the
> constructor. Why can't the manual tell me that? Why can't the example
> code include it?

*DON'T* put the pack in the constructor! One of the common ways to create a
Scroll Window (a frame with scroll bars intended to contain a scrollable
widget (like a text or canvas or listbox, etc.) uses grid and if the text is
already packed, this will fail with an error.

ALL Tk widget constructors leave the geometry manager (pack, grid, or place)
out. It is the responsibility of the programmer to add the appropriate
geometry manager code after creating the widget. This is always how this is
done. The geometry managers have many options controlling how the widget's
geometry is managed and none of these make sense as options to the widget
creation. There are also cases where the widget might not get set up with a
geometry manager right away or might get disassociated with a geometry manager
at some point (eg pack forget). Geometry management is a whole separate
process, and is always handled separately from widget creation.

>
>
> There was more struggle.
>
> snit::widget TopWindow {
> hulltype toplevel
> delegate option * to hull
> component of
> variable of
>
> constructor {args} {
> wm withdraw .
> wm resizable $win 1 1
> wm attributes $win -zoomed 0
> wm geometry $win 600x100+0+0
> wm title $win "test"
> tk appname "test"
> bind $win <Alt-q> {exit 0}
> bind $win <Alt-Q> {exit 0}
>
> install of using frame $win.of
> pack $of -fill both -expand 1
>
> $self configurelist $args
> }
> }
> TopWindow .toplevel
>
>
> Now, how do I add the read-only text widget to that toplevel?
>
> Again, a lot of struggle to figure this out:
>
> rotext .toplevel.of.rox
>
> Why can't the manual tell me that?

Did you read the man pages for *Tk* itself?

snit::widget and snit::widgetadaptor create widget constructors that behave
*EXACTLY* like native Tk widgets. All of the things talked about in the man
pages for Tk and all of the native Tk widgets and Tk geometry managers apply
to widgets created with snit::widget and snit::widgetadaptor apply.
snit::widget and snit::widgetadaptor create "commands" that can be dropped
into anyplace a any native Tk widget creation command would be at home.

snit::widgetadaptor MySpecialButton {
...
}

then

set B01 [MySpecialButton .b ...]
pack $B01

*JUST LIKE*

set B01 [button .b ...]
pack $B01

*OR*

set B01 [ttk::button .b ...]
pack $B01

>
> And I can only do that by explicitly referencing ".toplevel"
> which seems inadequate. There should be a variable that contains
> that toplevel path. There probably is, but heck if I know what
> that is.

set mytoplevel [TopLevel .toplevel]

*EXACTLY* like:

set mytoplevel [toplevel .toplevel]

>
> I'm still struggling with other things. Anyway, my point is
> the documentation has multiple examples of how to create a
> type but no examples whatsoever of how to call what the code
> is creating. It just assumes the reader knows because it's obvious.
> But it took me a long time to guess on my own.

That is because it is already documented elsewhere in the Tk man pages.

>
>
> Thank you for your guidance once again.
>

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

Subject: Re: My hang-up about OOP (snit)
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Fri, 28 Jun 2024 03:06 UTC
References: 1 2 3 4 5 6 7 8
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: My hang-up about OOP (snit)
Date: Fri, 28 Jun 2024 00:06:29 -0300
Organization: A noiseless patient Spider
Lines: 40
Message-ID: <20240628000629.61e6f107@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>
<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>
<20240626220932.62b9e27e@lud1.home>
<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>
<20240627180832.3c8fc106@lud1.home>
<76icnV37fZoBZeD7nZ2dnZfqnPudnZ2d@giganews.com>
<20240627212704.46c26379@lud1.home>
<zv6dnSg8IeFOg-P7nZ2dnZfqn_ednZ2d@giganews.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 28 Jun 2024 05:06:30 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="8baf39e74934074e0441f0f0115dbdac";
logging-data="3310592"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Bsihd3xw+ratAhP0qw2xL2MynwkP6Gn8="
Cancel-Lock: sha1:GVuOSRNOUp0pJ7kVicI0sh2gQSc=
View all headers

On Fri, 28 Jun 2024 02:24:19 +0000, Robert Heller wrote:

>Did you read the man pages for *Tk* itself?
>
>snit::widget and snit::widgetadaptor create widget constructors that
>behave *EXACTLY* like native Tk widgets.

I think I understand, but it took me a long time to grasp because I
think I was lured into something else.

snit::type dog {
# ....
} ::dog
% dog create spot
::spot
spot execute method

So I thought,

snit::widget textbox {
# ....
text -options blahblahblah

}

textbox create textbox1
textbox1 -otheroptions blahblahblah

But it's nothing like that! I thought I was going to create and refer
to widgets by some fancy name of my own choosing, but I'm not.
I was disappointed.

--
Luc
>>

Subject: Re: My hang-up about OOP (snit)
From: Robert Heller
Newsgroups: comp.lang.tcl
Organization: Deepwoods Software
Date: Fri, 28 Jun 2024 11:49 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!border-4.nntp.ord.giganews.com!nntp.giganews.com!Xl.tags.giganews.com!local-1.nntp.ord.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Fri, 28 Jun 2024 11:49:11 +0000
MIME-Version: 1.0
From: heller@deepsoft.com (Robert Heller)
Organization: Deepwoods Software
X-Newsreader: TkNews 3.0 (1.2.18)
Subject: Re: My hang-up about OOP (snit)
In-Reply-To: <20240628000629.61e6f107@lud1.home>
References: <20240625180928.43fcc5c1@lud1.home>??<ILKcnRhLs7Cl9eb7nZ2dnZfqnPqdnZ2d@giganews.com>??<20240626220932.62b9e27e@lud1.home>??<4wCdnSaPLuoGTOH7nZ2dnZfqnPudnZ2d@giganews.com>??<20240627180832.3c8fc106@lud1.home>??<76icnV37fZoBZeD7nZ2dnZfqnPudnZ2d@giganews.com>??<20240627212704.46c26379@lud1.home>??<zv6dnSg8IeFOg-P7nZ2dnZfqn_ednZ2d@giganews.com>
<20240628000629.61e6f107@lud1.home>
Newsgroups: comp.lang.tcl
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset="us-ascii"
Originator: heller@sharky4.deepsoft.com
Message-ID: <MLOcnQXJp5eqPuP7nZ2dnZfqn_udnZ2d@giganews.com>
Date: Fri, 28 Jun 2024 11:49:11 +0000
Lines: 67
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-dTjC/egoc3BEsvVTLgnMsD0cqRA6vrzetUR8rs+fp7TpF+vrd+9nx7RDotYbcw3GfTP/LB2XnXv1q64!vxbhxsdzvwY8AHaRUUHk/zybivkGn/kjWGhhMCPwXNoRDoZFeQ745AI04vbs1Tn1JfckDHDP2pnr!gbY=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
View all headers

At Fri, 28 Jun 2024 00:06:29 -0300 Luc <luc@sep.invalid> wrote:

>
> On Fri, 28 Jun 2024 02:24:19 +0000, Robert Heller wrote:
>
> >Did you read the man pages for *Tk* itself?
> >
> >snit::widget and snit::widgetadaptor create widget constructors that
> >behave *EXACTLY* like native Tk widgets.
>
>
> I think I understand, but it took me a long time to grasp because I
> think I was lured into something else.
>
> snit::type dog {
> # ....
> }
> ::dog
> % dog create spot
> ::spot
> spot execute method
>
>
> So I thought,
>
> snit::widget textbox {
> # ....
> text -options blahblahblah
>
> }
>
> textbox create textbox1
> textbox1 -otheroptions blahblahblah
>
> But it's nothing like that! I thought I was going to create and refer
> to widgets by some fancy name of my own choosing, but I'm not.
> I was disappointed.

Tk widgets, whether the "built in" (native) ones or ones created by snit (or
BWidget or any other Tcl/Tk widget extension) all *have* to obey the
convention that Tk widgets are in a hierarchical path:
".parent.child.grandchild" -- it does not matter if parent was created by a Tk
widget and child was created by a snit::widget and grandchild was created by a
BWidget (another Tk widget extension framework) class. This is *required* by
how the underlying structure of the Tk GUI subsystem works. All "widgets"
(windows) have to the be the child of some other widget (window) and container
widgets (eg toplevels, frames, etc.) can have children widgets. Only "." has
no parent and is in fact the final ancestor of all widgets. I believe this
parent and child structure is a standard feature of all GUI subsystems, not
just Tk. There are reasons for that, which could probably fill a whole
textbook / university course to explain.

Snit's "types" are not constrained by Tk -- they are their own thing
independent of Tk. Snit's "widgets" and "widgetadaptors" do use the same
internal structure as snit "types" (variables, methods, options, and
components), but their naming conventions are tied (hardwired) to follow the
same conventions as any other widget framework.

>
>

--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
heller@deepsoft.com -- Webhosting Services

1

rocksolid light 0.9.8
clearnet tor