[Obdisclaimer:-a cc'ing s.e.d only because some of you are no longer subscribed to the list and will likely not see this, otherwise.
And, its a substantial change in the API so worth noting.]
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).-a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
On 19/02/2026 22:04, Don Y wrote:
[Obdisclaimer:a cc'ing s.e.d only because some of you are no longer
subscribed to the list and will likely not see this, otherwise.
And, its a substantial change in the API so worth noting.]
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
Languages that allow call by reference to be qualified with a const or >readonly directive so that the routine reading the original object (no
copy made) is not allowed to alter the it in any way.
Detectable as a compile time fault if you do. Relying on all coders to
be disciplined is likely to be ahem... disappointing.
I can't be the only one to have seen shops where the journeymen are so >unskilled that getting C code to compile by the random application of
casts is the norm. Not written in C but the UK scandalous Horizon PO >accounting system was written by people of that calibre (thickness).
They compounded the problem by having expert witnesses perjure
themselves to convict entirely innocent postmasters of fraud because the >computer was "infallible". The resulting mess is still ongoing.
On 19/02/2026 22:04, Don Y wrote:
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).-a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
Languages that allow call by reference to be qualified with a const or readonly
directive so that the routine reading the original object (no copy made) is not
allowed to alter the it in any way.
Detectable as a compile time fault if you do. Relying on all coders to be disciplined is likely to be ahem... disappointing.
I can't be the only one to have seen shops where the journeymen are so unskilled that getting C code to compile by the random application of casts is
the norm. Not written in C but the UK scandalous Horizon PO accounting system
was written by people of that calibre (thickness).
They compounded the problem by having expert witnesses perjure themselves to convict entirely innocent postmasters of fraud because the computer was "infallible". The resulting mess is still ongoing.
On 2/20/2026 3:36 AM, Martin Brown wrote:
I can't be the only one to have seen shops where the journeymen are so
unskilled that getting C code to compile by the random application of casts >> is the norm. Not written in C but the UK scandalous Horizon PO accounting >> system was written by people of that calibre (thickness).
Most programming problems that I see are the result of creating bad models
of the problem being solved.-a Then, having to "bugger" what should have been a clean, straightforward implementation to bend the model to the reality. Anyone can code -- especially as you can SEE if your code "appears" to work without having to make a big investment in time or material/treasure.
But, moving from a single, self-contained application to an interactive service/agent seems to be a big leap; considerably harder than more mundane issues like multitasking (despite, IMO, being infinitely easier!).
I'm trying to spend (waste?) hardware resources to improve the quality
of the codebase -- especially for folks who likely have little/no experience developing such applications.-a In the real world, how many folks have written web servers or other similar multi-client services, etc.?-a Then, imagine the subset of those who have written agents!
On 2/20/2026 3:36 AM, Martin Brown wrote:
On 19/02/2026 22:04, Don Y wrote:
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).-a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
Languages that allow call by reference to be qualified with a const or
readonly directive so that the routine reading the original object (no
copy made) is not allowed to alter the it in any way.
That's a different problem.
A mutable object *intended* to be manipulated in the called scope
is EXPECTED to be altered by that invoked function.
Less obviously, another executing thread is likely NOT expected to
alter that object while the invoked function is executing!
While C doesn't really have cal-by-reference, the problem can
be illustrated using pointers instead of references.-a Consider:
object_t anObject;
// initialize anObject somehow
...
// act on anObject through a pointer to it
operator(&anObject, ...)
// reference the expected changes in anObject in someway
...
In a single threaded, single processor environment, one KNOWS that
nothing is dicking with anObject while operator() is running -- because operator() has exclusive use of the processor.
Consequently, after operator() completes, one knows that anObject reflects the operation performed by operator().
Add a second thread (or, second process having access to anObject).
Now, there is the possibility that the other actor can alter anObject while operator() is executing -- likely without expecting such an interaction.
And, after operator() has concluded, the next line of code can't assume
that anObject reflects operator()'s actions.
[This can be avoided by using call-by-copy-restore but that just
ensures "the next line of code" works and does nothing for the
other problems]
The biggest exposure is likely from another thread in the same
process container acting on anObject alongside the thread that
is executing the above code.-a Adding explicit locks can avoid
this (at a cost and another level of discipline).-a A better approach
is to structure the code so this "doesn't (but CAN!) happen"
[Almost every piece of code in my system is a service or an agency.
As such, they all try to be N copies of the same algorithm running
on N different instances of objects of a particular type.-a Easy
if you *design* for that case; tedious if you adopt /ad hoc/
methods!]
I use CoW to implement call-by-value semantics on objects thatSimilar to how GPUs do, if the operator() can perform its required calculations on a const reference to the data but its output can be
would typically be passed as call-by-reference.-a E.g., imagine
anObject is a single frame of video and operator() is going to
apply a masking function to it, eliding all but the "important"
parts of the frame for return to the caller.
On 2/20/2026 12:47 PM, Don Y wrote:
[Almost every piece of code in my system is a service or an agency.
As such, they all try to be N copies of the same algorithm running
on N different instances of objects of a particular type.-a Easy
if you *design* for that case; tedious if you adopt /ad hoc/
methods!]
Yeah, having mutable state in a multithreaded embedded environment without big-iron tools to manage mutable state across threads (like std::mutex and std::weak_ptr) kind of sucks!!
Even for single-threaded embedded stuff I like treating C++ more like a functional language and passing non-const references to anything very rarely,
those relationships are hard to reason about.
On 2/20/2026 12:47 PM, Don Y wrote:
I use CoW to implement call-by-value semantics on objects thatSimilar to how GPUs do, if the operator() can perform its required calculations
would typically be passed as call-by-reference.-a E.g., imagine
anObject is a single frame of video and operator() is going to
apply a masking function to it, eliding all but the "important"
parts of the frame for return to the caller.
on a const reference to the data but its output can be reduced to operations on
individual pixel values of integral type which don't depend on the output value
of neighboring pixels std::atomic is for that situation, and should be lock free for processors that have hardware support for atomics e.g. ARM v6 and later
On 2/20/2026 2:21 PM, bitrex wrote:
On 2/20/2026 12:47 PM, Don Y wrote:
[Almost every piece of code in my system is a service or an agency.
As such, they all try to be N copies of the same algorithm running
on N different instances of objects of a particular type.-a Easy
if you *design* for that case; tedious if you adopt /ad hoc/
methods!]
Yeah, having mutable state in a multithreaded embedded environment
without big-iron tools to manage mutable state across threads (like
std::mutex and std::weak_ptr) kind of sucks!!
Even for single-threaded embedded stuff I like treating C++ more like
a functional language and passing non-const references to anything
very rarely, those relationships are hard to reason about.
Something has to "do work" -- i.e., make changes.
E.g., the example of a single frame of video needing to be masked
can either be done by masking the original frame (thereby changing
it in the process) *or* by masking a copy of the original frame.
It's up to the goals of the algorithm as to which approach to pursue;
if you don;'t need to preserve the original (unmasked) frame, then
creating a copy of it for the sole purpose of treating it as const
is wasteful.
OTOH, creating a copy to ensure other actors' actions don't interfere
with your processing (and the validity of your actions) *has* value
(in that it leads to more predictable behavior).
Nowadays, its relatively easy to buy horsepower and other resources
so the question boils down to how you use them.
[My first "from scratch" commercial product had 12KB of ROM and 256
bytes of RAM plus the I/Os (motor drivers, etc.).-a The cost of just
the CPU board was well over $400 (when EPROM climbed to $50/2KB).
Spending $20 on a single node is a yawner...]
Decomposing a design into clients, services and agencies lets it
dynamically map onto a variety of different hardware implementations
and freely trade performance, power, size, latency, etc. as needed.
E.g., each object instance could be backed by a single server
instance -- or, all object instances can be backed by a single
server instance -- or, any combination thereof.-a Each server can
decide how much concurrency it wants to support (how many kernel
threads to consume) as well as how responsive it wants to be (how
much caching, preprocessing, etc. it uses to meet demands placed
on it).
On 2/20/2026 6:09 PM, Don Y wrote:
On 2/20/2026 2:21 PM, bitrex wrote:
On 2/20/2026 12:47 PM, Don Y wrote:
[Almost every piece of code in my system is a service or an agency.
As such, they all try to be N copies of the same algorithm running
on N different instances of objects of a particular type.-a Easy
if you *design* for that case; tedious if you adopt /ad hoc/
methods!]
Yeah, having mutable state in a multithreaded embedded environment
without big-iron tools to manage mutable state across threads (like
std::mutex and std::weak_ptr) kind of sucks!!
Even for single-threaded embedded stuff I like treating C++ more like
a functional language and passing non-const references to anything
very rarely, those relationships are hard to reason about.
Something has to "do work" -- i.e., make changes.
E.g., the example of a single frame of video needing to be masked
can either be done by masking the original frame (thereby changing
it in the process) *or* by masking a copy of the original frame.
It's up to the goals of the algorithm as to which approach to pursue;
if you don;'t need to preserve the original (unmasked) frame, then
creating a copy of it for the sole purpose of treating it as const
is wasteful.
OTOH, creating a copy to ensure other actors' actions don't interfere
with your processing (and the validity of your actions) *has* value
(in that it leads to more predictable behavior).
Nowadays, its relatively easy to buy horsepower and other resources
so the question boils down to how you use them.
[My first "from scratch" commercial product had 12KB of ROM and 256
bytes of RAM plus the I/Os (motor drivers, etc.).-a The cost of just
the CPU board was well over $400 (when EPROM climbed to $50/2KB).
Spending $20 on a single node is a yawner...]
Decomposing a design into clients, services and agencies lets it
dynamically map onto a variety of different hardware implementations
and freely trade performance, power, size, latency, etc. as needed.
E.g., each object instance could be backed by a single server
instance -- or, all object instances can be backed by a single
server instance -- or, any combination thereof.-a Each server can
decide how much concurrency it wants to support (how many kernel
threads to consume) as well as how responsive it wants to be (how
much caching, preprocessing, etc. it uses to meet demands placed
on it).
It sounds like you're describing some very hard realtime baremetal
system where you have the luxury of lots of memory to do very resource- intensive operations like full copies of video frames on the grounds of "predictability" (I think most embedded video processing on general-
purpose CPUs would try very hard to avoid doing any full copies), but
also can't afford the luxury of an MMU and/or a RTOS that supports some subest of POSIX, so you can use modern C++ features like smart pointers
and mutexes. Maybe that would add too much overhead.
On 2/20/2026 6:09 PM, Don Y wrote:
On 2/20/2026 2:21 PM, bitrex wrote:
On 2/20/2026 12:47 PM, Don Y wrote:
[Almost every piece of code in my system is a service or an agency.
As such, they all try to be N copies of the same algorithm running
on N different instances of objects of a particular type.-a Easy
if you *design* for that case; tedious if you adopt /ad hoc/
methods!]
Yeah, having mutable state in a multithreaded embedded environment without >>> big-iron tools to manage mutable state across threads (like std::mutex and >>> std::weak_ptr) kind of sucks!!
Even for single-threaded embedded stuff I like treating C++ more like a >>> functional language and passing non-const references to anything very
rarely, those relationships are hard to reason about.
Something has to "do work" -- i.e., make changes.
E.g., the example of a single frame of video needing to be masked
can either be done by masking the original frame (thereby changing
it in the process) *or* by masking a copy of the original frame.
It's up to the goals of the algorithm as to which approach to pursue;
if you don;'t need to preserve the original (unmasked) frame, then
creating a copy of it for the sole purpose of treating it as const
is wasteful.
OTOH, creating a copy to ensure other actors' actions don't interfere
with your processing (and the validity of your actions) *has* value
(in that it leads to more predictable behavior).
Nowadays, its relatively easy to buy horsepower and other resources
so the question boils down to how you use them.
[My first "from scratch" commercial product had 12KB of ROM and 256
bytes of RAM plus the I/Os (motor drivers, etc.).-a The cost of just
the CPU board was well over $400 (when EPROM climbed to $50/2KB).
Spending $20 on a single node is a yawner...]
Decomposing a design into clients, services and agencies lets it
dynamically map onto a variety of different hardware implementations
and freely trade performance, power, size, latency, etc. as needed.
E.g., each object instance could be backed by a single server
instance -- or, all object instances can be backed by a single
server instance -- or, any combination thereof.-a Each server can
decide how much concurrency it wants to support (how many kernel
threads to consume) as well as how responsive it wants to be (how
much caching, preprocessing, etc. it uses to meet demands placed
on it).
It sounds like you're describing some very hard realtime baremetal system where
you have the luxury of lots of memory to do very resource-intensive operations
like full copies of video frames on the grounds of "predictability" (I think most embedded video processing on general-purpose CPUs would try very hard to
avoid doing any full copies), but also can't afford the luxury of an MMU and/or
a RTOS that supports some subest of POSIX, so you can use modern C++ features
like smart pointers and mutexes. Maybe that would add too much overhead.
These are unusual requirements, to me anyway, I've done a decent amount of embedded programming over the years but IDK how much advice I can give here. For "big iron"-like tasks like multi-thread processing of large amounts of data
having an MMU and an embedded OS makes life a lot easier.
For simple devices like 8 bitters which are more used as "process controllers"
rather than to perform hardcore calculations like working on video, I find cooperative multitasking among state machines works pretty well, what mutable
state there is is mostly stored in the machine states.
Is this a high-frequency trading box? Are you building a salami-slicer
On 2/20/2026 11:07 PM, bitrex wrote:
Is this a high-frequency trading box? Are you building a salami-slicer
No. More IoT but with all of the processing in the leafs [sic]
instead of an unscalable "central processor" trying to coordinate
the activities of motes.
Why put a processor in a mote if all its going to do is sense
something or control an actuator -- based on decisions made by
some other "smarter" entity? Once you have the CPU and connectivity,
why not migrate the smarts out to the periphery (folks are slowly
starting to realize this is inevitable)
Don Y <blockedofcourse@foo.invalid> wrote:
On 2/20/2026 11:07 PM, bitrex wrote:
Is this a high-frequency trading box? Are you building a salami-slicer
No. More IoT but with all of the processing in the leafs [sic]
instead of an unscalable "central processor" trying to coordinate
the activities of motes.
Why put a processor in a mote if all its going to do is sense
something or control an actuator -- based on decisions made by
some other "smarter" entity? Once you have the CPU and connectivity,
why not migrate the smarts out to the periphery (folks are slowly
starting to realize this is inevitable)
Well, the point is that processor close to hardware can:
- do real time things
- reduce bandwith needed for communication
- reduce need for wires
Such processor may be quite cheap (I can buy resonable MCU at $0.2
per piece and modules with MCU at $2 each), usually does not need mass storage and can have tiny RAM. Small MCU-s may be cheaper than
specialized chips, so it make sense to use them just to unify
hardware and lower the cost.
OTOH more complicated algorithms may need a lot of data, large
persistent starage, a lot of RAM. Still, it is likely that a single
CPU can do all needed job. Single CPU make many things simpler. So
unless that is compelling need for more processing using relatively
dumb peripherial nodes and slightly more powerful cental node
makes a lot of sense.
Of course, in commercial settings people work on what they are
payed to do. IIUC developers of say Home Assistant get no
incentives to make it working on really low cost hardware,
so you get requiremets like 8 GB ram, 16 (or maybe 32) GB
filesystem for something that should comfortably run in 32 MB
RAM and 500 MB filesystem. Actually, IIUC comparable functionality
was available in the past on much smaller machines than the
32 MB RAM and 500 MB filesystem mentioned above, I am simply adding
a lot of slack, to allow higher-level coding and to reduce need
for micro-optimization.
On 19/02/2026 22:04, Don Y wrote:
[Obdisclaimer:-a cc'ing s.e.d only because some of you are no longer
subscribed to the list and will likely not see this, otherwise.
And, its a substantial change in the API so worth noting.]
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).-a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
Languages that allow call by reference to be qualified with a const or >readonly directive so that the routine reading the original object (no
copy made) is not allowed to alter the it in any way.
Detectable as a compile time fault if you do. Relying on all coders to
be disciplined is likely to be ahem... disappointing.
I can't be the only one to have seen shops where the journeymen are so >unskilled that getting C code to compile by the random application of
casts is the norm. Not written in C but the UK scandalous Horizon PO >accounting system was written by people of that calibre (thickness).
They compounded the problem by having expert witnesses perjure
themselves to convict entirely innocent postmasters of fraud because the >computer was "infallible". The resulting mess is still ongoing.
--
Martin Brown
In article <10n9deu$a7ej$1@dont-email.me>,
Martin Brown <'''newspam'''@nonad.co.uk> wrote:
On 19/02/2026 22:04, Don Y wrote:
[Obdisclaimer:-a cc'ing s.e.d only because some of you are no longer
subscribed to the list and will likely not see this, otherwise.
And, its a substantial change in the API so worth noting.]
Using similar mechanisms to those that I use in call-by-value RMIs,
I can protect against races for call-by-reference -- throwing an
exception or just spinning on any violations on the calling side.
Or, I can just let people rely on their own discipline to
ensure they don't introduce latent bugs via this mechanism
(resorting to call by value universally seems a bad idea
for legacy coders).-a As these types of races have typically
been hard to test for, I suspect it is worth the effort.
Any pointers to languages or IDLs that include such qualifying
adjectives?
Languages that allow call by reference to be qualified with a const or
readonly directive so that the routine reading the original object (no
copy made) is not allowed to alter the it in any way.
Detectable as a compile time fault if you do. Relying on all coders to
be disciplined is likely to be ahem... disappointing.
I can't be the only one to have seen shops where the journeymen are so
unskilled that getting C code to compile by the random application of
casts is the norm. Not written in C but the UK scandalous Horizon PO
accounting system was written by people of that calibre (thickness).
Using casts should be forbidden in the code standard.
If you want them, you should get approval from a senior programmer.
He will probably learn you that the cast wasn't necessary.
In article <10n9deu$a7ej$1@dont-email.me>,
I can't be the only one to have seen shops where the journeymen are so
unskilled that getting C code to compile by the random application of
casts is the norm. Not written in C but the UK scandalous Horizon PO
accounting system was written by people of that calibre (thickness).
Using casts should be forbidden in the code standard.
If you want them, you should get approval from a senior programmer.
He will probably learn you that the cast wasn't necessary.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 59 |
| Nodes: | 6 (1 / 5) |
| Uptime: | 16:19:34 |
| Calls: | 810 |
| Calls today: | 1 |
| Files: | 1,287 |
| D/L today: |
10 files (21,017K bytes) |
| Messages: | 193,384 |