Go watch Thomas Maul's presentation. Now.

2016-09-02 Thread David Adams
I wasn't able to tune into this 4DMethod user group presentation live but
caught it later. First off, thanks to Brent Raymond for doing such a great
job with 4DMethod. I don't know if everyone is taking advantage of this
great resource. Given the various time zones we all live in, having
presentations available for playback at any time is *massively* helpful.
There are lots of good presentations up there so check it out.

Anyway, for anyone expecting to continue working with 4D down the versions,
go watch this excellent presentation now! There's an embedded link to the
presentation here at the moment:

https://4dmethod.com/

The meeting starts with the usual helpful reviews of 4D news and business,
NUG threads and pointers to KB of interest. There's a bit of a technical
glitch in the middle and if you want to skip through that, move to between
36 and 37 minutes. (36:45 when I watched,)

I haven't been in 4D fanboi mode on this list much lately, so excuse me
while I gush a bit. You know how sometimes 4D makes you scratch your head
and then other times it takes your breath away because it does something so
elegantly? This is one of those "check it out, it's so elegant" times. So
check it out!

Many old-timers will recall that I've said "SET PROCESS VARIABLE is evil"
more than once. Without belaboring my entirely reasonable and balanced
position ;-), 15 R5/16.0 (ish) bring a new and fundamentally improved
native interprocess/inter-window communication systems. Thomas' demos are
clear and persuasive. The upcoming features aren't going to allow for every
type/pattern of message queue that you might want, but they do allow for
some very helpful and common ones.

* Passing messages between windows in one process or across processes on
one machine with CALL FORM (perhaps it should be named CALL WINDOW?). This
makes complex UI code way simpler to implement and more efficient to run.

* Passing messages between processes with CALL WORKER.

* In both cases, 'messages' are a method call with whatever parameters you
need. Thomas doesn't discuss it, but an obvious strategy is to pass JSON
objects. Then again, you can pass simple parameters as well, which can be
even easier to read and write. Your choice.

* Thread-safe, pre-emptive, avoids globals and semaphores, very efficient
polling, etc. Yeah, nicely done 4D.

I've been writing message queues in 4D for a really long time...the first
one was at 4D years ago to generate plug-in serial numbers. (There was a
special plug-in to do it that was tied to a single machine...and there was
no sort of RPC system in 4D Server at the time.) I figured out SET PROCESS
VARIABLE & friends enough to see their downsides and never used them again.
(I also never used subtables in productions after the first attempt, for
that matter.) Instead, I use record-based queues (which I still like) and
IPC communication with NTK (which I also still like.) The new commands
looks extremely well thought out and deceptively easy to use. (Meaning, you
could be forgiven for not even knowing how much complexity 4D is sheltering
you from, and how well they're doing it.) If you've done any sort of
queuing work yourself, you'll quickly appreciate that the new approach is
one of those areas where 4D is hitting it out of the park. Like I said
early, excuse my gushing...but this is an awesome set of features.

Note that the demo is showing features in unreleased versions so things may
change (improve). For example, it appears that the message queues die if 4D
shuts down or crashes. This is absolutely fine for some uses and a
deal-breaker for others. Perhaps CALL WORKER will gain an option to retain
unprocessed messages?

P.S. If anyone is interested in multi-platform queuing solutions, ping me.
I'm diving into RabbitMQ these days and it's sweet. Welsh Harris turned me
onto IronMQ and it also looks pretty great. It's more similar
architecturally to AWS's SQS than RabbitMQ but any of these three are
solid-looking choices for scalable, distributed systems.
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-02 Thread Brian Young
David, thank you for this writeup. :)

I also want to thank Brent and Ed for putting so much effort in to making a 
active, growing, online usergroup. Plus, thank you for inviting 4D to to 
participate. (including the 'hey 4D' hot seat)

You should watch the entire meeting. It's is worth the time.  But, if you would 
like a direct link to skip the technical difficulties, you can jump to here:

https://youtu.be/eEjrHR2BelE?t=36m57s

-Brian



On Sep 2, 2016, at 9:35 AM, David Adams 
mailto:dpad...@gmail.com>> wrote:

I wasn't able to tune into this 4DMethod user group presentation live but
caught it later. First off, thanks to Brent Raymond for doing such a great
job with 4DMethod. I don't know if everyone is taking advantage of this
great resource. Given the various time zones we all live in, having
presentations available for playback at any time is *massively* helpful.
There are lots of good presentations up there so check it out.

Anyway, for anyone expecting to continue working with 4D down the versions,
go watch this excellent presentation now! There's an embedded link to the
presentation here at the moment:

https://4dmethod.com/

The meeting starts with the usual helpful reviews of 4D news and business,
NUG threads and pointers to KB of interest. There's a bit of a technical
glitch in the middle and if you want to skip through that, move to between
36 and 37 minutes. (36:45 when I watched,)

I haven't been in 4D fanboi mode on this list much lately, so excuse me
while I gush a bit. You know how sometimes 4D makes you scratch your head
and then other times it takes your breath away because it does something so
elegantly? This is one of those "check it out, it's so elegant" times. So
check it out!

Many old-timers will recall that I've said "SET PROCESS VARIABLE is evil"
more than once. Without belaboring my entirely reasonable and balanced
position ;-), 15 R5/16.0 (ish) bring a new and fundamentally improved
native interprocess/inter-window communication systems. Thomas' demos are
clear and persuasive. The upcoming features aren't going to allow for every
type/pattern of message queue that you might want, but they do allow for
some very helpful and common ones.

* Passing messages between windows in one process or across processes on
one machine with CALL FORM (perhaps it should be named CALL WINDOW?). This
makes complex UI code way simpler to implement and more efficient to run.

* Passing messages between processes with CALL WORKER.

* In both cases, 'messages' are a method call with whatever parameters you
need. Thomas doesn't discuss it, but an obvious strategy is to pass JSON
objects. Then again, you can pass simple parameters as well, which can be
even easier to read and write. Your choice.

* Thread-safe, pre-emptive, avoids globals and semaphores, very efficient
polling, etc. Yeah, nicely done 4D.

I've been writing message queues in 4D for a really long time...the first
one was at 4D years ago to generate plug-in serial numbers. (There was a
special plug-in to do it that was tied to a single machine...and there was
no sort of RPC system in 4D Server at the time.) I figured out SET PROCESS
VARIABLE & friends enough to see their downsides and never used them again.
(I also never used subtables in productions after the first attempt, for
that matter.) Instead, I use record-based queues (which I still like) and
IPC communication with NTK (which I also still like.) The new commands
looks extremely well thought out and deceptively easy to use. (Meaning, you
could be forgiven for not even knowing how much complexity 4D is sheltering
you from, and how well they're doing it.) If you've done any sort of
queuing work yourself, you'll quickly appreciate that the new approach is
one of those areas where 4D is hitting it out of the park. Like I said
early, excuse my gushing...but this is an awesome set of features.

Note that the demo is showing features in unreleased versions so things may
change (improve). For example, it appears that the message queues die if 4D
shuts down or crashes. This is absolutely fine for some uses and a
deal-breaker for others. Perhaps CALL WORKER will gain an option to retain
unprocessed messages?

P.S. If anyone is interested in multi-platform queuing solutions, ping me.
I'm diving into RabbitMQ these days and it's sweet. Welsh Harris turned me
onto IronMQ and it also looks pretty great. It's more similar
architecturally to AWS's SQS than RabbitMQ but any of these three are
solid-looking choices for scalable, distributed systems.
**
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:4d_tech-unsubscr...@lists.4d.com
**

**
4D Internet Users Group

Re: Go watch Thomas Maul's presentation. Now

2016-09-02 Thread Tim Nevels
On Sep 2, 2016, at 1:36 PM, Brian Young wrote:

> I also want to thank Brent and Ed for putting so much effort in to making a 
> active, growing, online usergroup. Plus, thank you for inviting 4D to to 
> participate. (including the 'hey 4D' hot seat)
> 
> You should watch the entire meeting. It's is worth the time.  But, if you 
> would like a direct link to skip the technical difficulties, you can jump to 
> here:

I agree with Brian and David. I was at the Thomas Maul 4D Method presentation. 
Is that the right way to say I was watching on Google Hangout? Thomas gave a 
great presentation with a lot of detail, and examples. Everyone should see it 
and you will learn something new.

I asked a question about advice on how to use the new preemptive system and 
rewriting old code to use the new stuff. The surprising answer from Thomas was 
that he had done this for a project and would advise to not go rewrite old 
code. If it is running now and working, don’t go rewrite it. Leave it alone. He 
did and it introduced bugs that didn’t exist in the old code that was working 
just fine that he then had to go track down and fix. His advice is you are 
better off using the new v16 stuff for new things you need to implement, or to 
redo something that you need to speed up. 

Also another bit of info is on the new v16 data cache system that was announced 
in April at 4D Summit 2016 in Portland. I asked if it would be available in a 
v15R version before v16. Answer was it’s not ready yet. They had hoped it would 
be done and ready to be released in v16.0, but they have found a few issues 
that need to be fixed. So no new v16 cache system in v15R versions and probably 
not in v16.0. But it will be released some time during v16’s life. No need to 
rush in getting the new cache system out. The current one is working just fine. 
Better to make the new version rock solid first and then release it. I think 
that’s the right approach. 

Tim


Tim Nevels
Innovative Solutions
785-749-3444
timnev...@mac.com


**
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:4d_tech-unsubscr...@lists.4d.com
**

RE: Go watch Thomas Maul's presentation. Now

2016-09-04 Thread Thomas Maul
Upfront - thanks for your time watching - and the friendly comments.

> I asked if it would be available in a v15R version before v16. Answer was 
> it’s not ready yet. They had hoped it would be done and ready to be released 
> in v16.0, but they have found a few issues that need to be fixed. So no new 
> v16 cache system in v15R versions and probably not in v16.0. But it will be 
> released some time during v16’s life.

Sorry, it seems I was not clear on this point.
The engine for the new cache manager is done. It was started last Xmas, tested 
intensively and is even already in production usage in some internal systems.
It was NOT ready for 4D v15 R5 through, as reminder:
Every 3 month, usually around the time we  publish a final R-Release, we fork 
the next one.
This means, we take the latest version of our internal source (including all 
features and bug fixes done at that time) and start to REMOVE features. Every 
feature not fully tested is removed (=delayed for a following version).

R5 was forked end of May - at that time we did not finished all testing for the 
cache manager. As the cache manager is a very important part of the database 
server, we had a very long testing planed.

So, it is not in R5. But it will be in v16.

In v16 the cache manager will run in fully automatic mode. Only thing you can 
set/modify is cache size, similar as in current versions.
What's not in v16.x, is a set of features to fine tune the cache usage, to give 
different priorities to specific tables or index, which will improve 
performance even more for very large databases. And this will come with a 
following v16 R Release (development is finished, testing already started, but 
will need more time).

Thomas


4D Deutschland GmbH
Geschäftsführer Laurent Ribardière Telefon: +49-89-856 33 43-0
Amtsgericht München HRB 92258  Fax: +49-89-856 33 43-99
Obere Hauptstrasse 2   E-Mail:  thomas.m...@4d.com
85386 Eching - Deutschland Web: www.4D.com

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-05 Thread Cannon Smith
I also really enjoyed watching the video. It is a subject that I was really 
excited about at the Summit and I appreciate the 4DMethod user group making 
this possible.

In the video, Thomas talked about a new (to 4D) paradigm where all UI related 
code could run on the main thread (the Application process) and background 
processes (workers) could be used for potentially long-running code that 
shouldn't block the main thread. This is exactly what many other environments 
do and would be accomplished by opening all windows using DIALOG(*) from within 
the Application process context and then communicating between threads using 
CALL FORM (I really wish this was named CALL WINDOW) and CALL WORKER. I've been 
mulling this over and am excited about some possibilities, but also see several 
pitfalls that I don't know how to overcome with the current 4D language (at 
least not without slow workarounds). I'm hoping to receive some guidance from 
4D on these thoughts as well as spark discussion from everyone about these new 
features.

(To be clear, Thomas did not recommend converting existing applications to this 
approach. In fact, he recommended _not_ doing so. I have the luxury of having 
just started a new project, so I'm really interested in how this approach might 
work in real life.)

- There has been worry about not being able to access interprocess variables 
from a pre-emptive worker process. If all the windows are in the same process, 
I would expect that quite a few interprocess variables could be converted to 
process variables. These variables could be passed to a worker process when it 
needed to do some work so it had the most recent values. For example, some of 
us keep a list of currently open windows for building a "Windows" menu. 
Probably most of us keep this in an interprocess array right now and protect 
access to it using a semaphore. If all windows (and menus) were in the same 
process, this could become a process array and would not need to be protected 
by a semaphore anymore.

Having said that, I still think there is a need for workers to be able to 
occasionally access shared resources. I hope these features evolve so that 
shared resources can be accessed by protecting with a semaphore or some other 
locking mechanism. I understand that semaphores are somewhat expensive and, if 
used a lot, would negate the usefulness of pre-emptive processes since the 
underlying threads would be blocking so often. But I think they are still 
useful when used judiciously and are really quite fast when needed (just a 
small portion of a millisecond in most cases).

- The documentation says the Application process is automatically a worker 
process. I thought this was interesting because it means that if all an 
application's windows are in this process, we can use CALL FORM to execute code 
within a window's context, but we can also use CALL WORKER to execute code in 
that process, but not tied to a specific window. This "smells" important to me, 
but I can't quite put my finger on why. Something to keep in mind, though.

- I think this paradigm is interesting for progress indicators. I like the idea 
of showing progress right in the window with a spinner or thermometer. My 
current way to show progress is to open a progress window in another process 
since it is a bit tricky to update the UI of a window during the run loop. But 
if a worker process is doing all the work, the progress indicator could be 
shown in the window that started the work and the worker process could use CALL 
FORM periodically to tell it how much work was done. However, I see two 
problems I'm not sure how to overcome:
1. How can the user cancel some work that is being done? If I send a 
message using CALL WORKER to cancel the work, I don't think it gets the message 
until the work is done. Is it possible for a worker process to periodically 
check for new "messages" while in the middle of work? Or would the window 
itself have to chop up the work in some manner and only send the worker a bit 
at a time? That seems much slower as the two processes would have to have back 
and forth communication for each “block” of work.
2. By shifting the work to a worker process, the UI on the window stays 
active. In some cases this is desirable, but in others you may not want the 
user to be able to click or type anything in that window until the work is 
done. Something to consider.

- In my current code, I tend to let almost every window have its own process. 
One reason for this is that the window has full control over selections and 
current records in every table. Even when the widows are array and variable 
based, this is very helpful. It seems like things could get very complicated if 
you had several windows open in the same process. For example, what if two of 
the windows were list windows for the same table and a third table was editing 
a record in that table? I suppose I could use named selections, but they 

Re: Go watch Thomas Maul's presentation. Now.

2016-09-05 Thread Keisuke Miyako
1. has already been covered quite comprehensively by JPR; you got one half of 
the solution (chunking the task), the other half is that the worker calls 
itself recursively, instead of waiting instruction to drip. on a related point, 
when calling a worker (other than yourself), it is important to take into 
account that workers may finish their task in any order, so you need to 
coordinate for than when delegating a task to multiple workers.

2. I guess is will have to be managed logically by disabling the UI, perhaps by 
display a (translucent) image over the entire form.

> 2016/09/06 6:53、Cannon Smith  のメール:
>
>   1. How can the user cancel some work that is being done? If I send a 
> message using CALL WORKER to cancel the work, I don't think it gets the 
> message until the work is done. Is it possible for a worker process to 
> periodically check for new "messages" while in the middle of work? Or would 
> the window itself have to chop up the work in some manner and only send the 
> worker a bit at a time? That seems much slower as the two processes would 
> have to have back and forth communication for each “block” of work.
>   2. By shifting the work to a worker process, the UI on the window stays 
> active. In some cases this is desirable, but in others you may not want the 
> user to be able to click or type anything in that window until the work is 
> done. Something to consider.



宮古 啓介
セールス・エンジニア

株式会社フォーディー・ジャパン
〒150-0043
東京都渋谷区道玄坂1-10-2 渋谷THビル6F
Tel: 03-6427-8441
Fax: 03-6427-8449

keisuke.miy...@4d.com
www.4D.com/JP

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-05 Thread Cannon Smith
Hi Miyako,

I think that makes sense, but let me make sure I understand. Let’s say a window 
needed a worker to process 1000 items in a loop. You are saying that the 
worker’s code should be constructed so that the window can pass the 1000 items 
to it in one message and then the worker will process, say, 10 items and then 
send a message to itself (CALL WORKER?). In most cases the worker will receive 
this message and know to process the next 10 items. But if the window had sent 
a cancel message in the mean time, that will be the message that comes off the 
stack first. So the worker will cancel the job. And I guess it has to be smart 
enough to ignore the last message it sent to itself. Is that correct?

Thanks for the insight.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 5, 2016, at 6:43 PM, Keisuke Miyako  wrote:
> 
> 1. has already been covered quite comprehensively by JPR; you got one half of 
> the solution (chunking the task), the other half is that the worker calls 
> itself recursively, instead of waiting instruction to drip. on a related 
> point, when calling a worker (other than yourself), it is important to take 
> into account that workers may finish their task in any order, so you need to 
> coordinate for than when delegating a task to multiple workers.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-05 Thread David Adams
 On Mon, Sep 5, 2016 at 2:53 PM, Cannon Smith <
can...@synergyfarmsolutions.com>
> wrote: I also really enjoyed watching the video. It is a subject that I
was
> really excited about at the Summit and I appreciate the 4DMethod user
group
> making this possible.

> Thanks for any thoughts!

I'll jump in with a few thoughts...but they don't necessarily address your
problems directly. I've got a different perspective on queues because I
always think of them as multi-machine systems, which totally colors how I
look at queuing and message features.

First off, I'd say there's merit in thinking about CALL WINDOW (let's fact
it, they'll have to rename it CALL WINDOW or CALL FORM WINDOW
eventually...so why don't we pretend it's happened already) and CALL WORKER
as discrete features. They can interact, but they don't need to.
Personally, I'm a lot more interested in CALL WORKER, but CALL WINDOW is
probably vastly more important for UI work in 4D. In any case, I'm just
more interested in CALL WORKER as it relates 4D to the larger world of
messaging more obviously. (And because I really, really like headless tasks
and they're part of my core programming style.)

So, skipping CALL WINDOW for now and thinking about CALL WORKER, here are
some random thoughts:

* Think of tasks that can be processed without thinking how or where.

* If you really want to scale, you want to bring in resources past 4D
server. A generalized message bus can help with this. Instead of everything
having to happen on 4D Server or it's connected clients, you can have
processing happen over a range of clients. They can be written as
stand-alone 4D's, PHP, Python, Ruby, etc. How nice is that? That is very
nice. Very. Put another way, want a great way to get more
cores/thread/optimize 4D Server? Push work out onto other machines running
code outside of 4D Server. For a lot of systems, there are _heaps_ of tasks
that fit well with this. If you don't need to write data back to the 4D
database, you can often farm the work out. (Sending messages,
composing/preparing/building Web pages, generating SMS, performing various
calculations, etc.)

* If you want a generalized message queue...or if you think that you might
want one...pass one parameter as your message, and make that message a JSON
block. This should work fine with CALL WORKER or any other message queue.
The point is that the payload of the message is JSON with whatever data you
need...the mechanics of message transfer can be modified, as needed. For
example, you might start with CALL WORKER, then move to SQS and 4D
stand-alones that read the messages. This transition could be pretty tidy.

* Yeah, push rather than pull-polling. The wrong polling model for messages
can really kill performance and throughput for no gain. Don't think of
client-server, think of publisher & consumer. And don't think of them as
bits of software think of them as roles in a message exchange. Thomas has a
nice sort of example of this as an aside in his talk. When you're
implementing an RPC pattern with EXECUTE ON SERVER, he says not to poll the
server from the client but, instead, to use EXECUTE ON CLIENT from the
server to the client to deliver finished results. Lots more efficient
because there isn't any extra checking for incomplete results. In this
example, the client calls the server and the server calls the client. So,
"client" and "server" don't mean anything - you've got one piece of
software sending a message to another. More like email than a Web server.

* IP variables, semaphores, etc. Forget it. Brittle, not going to persist,
4D specific, can't scale, a real headache. I've written code to do all of
that, it can work perfectly...but it's easy to break. Use records. Just to
be entirely clear, I'm not saying that IP variables (etc.) can't be
programmed to work perfectly, I'm saying that it's a dead-end. It hasn't
made sense in server-side programing for a long time. (Read: Since day 1.)
If it doesn't work in triggers, it probably doesn't make sense in other
server side code. Just my opinion, but this time I'm right ;-)

* Speaking of records, you can have the fanciest message bus on earth and
there are _still_ times when you're going to need a database to track
state/condition of a task, make message persist, log things, etc. Not
strange...very normal. Given that, if you've got very complex or large data
to transfer, you can stash it in a record and then your message JSON should
include a reference to the record so that the worker can retrieve all of
the required details. This strategy will prepare you to deal with
cloud-based message queues which often have fairly restrictive message
payload limits.

* But what if I'm in a transaction! Not a problem for me that often, but
CALL WORKER gets around that quite beautifully in most scenarios that I can
think of - you just threw the problem over the wall into another process.

* Regarding passing selections, etc. A traditional (non-4D) way of dealing
with this is to 

Re: Go watch Thomas Maul's presentation. Now.

2016-09-07 Thread John DeSoi
Great presentation, I'm also excited about the upcoming features. Here are some 
thoughts about the implementation details. 

CALL WORKER and CALL FORM are adding more 4D commands that take a method name 
as string. 4D does not have anything like closures or procedure pointers, so it 
introduces even more ways to break your code when you change a method name that 
is embedded somewhere as a string (or even a generated string). Don't forget 
about ON ERR CALL, New Process, and EXECUTE METHOD. It seems trivial to fix - 
just add a command, e.g. "Method name", that takes the *tokenized* method name 
and returns the method name as a string for use in any of the above commands. 
Now the design environment can really tell you where the method is referenced. 
If you agree, vote for the future request here:

http://forums.4d.fr/Post/EN/17984703/1/17984704


My second concern is that a method cannot be preemptive if it calls a 
non-preemptive command. Any any callers of that method also cannot be 
preemptive. A compile time error is generated in all cases.

This seems like an extreme limitation when it would be easy to arrange for the 
method to conditionally avoid calling the non-preemptive commands when in 
preemptive mode. Developers do this all the time for generic methods that need 
to be run in different contexts. A method that runs on the server can't show a 
user interface and it is easy to adjust the method to do something different 
when it runs on the server.

The compile time error means that separate methods for the same functionality 
will often need to be created. For example, I have a "NET_Send" method which 
can transport a blob using a plugin or HTTP Post. Assuming the HTTP Post method 
allows preemption but the plugin does not, I now have to split that into two 
separate methods. If there are hundreds of callers to the original method, now 
I have to change all of that code creating duplicate methods just so one option 
can work in preemptive mode.

Why not provide an option to get compile warnings instead of errors? Would it 
be that difficult for the compiler just to emit a runtime error if a 
non-preemptive command was called in a preemptive process?

Looking forward to v16!

John DeSoi, Ph.D.



> On Sep 5, 2016, at 4:53 PM, Cannon Smith  
> wrote:
> 
> I also really enjoyed watching the video. It is a subject that I was really 
> excited about at the Summit and I appreciate the 4DMethod user group making 
> this possible.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-07 Thread Keisuke Miyako
in reality, "preemptive or not" is a property of the thread, not the method.
the compiler needs to now how to start a thread before your code reaches a 
conditional statement.

a warning won't work, you will simply get a runtime error even if you find a 
way to "fool" the compiler.
(for example, by conjuring a method name passed to "New process" by string 
concatenation)

the idea is to leave all method properties to "agnostic",
and only set "preemptive" for methods that specifically start a process 
(=thread);
via New process, Execute on server, or a menu item.

all generic subroutines will simply inherit the property of the thread in which 
it was called.

no need for duplicates.

> 2016/09/08 10:25、John DeSoi  のメール:
>
> The compile time error means that separate methods for the same functionality 
> will often need to be created. For example, I have a "NET_Send" method which 
> can transport a blob using a plugin or HTTP Post. Assuming the HTTP Post 
> method allows preemption but the plugin does not, I now have to split that 
> into two separate methods. If there are hundreds of callers to the original 
> method, now I have to change all of that code creating duplicate methods just 
> so one option can work in preemptive mode.
>
> Why not provide an option to get compile warnings instead of errors? Would it 
> be that difficult for the compiler just to emit a runtime error if a 
> non-preemptive command was called in a preemptive process?



宮古 啓介
セールス・エンジニア

株式会社フォーディー・ジャパン
〒150-0043
東京都渋谷区道玄坂1-10-2 渋谷THビル6F
Tel: 03-6427-8441
Fax: 03-6427-8449

keisuke.miy...@4d.com
www.4D.com/JP

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-08 Thread John DeSoi
No need for duplicates as long as I don't care about having any pre-emptive 
processes, right? In the current design, the method that starts the process and 
every method in it's call chain must have only pre-emptive commands if I want 
it to run in pre-emptive mode. Correct?

John DeSoi, Ph.D.


> On Sep 7, 2016, at 10:46 PM, Keisuke Miyako  wrote:
> 
> the idea is to leave all method properties to "agnostic",
> and only set "preemptive" for methods that specifically start a process 
> (=thread);
> via New process, Execute on server, or a menu item.
> 
> all generic subroutines will simply inherit the property of the thread in 
> which it was called.
> 
> no need for duplicates.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-13 Thread Cannon Smith
I got to wondering how expensive it really is to used named selections 
everywhere and then move them to the current selection to do some work on them 
and then back again. It turns out that it is really fast if you use CUT NAMED 
SELECTION and USE NAMED SELECTION to move it back and forth and it doesn’t seem 
to matter how many records are in the named selection. I suspect that when 
using these two commands, internally 4D just updates a pointer or something 
like that.

To test I created selections of varying sizes and then moved them into a named 
selection and then back into the current selection thousands of times. Each 
cycle averaged 3-8 microseconds (not milliseconds)!

Maybe there are other gotchas I’m not thinking of, but based on these tests it 
seems like it would be possible to have all an application’s windows in the 
main process as long as they all used named selections and just moved them 
temporarily into the current selection to work on it before moving it back into 
the named selection.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 5, 2016, at 3:53 PM, Cannon Smith  
> wrote:
> 
> - In my current code, I tend to let almost every window have its own process. 
> One reason for this is that the window has full control over selections and 
> current records in every table. Even when the widows are array and variable 
> based, this is very helpful. It seems like things could get very complicated 
> if you had several windows open in the same process. For example, what if two 
> of the windows were list windows for the same table and a third table was 
> editing a record in that table? I suppose I could use named selections, but 
> they seem limited. For example, I don't know how to programmatically ask a 
> named selection to sort itself a certain way without making it the current 
> selection and then pushing the current selection back into the named 
> selection. Is this an expensive operation? I don't know as I've not tested 
> it. Intuitively it seems like it would be. It is certainly expensive code 
> wise in the sense that I'd have to remember to never accidentally use the 
> current selection except to do temporary work for a named selection.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-13 Thread Tim Nevels
On Sep 13, 2016, at 2:00 PM, Cannon Smith wrote:

> I got to wondering how expensive it really is to used named selections 
> everywhere and then move them to the current selection to do some work on 
> them and then back again. It turns out that it is really fast if you use CUT 
> NAMED SELECTION and USE NAMED SELECTION to move it back and forth and it 
> doesn’t seem to matter how many records are in the named selection. I suspect 
> that when using these two commands, internally 4D just updates a pointer or 
> something like that.

You are exactly correct. I remember many years ago at a DEVCON, that was before 
the 4D Summits, Laurent speaking about named selections and how doing a CUT 
NAMED SELECTION was super efficient because it just copied a 4 byte pointer to 
the current selection to another location with a name assigned to it.  Same for 
the USE SELECTION. Internally it is just a quick pointer assignment. 

This was back with 4D Server v1 and Macintosh 68K CPUs. A great 4D Server 
machine back then was a Quadra 900 with a 25MHz 68040 processor and 16MB or 
RAM. Yeah, 16 megabytes. The Quadra 900 had a list price of $8,500 in 1991. 

Tim


Tim Nevels
Innovative Solutions
785-749-3444
timnev...@mac.com


**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-13 Thread Cannon Smith
Hi Tim,

I suspected as much. Thanks for the confirmation!

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 13, 2016, at 2:27 PM, Tim Nevels  wrote:
> 
> You are exactly correct. I remember many years ago at a DEVCON, that was 
> before the 4D Summits, Laurent speaking about named selections and how doing 
> a CUT NAMED SELECTION was super efficient because it just copied a 4 byte 
> pointer to the current selection to another location with a name assigned to 
> it.  Same for the USE SELECTION. Internally it is just a quick pointer 
> assignment. 
> 

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-13 Thread Keisuke Miyako
2 tips:

1.

CUT NAMED SELECTION doesn't unload the current record;
the current selection will be empty but you keep an out-of-selection current 
record.

2.

you need to touch the highlight set after a CUT/COPY sequence on a listbox

e.g.

CUT NAMED SELECTION([Invoice];"$temp")
USE SET("$List1Highlight")
RELATE MANY SELECTION([InvoiceDetail]invoice)
USE NAMED SELECTION("$temp")

//release the current record
UNLOAD RECORD([Invoice])

//touch to force redraw
COPY SET("$List1Highlight";"$List1Highlight")

> 2016/09/13 23:57、Cannon Smith  のメール:
>
> Maybe there are other gotchas I’m not thinking of



宮古 啓介
セールス・エンジニア

株式会社フォーディー・ジャパン
〒150-0043
東京都渋谷区道玄坂1-10-2 渋谷THビル6F
Tel: 03-6427-8441
Fax: 03-6427-8449

keisuke.miy...@4d.com
www.4D.com/JP

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-13 Thread Cannon Smith
Good to know. Thanks, Miyako!

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 13, 2016, at 3:21 PM, Keisuke Miyako  wrote:
> 
> 2 tips:

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Kirk Brooks
Cannon,
What's the benefit of doing that? In my typical work I deal with things
that want to be open in multiple windows, like sales orders, items, trips,
etc. So I haven't based anything on the 'traditional' output form/input
form / drill-down architecture for - a really long time. Is that the kind
of situation this would be a benefit for?

It is cool to know these things are so speedy and have such low overhead.

On Tue, Sep 13, 2016 at 7:57 AM, Cannon Smith <
can...@synergyfarmsolutions.com> wrote:

>  it seems like it would be possible to have all an application’s windows
> in the main process as long as they all used named selections and just
> moved them temporarily into the current selection to work on it before
> moving it back into the named selection.
>


-- 
Kirk Brooks
San Francisco, CA
===
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Chip Scheide
maybe a bit late -
the biggest problem with named selections
they are static.
unlike a set, you can simply add or remove records from a named 
selection.

Of course adding or removing records from a named selection would also 
require resorting.
So the cost of using a named selection increases - possible a lot - if 
you are trying to use them in a context where you need to add/delete 
from the selection.

Also - depending on the sorting complexity, the sort could be 
'expensive'
a simple sort on a field of the table in the named selection is not too 
expensive,
however, a cross relational sort, or worse a sort by formula could get 
very expensive.
And having to apply the sort criteria repeatedly could introduce delays 
the user would find annoying to unacceptable.

 
Sets:
create set([table];"Myset")

Add to set([table];"Myset")
Create Set([table];"To_be_Unioned")
Union("Myset;"To_be_Unioned";"Myset")
Intersection("Myset;"To_be_Unioned";"Myset")
Difference("Myset;"To_be_Unioned";"Myset")
Use Set("Myset")
clear Set("Myset")
Order By([table];[table]Field;>)
** Note this only needs to be done once - just before display

Named selections
Copy Named Selection([table];"MySelection") (alternatively Cut Named 
Selection)

Adding to it?
create record([table])
save record([table]
create set([table];"ToAdd")
use named selection("MySelection")
create set([table];"Add_to")
Union("Add_to";"ToAdd";"Add_to")
Order By([table];[table]Field;>)
Copy Named Selection([table];"MySelection") (alternatively Cut Named 
Selection)
** Note this would need to be done every time a record was added

Deleting from?
see above, replace Create/save with a Query


I think you can see my point -
Yes Named selections have many uses, but I do not see them as a 
replacement for sets when working with displayed lists of records where 
users can/are adding removing records from the display/table


On Tue, 13 Sep 2016 08:57:39 -0600, Cannon Smith wrote:
> I got to wondering how expensive it really is to used named 
> selections everywhere and then move them to the current selection to 
> do some work on them and then back again. It turns out that it is 
> really fast if you use CUT NAMED SELECTION and USE NAMED SELECTION to 
> move it back and forth and it doesn’t seem to matter how many records 
> are in the named selection. I suspect that when using these two 
> commands, internally 4D just updates a pointer or something like that.
> 
> To test I created selections of varying sizes and then moved them 
> into a named selection and then back into the current selection 
> thousands of times. Each cycle averaged 3-8 microseconds (not 
> milliseconds)!
> 
> Maybe there are other gotchas I’m not thinking of, but based on these 
> tests it seems like it would be possible to have all an application’s 
> windows in the main process as long as they all used named selections 
> and just moved them temporarily into the current selection to work on 
> it before moving it back into the named selection.
> 
> --
> Cannon Smith
> Synergy Farm Solutions Inc.
> Hill Spring, AB Canada
> 403-626-3236
> 
> 
> 
> 
>> On Sep 5, 2016, at 3:53 PM, Cannon Smith 
>>  wrote:
>> 
>> - In my current code, I tend to let almost every window have its own 
>> process. One reason for this is that the window has full control 
>> over selections and current records in every table. Even when the 
>> widows are array and variable based, this is very helpful. It seems 
>> like things could get very complicated if you had several windows 
>> open in the same process. For example, what if two of the windows 
>> were list windows for the same table and a third table was editing a 
>> record in that table? I suppose I could use named selections, but 
>> they seem limited. For example, I don't know how to programmatically 
>> ask a named selection to sort itself a certain way without making it 
>> the current selection and then pushing the current selection back 
>> into the named selection. Is this an expensive operation? I don't 
>> know as I've not tested it. Intuitively it seems like it would be. 
>> It is certainly expensive code wise in the sense that I'd have to 
>> remember to never accidentally use the current selection except to 
>> do temporary work for a named selection.
> 
> **
> 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:4d_tech-unsubscr...@lists.4d.com
> **
**
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:4d_tech-unsubscr...@lists.4d.com
*

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Cannon Smith
I don’t use the traditional output form/input form drill down either. But your 
question is exactly the one I’m trying to explore. I think most of us have 
traditionally programmed in 4D with one process for each window. Up until now 
all these “processes” were really on the same thread as far as the OS was 
concerned and 4D was doing the time slicing. With the introduction of 
preemptive processes, we now have the ability to have our code run on different 
OS threads. All the other environments I know of use one thread for all the UI 
and other threads as needed for background or potentially long running tasks. 
This is akin to putting all our windows in the Application process and using 
preemptive processes for background tasks. If I heard right, Thomas alluded to 
this as an idea if you had the chance to start an app from scratch.

I suppose if we continue to use normal processes for windows and 4D continues 
to time-slice on the UI thread, it amounts to the same thing. So, is there a 
benefit to keeping all UI in the Application process? Does it out-weigh the 
costs of doing it? I’m really not sure, but that is what I’m trying to think 
through and understand.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 14, 2016, at 2:26 AM, Kirk Brooks  wrote:
> 
> What's the benefit of doing that? In my typical work I deal with things
> that want to be open in multiple windows, like sales orders, items, trips,
> etc. So I haven't based anything on the 'traditional' output form/input
> form / drill-down architecture for - a really long time. Is that the kind
> of situation this would be a benefit for?
> 

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Cannon Smith
Hi Chip,

Thanks for chiming in. I totally agree that named selections shouldn’t be used 
where sets can be used. I was only considering named selections in places where 
the current selection would normally be used. Intuitively I thought that moving 
a named selection into the current selection to work on it (sort, new query, 
add records, etc.) and then back into the named selection would be costly, but 
it turns out that it has almost zero cost when used in the specific way 
mentioned.

Thanks.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 14, 2016, at 8:00 AM, Chip Scheide <4d_o...@pghrepository.org> wrote:
> 
> I think you can see my point -
> Yes Named selections have many uses, but I do not see them as a 
> replacement for sets when working with displayed lists of records where 
> users can/are adding removing records from the display/table
> 

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Kirk Brooks
Cannon,
OK, I see what your talking about. Frankly I have no idea what the best
approach is. This is the sort of thing I'll wait to hear what some of the
4D luminaries suggest. From what I am understanding about the benefits of
multi-threading I'm not at all clear on how many actual applications will
be able to actually take advantage of it. People who know a lot more about
this sort of thing than I do seem to be saying it's actually a small subset
of apps that can actually benefit from it. Plus to do so will require
significant re-writes of code. And I'm hearing a pretty consistent message
about that - namely don't do it. Be it taking advantage of multi-threading
or fully exploiting c-objects. Though I have found the benefits of judicial
refactoring to use c-objects worthwhile on balance.

I will say that I have been moving in the direction of condensing, or
modularizing, forms to work within the scope of themselves, as it were. The
old habits of having forms directly manipulating IP vars and even process
vars is something I'm reducing or eliminating. Form objects and dynamic
variables allow this. This makes it possible to think about the window as
its own scope, I suppose, though that hasn't really been my motivation. So
to your point it facilitates containing the UI in a single, or fewer,
processes.

Which still begs your original question - does it really matter?


On Wed, Sep 14, 2016 at 8:44 AM, Cannon Smith <
can...@synergyfarmsolutions.com> wrote:

> With the introduction of preemptive processes, we now have the ability to
> have our code run on different OS threads. All the other environments I
> know of use one thread for all the UI and other threads as needed for
> background or potentially long running tasks. This is akin to putting all
> our windows in the Application process and using preemptive processes for
> background tasks. If I heard right, Thomas alluded to this as an idea if
> you had the chance to start an app from scratch.
>
> I suppose if we continue to use normal processes for windows and 4D
> continues to time-slice on the UI thread, it amounts to the same thing. So,
> is there a benefit to keeping all UI in the Application process? Does it
> out-weigh the costs of doing it? I’m really not sure, but that is what I’m
> trying to think through and understand.
>

-- 
Kirk Brooks
San Francisco, CA
===
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Tom Dillon
Kirk Brooks wrote:

>What's the benefit of doing that? In my typical work I deal with things
>that want to be open in multiple windows, like sales orders, items, trips,
>etc. So I haven't based anything on the 'traditional' output form/input
>form / drill-down architecture for - a really long time. Is that the kind
>of situation this would be a benefit for?

How different is your interface from the traditional one?

-- 
   --
   Tom Dillon   825 N. 500 W.
   DataCraft   Moab, UT 84532
   tomdil...@datacraft-inc.com   720/209-6502
   --
Imagination is more important than knowledge,
because everything we know, first had to be imagined.
--- Albert Einstein 
   --


**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Kirk Brooks
Hey Tom,
I get the sense a lot of 4D dbs are built around the idea you choose a
table by starting with an output list form, do some sort of query to narrow
down the selection, double click on a record to open it into an input form
which may show lists of related records and then you drill down into those.
The key thing is all this is taking place in the single window.

My approach has been to make an interface for some aspect of the total
'job' and build lists that relate to that. I work with Orders a lot so I've
got several interfaces that provide ways to look at lists of them. 'My
List' let's users choose lists of order relevant to them, like in process,
quotes, etc. There's also an Order Finder that let's 'em find orders by
simple criteria: number, name, address, etc. I even build a popup list of
the most recent 10 orders when you right click on a customer name in the
'Partner Picker'. Regardless of where you ask to look at an order it opens
a new window, in a new process and displays the order. Unlike the
drill-down approach this let's you open several orders at the same time and
work with them.

Having said all that I don't have any real data on this - just perceptions
from conversations.

On Wed, Sep 14, 2016 at 12:16 PM, Tom Dillon 
wrote:

> How different is your interface from the traditional one?
>

-- 
Kirk Brooks
San Francisco, CA
===
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread John DeSoi

> On Sep 14, 2016, at 10:44 AM, Cannon Smith  
> wrote:
> 
> All the other environments I know of use one thread for all the UI and other 
> threads as needed for background or potentially long running tasks. This is 
> akin to putting all our windows in the Application process and using 
> preemptive processes for background tasks. If I heard right, Thomas alluded 
> to this as an idea if you had the chance to start an app from scratch.

It is a terrible limitation and one of the reasons I stopped using some other 
development tools. For example, if a process wants to get a user confirmation 
it must call the main process to show the dialog. Then the dialog has to make 
*callbacks* back to the process to continue (CALL WORKER?, CALL FORM?). Things 
that can be handled very simply in 4D a few lines of conditional statements 
turn in to multiple procedures having to deal with interprocess communication. 

John DeSoi, Ph.D.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Cannon Smith
Yep, for sure. I’d love to hear more about this aspect from 4D itself. There is 
lots of information about messaging between processes, but not much on this 
part yet.

Thanks.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 14, 2016, at 11:32 AM, Kirk Brooks  wrote:
> 
> Which still begs your original question - does it really matter?

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Cannon Smith
Hi John,

I wondered about that. I would have thought that would be pretty rare if the 
code was structured right, but it sounds like you ran into it quite often?

Thanks for the feedback.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 14, 2016, at 2:56 PM, John DeSoi  wrote:
> 
> It is a terrible limitation and one of the reasons I stopped using some other 
> development tools. For example, if a process wants to get a user confirmation 
> it must call the main process to show the dialog. Then the dialog has to make 
> *callbacks* back to the process to continue (CALL WORKER?, CALL FORM?). 
> Things that can be handled very simply in 4D a few lines of conditional 
> statements turn in to multiple procedures having to deal with interprocess 
> communication. 

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread John DeSoi
Hi Cannon,

> On Sep 14, 2016, at 4:35 PM, Cannon Smith  
> wrote:
> 
> I wondered about that. I would have thought that would be pretty rare if the 
> code was structured right, but it sounds like you ran into it quite often?

Yes, I ran into it all the time and it has nothing to do with problem code 
structure. It has to do with two rules that are common in Mac environments that 
support multi-processing. 

1. All user interface and interaction must occur on the main thread.

2. No I/O or long execution can occur on the main thread -- otherwise the 
interface is locked up.

So everything ends up being done with callbacks. 

It is not just the Mac, consider any modern Javascript environment. If you make 
a I/O request, you can't just wait for the result and write an if/then 
statement to handle it. Everything is done by passing callbacks and closures 
around. In my opinion, it is more difficult to read, write, and maintain.


John DeSoi, Ph.D.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Tim Nevels
On Sep 14, 2016, at 4:35 PM, Cannon Smith wrote:

> Yep, for sure. I’d love to hear more about this aspect from 4D itself. There 
> is lots of information about messaging between processes, but not much on 
> this part yet.

Here’s my perspective on new 4D features. They are great and they can be 
useful. Can be useful to you. May be useful to you. But maybe not.

Just because 4D adds a new feature to 4D does not mean all developers should 
and/or need to use that new feature. New features are a new tool you may find 
useful. But you may find for your particular application you have no need for 
new feature. 

4D commands and features are like tools in your toolbox. 

Example: Say you are a carpenter and you build typical wood frame houses. 
Someone releases a MIG welder that uses a new technology to automatically 
select the proper type of shielding gas and mixture. You don’t have to choose 
argon, oxygen, helium, carbon dioxide or the mixture.  This is a great feature… 
if you are a welder. But if you work 99.9% of the time with wood, you’ll find 
it very hard to find a use for this new MIG welder. 

Here is a 4D example: v3 and multiple processes and multiple windows. Fantastic 
4D feature I use all the time in almost all my 4D projects, except for one. I 
wanted to update that app to have multiple windows. I thought it would be so 
much more useful to the client. 

So I did a little work and made a demo with this app of how it could work with 
multiple windows and showed it to the client hoping to get approval to do the 
upgrade work on the app. I just knew they were going to love it.

They hated it! I was shocked. They complained this made things too complicated. 
They liked only having one window open at a time. They didn’t want to have all 
this “power”. They wanted to do only one  thing at a time. They had no need or 
desire to have several windows open at once to do comparison of information or 
any of the other reasons I could come up with. So this great feature of 
multiple windows open at once in 4D was a feature this client did not want any 
part of. 

I’m going to continue to evaluate the new worker processes and preemptive 
features in v16. Right now I don’t have any existing problems or situations 
where I can immediately see it would be valuable. Maybe there will be in the 
future. Maybe not. 

I’m glad I will have this new tool in my toolbox so that if I do run into a 
situation where I need it, I can use it. 

So what would be a good use or a “need” for worker processes? From what I 
understand so far, the primary value of worker processes is the ability speed 
of a time consuming process by breaking it into pieces and spreading the load 
across multiple processors/cores. 

Say you have a super complex query that currently takes 10 seconds to run. 
You’d like it to run in 2 seconds. You figure out a way to break the query into 
5 parts. Each part runs in 2 seconds and you can combine the results of all 5 
parts easily. 

Now having 5 worker processes that are pre-emptive, can all run simultaneously 
and can use all the cores in your CPU is exactly the tool you need. In a short 
time you can improved the speed of this operation by a factor of 5. 

Before we had a tool like this you would have probably tried to do some kind of 
caching of query results or hashing or some other scheme to speed up that slow 
query. Maybe a lot more work. More tables, updating data in triggers and 
testing, testing, testing. Using worker processes avoids all this. You just use 
brute force and the full power of your computer to get the job done faster. 

I’m not sure there is going to be a lot of value in trying to use worker 
processes to do all the processing and let the UI process be stupid and just 
sit there waiting for a message from a worker that he’s got the work done that 
you need unless your UI is currently sluggish due to excessive processing going 
on. Is that the problem you are trying to resolve using worker processes?

Or do you want to use worker processes just for the sake of using them and the 
pure enjoyment of doing it. That can also be a valid reason. :)

Tim


Tim Nevels
Innovative Solutions
785-749-3444
timnev...@mac.com


**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread James Crate

> On Sep 14, 2016, at 6:32 PM, John DeSoi  wrote:
> 
> Hi Cannon,
> 
>> On Sep 14, 2016, at 4:35 PM, Cannon Smith  
>> wrote:
>> 
>> I wondered about that. I would have thought that would be pretty rare if the 
>> code was structured right, but it sounds like you ran into it quite often?
> 
> Yes, I ran into it all the time and it has nothing to do with problem code 
> structure. It has to do with two rules that are common in Mac environments 
> that support multi-processing. 
> 
> 1. All user interface and interaction must occur on the main thread.
> 
> 2. No I/O or long execution can occur on the main thread -- otherwise the 
> interface is locked up.
> 
> So everything ends up being done with callbacks. 

I only started writing Cocoa apps about 10 years ago, but I haven’t run into 
any real problems with the Cocoa way of doing things. Especially now with 
NSOperationQueue/NSOperation or GCD and blocks, it has become very easy to 
write multi-threaded code. Back in the days of using NSThread it was probably 
more work and more annoying, but even then there was 
performSelector:onMainThread:waitUntilDone:. Nowadays there are so many more 
options. I think the only time I’ve ever even had to implement a callback is 
for file system event notifications.

However, I’d be hard-pressed to think of anything to use 4D’s implementation of 
worker threads (as I’ve heard them discussed) that wouldn’t be easier to 
accomplish some other way. 

For example, will CALL FORM be able to be implemented as elegantly as Cocoa’s 
NSNotification system? Or will it be the same level of terrible as CALL PROCESS 
and On Outside Call?

Jim Crate

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread David Adams
> On Thu, Sep 15, 2016 at 8:36 AM, Tim Nevels  wrote:

> Here’s my perspective on new 4D features. They are great and they can be
> useful. Can be useful to you. May be useful to you. But maybe not.

> So I did a little work and made a demo with this app of how it could work
with
> multiple windows and showed it to the client hoping to get approval to do
the
> upgrade work on the app. I just knew they were going to love it.
>
> They hated it!

Thanks for posting this, I've seen it too. Yeah, it's true - what we like
often isn't representative of what end users want. Single-window apps are
becoming more and more the norm so what you found is only more likely going
down the road.


> Or do you want to use worker processes just for the sake of using them
and the
> pure enjoyment of doing it. That can also be a valid reason. :)

I'm not that worked up about CALL FORM WINDOW, but I can think of a few
places where it would be very nice. Then again, I'm *way* more into
headless code than UI work. (I do plenty of UI work, but I like headless
code.) Getting CALL WORKER to support a UI? I haven't really thought about
it that much...that's not the most obvious case for me. A lot of UI-bound
tasks aren't straightforward to parallelize and then there's a lot of
threshing/overhead potential in managing the messaging. On the other hand,
I'm really, really, really into background tasks.

Don't think of CALL WORKER as a subordinate tool for CALL FORM WINDOW.
They're totally different, at least in my mind. As I probably said at the
top of this thread, I've been writing task queues for about 30 years (!)
and can't imagine life without them. So many uses. If you want to scale
(really scale), you need distributed processing. If you want to manage
distributed processing, you need a task/message-oriented architecture. Does
CALL WORKER fit into this? Kind of. Not 100% since it seems to be
single-machine oriented, but it's a great first step and, if you set your
code up right, you can pretty seamlessly extend it to a multi-machine or
multi-language solution based on records (which also adds persistence, if
you need it, and traceability when you want it) and/or an external queuing
system (IronMQ looks pretty good, I have to say.)

A few other notes:

* If anyone is thinking about how to use process/IP vars in CALL WORKER,
you're thinking about it wrong. Not because you're a bad person, and not
primarily for technical reasons. A task should be *atomic* and not bound to
the original calling context. Anything else is a huge, snarly, evil box of
goo. Filled with rusty razorblades. Forget variables, they're completely
unhelpful in this context. Unless you want to stand on a bunch of gooey,
rusty razorblades.

* Pre-emptive vs. cooperative threads. Is this the new "For loops are
faster" of the 4D world? Seriously, most of us and most of our apps
absolutely won't know or care. The guys in France that write 4D and 4D
Server? Yes, they should care. A lot. Us? Not so much. I'm filing under
"worry about it when I've got a reason to". Apart from that, I'll go with
the words of Bill Atkinson (he wrote QuickDraw and HyperCard, back in the
day): "How do you get a 400% optimization? Stop doing something stupid."
So, I'll just try not to do obviously stupid things ;-)

* Don't think of messaging as client-server. Think of it as sender and
recipient. Then a lot of the confusion/complexity about callbacks looks
different. A callback is a return address. The state of the art has changed
in the field a lot in the past decades...queuing has gone from being a
arcane, back-office/mainframe subject to a core component of the software
we use every day. The right or wrong polling strategy can make or break
you. This isn't news...but now it's common knowledge. (Long-polling or push
instead of constant repolling. Constant repolling is the naive
approach...I've used it...it's obvious...I now hand my head in shame. It
really does saturate resources way too fast for no reason. I like push
everywhere now.)

CALL WORKER has a lot of potential and I think will be a gentle
introduction to task queues for a lot of 4D developers. They look dead easy
to use. Impressively so...way to go 4D. Given their limits (as I understand
them), I'll repeat a few recommendations or anyone that thinks that they
_might_ move towards a multi-machine or multi-platform system in the future:

1) Ignore process and IP variables. Period. (In fact, I'd recommend this no
matter what - mingling variables this way is kind of a crappy way to code
anyway.)

2) Make your payload one parameter, and make that JSON. (Real JSON that any
language can parse.)

3) If you need larger/more complex data, store it in a record/file/whatever
and include a reference in the JSON that enables the worker/task process to
load the details.

That's it. If you don't ever plan to go beyond the built-in feature set,
then I think that point #2 can be ignored. It's pretty sweet that 4D lets
you pass raw parameters in -

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread John DeSoi
I could possibly agree with this if objects were more powerful and complete, 
but in the current implementation it just invites mistakes and maintenance 
issues. Object property names are just strings. Unless you build your own 
system where every property is an object that can provide meta-data, you can't 
even determine the type of the property. 4D objects are not self-describing as 
in other object systems. Having variables (and parameters) allows type checking 
and cross referencing to understand where things are used in the code base. If 
I have 100 instances of "name" as a property in my code, there is no way to 
safely make a change to that if I only want it to impact a subset of my objects.

If you could declare constants in code without restarting 4D, it might change 
my mind.

John DeSoi, Ph.D.


> On Sep 14, 2016, at 6:44 PM, David Adams  wrote:
> 
> 1) Ignore process and IP variables. Period. (In fact, I'd recommend this no
> matter what - mingling variables this way is kind of a crappy way to code
> anyway.)
> 
> 2) Make your payload one parameter, and make that JSON. (Real JSON that any
> language can parse.)

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread David Adams
On Thu, Sep 15, 2016 at 11:11 AM, John DeSoi  wrote:

> I could possibly agree with this if objects were more powerful and
complete,
> but in the current implementation it just invites mistakes and maintenance
> issues. Object property names are just strings. Unless you build your own
> system where every property is an object that can provide meta-data, you
can't
> even determine the type of the property. 4D objects are not
self-describing as
> in other object systems. Having variables (and parameters) allows type
> checking and cross referencing to understand where things are used in the
code
> base. If I have 100 instances of "name" as a property in my code, there
is no
> way to safely make a change to that if I only want it to impact a subset
of my
> objects.

All fair criticisms and observations. For sure, 4D's lack of understanding
of types past the built-in simples is a long-standing frustration. C_OBJECT
is kind of misleading -they're not structs/records/objects... they're more
like C_STRUCTURED_TEXT, as you point out.

For anyone planning to use CALL WORKER solely as designed, then the direct
parameter passing looks great. This is what Thomas demonstrated and it
makes for some very simple+powerful+readable code. Alternatively, the
just-one-JSON-block probably adds complexity with no benefit to most
examples, in this case.

But you have to pick your fights in 4D (or anything else)...If you think
that you'll want to move to a larger system with custom features, you'll
need records or documents and, at that point, the direct primitive
parameters are likely to be a pain. They don't translate outside of 4D and
don't map easily to anything _in_ 4D, apart from a big BLOB. In case it's
not clear, I've been down this particular road before...I was going with
specific fieldsa big BLOB was ultimately easier to work with.JSON is
the new BLOB ;-) Anyway with just one data container, your transport and
data storage code can be written once and then forgotten about.

For what it's worth, the task queues that I've written or been involved
with in the past didn't have a huge number of different message types. So,
it wasn't a matter of hundreds of different messages - more like a dozen or
two. At that point, the code for composing and then parsing a message isn't
that hard to verify. For every composition (sender) you've got a reader
(receiver.) They need to be kept in sync. Not entirely generic, but
error-free once you're done. (Entirely generic is overrated, IMO...and I've
been guiltier than many of going too far in that direction.) Put another
way, once the message format is stable and the code to build/consume the
message is verified, you're done. Nothing needs to change in that area
again. Message formats *should* end up being very stable over time or else
something else is going wrong in the system and/or it's early days and
your'e still in discovery mode. Oh, reminder: Put version numbers in
messages as part of your standard format so that you know if you're getting
an obsolete format, want to switch up your parser code to support multiple
versions, etc.
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Kirk Brooks
John,

On Wed, Sep 14, 2016 at 6:11 PM, John DeSoi  wrote:

> If you could declare constants in code without restarting 4D, it might
> change my mind.
>

​I'm using Vincent's excellent 4DPOP​

​constants module to do just this. Yeah you have to do some restarts while
you're developing but if you set up the constant names well (and this could
be another thread unto itself) ​you have a nice popup set of key names to
use for constructing c-objs.

I just completed a big refactoring of some code along David's description.
The idea is to have 4D assemble some complex data into a JSON which can
then be handed off to a 4D form for display and editing or to a web page.
The edits go into the JSON and that gets handed back to 4D - and 4D knows
what to do with it. This issue of consistently naming the keys quickly
appeared - even with many accessor methods.

I found the constants a great help.

-- 
Kirk Brooks
San Francisco, CA
===
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread Keisuke Miyako
actually, I beg to differ on this.

inter-process variables, yes, I suppose you can work around them.

but I have not yet found a good way to write worker code without using process 
variables.

true, you can run a worker recursively, passing local/contextual information as 
arguments packed as an object,
but what about large data or more specifically, arrays?

of course you can insert the array in an object too,
but as I understand, an object passed to a worker is copied, not referenced,
so I would imagine there is going to be a huge over-head
when, for example, a worker is progressively building an array in the 
background.

a process variable, to me, seems to be the ideal data buffer for such tasks.

given that a preemptive worker has no UI,
the variable is insulated from other processes,
unlike classic process variables that are bound to a form object.

but then, any process can run a method in that worker's context,
so the real gem of preemptive coding in 4D could well be in
how the methods are logically organised.

perhaps one can ASSERT that a method can only be called from a certain worker.
so the standard signature could be something like

MyWorker (Current process name;object{;object}...)

so that the worker always know who called it.

finally, in development,
a worker can be aborted (and the process variables destroyed),
but a caller might keep calling it in a loop and thus create a new instance,
so it might be useful to protect the recursive code in the callee method that 
uses process variables.

> 2016/09/15 8:44、David Adams  のメール:
>
> 1) Ignore process and IP variables. Period. (In fact, I'd recommend this no
> matter what - mingling variables this way is kind of a crappy way to code
> anyway.)



宮古 啓介
セールス・エンジニア

株式会社フォーディー・ジャパン
〒150-0043
東京都渋谷区道玄坂1-10-2 渋谷THビル6F
Tel: 03-6427-8441
Fax: 03-6427-8449

keisuke.miy...@4d.com
www.4D.com/JP

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-14 Thread David Adams
On Thursday, September 15, 2016, Keisuke Miyako 
wrote:

> actually, I beg to differ on this.
>
> inter-process variables, yes, I suppose you can work around them.
>
> but I have not yet found a good way to write worker code without using
> process variables.
>
>
Right, I said something stupid. I think that's the technical term ;-) I was
only thinking of process vars used for IP communication with the set/get
commands. Within a worker? Whatever works. If you scale out to a larger
system, you have to consider what works there. If you're in another
language, the code will be a complete rewrite anyway.

Put more succinctly, I'm saying

* limit messages to parameters
* if you expect to move beyond the built-in feature set, consolidate on a
JSON block (real JSON for interopability)
* if you need to pass something large or unwieldy, stick it in a resource
and pass the resource reference in the JSON.

If you do all of that and later find you want to run jobs in Python using
SQS, you'll be in good shape. For 'SQS', insert your queue name here and
for 'Python', insert your language. Everything speaks HTTP, SQL, and JSON
these days.
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-15 Thread Welsh Harris
Great presentation and such an awesome new feature!

Really like your example for logging David, CALL WORKER makes this so easy/fast 
without messing with semaphores and such.  Huge deal for job queues.

I've been working on some front end stuff and have come up with least 3 really 
nice use cases for using CALL WORKER with CALL FORM.  All of these examples can 
be done without CALL WORKER/FORM, but they seem to make it easier...

1. Async data fetching

If you want async data fetching just like you have with ajax in the web 
browser, now it really easy to setup.  And if you are fetching data from a 3rd 
party it is probably a good idea.  For instance, while 4D is running an HTTP 
GET, the user interface is locked.  If you are getting data from a 3rd party 
you can't be sure how long it will take.  So you might lock up the interface 
for a while as HTTP GET is waiting for a response.  That is a bad experience 
for the user.  Now you can just call a worker to get the data and your UI is 
still responsive.  When the worker is done it can call the form with the 
retrieved data.

- CALL WORKER("HttpGetAsync1";"HttpGetAsync";$Input_o;"CallbackMethod";Current 
form window)
- When the worker is done it calls CallbackMethod($Output_o)

2. Lots of async data fetching

What if you want to pull a bunch of stuff from a 3rd party to display in the 
UI, how about a bunch of pictures from Amazon S3?  Don't just grab one at a 
time, do what a web browser would do and fire up 8 workers and make 8 http 
requests at a time to pull them faster.  Same concept as above but just cycle 
through calling workers named HttpGetAsync1, HttpGetAsync2, HttpGetAsync3, etc. 
 Once you get to 8, cycle back and call HttpGetAsync1 again.  What's so great 
about CALL WORKER is you don't have to worry about whether HttpGetAsync1 is 
already busy making a request, just keep calling it and 4D will handle queuing 
all the requests for you.

3. Modal screen example

What if you want a modal screen behind a modal dialog like in this example:
http://www.w3schools.com/bootstrap/bootstrap_modal.asp

Now it is really easy:
MainForm_WinRef_l:=Current form window
DIALOG("MyForm";*) //note the asterisk, learned from Thomas's presentation
OBJECT SET VISIBLE(*;"ModalScreen";True)

Now when you close the dialog just call the window to tell it to hide the 
ModalScreen object:
CALL FORM(MainForm_WinRef_l;"HideModalScreen")

Code in HideModalScreen is just:
OBJECT SET VISIBLE(*;"ModalScreen";False)



Fun stuff,
Welsh

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-15 Thread Cannon Smith
Thanks James and John. I appreciate your perspectives.

--
Cannon Smith
Synergy Farm Solutions Inc.
Hill Spring, AB Canada
403-626-3236




> On Sep 14, 2016, at 5:27 PM, James Crate  wrote:
> 
> I only started writing Cocoa apps about 10 years ago, but I haven’t run into 
> any real problems with the Cocoa way of doing things. Especially now with 
> NSOperationQueue/NSOperation or GCD and blocks, it has become very easy to 
> write multi-threaded code. Back in the days of using NSThread it was probably 
> more work and more annoying, but even then there was 
> performSelector:onMainThread:waitUntilDone:. Nowadays there are so many more 
> options. I think the only time I’ve ever even had to implement a callback is 
> for file system event notifications.

**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-15 Thread Chip Scheide
Just to poke at Dave a bit  :)

On Wed, 14 Sep 2016 20:11:44 -0500, John DeSoi wrote:
> If you could declare constants in code without restarting 4D, it 
> might change my mind.

Isn't this what IP variables are for?
Chip
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-15 Thread David Adams
On Thu, Sep 15, 2016 at 11:34 PM, Welsh Harris 
wrote:

> Great presentation and such an awesome new feature!
>
> Really like your example for logging David, CALL WORKER makes this so
> easy/fast without messing with semaphores and such.  Huge deal for job
queues.
>
> I've been working on some front end stuff and have come up with least 3
really
> nice use cases for using CALL WORKER with CALL FORM.  All of these
examples
> can be done without CALL WORKER/FORM, but they seem to make it easier...

Hey Welsh, good post. You're right, CALL WORKER + CALL FORM could be really
great for any sort of real-time/streaming data. From the logging example,
perhaps the log worker posts critical errors to a display form. So, only
important stuff is showing up in real-time in the UI while everything is
still getting logged normally. I guess that you could filter and
selectively display all sorts of data: graphs, lists filtered by
user/machine/etc. That all fits into what Thomas showed, too. I liked the
way his demo used two instances of the same form to show different
information in different windows, for example.

And, yeah, you could do all of the above in native 4D now but...so much
uglier and harder.
**
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:4d_tech-unsubscr...@lists.4d.com
**

Re: Go watch Thomas Maul's presentation. Now.

2016-09-15 Thread David Adams
aOn Thu, Sep 15, 2016 at 11:11 AM, John DeSoi  wrote:

> I could possibly agree with this if objects were more powerful and
complete,
> but in the current implementation it just invites mistakes and maintenance
> issues. Object property names are just strings. Unless you build your own
> system where every property is an object that can provide meta-data, you
can't
> even determine the type of the property. 4D objects are not
self-describing as
> in other object systems. Having variables (and parameters) allows type
> checking and cross referencing to understand where things are used in the
code
> base. If I have 100 instances of "name" as a property in my code, there
is no
> way to safely make a change to that if I only want it to impact a subset
of my
> objects.

I was just thinking about John's post again and think it's worth more
comment. John's points are all right. If you look at Thomas' presentation,
you'll see how clear and readable calls to CALL WORKER on when you pass
parameters. In contrast, passing through a JSON block or reference of some
kind is completely opaque. You can't see what's going on from the call, you
have to figure out what's going into the JSON. This is potentially a quick
road to hard to debug, hard to trace, sloppy code. I truly detest the habit
in JavaScript to pass around these ginormous JSON manifests. Ugh.
(Particularly in JavaScript where closures are super nice...we just don't
have anything like them in 4D.)

Anyway, I can clearly complain about anything ;-)

I've been recommending a JSON-messaging strategy for a *minority* of cases.
Namely, the situations where CALL WORKER is going to be extended to a
multi-machine setup of any kind. Say, for example, that you want to pass
message to a compiled-and-merged app. That's a sweet setup. You can get
very stable little 'clients' using pure 4D code. In fact, you can set up
build parameters so that you main system and the compiled-and-merged
versions come out of the same code base. In that situation, you'll be happy
to have JSON blocks. But how often is this going to be the case? I don't
know. I'd guess the minority - maybe never for some people. (For me it's
'always' because I'm used to distributed processing and that's how I think
about it...but that's me.) Is it worth overbuilding something for a
minority case you might not have? Usually not. Sometimes it is and then
it's a bit+ painful to do a rewrite...but what about the times you
overwrite Just In Case and never need the extra features? I always feel
foolish for having wasted the time and effort to make a *more* complex
system for zero gain. So potentially, a painful rewrite or potentially
hanging your head in shame over pointlessly complex code. Like so many
things, judgement call.

So:

* If you're only ever going to use CALL WORKER on one machine, as designed,
use raw parameters. This makes for much better and more readable 4D code
that a new programmer can pick up right away.

* If you're going to extend or replace CALL WORKER _for sure_, I'd suggest
starting with JSON blocks and working out some generalized tools for
naming/documentation/parsing/building/validating along the way.

* If you _might_ extend or replace CALL WORKER, it's a tougher call. Go
with your gut. In any case, you could always write a CALL WORKER adapter
where your normal CALL WORKER handlers write reformatted messages as JSON
blocks for your extended system.

File under "it depends." Judgement calls. That's why we get the medium
bucks.
**
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:4d_tech-unsubscr...@lists.4d.com
**