Components: How do you reuse utility code?

classic Classic list List threaded Threaded
38 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Components: How do you reuse utility code?

4D Tech mailing list
I try out components every couple of versions and inevitably seem to give
up on them. I really like the idea, but am not sold on the implementation.
Since other people seem to be using them very happily, I suspect there are
some concepts or practices that I'm missing.

<rant>It's a complete nightmare that there isn't a clear boundary between
host and component. Some things are distinct (variables), some are shared,
some are sort of shared (method names). What makes this a nightmare is
that *there
is no syntax for distinguishing what you're talking about*. A few 4D
commands take a * parameter to overcome this very problem, but we have
nothing like that. What your code operates on depends on where its located,
You really have to keep a lot in your head to predict, understand, and
control this.</rant>

Anyway, before I sink more time into this, I figured I'd ask for some
advice. Here's the deal, I've got a standard module called ErrorStack where
I can, well, stack errors. That way you can run a bunch of lines of code
without constantly checking for errors - but then go back and check that
they were all okay. Nice for handling inputs, etc. If I bake the code into
a component and copy the code into the host, it's just a total mess. Unless
you duplicate and rename everything, it won't work. If you do duplicate and
rename everything, what a hassle. So I'm imagining that I should have
something like this:

Host.4DB
/Components
   ErrorStack.4dbase
   MessageHub.4dbase

So, Host.4DB and the .4DB/.4DC inside of MessageHub.4dbase would _both_ use
ErrorStack.4dbase. Is that the right idea? So, my source for MessageHub
would _not_ have the ErrorStack module but would have a copy of the
component?

Is that the general idea? Does that even work? Is there a better approach?

I'd like this to work out and I'm open to reworking and partitioning code a
bit to make it happen. But if it's just going to be a long, weird, mess I'd
rather know soon so that I can bail and move onto more dignified pursuits.
I mean, if I want to screw around all day pointlessly I can always try and
get better at configuring Apache...
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
Hi David,

Reading your comments on components has given me a lot to think about. So
examining how ​I tend to look at components​ I find I break them down into
two general areas:

1) as a repository for a core set of functions
2) as more or less independent sub-programs


​#1 - core functions
I'd put Cannon Smith's object component in this category. I actually call
mine 'Framework' and it's got a couple of hundred methods or so that
generally do specific things. String, date, array, math, and so on kinds of
things. A lot of listbox and form object methods. Basically all the things
I will tend to use as part of my style. Heck, there's even a module made up
of the methods from one of the hash technotes you wrote. The component has
its own error handling system and the methods in it either refer only to
other component methods or a plugin (which must reside in the database so
those are pretty rare). The overall strategy is these are things the host
database will call on when needed to enrich the life of the host. I also
include some developer tools I find handy. I can drop this into a brand new
structure and have most of what I need to get to work.

#2) - sub programs
In this ring we have more developed applications which really are nearly
complete apps on their own. I expect these to manage their own errors and
be well tested and solid. Bruno LeGay's component for uploading to AWS is
one. Peter Jackobsen's Code Wallet is another that comes to mind. ​

In contrast to the previous case I expect these to offer me a limited
number of hooks or front facing methods.

I always use compiled components. And I dearly wish 4D offered a pref that
would allow me to have them appear with a different color from regular
methods in the editor.

​So, how does this work when I'm actually using it? The methods in #1 are
generally well tested. If something does throw an error I open the source
code, fix it, recompile and restart.

Or I write a local method to take over that function from the component.
There are two ways to spot duplicated methods: 1) they appear as warnings
in the complier and 2) I have a method in the component that will show me a
list of them.

I like being able to override the component with a local method. The
problem is when I may write a local version of a method and forget to go
back and update the component. ​

I like being able to use aliases of components in the database folders. I
keep 2 folders in the main folder for each 4D version: Component DBs for
the uncompiled databases and Component Builds for the built ones. This way
when I update one of my 'core' components all my databases are updated with
the newest version because they all refer to that folder by way of aliases.
This works for me in the large majority of cases.

Somethings have never worked well in a component for me. Inherited forms -
it would be really great if these worked but I haven't been able to make it
happen. Functionality specific to a particular database has never seemed
like a good idea either but I may not be thinking creatively enough. Though
I guess it could be useful for some sort of licensing scheme.

I have never expected or really wanted a component to share the same memory
space as the calling process so that's not an issue for me. I actually like
the black box approach they compel you to take.

The final thing about components is to have some useful material in the
comments because that's the only way to get a tip to show up when you're
using it. I've been using an approach like Wayne talked about for several
years and it's really great for components. Before building I run the macro
and update the comments of all the component methods with the comments from
the method. So nice to have that reminder of what params do what.

--
Kirk Brooks
San Francisco, CA
=======================

*The only thing necessary for the triumph of evil is for good men to do
nothing.*

*- Edmund Burke*
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
I prefix all methods shared with the host with an underscore so I can
easily see what I have shared.


> --
Jim Dorrance
[hidden email]
[hidden email]
www.4d.dorrance.eu

PS: If you know of anyone that needs an experienced 4D programmer to add
energy and experience to their team, please let me know. I have
experience in many areas. Reasonable rates. Remote or Paris only.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
David,

I would forget about the error stack idea.

Kirk's thoughts are all good except beware the Object one (putting Cannon's
module in a component).

I did that but… somethings work slightly different, off the top of my head
I can't recall what they are. In the end I just gave up and copied the
module in directly (although I did edit all the comments so they worked
with my Comment writing code).

Normally my components have a 2-3 character prefix which means you still
have a massive 27-28 characters for your method name!!!!

For example:
SYN_ServerIdentifier
FND_KVP_Text (Of course when writing a Foundation component you also lose
another four characters).
etc

Like Kirk, I've had no success with inherited forms.

The easiest way is to create a project form which can be copied from
structure to structure and control it with component methods.

An excellent example of this approach is Listbox Magic by Barclay Berry.

This doesn't apply to forms that the component has total control of
obviously.



Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>


On 20 April 2017 at 17:14, Jim Dorrance via 4D_Tech <[hidden email]>
wrote:

> I prefix all methods shared with the host with an underscore so I can
> easily see what I have shared.
>
>
> > --
> Jim Dorrance
> [hidden email]
> [hidden email]
> www.4d.dorrance.eu
>
> PS: If you know of anyone that needs an experienced 4D programmer to add
> energy and experience to their team, please let me know. I have
> experience in many areas. Reasonable rates. Remote or Paris only.
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> FAQ:  http://lists.4d.com/faqnug.html
> Archive:  http://lists.4d.com/archives.html
> Options: http://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list

> Le 20 avr. 2017 à 08:01, David Adams via 4D_Tech <[hidden email]> a écrit :
>
> [...] I've got a standard module called ErrorStack where
> I can, well, stack errors. [...]

I gave up on a "complete" error management embedded in a component, in 4D it mostly relies on process variables that are not shared.
BTW if someone has good ideas to turn around…

--
Arnaud de Montard


**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
I think components are great for methods that:

1.  Rely only on local variables.

2.  Are useful everywhere (Generic, Utility etc.)  I call mine Core_

3.  If a component method is causing issues.

 I copy and paste it into the host library fix the issue.

________________________________
From: 4D_Tech <[hidden email]> on behalf of David Adams via 4D_Tech <[hidden email]>
Sent: Thursday, April 20, 2017 6:01 AM
To: 4D iNug Technical
Cc: David Adams
Subject: Components: How do you reuse utility code?

I try out components every couple of versions and inevitably seem to give
up on them. I really like the idea, but am not sold on the implementation.
Since other people seem to be using them very happily, I suspect there are
some concepts or practices that I'm missing.

<rant>It's a complete nightmare that there isn't a clear boundary between
host and component. Some things are distinct (variables), some are shared,
some are sort of shared (method names). What makes this a nightmare is
that *there
is no syntax for distinguishing what you're talking about*. A few 4D
commands take a * parameter to overcome this very problem, but we have
nothing like that. What your code operates on depends on where its located,
You really have to keep a lot in your head to predict, understand, and
control this.</rant>

Anyway, before I sink more time into this, I figured I'd ask for some
advice. Here's the deal, I've got a standard module called ErrorStack where
I can, well, stack errors. That way you can run a bunch of lines of code
without constantly checking for errors - but then go back and check that
they were all okay. Nice for handling inputs, etc. If I bake the code into
a component and copy the code into the host, it's just a total mess. Unless
you duplicate and rename everything, it won't work. If you do duplicate and
rename everything, what a hassle. So I'm imagining that I should have
something like this:

Host.4DB
/Components
   ErrorStack.4dbase
   MessageHub.4dbase

So, Host.4DB and the .4DB/.4DC inside of MessageHub.4dbase would _both_ use
ErrorStack.4dbase. Is that the right idea? So, my source for MessageHub
would _not_ have the ErrorStack module but would have a copy of the
component?

Is that the general idea? Does that even work? Is there a better approach?

I'd like this to work out and I'm open to reworking and partitioning code a
bit to make it happen. But if it's just going to be a long, weird, mess I'd
rather know soon so that I can bail and move onto more dignified pursuits.
I mean, if I want to screw around all day pointlessly I can always try and
get better at configuring Apache...
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
lists.4d.com<http://lists.4d.com/faqnug.html>
lists.4d.com
Information about the 4D Tech Mailing List <[hidden email]>, 4D Biz Mailing List <[hidden email]>, and 4D Pub Mailing List <[hidden email] ...



Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
 On Thu, Apr 20, 2017 at 16:57 Kirk Brooks via 4D_Tech <[hidden email]>
wrote:

> 1) as a repository for a core set of functions
> 2) as more or less independent sub-programs

That makes sense. I guess what I'm trying to get advice on is how to share
utility code with a host and other components:

MyBigDatabase
|____Components
         |____ErrorStack
              |____ErrorStack.4dbase
                    |____ErrorStack.4DC
         |____MessageHub
              |____MessageHub.4dbase
                    |____MessageHub.4DC
                         Components
                          |____ErrorStack
                               |____ErrorStack.4dbase
                                    |____ErrorStack.4DC

See what I'm saying? Does the above work? I'm asking without trying because
others already know and I'm running out of time I'm willing to devote to
basic research on 4D components in V16.
>
> I always use compiled components.
I've been testing all of this out with interpreted ones and much appreciate
that you can at least see the component's source. For production, I'd use
compiled components.

> And I dearly wish 4D offered a pref that
> would allow me to have them appear with a different color from regular
> methods in the editor.

What an outstanding idea! How hard could it be? Please set up a feature
request on the forums and post back here. I'll vote for it, for sure.

> Or I write a local method to take over that function from the component.
> There are two ways to spot duplicated methods: 1) they appear as warnings
> in the complier

Not for me they don't. I've set this up on purpose and they aren't detected.

> I like being able to override the component with a local method. The
> problem is when I may write a local version of a method and forget to go
> back and update the component. ​

I have no problem with the concept of an override, it's just that it's a
bit obscure if/when it is happening. There is no way to address a specific
instance/scope of the method.


> I have never expected or really wanted a component to share the same
memory
> space as the calling process so that's not an issue for me. I actually
like
> the black box approach they compel you to take.

Man, I wish 4D gave us a black box. What I'm seeing is more of a soggy
brown cardboard box. The variables are in their own weird space *without an
address*. You just implicitly have to know what context the code is running
in. And that code may or may not be running in the host or the component. I
find this hard to get my head around because it's a murky design. There
isn't a crisp line and there is no way to specify where you're talking to.
You just have to know. I'm not loving it.

It's hard to talk about a lot of language concepts in 4D because 4D is
missing so much. I kind of hoped that components would deliver more than
they do. I admit the business of them having their own variable space is
appealing...but it's done is such a peculiar way. I really don't like that
they don't have their own addressable execution paths. Very weird. I notice
a lot of people on the list being excited about "dot notation." Why? Who
cares? The benefit of object dot notation isn't the dots, it's the objects.
We have _nothing_ like that in 4D. The closest I've come to date are
workers. A worker has a crisp boundary (a process), you can communicate
with it via an API-like system (if you program it that way), and you can
make methods private (by testing the execution context name and type.) So,
yeah, that's okayish. Also, a worker is something that you can create at
runtime and where you can create multiple instances without adding new
methods. That all feels natural to me.

Note: You can absolutely screw up what I just said about using workers in a
novel way. Just mess with them using GET/SET PROCESS VARIABLES. Whoever
thought they were a good idea? I'll say this, if those commands are the
answer, someone really didn't understand the question.

4D components are weird because they have their own little variable space -
but where is it? How do you address it? More to the point, how do you know
when you're address it? It's sort of within the current process. But you
can't address it specifically. It makes the code pointlessly hard to
follow. The component isn't a runtime object, it's something baked right
into the code. I don't even know what you call that.

> The final thing about components is to have some useful material in the
> comments because that's the only way to get a tip to show up when you're
> using it. I've been using an approach like Wayne talked about for several
> years and it's really great for components. Before building I run the
macro
> and update the comments of all the component methods with the comments
from
> the method. So nice to have that reminder of what params do what.

That seems like really solid advice from you, Wane, et al.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
David,

On Thu, Apr 20, 2017 at 3:22 PM, David Adams via 4D_Tech <
[hidden email]> wrote:

>  On Thu, Apr 20, 2017 at 16:57 Kirk Brooks via 4D_Tech <
> [hidden email]>
> wrote:
>
> > 1) as a repository for a core set of functions
> > 2) as more or less independent sub-programs
>
> That makes sense. I guess what I'm trying to get advice on is how to share
> utility code with a host and other components:
> ​...
>  Does the above work?

​Yes. but. the times I've tried it really got to be a mess. You know that
old joke? "You change one little thing..."​

The biggest problem is when you compile each component must have its own
copy of utilized components within. In your example you change one little
thing in Error Stack and you've got to rebuild everything - and in the
correct order. Not happy.


> I'm asking without trying because
> others already know and I'm running out of time I'm willing to devote to
> basic research on 4D components in V16.
>
​I think if you orient your view of of components as tool packets you'll be
better served. ​


> > And I dearly wish 4D offered a pref that
> > would allow me to have them appear with a different color from regular
> > methods in the editor.
>
> What an outstanding idea! How hard could it be? Please set up a feature
> request on the forums and post back here. I'll vote for it, for sure.
>
> > Or I write a local method to take over that function from the component.
> > There are two ways to spot duplicated methods: 1) they appear as warnings
> > in the complier
>
> Not for me they don't. I've set this up on purpose and they aren't
> detected.
>
> > I like being able to override the component with a local method. The
> > problem is when I may write a local version of a method and forget to go
> > back and update the component. ​
>
> I have no problem with the concept of an override, it's just that it's a
> bit obscure if/when it is happening. There is no way to address a specific
> instance/scope of the method.
>
​The visiual cue would help. I'll put that on the forum tonight.


> > the black box approach they compel you to take.
>
> Man, I wish 4D gave us a black box. What I'm seeing is more of a soggy
> brown cardboard box.

​Made me laugh.


> The variables are in their own weird space *without an
> address*. You just implicitly have to know what context the code is running
> in. And that code may or may not be running in the host or the component. I
> find this hard to get my head around because it's a murky design. There
> isn't a crisp line and there is no way to specify where you're talking to.
> You just have to know. I'm not loving it.
>
​True but you can work with it. So long as it's consistently enforced it's
not so big a deal. You can always pass pointers to vars on the 4D side.

I should point out, though, that my style of programming stays away from
large memory blocks that I expect to be stable or controlled during the
life of the session. I use some of those, of course, but not extensively.
So some of these cncerns about memory management aren't so large for me.
This may be why it's not so much of a concern. ​



> Note: You can absolutely screw up what I just said about using workers in a
> novel way. Just mess with them using GET/SET PROCESS VARIABLES. Whoever
> thought they were a good idea? I'll say this, if those commands are the
> ans
> ​Pro​
> wer, someone really didn't understand the question.
>
​I think they were pretty good solutions at the time - which was what, 20
years ago?​ Otherwise I agree, they're dodgy and in a busy system I think
the time you'd spend setting & clearing semaphores to control them would
obviate the benefit of using them. Your suggestion of just using a table is
much better there.

4D components are weird because they have their own little variable space -
> but where is it? How do you address it? More to the point, how do you know
> when you're address it? It's sort of within the current process. But you
> can't address it specifically. It makes the code pointlessly hard to
> follow. The component isn't a runtime object, it's something baked right
> into the code. I don't even know what you call that.
>
​Well this is the opacity of the soggy cardboard isn't it? Think of them as
microwave ovens maybe. You open it up, put some stuff in, adjust some
settings and turn it on (lose). Then you get out the finished result. You
could get involved in modulating the microwaves yourself - but why?

If you're writing your own component you could include methods to sync
component vars with program vars - you'd just have to pass in the pointers
to the program vars. IP vars in a component are available to the component
in all component processes. ​

--
Kirk Brooks
San Francisco, CA
=======================

*The only thing necessary for the triumph of evil is for good men to do
nothing.*

*- Edmund Burke*
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
Hi,

Feature Request for different style in method editor:

http://forums.4d.fr/Post//19321897/1/


Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>


On 21 April 2017 at 09:04, Kirk Brooks via 4D_Tech <[hidden email]>
wrote:

> David,
>
> On Thu, Apr 20, 2017 at 3:22 PM, David Adams via 4D_Tech <
> [hidden email]> wrote:
>
> >  On Thu, Apr 20, 2017 at 16:57 Kirk Brooks via 4D_Tech <
> > [hidden email]>
> > wrote:
> >
> > > 1) as a repository for a core set of functions
> > > 2) as more or less independent sub-programs
> >
> > That makes sense. I guess what I'm trying to get advice on is how to
> share
> > utility code with a host and other components:
> > ​...
> >  Does the above work?
>
> ​Yes. but. the times I've tried it really got to be a mess. You know that
> old joke? "You change one little thing..."​
>
> The biggest problem is when you compile each component must have its own
> copy of utilized components within. In your example you change one little
> thing in Error Stack and you've got to rebuild everything - and in the
> correct order. Not happy.
>
>
> > I'm asking without trying because
> > others already know and I'm running out of time I'm willing to devote to
> > basic research on 4D components in V16.
> >
> ​I think if you orient your view of of components as tool packets you'll be
> better served. ​
>
>
> > > And I dearly wish 4D offered a pref that
> > > would allow me to have them appear with a different color from regular
> > > methods in the editor.
> >
> > What an outstanding idea! How hard could it be? Please set up a feature
> > request on the forums and post back here. I'll vote for it, for sure.
> >
> > > Or I write a local method to take over that function from the
> component.
> > > There are two ways to spot duplicated methods: 1) they appear as
> warnings
> > > in the complier
> >
> > Not for me they don't. I've set this up on purpose and they aren't
> > detected.
> >
> > > I like being able to override the component with a local method. The
> > > problem is when I may write a local version of a method and forget to
> go
> > > back and update the component. ​
> >
> > I have no problem with the concept of an override, it's just that it's a
> > bit obscure if/when it is happening. There is no way to address a
> specific
> > instance/scope of the method.
> >
> ​The visiual cue would help. I'll put that on the forum tonight.
> ​
>
> > > the black box approach they compel you to take.
> >
> > Man, I wish 4D gave us a black box. What I'm seeing is more of a soggy
> > brown cardboard box.
>
> ​Made me laugh.
> ​
>
> > The variables are in their own weird space *without an
> > address*. You just implicitly have to know what context the code is
> running
> > in. And that code may or may not be running in the host or the
> component. I
> > find this hard to get my head around because it's a murky design. There
> > isn't a crisp line and there is no way to specify where you're talking
> to.
> > You just have to know. I'm not loving it.
> >
> ​True but you can work with it. So long as it's consistently enforced it's
> not so big a deal. You can always pass pointers to vars on the 4D side.
>
> I should point out, though, that my style of programming stays away from
> large memory blocks that I expect to be stable or controlled during the
> life of the session. I use some of those, of course, but not extensively.
> So some of these cncerns about memory management aren't so large for me.
> This may be why it's not so much of a concern. ​
>
>
>
> > Note: You can absolutely screw up what I just said about using workers
> in a
> > novel way. Just mess with them using GET/SET PROCESS VARIABLES. Whoever
> > thought they were a good idea? I'll say this, if those commands are the
> > ans
> > ​Pro​
> > wer, someone really didn't understand the question.
> >
> ​I think they were pretty good solutions at the time - which was what, 20
> years ago?​ Otherwise I agree, they're dodgy and in a busy system I think
> the time you'd spend setting & clearing semaphores to control them would
> obviate the benefit of using them. Your suggestion of just using a table is
> much better there.
>
> 4D components are weird because they have their own little variable space -
> > but where is it? How do you address it? More to the point, how do you
> know
> > when you're address it? It's sort of within the current process. But you
> > can't address it specifically. It makes the code pointlessly hard to
> > follow. The component isn't a runtime object, it's something baked right
> > into the code. I don't even know what you call that.
> >
> ​Well this is the opacity of the soggy cardboard isn't it? Think of them as
> microwave ovens maybe. You open it up, put some stuff in, adjust some
> settings and turn it on (lose). Then you get out the finished result. You
> could get involved in modulating the microwaves yourself - but why?
>
> If you're writing your own component you could include methods to sync
> component vars with program vars - you'd just have to pass in the pointers
> to the program vars. IP vars in a component are available to the component
> in all component processes. ​
>
> --
> Kirk Brooks
> San Francisco, CA
> =======================
>
> *The only thing necessary for the triumph of evil is for good men to do
> nothing.*
>
> *- Edmund Burke*
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> FAQ:  http://lists.4d.com/faqnug.html
> Archive:  http://lists.4d.com/archives.html
> Options: http://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
On 21 April 2017 at 09:06, Wayne Stewart <[hidden email]> wrote:

> http://forums.4d.fr/Post//19321897/1/


​Well that link doesn't appear to work (but go to the forum and vote
anyway).​



Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
Components calling components?
Get used to EXECUTE METHOD, this works and is the easiest way to achieve
this.
Of course it sort of negates the benefits of compiling so don't do it in a
loop!

That's why the Foundation shell went from a bunch of small components in
2003/2004 days to one big component for v11+.  You can still see a lot of
legacy code in the source, checking for the existence of components before
calling it.  This is unnecessary now as it definitely is present!




Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>


On 21 April 2017 at 09:07, Wayne Stewart <[hidden email]> wrote:

>
> On 21 April 2017 at 09:06, Wayne Stewart <[hidden email]>
> wrote:
>
>> http://forums.4d.fr/Post//19321897/1/
>
>
> ​Well that link doesn't appear to work (but go to the forum and vote
> anyway).​
>
>
>
> Regards,
>
> Wayne
>
>
> [image: --]
> Wayne Stewart
> [image: http://]about.me/waynestewart
> <http://about.me/waynestewart>
>
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
> >  Does the above work?
> >
> ​Yes. but. the times I've tried it really got to be a mess.

So then, "no" :(


> I should point out, though, that my style of programming stays away from
> large memory blocks that I expect to be stable or controlled during the
> life of the session. I use some of those, of course, but not extensively.
> So some of these concerns about memory management aren't so large for me.
> This may be why it's not so much of a concern. ​

I'm not sure what you mean about "large memory blocks, etc.", but I can say
that memory management isn't on my list of concerns here. At all.

> ​I think they were pretty good solutions at the time - which was what, 20
> years ago?​

Nope, they were always a crap idea. I hated them on day one and my
reasoning has not changed. (I have used them enough to understand how to
use them correctly and to see the places where they're handy.) It is
fundamentally wrong that a process can change the state of another process
without any form of permission or negotiation. A message queue was always a
better solution and they were well-known at the time. We still don't have a
native queue in 4D, but there's some progress with CALL WORKER/CALL FORM
(if used correctly, you can absolutely use these commands in terrible ways
- but you don't have to.) 4D wasn't cutting new ground when it came to
concurrent processes. Although they did a great job of bringing to the
masses in a very easy to use way. Kudos. The basic programming issues and
tools around concurrency got thought through before 4D ever existed. First
and foremost by Edsger Dijkstra. He invented the semaphore along the way,
believe it or not. But my disgust at GET/SET VARIABLE is well established
already, so I'll (try to) stop now.

> If you're writing your own component you could include methods to sync
> component vars with program vars - you'd just have to pass in the pointers
> to the program vars. IP vars in a component are available to the component
> in all component processes. ​

Ugh. I'm just trying to find a strategy that's workable but not too
onerous. I may not have mentioned, but I'm not trying to share variables
directly. I've got calls like:

ErrorStack_GetStack () : Error stack object
When this routine is called, there is no error stack object. Instead, the
actual stack is an object array and some support variables. For 99% of the
time, it's a lot simpler to work with the object array than a C_OBJECT with
an embedded array. When I need to dump the stack to text or to an object,
that's the only time I need a single object. The outside world hasn't got
access to the arrays, etc., but it can ask for an object version of them.
The outside world doesn't know there isn't a C_OBJECT because that's all it
can see or get. Put another way, ErrorStack is already API-oriented. But
what data does ErrorStack_GetStack() package? That's what gets confusing. I
absolutely don't want to write a bunch of code that delves into the hidden
locations 4D has allocated. I also don't want to expose my underlying
implementation. Pointers smell wrong here too, particularly since what I'm
returning is generated on the spot.

I might give components one more try by putting everything into an
OmniJumble component and having the host call it all of the time. Not
really a sensible way to organize libraries, but it may be as good as I can
get. My main goal, in this case, is to hide a lot of the plumbing on a
large body of code. I'm not trying to hide the code per se (if I give out
the component, I'd give out the code), but to make the calls easier to work
with. Your idea about colored method names would help here too.

On Fri, Apr 21, 2017 at 9:04 AM, Kirk Brooks via 4D_Tech <
[hidden email]> wrote:

> David,
>
> On Thu, Apr 20, 2017 at 3:22 PM, David Adams via 4D_Tech <
> [hidden email]> wrote:
>
> >  On Thu, Apr 20, 2017 at 16:57 Kirk Brooks via 4D_Tech <
> > [hidden email]>
> > wrote:
> >
> > > 1) as a repository for a core set of functions
> > > 2) as more or less independent sub-programs
> >
> > That makes sense. I guess what I'm trying to get advice on is how to
> share
> > utility code with a host and other components:
> > ​...
> >  Does the above work?
>
> ​Yes. but. the times I've tried it really got to be a mess. You know that
> old joke? "You change one little thing..."​
>
> The biggest problem is when you compile each component must have its own
> copy of utilized components within. In your example you change one little
> thing in Error Stack and you've got to rebuild everything - and in the
> correct order. Not happy.
>
>
> > I'm asking without trying because
> > others already know and I'm running out of time I'm willing to devote to
> > basic research on 4D components in V16.
> >
> ​I think if you orient your view of of components as tool packets you'll be
> better served. ​
>
>
> > > And I dearly wish 4D offered a pref that
> > > would allow me to have them appear with a different color from regular
> > > methods in the editor.
> >
> > What an outstanding idea! How hard could it be? Please set up a feature
> > request on the forums and post back here. I'll vote for it, for sure.
> >
> > > Or I write a local method to take over that function from the
> component.
> > > There are two ways to spot duplicated methods: 1) they appear as
> warnings
> > > in the complier
> >
> > Not for me they don't. I've set this up on purpose and they aren't
> > detected.
> >
> > > I like being able to override the component with a local method. The
> > > problem is when I may write a local version of a method and forget to
> go
> > > back and update the component. ​
> >
> > I have no problem with the concept of an override, it's just that it's a
> > bit obscure if/when it is happening. There is no way to address a
> specific
> > instance/scope of the method.
> >
> ​The visiual cue would help. I'll put that on the forum tonight.
> ​
>
> > > the black box approach they compel you to take.
> >
> > Man, I wish 4D gave us a black box. What I'm seeing is more of a soggy
> > brown cardboard box.
>
> ​Made me laugh.
> ​
>
> > The variables are in their own weird space *without an
> > address*. You just implicitly have to know what context the code is
> running
> > in. And that code may or may not be running in the host or the
> component. I
> > find this hard to get my head around because it's a murky design. There
> > isn't a crisp line and there is no way to specify where you're talking
> to.
> > You just have to know. I'm not loving it.
> >
> ​True but you can work with it. So long as it's consistently enforced it's
> not so big a deal. You can always pass pointers to vars on the 4D side.
>
> I should point out, though, that my style of programming stays away from
> large memory blocks that I expect to be stable or controlled during the
> life of the session. I use some of those, of course, but not extensively.
> So some of these cncerns about memory management aren't so large for me.
> This may be why it's not so much of a concern. ​
>
>
>
> > Note: You can absolutely screw up what I just said about using workers
> in a
> > novel way. Just mess with them using GET/SET PROCESS VARIABLES. Whoever
> > thought they were a good idea? I'll say this, if those commands are the
> > ans
> > ​Pro​
> > wer, someone really didn't understand the question.
> >
> ​I think they were pretty good solutions at the time - which was what, 20
> years ago?​ Otherwise I agree, they're dodgy and in a busy system I think
> the time you'd spend setting & clearing semaphores to control them would
> obviate the benefit of using them. Your suggestion of just using a table is
> much better there.
>
> 4D components are weird because they have their own little variable space -
> > but where is it? How do you address it? More to the point, how do you
> know
> > when you're address it? It's sort of within the current process. But you
> > can't address it specifically. It makes the code pointlessly hard to
> > follow. The component isn't a runtime object, it's something baked right
> > into the code. I don't even know what you call that.
> >
> ​Well this is the opacity of the soggy cardboard isn't it? Think of them as
> microwave ovens maybe. You open it up, put some stuff in, adjust some
> settings and turn it on (lose). Then you get out the finished result. You
> could get involved in modulating the microwaves yourself - but why?
>
> If you're writing your own component you could include methods to sync
> component vars with program vars - you'd just have to pass in the pointers
> to the program vars. IP vars in a component are available to the component
> in all component processes. ​
>
> --
> Kirk Brooks
> San Francisco, CA
> =======================
>
> *The only thing necessary for the triumph of evil is for good men to do
> nothing.*
>
> *- Edmund Burke*
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> FAQ:  http://lists.4d.com/faqnug.html
> Archive:  http://lists.4d.com/archives.html
> Options: http://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
On Fri, Apr 21, 2017 at 9:16 AM, Wayne Stewart via 4D_Tech <
[hidden email]> wrote:

> Components calling components?
> Get used to EXECUTE METHOD, this works and is the easiest way to achieve
> this.
>

Seriously? Wow. Well, at least now I know. Thanks for saving me some time!
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
> > Or I write a local method to take over that function from the component.
> > There are two ways to spot duplicated methods: 1) they appear as
warnings
> > in the complier
>
> Not for me they don't. I've set this up on purpose and they aren't
> detected.

Okay, I've seen it now for the first time. Four 'overrides' are reported -
but there are several dozen 'overrides'.

So, if no conflict is reported, I think the result should be

    Everything seems okay.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
> On Apr 20, 2017, at 6:04 PM,David Adams wrote:
>
> That makes sense. I guess what I'm trying to get advice on is how to share
> utility code with a host and other components:
>
> MyBigDatabase
> |____Components
>         |____ErrorStack
>              |____ErrorStack.4dbase
>                    |____ErrorStack.4DC
>         |____MessageHub
>              |____MessageHub.4dbase
>                    |____MessageHub.4DC
>                         Components
>                          |____ErrorStack
>                               |____ErrorStack.4dbase
>                                    |____ErrorStack.4DC
>
> See what I'm saying? Does the above work? I'm asking without trying because
> others already know and I'm running out of time I'm willing to devote to
> basic research on 4D components in V16.

4D supports only a single level of components. You can’t have components inside of components. It would be a nice feature to have in some situations.

> 4D components are weird because they have their own little variable space -
> but where is it? How do you address it? More to the point, how do you know
> when you're address it? It's sort of within the current process. But you
> can't address it specifically. It makes the code pointlessly hard to
> follow. The component isn't a runtime object, it's something baked right
> into the code. I don't even know what you call that.

I think we sometimes forget that 4D is not a 3GL programming language like C or C++. 4D is a 4GL language. You don’t get all the feature, benefits and capabilities of a 3GL language in a 4GL language. Remember why we all use 4D instead of using C++. You can get so much more done with 4D in less time and with less programming effort than doing it in C++.

4D provides many things that you can get from 3GL languages with less effort but with limitations. If you want something without the limitations you can have it, but not with 4D. Switch to C++ and you can have everything that you want. But then you will have to build it yourself or use code libraries and frameworks others have built. And that’s brings it’s own set of problems and issues to deal with.

Also 4D is an environment that has a long history with a tremendous amount of legacy support. To provide many new features and capabilities that many want could quite possibly require dropping legacy support. And that means you might have to start over from scratch. Can’t upgrade from an older version of 4D.

I’m sure the 4D engineers, when they were designing the component architecture, did the best they could in the 4D environment they were working with. They had to work within a system that they already had. They couldn’t start from scratch. They had to integrate components into the existing 4D environment. And that includes supporting the 4D Compiler.

Consider the complexities of integrating components that may or may not be compiled and then building a final compiled 4D application incorporating these components. Now include a multi-level component architecture that goes n levels deep. Think 4D compiler linking nightmares.

Makes me think of the proverb “You can’t have you cake and eat it too”. :)

Tim

********************************************
Tim Nevels
Innovative Solutions
785-749-3444
[hidden email]
********************************************

**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
You can have components calling other components from within a host
database.

Host
Component A
Component B

Option 1:  Easy!
If Component A calls B, then during development of A you need to have a
copy of B in its component folder.  To compile Comp A you must have a
compiled version of Comp B.

Then in the host you have Comp A & B in the host's component folder but not
the Comp B component within the Comp A (as required during development).

Option 2:  Not so easy
Comp A calls B and Comp B calls A
In order to compile A you need a compiled B in A's component folder.  In
order to compile B you need to have a compiled A in B's component folder.
See the problem?
That's where EXECUTE METHOD comes into play.  Using EXECUTE METHOD you can
call B from A and effectively hide it from the compiler.  However there's a
speed hit for that but it is possible.

Last thought:
When building your component please go to the fourth tab (Plugins &
Components) and turn OFF all the plugins and components that you don't
use.  Otherwise you'll get messages about 4D SVG (for example) needing to
be recompiled because you said it was required.



Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>


On 21 April 2017 at 10:44, Tim Nevels via 4D_Tech <[hidden email]>
wrote:

> > On Apr 20, 2017, at 6:04 PM,David Adams wrote:
> >
> > That makes sense. I guess what I'm trying to get advice on is how to
> share
> > utility code with a host and other components:
> >
> > MyBigDatabase
> > |____Components
> >         |____ErrorStack
> >              |____ErrorStack.4dbase
> >                    |____ErrorStack.4DC
> >         |____MessageHub
> >              |____MessageHub.4dbase
> >                    |____MessageHub.4DC
> >                         Components
> >                          |____ErrorStack
> >                               |____ErrorStack.4dbase
> >                                    |____ErrorStack.4DC
> >
> > See what I'm saying? Does the above work? I'm asking without trying
> because
> > others already know and I'm running out of time I'm willing to devote to
> > basic research on 4D components in V16.
>
> 4D supports only a single level of components. You can’t have components
> inside of components. It would be a nice feature to have in some situations.
>
> > 4D components are weird because they have their own little variable
> space -
> > but where is it? How do you address it? More to the point, how do you
> know
> > when you're address it? It's sort of within the current process. But you
> > can't address it specifically. It makes the code pointlessly hard to
> > follow. The component isn't a runtime object, it's something baked right
> > into the code. I don't even know what you call that.
>
> I think we sometimes forget that 4D is not a 3GL programming language like
> C or C++. 4D is a 4GL language. You don’t get all the feature, benefits and
> capabilities of a 3GL language in a 4GL language. Remember why we all use
> 4D instead of using C++. You can get so much more done with 4D in less time
> and with less programming effort than doing it in C++.
>
> 4D provides many things that you can get from 3GL languages with less
> effort but with limitations. If you want something without the limitations
> you can have it, but not with 4D. Switch to C++ and you can have everything
> that you want. But then you will have to build it yourself or use code
> libraries and frameworks others have built. And that’s brings it’s own set
> of problems and issues to deal with.
>
> Also 4D is an environment that has a long history with a tremendous amount
> of legacy support. To provide many new features and capabilities that many
> want could quite possibly require dropping legacy support. And that means
> you might have to start over from scratch. Can’t upgrade from an older
> version of 4D.
>
> I’m sure the 4D engineers, when they were designing the component
> architecture, did the best they could in the 4D environment they were
> working with. They had to work within a system that they already had. They
> couldn’t start from scratch. They had to integrate components into the
> existing 4D environment. And that includes supporting the 4D Compiler.
>
> Consider the complexities of integrating components that may or may not be
> compiled and then building a final compiled 4D application incorporating
> these components. Now include a multi-level component architecture that
> goes n levels deep. Think 4D compiler linking nightmares.
>
> Makes me think of the proverb “You can’t have you cake and eat it too”. :)
>
> Tim
>
> ********************************************
> Tim Nevels
> Innovative Solutions
> 785-749-3444
> [hidden email]
> ********************************************
>
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> FAQ:  http://lists.4d.com/faqnug.html
> Archive:  http://lists.4d.com/archives.html
> Options: http://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Tim, I finally said "what the heck" and am giving my blunt opinions below.
Don't take the torrent as directed at you. I think that you made an
intelligent and high-level argument. I mean, you're wrong, but at I don't
hold that against you ;-) That's not an ironic smiley face...I grew up in
schools where the whole class period might be spent fighting about stuff.
They thought it was good for us. In a way, it was...in another way, not so
much.

> 4D supports only a single level of components. You can’t have components
> inside of components. It would be a nice feature to have in some
situations.

Thanks for the confirmation. This makes 4D components pretty much a
non-starter for me. I can see how if you know this (and the other)
restrictions in mind, you could do an okay job. As an example, Cannon's
Obj_ module isn't a component, but I just compiled it to one and, so far,
it seems fine.

> I think we sometimes forget that 4D is not a 3GL programming language
like C
> or C++. 4D is a 4GL language. You don’t get all the feature, benefits and
> capabilities of a 3GL language in a 4GL language. Remember why we all use
4D
> instead of using C++. You can get so much more done with 4D in less time
and
> with less programming effort than doing it in C++.

I appreciate your point, but don't forget for a minute that 4D is what it
is. Then again, the language hasn't been improved since the 1980s, and that
has nothing whatever to do with it being a nGL. I tend to think of it as a
structure language because, well, it's sort of a subset of Pascal. Pascal
is famous as a structured language because that's where it comes form. Many
structure paradigms are with us today, albeit in different outfits, and
many new concepts have been added as computer science has advanced.
Structure programming was *obsessed* with the flow of control through the
system and the use of proper control structures. We've got the basics in 4D
(and always have)

If...then...else
Begin...end (in various flavors)
Case of...

That's it. The 4D collection is somewhat simplified, but that's not all
bad. I like 4D's version of the case structure, for example, although a
purist would declare it Forever Unclean! Case was meant to be a clean way
of doing a multi-part if. More like a switch in a lot of languages. 4D lets
you combine different tests in the same structure. Nice, but less easy to
test formally. Back in the Day, Dijkstra and the crew really believed that
it would be possible to prove the correctness of computer programs, like
math proofs. They tried, made a ton of progress, gave us some great ideas
and practices...and realized that formal proofs weren't going to happen.
(The world of formally correct program still exists, but tends not to use
languages anything like Pascal or C++, for that matter.)

Structured Programming wanted there to be a single point of entry for any
method, and a single exit. Again, obsessed with testable and predictable
code. It was a different world, when "GOTO considered harmful" came out,
the basic control structures that we can take for granted didn't exist. We
take them for granted now because they solved a fundamental problem that
didn't change. The point of Pascal was to make the language itself remove
entire categories of problem before they ever happened. (As is the
motivation for many new languages.)

So, way back in the day, before 4D, we had things like:

* Semaphores
* Constants
* Message queues
* Records (structs, the basis of Abstract Data Types, part of what evolved
into Objects)
* Enumerated types
* Domains (custom types defined by a range of possible values)
...and more.

When was this? The late 1970s? I'm not talking about anything particularly
modern or particularly hard. Man, our life would be *so* much easier with
what Pascal called 'records' and C called 'structs." Here, I just dug up a
Pascal example:

type
record-name = record
   field-1: field-type1;
   field-2: field-type2;
   ...
   field-n: field-typen;
end;
Here is the way you would declare the Book record −

type
Books = record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: integer;
end;
The record variables are defined in the usual way as

var
   r1, r2, ... : record-name;
Alternatively, you can directly define a record type variable as −

var
Books : record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: integer;
end;

4D could throw in with some syntactic sugar to make it look less geeky but,
honestly, how hard is that? It's *vastly* simpler than trying to do
something like that with C_OBJECT. with C_OBJECT, you get a kind of data
structure, but you get *no* help from the compiler on type validation.
Beyond that, the 4D language's incomplete support for JSON makes it
*impossible* to retrofit your own meta-data/schema system to (laboriously)
do your own type enforcement.

Man, wouldn't it be nice if you had a structure defining, oh, let's say a
process setup:

$customers := New(ProcessSetup)
$customers.name  := "Customers"
$customers.table := ->MyBigArrayOfStuff
$customers.max_rows := 100

...and then the 4D compiler kicks back the obvious error:

    $customers.table points to an array instead of a table.

So much easier and better than what we have today. Despite using dots,
that's not an object. It's a typed data structure. We need it, we've always
needed it, and it's easier than what we've got now.

Since I've used 4D, here's what they've added to the language:

    Processes
    GOTO or eval in a variety of sexy skirts

That's it. I'm afraid that the Structured Programming's prohibition on
GOTO, which was broadly misunderstood, has lead to an avoidance of proper
approaches to exception handling. There just isn't a better way to do
exceptions or other interrupts than a goto. I mean, regardless if it is
managed through a callback or a control structure, regardless of what you
get (an event record or object, a code, whatever), it's still formally a
goto. What else would it be? Right now we've got ON ERR CALL and it doesn't
really work reliably or universally. What we need is something more like
Try/Catch.

Why am I talking about Structured Programming at all?
-- Because 4D came from Pascal

-- Because Pascal came form Structured Programming

-- Because Structured Programming came from Dijkstra thinking hard and well
about the complete nightmare that was code in his day. (I just read up on
him and have a total nerd crush. The guy was intense and amazing. We owe
him, well, almost everything. there is a straight line form him through to
the most advanced languages today.)

> 4D provides many things that you can get from 3GL languages with less
effort
> but with limitations. If you want something without the limitations you
can
> have it, but not with 4D. Switch to C++ and you can have everything that
you
> want.

Yeah, it won't be C++. I also think your argument is a bogus. I mean, 4D
has added tons of features down the years, why on earth couldn't they
improve the language? Why is this most fundamental and important of
features supposed to be "take it or leave it." That may well be the case
(it seems to be), but I completely reject that there's a defensible reason
for this. You could easily have a 4DGL with a better language (Delphi!)
Plenty have existed. An improved language would be a huge benefit to us,
reduce bugs, make it easier for us to scale out our code, etc. I'm not
asking them to reject their structured roots, I'm asking them to embrace
them. Instead, they've been bolting on yet more versions of EXECUTE (eval),
which is about as antithetical to structured principles as you can possible
get. And no scaffolding. They don't protect us at all with EXECUTE in its
many forms. I mean, the amount of time poured into object fields. Object
fields? Why? It's a feature to be used sparingly, if at all. Cool when you
need it, but if you need it often - you are definitely are misunderstand
something. But the core language features? EVERYONE benefits from
improvements there.

And again, I'm not asking for 4D to do a completely new language. No
thanks, we have a zillion modern languages to choose from. I'm asking for a
sensible evolution of the language:

* Data structures that were in Pascal back when 4D was a baby.
* Exception handling like any sensible language.

Those two alone would help improve quality by huge, huge amounts.

> Also 4D is an environment that has a long history with a tremendous
amount of
> legacy support.

For sure. And there is no end to my respect for 4D for maintaining support
so well for so long. They have done an amazing job, and not one to be taken
for granted. I don't think anyone even comes close to them in this area.
Kudos^2. We should all be grateful. I am.

> To provide many new features and capabilities that many want
> could quite possibly require dropping legacy support.

Adding structures? Nope, that breaks absolutely nothing. Improving
exception handling? That might. Well, it also might because silent
exceptions now appear. But if they added it through a new control structure
(try/catch), then, presumably, old code could work as it does until you
choose to use the new structure.

> I’m sure the 4D engineers, when they were designing the component
> architecture, did the best they could in the 4D environment they were
working
> with. They had to work within a system that they already had. They
couldn’t
> start from scratch. They had to integrate components into the existing 4D
> environment. And that includes supporting the 4D Compiler.

Sure, but that doesn't mean that they came up with a great solution, albeit
perhaps the best they could. Given how various features have been
implemented in the past few years, I don't get the impression they've got a
language guy on the team. They're a special breed and a bit rare. I never
hear anything out of France that sounds like they've been thinking about
the language itself.

Anyway, I've tossed everything I need into one giant component and then
compiled OJB_Module on its own. (It's in my big component but not shared.)
I'll try it out and see how it goes. If it works and keeps all of the
distracting plumbing out of view, I'll try and use it.

> Consider the complexities of integrating components that may or may not be
> compiled and then building a final compiled 4D application incorporating
these
> components. Now include a multi-level component architecture that goes n
> levels deep. Think 4D compiler linking nightmares.

Yes, a linker. That's what's needed. Otherwise, it leaves us with not so
many great choices. If they did the linker, we would all benefit. Linkers
aren't exactly a modern tool - there's plenty of existing art out there.

> Makes me think of the proverb “You can’t have you cake and eat it too”. :)

I'm pro cake! I'm pro eating it, and I'm pro having it.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
Thanks Wayne, so for development:

MessageHub
   Components
      ErrorStack

For deployment

Host
    Components
         ErrorStack
         MessageHub  (no ErrorStack component here)

Host calls ErrorStack
MessageHub calls ErrorStack

In development of MessageHub, it calls ErrorStack in its Components folder.

In deployment Host and MessageHub bot call ErrorStack in
   Host/Components/ErrorStack

Is that right? If so, I can deal with that. Seems okay to me. Much better
than I feared. It looks like it satisfies Tim's rule of components nesting
to only one level...it's still just one level at a time. If this does work,
it's because there really is only one project-wide method namespace - so
whoever looks for a method finds the 'closest' one, I guess.

I won't use the EXECUTE METHOD across components. Sounds like the tool of
Satan. Not sure, but it smells of sulphur...
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
Speaking of nerd crushes, here are the names of people that I find
particularly inspirational for the broad and lasting contributions they've
made (or are making) to our fields. Other people will have their own
equally sensible lists:

Mike Bostock
Edsger W. Dijkstra
Martin Fowler
Steve McConnell
Bertrand Meyer
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Components: How do you reuse utility code?

4D Tech mailing list
In reply to this post by 4D Tech mailing list
One of the big pluses of EXECUTE METHOD is working around does this exist?
If the component is present run this method if it isn't don't try.

And of course, it completely hides the need for a component from 4D.  This
can be very useful.

On a number of occasions I've tried to open a structure and it says NO -
you need the component, that's it. End of story.  Can't open in interpreted
mode even because the component is missing.

The specific circumstance this occurs is if Comp A needs Comp B but when
launching Host Comp B is not present.  To get around that particular
problem, remove Comp A from Host so it doesn't check Comp A's requirements.



Regards,

Wayne


[image: --]
Wayne Stewart
[image: http://]about.me/waynestewart
<http://about.me/waynestewart>


On 21 April 2017 at 11:48, David Adams via 4D_Tech <[hidden email]>
wrote:

> Thanks Wayne, so for development:
>
> MessageHub
>    Components
>       ErrorStack
>
> For deployment
>
> Host
>     Components
>          ErrorStack
>          MessageHub  (no ErrorStack component here)
>
> Host calls ErrorStack
> MessageHub calls ErrorStack
>
> In development of MessageHub, it calls ErrorStack in its Components folder.
>
> In deployment Host and MessageHub bot call ErrorStack in
>    Host/Components/ErrorStack
>
> Is that right? If so, I can deal with that. Seems okay to me. Much better
> than I feared. It looks like it satisfies Tim's rule of components nesting
> to only one level...it's still just one level at a time. If this does work,
> it's because there really is only one project-wide method namespace - so
> whoever looks for a method finds the 'closest' one, I guess.
>
> I won't use the EXECUTE METHOD across components. Sounds like the tool of
> Satan. Not sure, but it smells of sulphur...
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> FAQ:  http://lists.4d.com/faqnug.html
> Archive:  http://lists.4d.com/archives.html
> Options: http://lists.4d.com/mailman/options/4d_tech
> Unsub:  mailto:[hidden email]
> **********************************************************************
>
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[hidden email]
**********************************************************************
12