Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Never Let a Bad State Happen



Permlink Replies: 300 - Last Post: Mar 2, 2016 12:11 PM Last Post By: Quentin Correll
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 8:03 AM
Below is a section of my book "More Coding in Delphi" discussing the
issue of 'nil' in code.

Note that Dalija will be happy, as I concede that nil can, for specific
purposes, be used. I'm happy to eat my previous words on the topic
after reviewing what I actually wrote in my book. I was wrong to assert
that nil should never be allowed.

I still stand by my statements that nil should never be accepted by a
method as an argument and that nil should never be exposed by an API or
returned by a function.

Bruce will be happy because I explain myself better and started a new
thread. ;-)

Note that the segment is written in Markdown.



### Never Let a Bad State Happen

Another aspect of encapsulation that gets short shrift is the notion
that a class should never allow itself to be put into a bad or
non-functional state. Encapsulation dictates that you not only hide
your internals, but you protect them from being placed in bad or
impossible states.

The first thing this means is that no internal object instance should
ever be exposed as nil. If you have an object as an internal member,
you should ensure that it is created before it is needed, and that it
remains created and valid throughout the time that it is exposed to the
end user.

A> Note that this position allows for "lazy" initialization of objects,
that is, the creation of objects on demand rather than on the
initialization of the object. Your internal pointers can be nil, but
that fact should never be exposed to the consumer of your object.

Here's an example of what I mean -- that is, what not to do:

function GetListOfWidgets: TWidgetCollection;
begin
if Widgets.Count = 0 then
begin
Result := nil
end else
begin
Result := Widgets; // Of type TWidgetCollection
end;
end;

This function could return nil. Therefore, any code that consumes
`GetListOfWidgets` had to check for `nil` every time. This can be
tedious. Rather than returning `nil`, the code should instead return an
empty list to indicate that there are no widgets in the collection.

A class should never be allowed to present itself to the consumer as
`nil`. Normally, this means you should create your internal objects in
the constructor of the containing class and never free them until the
destructor is called. If you have some need to "reset" your class
during its lifetime, then have a routine that does that explicitly.
Always protect your internal classes so that a consumer can never see a
bad state - especially `nil`.

--
Nick
Delphi Programming is Fun
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 8:21 AM   in response to: Nick Hodges in response to: Nick Hodges
Note that the section quoted above is from a larger section on
Encapsulation -- it's good encapsulation practice to never let your
references be exposed as nil.

--
Nick
Delphi Programming is Fun

Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 9:26 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Rather than returning `nil`, the code should instead return
an empty list to indicate that there are no widgets in the collection.

Why not use "if GetListOfWidgets(List)"?

If inside a 15 million loop, I'm sure this short nil test will be
quicker than each time creating and destroying the list.
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 9:56 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Why not use "if GetListOfWidgets(List)"?

You could do that, sure. In fact, as long as List isn't nil, that
would probably work better in a huge loop.

--
Nick
Delphi Programming is Fun
David Millington

Posts: 257
Registered: 5/29/05
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 10:12 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:
Nick Hodges wrote:
Rather than returning `nil`, the code should instead return
an empty list to indicate that there are no widgets in the collection.

Why not use "if GetListOfWidgets(List)"?

If inside a 15 million loop, I'm sure this short nil test will be
quicker than each time creating and destroying the list.

Because it's a reasonable assumption that the objects own the list. It's rare (before ARC, or unless using interfaces but even then) to have a method like that return an object that the caller is responsible for freeing. When that happens it needs to be explicit.

I'd prefer the code to read something like,

property Widgets : TWidgetCollection read GetListOfWidgets; // Or whatever

function GetListOfWidgets: TWidgetCollection;
begin
if not Assigned(FWidgets) then
FWidgets := TWidgetCollection.Create;

Result := FWidgets;
end;

Thus being an example of lazy instantiation, and also never exposing nil to the class consumer.
David Millington

Posts: 257
Registered: 5/29/05
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 10:29 AM   in response to: David Millington in response to: David Millington
David Millington wrote:
Because it's a reasonable assumption that the objects own the list. It's rare (before ARC, or unless using interfaces but even then) to have a method like that return an object that the caller is responsible for freeing. When that happens it needs to be explicit.

I misread your code, and thought:

if GetListOfWidgets(List)

was in fact meant to be:

if Assigned(GetListOfWidgets)...

Apologies for the misunderstanding. Yes, passing in a var param to something that is initialised is a good way to do it.
David Novo

Posts: 40
Registered: 8/5/07
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 14, 2016 11:30 AM   in response to: Nick Hodges in response to: Nick Hodges
Hi Nick,

Your presumption is the NIL represents a bad state, and that objects should return a NULL object instead of NIL. But there are many cases where the caller does not handle nil in the same way, and passing a NULL object does not allow the caller to behave the way they want because they do not know the result was in fact null.

for example, lets say an object can optionally return a strategy object based on its state. Someone else has a list of these and needs to do something on the first object with a strategy.

for i:=0 to list.count-1 do
begin
theStrat:=list[i].GetStrategy
if Assigned(theStrat) then do something and exit the loop

in another case someone holds an object that can return the strategy. But in that case, if the strategy returns nil it is an exception.

Of course you can introduce another method called .HasStrategy and check that all the time instead of checking for nil, but that is just introducing another method.

A more complex situation is where you have to pass the returned strategy (including perhaps NIL) to an anonymous method. The different anonymous methods handle NIL differently. If the GetSTrategy returned NULL object, the different anonymous methods would have to call something like .AreYouNull on the Strategy to know its really the NULL strategy and not start calling methods on the strategy because they need to handle NIL differently.

There are different scenario and any dogmatic rules will fail.

Not having a raincoat is not the same as having a NullRaincoat. If I am adding my raincoats to a list and they have a name and color, the NullRaincoat will return "NoName" and clNone. I certainly don't want to add those to the list. Then I have to introduce .IsValid to the Raincoat class to avoid the NULL state. It add quite a bit of mess in order to avoid a nil, IMHO

Nick Hodges wrote:
Always protect your internal classes so that a consumer can never see a
bad state - especially `nil`.

--
Nick
Delphi Programming is Fun
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 5:15 AM   in response to: David Novo in response to: David Novo
David Novo wrote:

but that is just introducing another method.

Why is that bad?


--
Nick
Delphi Programming is Fun

David Novo

Posts: 40
Registered: 8/5/07
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:31 PM   in response to: Nick Hodges in response to: Nick Hodges
I would not say its "bad" per se. But I fail to see a huge difference between

Make sure every time you try to use this object, you have to check assigned first
Make sure every time you try to use this object, you have to call .AreYouNull method on the object and implement special behavior if it is null

In fact, in the latter case, I would rather it crash by accessing the null, than introduce subtle and non-obvious bugs in places I forgot to call .AreYouNull before using it. In our software, it is better to crash than return incorrect results to the user. It will also be found quicker by our automated testing system .

A NULL object pattern is very useful when all consumers treat the null object the same way. Then that behavior can be encapsulated in the Null object.
If callers treat the null object differently (in a way that cannot be determined by the thing that creates the Null object) then there is not much point to a NULL object pattern. Then you are just forcing the pattern so you can say that you NEVER use Nulls. Which may be a cool slogan to have on a T-Shirt I guess :-)


Nick Hodges wrote:

Why is that bad?
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 3:16 AM   in response to: David Novo in response to: David Novo
David Novo wrote:
I would not say its "bad" per se. But I fail to see a huge difference between

Make sure every time you try to use this object, you have to check assigned first
Make sure every time you try to use this object, you have to call .AreYouNull method on the object and implement special behavior if it is null

In fact, in the latter case, I would rather it crash by accessing the null, than introduce subtle and non-obvious bugs in places I forgot to call .AreYouNull before using it. In our software, it is better to crash than return incorrect results to the user. It will also be found quicker by our automated testing system .

A NULL object pattern is very useful when all consumers treat the null object the same way. Then that behavior can be encapsulated in the Null object.
If callers treat the null object differently (in a way that cannot be determined by the thing that creates the Null object) then there is not much point to a NULL object pattern. Then you are just forcing the pattern so you can say that you NEVER use Nulls. Which may be a cool slogan to have on a T-Shirt I guess :-)

Exactly.

It is just moving logic and possible errors into another level that is
more complex and more error prone than using nil.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
david hoke

Posts: 616
Registered: 2/9/07
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 6:11 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:

David Novo wrote:

but that is just introducing another method.

Why is that bad?

Because in some performance-related circumstances, it can cost real
money.

The same has been observed to be true even just introducing another
variable to be used as a (memory/structuring) flag in a loop, method
calls tend to have much greater overhead than simple variables.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:08 PM   in response to: david hoke in response to: david hoke
david hoke wrote:

Nick Hodges wrote:

David Novo wrote:

but that is just introducing another method.

Why is that bad?

Because in some performance-related circumstances, it can cost real
money.

The same has been observed to be true even just introducing another
variable to be used as a (memory/structuring) flag in a loop, method
calls tend to have much greater overhead than simple variables.

Not that much anymore, actually.

--
Rudy Velthuis http://www.rvelthuis.de

"Forgive your enemies, but never forget their names."
-- John F. Kennedy (1917-1963)
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 6:48 AM   in response to: Nick Hodges in response to: Nick Hodges
"Nick Hodges" wrote on Mon, 15 Feb 2016 05:15:37 -0800:

David Novo wrote:

but that is just introducing another method.

Why is that bad?

Why is it necessary? Much better, IMO, to understand what a pointer
variable is, than to assume that nil=bad.

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 7:11 AM   in response to: Brandon Staggs in response to: Brandon Staggs
Brandon Staggs wrote:

IMO, to understand what a pointer
variable is, than to assume that nil=bad.

Okay.

--
Nick
Delphi Programming is Fun
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:17 PM   in response to: Brandon Staggs in response to: Brandon Staggs
Brandon Staggs wrote:

"Nick Hodges" wrote on Mon, 15 Feb 2016 05:15:37 -0800:

David Novo wrote:

but that is just introducing another method.

Why is that bad?

Why is it necessary? Much better, IMO, to understand what a pointer
variable is, than to assume that nil=bad.

Nil is not bad. It is a special value that causes a nice access
violation if you reference it. To avoid that, you must check for it,
and that is one step extra in EVERY access, a step that can easily be
forgotten. This makes your code more error prone than necessary. And it
is not faster either. On the contrary. Even if the object is valid most
of the time, you must still do the nil check followed by a conditional
jump ON EVERY ACCESS, even when usually that is a waste of time.

ISTM that is is much better to make the object valid all the time, so
the nil check can be avoided (wasting less time) and the nil check
can't be forgotten (avoiding an AV).

Forcing the users of your code (even if that is just you) to check for
nil puts a burden on them, and is a possible source of error.

--
Rudy Velthuis http://www.rvelthuis.de

"I am become death, shatterer of worlds."
-- Robert J. Oppenheimer (1904-1967) (citing from the
Bhagavad Gita, after witnessing the world's first nuclear
explosion)
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 4:19 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
"Rudy Velthuis" wrote on Thu, 18 Feb 2016 15:17:22 -0800:

that is one step extra in EVERY access

Not at all. If you are aware of the scope of your variables, there is
no need to check it every time.

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:13 AM   in response to: Brandon Staggs in response to: Brandon Staggs
Brandon Staggs wrote:

"Rudy Velthuis" wrote on Thu, 18 Feb 2016 15:17:22 -0800:

that is one step extra in EVERY access

Not at all.

Yes, it is. If you must check for nil on every access that is one extra
step on EVERY access.

--
Rudy Velthuis http://www.rvelthuis.de

"Barabási's Law of Programming: Program development ends when the
program does what you expect it to do - whether it is correct or
not." -- Albert-László Barabási
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:41 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
"Rudy Velthuis" wrote on Sat, 20 Feb 2016 05:13:20 -0800:

Brandon Staggs wrote:

"Rudy Velthuis" wrote on Thu, 18 Feb 2016 15:17:22 -0800:

that is one step extra in EVERY access

Not at all.

Yes, it is. If you must check for nil on every access that is one extra
step on EVERY access.

Why did you snip the rest of my post and reply as if I had not
explained what I meant?

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
David Erbas-White

Posts: 202
Registered: 10/11/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 6:28 PM   in response to: Brandon Staggs in response to: Brandon Staggs
On 2/21/2016 11:41 AM, Brandon Staggs wrote:

Why did you snip the rest of my post and reply as if I had not
explained what I meant?

Oh! Oh! I know! Pick me!!!

...because it's Rudy?!?

David Erbas-White
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:50 AM   in response to: David Novo in response to: David Novo
David Novo wrote:

Hi Nick,

Your presumption is the NIL represents a bad state

Well, try to access it and see what happens. <g>

"Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end." — Henry Spencer

It represents a special state, for which you must check. You can forget
such a check, so a state that requires such a check is not ideal and
the code is fragile. A situation where such a check is not necessary,
because it can't fail, is preferrable. It is not so hard to create only
such situations.

--
Rudy Velthuis http://www.rvelthuis.de

"A C program is like a fast dance on a newly waxed dance
floor by people carrying razors." -- Waldi Ravens.
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 1:38 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 15.02.2016 um 15:50 schrieb Rudy Velthuis (TeamB):
David Novo wrote:

Hi Nick,

Your presumption is the NIL represents a bad state

Well, try to access it and see what happens. <g>

"Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end." — Henry Spencer

It represents a special state, for which you must check. You can forget
such a check, so a state that requires such a check is not ideal and
the code is fragile. A situation where such a check is not necessary,
because it can't fail, is preferrable. It is not so hard to create only
such situations.

Hm, in case of that raincoat a NULL raincoat presents a special state
which needs to be checked for as well ;-)

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 3:43 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Hm, in case of that raincoat

What raincoat?

--
Rudy Velthuis http://www.rvelthuis.de

"Pain is certain, suffering is optional."
-- Buddha
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 11:37 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 16.02.2016 um 00:43 schrieb Rudy Velthuis (TeamB):
Markus Humm wrote:

Hm, in case of that raincoat

What raincoat?

The one from David Novo's post you had replied to.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 2:03 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:

Encapsulation dictates that you not only hide
your internals, but you protect them from being placed in bad or
impossible states.

FWIW, I think that is the main purpose of encapsulation: to prevent
access from outside to the state you want to protect.

The first thing this means is that no internal object instance should
ever be exposed as nil. If you have an object as an internal member,
you should ensure that it is created before it is needed, and that it
remains created and valid throughout the time that it is exposed to
the end user.

A> Note that this position allows for "lazy" initialization of
objects, that is, the creation of objects on demand rather than on the
initialization of the object.

While I see that lazy initialization is widely accepted, I personally
wouldn't use it. In your getter method, you must constantly check if
the internal item that is accessed is nil, even after it was created
and exposed. That is, IMO, a lot of wasted time. And it requires
slightly more complicated and slightly less readable code, a possible
source of error.
--
Rudy Velthuis http://www.rvelthuis.de

"You can't say civilizations don't advance, because they kill
you in a new way in each war."
-- Will Rogers
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 11:51 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I personally
wouldn't use it.

Lazy instantiation is often inevitable when you map objects to data. Basic example:

Type tPerson=class
private
   fname:String;
   fID:tGuid;
   ffather,fmother:tPerson;
   function getname:String;
   procedure setname(const value:String);
   function getfather:tPerson;
   function getmother:tPerson;
public
   Constructor CreateFromDB(aID:tguid; Db:tDatabase);
   Property ID:tGuid read fID;
   Property name:String read getname write setname;
   Property father:tPerson read getfather;   
   Property mother:tPerson read getmother;
end;

Now if lazy instantiation weren't an option..... then creating a tPerson would cause a recursion which would immediately load all his ancestors from the database up to Adam and Eve. And this class doesn't even implement siblings yet...

Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 8:36 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Am 17.02.2016 um 08:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I personally
wouldn't use it.

Lazy instantiation is often inevitable when you map objects to data. Basic example:

Type tPerson=class
private
   fname:String;
   fID:tGuid;
   ffather,fmother:tPerson;
   function getname:String;
   procedure setname(const value:String);
   function getfather:tPerson;
   function getmother:tPerson;
public
   Constructor CreateFromDB(aID:tguid; Db:tDatabase);
   Property ID:tGuid read fID;
   Property name:String read getname write setname;
   Property father:tPerson read getfather;   
   Property mother:tPerson read getmother;
end;

Now if lazy instantiation weren't an option..... then creating a tPerson would cause a recursion which would immediately load all his ancestors from the database up to Adam and Eve. And this class doesn't even implement siblings yet...


Even more what would happen if the DB doesn't contain a father/mother
for some person? Will those then be nil?

Greetings

Markus
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 8:48 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:
Am 17.02.2016 um 08:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I personally
wouldn't use it.

Lazy instantiation is often inevitable when you map objects to data. Basic example:

Type tPerson=class
private
   fname:String;
   fID:tGuid;
   ffather,fmother:tPerson;
   function getname:String;
   procedure setname(const value:String);
   function getfather:tPerson;
   function getmother:tPerson;
public
   Constructor CreateFromDB(aID:tguid; Db:tDatabase);
   Property ID:tGuid read fID;
   Property name:String read getname write setname;
   Property father:tPerson read getfather;   
   Property mother:tPerson read getmother;
end;

Now if lazy instantiation weren't an option..... then creating a tPerson would cause a recursion which would immediately load all his ancestors from the database up to Adam and Eve. And this class doesn't even implement siblings yet...


Even more what would happen if the DB doesn't contain a father/mother
for some person? Will those then be nil?

On the other hand null (nil) values can pose a serious problems :)

How do I correctly pass the string “Null” (an employee's proper surname) to a SOAP web service from ActionScript 3?
http://stackoverflow.com/q/4456438/4267244

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 11:15 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Even more what would happen if the DB doesn't contain a father/mother
for some person? Will those then be nil?

For those special cases there's a John and Jane Doe which the database sets using a default constraint...

Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:19 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Am 18.02.2016 um 08:15 schrieb Arthur Hoornweg:
Markus Humm wrote:

Even more what would happen if the DB doesn't contain a father/mother
for some person? Will those then be nil?

For those special cases there's a John and Jane Doe which the database sets using a default constraint...


Means the database tells me the father's name is John Doe. But how can I
distinguish that from "the real John Doe" if it should exist? ;-)

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 11:41 PM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I
personally wouldn't use it.

Lazy instantiation is often inevitable when you map objects to data.


How so? I don't think it is inevitable.

--
Rudy Velthuis http://www.rvelthuis.de

"Puritanism: The haunting fear that someone, somewhere, may be
happy." -- H. L. Mencken
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:20 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 18.02.2016 um 08:41 schrieb Rudy Velthuis (TeamB):
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I
personally wouldn't use it.

Lazy instantiation is often inevitable when you map objects to data.


How so? I don't think it is inevitable.

Because otherwise you might end uploading big junks of data into memory
just to avoid lazy initialoization.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:27 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Am 18.02.2016 um 08:41 schrieb Rudy Velthuis (TeamB):
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I
personally wouldn't use it.

Lazy instantiation is often inevitable when you map objects to

data.

How so? I don't think it is inevitable.

Because otherwise you might end uploading big junks of data into
memory just to avoid lazy initialoization.

No, sorry, that's not true. I never said you could not instantiate an
object when it is needed, and not earlier. That does not require lazy
initialization, though. It all depends on who needs access to the
object, and how long or short lived that access must be.
--
Rudy Velthuis http://www.rvelthuis.de

"Simplicity is the ultimate sophistication."
-- Leonardo da Vinci
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 10:03 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 18.02.2016 um 23:27 schrieb Rudy Velthuis (TeamB):
Markus Humm wrote:

Am 18.02.2016 um 08:41 schrieb Rudy Velthuis (TeamB):
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

While I see that lazy initialization is widely accepted, I
personally wouldn't use it.

Lazy instantiation is often inevitable when you map objects to

data.

How so? I don't think it is inevitable.

Because otherwise you might end uploading big junks of data into
memory just to avoid lazy initialoization.

No, sorry, that's not true. I never said you could not instantiate an
object when it is needed, and not earlier. That does not require lazy
initialization, though. It all depends on who needs access to the
object, and how long or short lived that access must be.

But then you have to check everytime whether the data has already been
loaded / the object is already constructed.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:14 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

But then you have to check everytime whether the data has already been
loaded / the object is already constructed.

No, no, no, no, no. Of course not. You just limit the scope in which it
is instantiated and you free it near the very end of that scope.

--
Rudy Velthuis http://www.rvelthuis.de

"Men who believe absurdities will commit atrocities."
-- Voltaire
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 4:03 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Below is a section of my book "More Coding in Delphi" discussing the
issue of 'nil' in code.

Note that Dalija will be happy, as I concede that nil can, for specific
purposes, be used. I'm happy to eat my previous words on the topic
after reviewing what I actually wrote in my book. I was wrong to assert
that nil should never be allowed.

I am happy :)

I still stand by my statements that nil should never be accepted by a
method as an argument and that nil should never be exposed by an API or
returned by a function.

Exceptions, exceptions :)

constructor TComponent.Create(AOwner: TComponent); <- nil is allowed here
 
 
function TCollection.FindName(const Name: string): TCollectionItem;
var Item: TCollectionItem;
begin
  Result := nil;
  for Item in Items do
    if Item.DisplayName = Name then
      begin
         Result := Item;
         break;
      end;  
end;
 


Above code perfectly acceptable, especially in base frameworks. Creating
empty collection item would be overkill there. You don't know how actual
TCollectionItem class looks like and what would be repercussions of creating
its instance. Returning nil is preferable here. Although at some point at higher
level you may want to wrap that function and in case it gives you nil you
could create and return empty object to your consumers.

So never say never to anything. It is preferable not to use nil, because it is safer
but there are exceptions to that.

Bruce will be happy because I explain myself better and started a new
thread. ;-)

I guess so :)


function GetListOfWidgets: TWidgetCollection;
begin
if Widgets.Count = 0 then
begin
Result := nil
end else
begin
Result := Widgets; // Of type TWidgetCollection
end;
end;

This function could return nil. Therefore, any code that consumes
`GetListOfWidgets` had to check for `nil` every time. This can be
tedious. Rather than returning `nil`, the code should instead return an
empty list to indicate that there are no widgets in the collection.

Maybe not the best example in the world. Or at least it does not
explain perfectly what you are trying to say. Why?

Because I cannot imagine myself writing code from your example.
If I already have Widgets collection I would simply return that collection
regardless of its count.

On the other hand, if in my internal state Widgets collection is nil if
there are no items in it, then we could discuss whether returning nil
would be appropriate, or it would be better to create Widgets and return
empty list.

I would say don't return nil in above case, but again I can see possible
exceptions. (I'll try to elaborate later on in another post)

A class should never be allowed to present itself to the consumer as
`nil`. Normally, this means you should create your internal objects in
the constructor of the containing class and never free them until the
destructor is called. If you have some need to "reset" your class
during its lifetime, then have a routine that does that explicitly.
Always protect your internal classes so that a consumer can never see a
bad state - especially `nil`.

It is sound advice, but there are still exceptions to that rule ;-)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 5:15 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Exceptions, exceptions :)

Both of the ones you list are merely design flaws in the VCL.

Because I cannot imagine myself writing code from your example.

Neither can I. It's a bad example on purpose. ;-)


--
Nick
Delphi Programming is Fun

Arnaud Bouchez

Posts: 137
Registered: 8/2/15
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 5:54 AM   in response to: Nick Hodges in response to: Nick Hodges
Dalija Prasnikar wrote:
Exceptions, exceptions :)

IMHO Exceptions should be exceptional.
Never use an exception but for a "panic" state of the application.
Arnaud Bouchez

Posts: 137
Registered: 8/2/15
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 5:55 AM   in response to: Arnaud Bouchez in response to: Arnaud Bouchez
Arnaud Bouchez wrote:
Never use an exception but for a "panic" state of the application.

https://golang.org/doc/faq#exceptions
Mike Margerum

Posts: 590
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:20 AM   in response to: Arnaud Bouchez in response to: Arnaud Bouchez

I love the explicitness of GO's error handling. I handle it. I bubble
it up if I choose to. No ambiguity.

I like being able to write async code imperatively simply by placing the
word "go" in front of my function. I don't want to have to think
asynchronously to write my code that runs asynchronously. These
goroutines are extremely lightweight. You can run thousands of them.

There are no objects, just interfaces that get implemented implicitly
just by matching function signatures.

You have everything you need to build scalable web services / apps right
in the GO standard library. The only external dependencies I have are
gorilla mux for routing and and ODBC SQL driver.

Everything is explicit and opinionated. I don't mind an opinionated
language if guys like Rob Pike and Ken Thompson are at the helm.

GO is so great and I can say that after writing thousands of lines of
server code in it.

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:54 AM   in response to: Arnaud Bouchez in response to: Arnaud Bouchez
Arnaud Bouchez wrote:

Dalija Prasnikar wrote:
Exceptions, exceptions :)

IMHO Exceptions should be exceptional.
Never use an exception but for a "panic" state of the application.

I think Nick meant: exceptions to the general rule. Not exceptions as a
programming mechanism.

--
Rudy Velthuis http://www.rvelthuis.de

"Programming can be fun, so can cryptography; however they
should not be combined." -- Kreitzberg and Shneiderman
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 7:02 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Arnaud Bouchez wrote:

Dalija Prasnikar wrote:
Exceptions, exceptions :)

IMHO Exceptions should be exceptional.
Never use an exception but for a "panic" state of the application.

I think Nick meant: exceptions to the general rule. Not exceptions as a
programming mechanism.

Actually, I said that. And yes, I meant it the way you said :)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Arnaud Bouchez

Posts: 137
Registered: 8/2/15
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 7:05 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:
Actually, I said that. And yes, I meant it the way you said :)

Sorry for my misunderstanding.
:(
I imagined it was about raising an exception instead of using nil as a flag.
;)
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 7:11 AM   in response to: Arnaud Bouchez in response to: Arnaud Bouchez
Arnaud Bouchez wrote:
Dalija Prasnikar wrote:
Actually, I said that. And yes, I meant it the way you said :)

Sorry for my misunderstanding.
:(
I imagined it was about raising an exception instead of using nil as a flag.
;)

I guessed so, but Rudy was faster in his reply that me :)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:59 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Dalija Prasnikar wrote:

Exceptions, exceptions :)

Both of the ones you list are merely design flaws in the VCL.

Nope.

In first case you have to allow nil owner because (if nothing else)
at some point in your component hierarchy you will have root element
with nil owner.

In second case, I think I have demonstrated why creating and returning
empty instance would be wrong. TCollection is one of the base classes
and you don't know where and how it will be used. You have no idea of
what TCollectionItem it might store, creating one might have deeper
implications. Also, you may have valid cases of allowing empty instances in
your hierarchy, but you want to differentiate between actually finding existing
instance in collection or not. If you return nil you can cater for all use cases.
If you create empty item, you cannot.

At least not without adding additional methods into TCollectionItem base class
that would allow you to test whether or not that Item is empty (null) or whatever
you might need in such case. That adds additional unnecessary code in
TCollectionItem class.


Because I cannot imagine myself writing code from your example.

Neither can I. It's a bad example on purpose. ;-)

With such bad example you lose your punch line. You don't want to present
me with code I would never write and try to convince me that I should not
return nil in that case. Of course, I wouldn't. But, such bad example cannot
possibly stop me from returning nil. You should use code I would write and
then demonstrate why it is bad idea to return nil in that code.

Of course, you would have hard time convincing me that too because I know
there are places where returning nil is perfectly acceptable.

If you say never return nil or never pass nil, you will divide your readers into
two groups. first are the ones that will say that is total nonsense, I know why
I want to return or pass nil. Others would embrace your premise and some day
they may find themselves writing some hideous code because they will avoid
using nil in case where they actually should use nil.

That is bad for you and for your readers and for teaching people that nil is not
always the best option.

What I would do is to make example where nil is acceptable and why, and I
would also make example where there is another, better way and also explain why.

With my TCollection example, you could use that as first one, and then you may
introduce some leaf (final) collection class with well defined items and wrap
"bad" nil returning function into another safer one that does not return nil.

If you can show wide variety of code with explanations why is some better and
when then you show that you have thoroughly covered problem you talk about
and you might teach people to use safer approach when such approach is
acceptable. Otherwise, you make yourself open for attacks from other side
that knows exceptions to the rule you want to teach :)

The lower the code (class) is in some framework hierarchy, the more
potential use cases and consumers it may have and you have to be more flexible
with such classes. And when it comes to some final or top level classes you
can go ahead and build Fort Knox around them if you like, because there you
can more easily see or define how is that class going to be used.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:04 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Nope.

All of what you wrote assumes that the VCL works as it does today.


--
Nick
Delphi Programming is Fun

Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:12 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Dalija Prasnikar wrote:

Nope.

All of what you wrote assumes that the VCL works as it does today.

Then how would you redesign it? At least some parts?

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:40 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:


Then how would you redesign it? At least some parts?

LOL -- Well, that's a huge question, isnt' it. ;-)

--
Nick
Delphi Programming is Fun
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 1:42 PM   in response to: Nick Hodges in response to: Nick Hodges
Am 15.02.2016 um 17:40 schrieb Nick Hodges:
Dalija Prasnikar wrote:


Then how would you redesign it? At least some parts?

LOL -- Well, that's a huge question, isnt' it. ;-)

Which you try to avoid to answer, isn't it? ;-)
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 1:51 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Which you try to avoid to answer, isn't it? ;-)

How many pages long do you think it would be?

--
Nick
Delphi Programming is Fun
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 11:38 AM   in response to: Nick Hodges in response to: Nick Hodges
Am 15.02.2016 um 22:51 schrieb Nick Hodges:
Markus Humm wrote:

Which you try to avoid to answer, isn't it? ;-)

How many pages long do you think it would be?

You could start with some simple bullet points to simply share your high
level ideas. No need to delve into every detail.
So one screen full should already cover quite a lot.

Greetings

Markus
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 3:03 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Dalija Prasnikar wrote:


Then how would you redesign it? At least some parts?

LOL -- Well, that's a huge question, isnt' it. ;-)

I didn't ask you to redesign the whole darn thing ;-)

Just give us some solutions... you cannot just say it is bad
in needs to be redesigned and leave it at it. How is important
part.

How about solving TComponent.Create(AOwner: TComponent) where
owner can be nil. How would you handle root component?

Or TControl.PopupMenu property that links to external component,
how would you solve that one (and VCL is full of references like that one)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar

Christopher Burke

Posts: 580
Registered: 9/25/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 5:04 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Just give us some solutions...

Solutions can't be given for a number of practical cases.

If one talks theory - one can solve all the problems you want :)

In theory - no-one on Earth should be starving.

Theory is a wonderful place to dream, but a poor place to earn a living.

Unless like Nick you write books, because books are meant to give you
best practice so you can AIM for best practice - not so you can achieve
it.
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 6:30 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

How about solving TComponent.Create(AOwner: TComponent) where
owner can be nil. How would you handle root component?

I'd probably have the root component be a special component designed to
be the root component.

--
Nick
Delphi Programming is Fun
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 12:26 PM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Dalija Prasnikar wrote:

How about solving TComponent.Create(AOwner: TComponent) where
owner can be nil. How would you handle root component?

I'd probably have the root component be a special component designed to
be the root component.

Can you add more details how would those classes look like (regarding to
Owner field)?

And you didn't say how would you solve reference to another component so
that it doesn't use nil.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 11:27 PM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:

All of what you wrote assumes that the VCL works as it does today.

The Visual Component Library is a prime example of how it makes perfectly good sense to expose NIL pointers in published properties. The whole event handling system of tComponent is based on properties like OnClick, OnKeyPress, OnResize... And all of these are NIL by default, and also published.

"Booking" an event involves setting the event handler to a valid callback method. If you're no longer interested in events you set the handler to NIL. By consequence, the VCL components need to do NIL checks such as

If assigned (fOnClick) then
   fOnClick(Self);


Delphi's event system clearly follows the pattern of "a pointer should be either valid or NIL to indicate it's not in use".
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 12:53 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

The Visual Component Library is a prime example of how it makes
perfectly good sense to expose NIL pointers in published properties.

No, it isn't. What if a control exposed a nil Font? Most code using
fonts would fail.

--
Rudy Velthuis http://www.rvelthuis.de

"The biggest conspiracy of all is the claim that there are no
conspiracies!"
-- Michael Rivero
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 1:58 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

No, it isn't. What if a control exposed a nil Font? Most code using
fonts would fail.

Then the control doesn't use a font. A push button, for example, may not need a font at all. However, if the control exposes a canvas then the documented rules for tCanvas should apply.

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 6:18 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

No, it isn't. What if a control exposed a nil Font? Most code using
fonts would fail.

Then the control doesn't use a font.

If I access a font on a control, no matter which, it should exist and I
should be able to set its properties without checking for nil first.

And I am sure that most code setting the font properties on a control
does not (and does not need to) check for nil, just because the font is
always valid.
--
Rudy Velthuis http://www.rvelthuis.de

"Never test for an error condition you don't know how to handle."
-- Steinbach's Guideline for Systems Programmers.
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:21 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 18.02.2016 um 15:18 schrieb Rudy Velthuis (TeamB):
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

No, it isn't. What if a control exposed a nil Font? Most code using
fonts would fail.

Then the control doesn't use a font.

If I access a font on a control, no matter which, it should exist and I
should be able to set its properties without checking for nil first.

And I am sure that most code setting the font properties on a control
does not (and does not need to) check for nil, just because the font is
always valid.

So if a control has a OnClick handler option it shopuld never be nil?
What should it be then?

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:29 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

So if a control has a OnClick handler option it shopuld never be nil?

Not necessarily. There could be a default NOP implementation. I would
prefer such a solution.

--
Rudy Velthuis http://www.rvelthuis.de

"War is fear cloaked in courage." -- General William Westmoreland
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 7:51 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I would
prefer such a solution.

The onClick handler is not an object. It points to a method outside of the control and is assigned from the outside, it is not the control that manages its state.

Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 10:04 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I would
prefer such a solution.

The onClick handler is not an object. It points to a method outside of the control and is assigned from the outside, it is not the control that manages its state.


Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:17 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I
would >> prefer such a solution.


The onClick handler is not an object. It points to a method outside
of the control and is assigned from the outside, it is not the
control that manages its state.

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

Indeed. Perhaps not TNotifyEvent, but my version of it. And it can be
the same one for all "unassigned" event handlers of the same type.

--
Rudy Velthuis http://www.rvelthuis.de

"We do have a zeal for laughter in most situations, give or
take a dentist." -- Joseph Heller
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:29 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Markus Humm wrote:

Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I
would >> prefer such a solution.


The onClick handler is not an object. It points to a method outside
of the control and is assigned from the outside, it is not the
control that manages its state.

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

Indeed. Perhaps not TNotifyEvent, but my version of it. And it can be
the same one for all "unassigned" event handlers of the same type.

Brilliant design.

Reading this makes me immensely happy that framework designers on various
platforms and tools decided to go with darn nil pattern after all.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:29 PM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Markus Humm wrote:

Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I
would >> prefer such a solution.


The onClick handler is not an object. It points to a method
outside of the control and is assigned from the outside, it is
not the control that manages its state.

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

Indeed. Perhaps not TNotifyEvent, but my version of it. And it can
be the same one for all "unassigned" event handlers of the same
type.

Brilliant design.

Not really. It is something that has been done for ages: default
implementation.

Reading this makes me immensely happy that framework designers on
various platforms and tools decided to go with darn nil pattern after
all.

Why are you so happy about it? You love less safety and more work?

--
Rudy Velthuis http://www.rvelthuis.de

"I do note with interest that old women in my books become young
women on the covers... this is discrimination against the
chronologically gifted."
--Terry Pratchett
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 1:32 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Markus Humm wrote:

Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I
would >> prefer such a solution.


The onClick handler is not an object. It points to a method
outside of the control and is assigned from the outside, it is
not the control that manages its state.

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

Indeed. Perhaps not TNotifyEvent, but my version of it. And it can
be the same one for all "unassigned" event handlers of the same
type.

Brilliant design.

Not really. It is something that has been done for ages: default
implementation.

Reading this makes me immensely happy that framework designers on
various platforms and tools decided to go with darn nil pattern after
all.

Why are you so happy about it? You love less safety and more work?

I have far less work and cleaner code using nil.

And I do love safety, but not when it makes things more complicated.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:16 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Markus Humm wrote:

Am 19.02.2016 um 16:51 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP
implementation. I would >> prefer such a solution.


The onClick handler is not an object. It points to a method
outside of the control and is assigned from the outside, it
is not the control that manages its state.

Rudy's idea is to generate quite a lot of code automatically
or invisibly by spending the component an empty event handler
of the TNotifyEvent type which is automatically assigned to
all events on creation of that object.

Indeed. Perhaps not TNotifyEvent, but my version of it. And it
can be the same one for all "unassigned" event handlers of the
same type.

Brilliant design.

Not really. It is something that has been done for ages: default
implementation.

Reading this makes me immensely happy that framework designers on
various platforms and tools decided to go with darn nil pattern
after all.

Why are you so happy about it? You love less safety and more work?

I have far less work and cleaner code using nil.

I doubt that. It certainly isn't cleaner and probably not less work
either.

And I do love safety, but not when it makes things more complicated.

Why would it makes things more complicated? On the contrary. Nil makes
things complicated.

--
Rudy Velthuis http://www.rvelthuis.de

"Put your hand on a hot stove for a minute, and it seems like
an hour. Sit with a pretty girl for an hour, and it seems like
a minute. That's relativity."
-- Albert Einstein
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 11:05 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija,

| I have far less work and cleaner code using nil.

Ditto. When needed.

--

Q -- XanaNews 1.19.1.372 - 2016-02-22 11:05:10
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:13 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

That's quite clear, but (A) it costs CPU cycles because the component keeps calling this dummy function all the time without need, and (B) it offers no additional security because I can still set an event handler and mismanage the life time. All it does is satisfy a dogma.

It has possible side effects too, some components use events for other things than notification (tfield.ongettext just to name one) . So instead of checking for NIL, the component would have to check for the dummy method.

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:27 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Markus Humm wrote:

Rudy's idea is to generate quite a lot of code automatically or
invisibly by spending the component an empty event handler of the
TNotifyEvent type which is automatically assigned to all events on
creation of that object.

That's quite clear, but (A) it costs CPU cycles because the component
keeps calling this dummy function all the time without need,


It is a nop, so only a ret is performed. Probably faster than a test
and a conditional branch.

But what makes it better is that you can't forget to check for nil,
because you don't have to check for it.

--
Rudy Velthuis http://www.rvelthuis.de

"Men are not punished for their sins, but by them."
-- Elbert G Hubbard
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:15 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

Not necessarily. There could be a default NOP implementation. I
would prefer such a solution.

The onClick handler is not an object.


But it is something that can be nil. Which means that every time I want
to call it, I must check if it is assigned. That is one extra step on
each access.

--
Rudy Velthuis http://www.rvelthuis.de

"Computers make it easier to do a lot of things, but most of the
things they make it easier to do don't need to be done."
-- Andy Rooney.
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:20 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

But it is something that can be nil. Which means that every time I want
to call it, I must check if it is assigned. That is one extra step on
each access.

tForm alone has some 30 event handlers and setting all of these to a dummy routine involves 30 steps. Whereas the constructor nicely sets them all to NIL without additional cost.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:25 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

But it is something that can be nil. Which means that every time I
want to call it, I must check if it is assigned. That is one extra
step on each access.

tForm alone has some 30 event handlers and setting all of these to a
dummy routine involves 30 steps.

Not at all. That would be done in the constructor of my version of the
VCL (RV-VCL <g>).

--
Rudy Velthuis http://www.rvelthuis.de

"Whenever I hear anyone arguing for slavery, I feel a strong
impulse to see it tried on him personally."
-- Abraham Lincoln
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:47 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Not at all. That would be done in the constructor of my version of the
VCL (RV-VCL <g>).

That can't be done because some of the event handlers have different signatures.
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 12:43 PM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Am 22.02.2016 um 15:47 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not at all. That would be done in the constructor of my version of the
VCL (RV-VCL <g>).

That can't be done because some of the event handlers have different signatures.

I guess Rudy's solution would use RTTI if possible to determine which
handler has which signature. Or they could be annotated with attributes.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 23, 2016 2:58 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Am 22.02.2016 um 15:47 schrieb Arthur Hoornweg:
Rudy Velthuis (TeamB) wrote:

Not at all. That would be done in the constructor of my version of
the >> VCL (RV-VCL <g>).

That can't be done because some of the event handlers have
different signatures.

I guess Rudy's solution would use RTTI if possible to determine which
handler has which signature.

Huh? The constructor KNOWS the types of events the object exposes. No
need for RTTI, this can be done at compile time.
--
Rudy Velthuis http://www.rvelthuis.de

"A woman is an occasional pleasure but a cigar is always a smoke."
-- Groucho Marx
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 3:19 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Huh? The constructor KNOWS the types of events the object exposes. No
need for RTTI, this can be done at compile time.

That's one tedious constructor then, just to omit a few NIL checks.

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 5:33 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

Huh? The constructor KNOWS the types of events the object exposes.
No need for RTTI, this can be done at compile time.

That's one tedious constructor then, just to omit a few NIL checks.

Huh? What is tedious about a constructor, er... constructing and
initializing the classes and other types it needs? That is, AFAIK, what
constructors do.
--
Rudy Velthuis http://www.rvelthuis.de

"Written laws are like spider's webs; they will catch, it is
true, the weak and poor, but would be torn in pieces by the
rich and powerful."
-- Anacharsis
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 23, 2016 2:57 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

Not at all. That would be done in the constructor of my version of
the VCL (RV-VCL <g>).

That can't be done because some of the event handlers have different
signatures.

Of course there would be a default (NOP) implementation for every event
type. No biggie.
--
Rudy Velthuis http://www.rvelthuis.de

"Comedy is simply a funny way of being serious."
-- Peter Ustinov (1921-2004)
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 6:19 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Delphi's event system clearly follows the pattern of "a pointer
should be either valid or NIL to indicate it's not in use".

Yep, and I bet that design could be improved upon if, after 21 years,
the VCL were completely redesigned.

--
Nick
Delphi Programming is Fun
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:22 AM   in response to: Nick Hodges in response to: Nick Hodges
Am 18.02.2016 um 15:19 schrieb Nick Hodges:
Arthur Hoornweg wrote:

Delphi's event system clearly follows the pattern of "a pointer
should be either valid or NIL to indicate it's not in use".

Yep, and I bet that design could be improved upon if, after 21 years,
the VCL were completely redesigned.

Which reminds me of the high level design overview Nick wanted to post
about the new design he'd do ;-)

Greetings

Markus
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:23 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:

Yep, and I bet that design could be improved upon if, after 21 years,
the VCL were completely redesigned.

If I had anything to say in it, I'd make it interface based.

Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:55 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

If I had anything to say in it, I'd make it interface based.

As would I.

--
Nick
Delphi Programming is Fun
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:33 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:

Arthur Hoornweg wrote:

If I had anything to say in it, I'd make it interface based.

As would I.

I wouldn't, but I would certainly make it interface supporting.

--
Rudy Velthuis http://www.rvelthuis.de

"In the end, everything is a gag." -- Charlie Chaplin (1889-1977)
James Woodard

Posts: 15
Registered: 11/5/04
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 12:01 PM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
"Dalija Prasnikar" wrote in message news:806463 at forums dot embarcadero dot com...

Nick Hodges wrote:

While I could never hold a candle to either of you regarding programming
theory, I can think of one case that happens often in my own classes.

TExampleClass = class
private
fID: integer;
public
constructor create;
destructor destroy; override;

property ID: integer read fID write fID;
end;

TExampleClassList = class
private
fList: TObjectLIst;

function GetExampleAt(index: integer): TExampleClass;
public
constructor Create;
destructor Destroy;

property Example[index: integer]: TExampleClass read GetExampleAt;
end;

Now, leaving aside the obvious constructors/destructors, the main
concentration is on the Example property for TExampleClassList;

function TExampleClassList.GetExampleAt(index: integer): TExampleClass;
begin
if (fList.Count > 0) and (index >= 0) and (index < fList.Count) then
result := TExampleClass(fList[index])
else
result := nil;
end;

No amount of pre-testing can stop an occasional wrong index to be passed
depending on the situation. How would you change this type of situation and
what would you return if an invalid index is passed?

Woody
David Millington

Posts: 257
Registered: 5/29/05
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 12:09 PM   in response to: James Woodard in response to: James Woodard
James Woodard wrote:
the main concentration is on the Example property for TExampleClassList;

function TExampleClassList.GetExampleAt(index: integer): TExampleClass;
begin
if (fList.Count > 0) and (index >= 0) and (index < fList.Count) then
result := TExampleClass(fList[index])
else
result := nil;
end;

No amount of pre-testing can stop an occasional wrong index to be passed
depending on the situation. How would you change this type of situation and
what would you return if an invalid index is passed?

Personally, that to me is an exceptional situation - index out of bounds. Assuming the class has a Count property, and exposes the items via an indexed property that calls into GetExampleAt, then an index out of bounds is a programming error. I'd raise an EOutOfBounds exception (or whatever it is. EIndexOutOfBounds? I can't remember the name.)

Edit: I notice your example class doesn't have a Count property, even though it has an indexed property. I'd say that's an error.

Edited by: David Millington on Feb 16, 2016 7:09 AM
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 3:12 AM   in response to: James Woodard in response to: James Woodard
James Woodard wrote:
"Dalija Prasnikar" wrote in message news:806463 at forums dot embarcadero dot com...

Nick Hodges wrote:

While I could never hold a candle to either of you regarding programming
theory, I can think of one case that happens often in my own classes.

TExampleClass = class
private
fID: integer;
public
constructor create;
destructor destroy; override;

property ID: integer read fID write fID;
end;

TExampleClassList = class
private
fList: TObjectLIst;

function GetExampleAt(index: integer): TExampleClass;
public
constructor Create;
destructor Destroy;

property Example[index: integer]: TExampleClass read GetExampleAt;
end;

Now, leaving aside the obvious constructors/destructors, the main
concentration is on the Example property for TExampleClassList;

function TExampleClassList.GetExampleAt(index: integer): TExampleClass;
begin
if (fList.Count > 0) and (index >= 0) and (index < fList.Count) then
result := TExampleClass(fList[index])
else
result := nil;
end;

No amount of pre-testing can stop an occasional wrong index to be passed
depending on the situation. How would you change this type of situation and
what would you return if an invalid index is passed?

Primary depends on what do you mean by wrong index. Is it pure error where
raising exception is in order, or you would allow wrong index as part of normal
workflow that just needs to be handled differently.

I would go for two options, first one is raising OutOfRange error, second is returning
nil. I am leaning toward second one, because it is more flexible. And accessing nil
instance would throw AV, so in case of bug you need to fix it makes very little
difference if you know that it is out of range error or accessing nil. But it really
depends on context in which that code would be used.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
David Millington

Posts: 257
Registered: 5/29/05
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:23 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
It's a bad example on purpose. ;-)

Clearly what we need is a new implementation of FreeAndNil, with excellent top-notch use of exceptions and beloved language features like 'with'. I'm sure Nick will love this. Want to put it in your book, if you need an example of Good (ahem cough cough choke) Code?

(Don't judge me.)

type
  TNilChecker = record
  private
    FObj : TObject;
  public
    constructor CreateFromObj(Obj : TObject);
    function Assigned : Boolean;
  end;
 
...
 
constructor TNilChecker.CreateFromObj(Obj : Object);
begin
  if not Assigned(Obj) then
    raise ENilException.Create;
  FObj := Obj;
end;
 
function TNilChecker.Assigned : Boolean;
begin
  Result := FObj <> nil;
end;
 
procedure FreeAndNil(var Obj : TObject);
begin
  try
    with TNilChecker.CreateFromObj(Obj) do
      if Assigned do begin
        Obj.Free;
        Obj := nil;
      end;
  except
    on E : ENilException do ; // Obj is already nil, no need for action
  end;
end;


Ok. How much bad code can I put in one post? I am extraordinarily, incredibly happy with this abomination :D

Edit: Announcing the Bad Delphi Code Competition: https://parnassus.co/bad-delphi-code-the-competition/

Edited by: David Millington on Feb 16, 2016 3:24 AM

Edited by: David Millington on Feb 16, 2016 4:46 AM
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:41 AM   in response to: David Millington in response to: David Millington
You are a bad, bad man.

--
Nick
Delphi Programming is Fun

David Millington

Posts: 257
Registered: 5/29/05
Re: Never Let a Bad State Happen [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 10:13 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
You are a bad, bad man.

Thank you :)
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 12:00 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

function TCollection.FindName(const Name: string): TCollectionItem;
var Item: TCollectionItem;
begin
  Result := nil;
  for Item in Items do
    if Item.DisplayName = Name then
      begin
         Result := Item;
         break;
      end;  
end;
 

IMHO not the best example, since this is a "search" function and the result is abused to give both answers (successful or not, and if yes, which item found). Wouldn't a boolean be more appropriate?


 
 
 function TCollection.HaveName(const Name: string; OUT aMatch:tCollectionitem):Boolean;
 var Item: TCollectionItem;
 begin
   aMatch := nil;
   Result:=False; 
   for Item in Items do
     if Item.DisplayName = Name then
       begin
          aMatch := Item;
          Exit(True);
       end;  
 end;
 
 
 
If fColl.HaveName('somebody', item) then
begin
  ...do something with item
end;
 
 
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 2:36 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:
Dalija Prasnikar wrote:

function TCollection.FindName(const Name: string): TCollectionItem;
var Item: TCollectionItem;
begin
  Result := nil;
  for Item in Items do
    if Item.DisplayName = Name then
      begin
         Result := Item;
         break;
      end;  
end;
 

IMHO not the best example, since this is a "search" function and the result is abused to give both answers (successful or not, and if yes, which item found). Wouldn't a boolean be more appropriate?

 
 
 
 function TCollection.HaveName(const Name: string; OUT aMatch:tCollectionitem):Boolean;
 var Item: TCollectionItem;
 begin
   aMatch := nil;
   Result:=False; 
   for Item in Items do
     if Item.DisplayName = Name then
       begin
          aMatch := Item;
          Exit(True);
       end;  
 end;
 
 
 
If fColl.HaveName('somebody', item) then
begin
  ...do something with item
end;
 
 

Not really.

First, I prefer function returning actual result rather than moving most
important part into out parameter. I am reserving out parameters for
cases where there is no simple alternative and I need to return two
or more complex variables. In above case nil is non-ambiguous flag
and I don't see the reason for separating it.

Also with function result code is more obvious at place of call than with
out parameter. In case of out parameter you have to know that function
uses out parameter. That might not be so clear if anyone else has to
read and understand your code.

My code can also be extended to work with generics adding additional
type safety.

function TCollection<T>.FindName(const Name: string): T;

That is not possible with var parameters because you would get
E2033 Types of actual and formal var parameters must be identical error.

Also with out parameters, if found item needs to be assigned to other class property,
that accepts nil as valid value, I would have to introduce additional variable
to make that code work.

There are some cases where your approach would not suffer from mentioned
limitations, but I like to be consistent in my coding style. Using boolean approach
in some cases and out parameter in other would be confusing.

And in some other languages you don't have out parameters (Java). Again, I like to
keep my coding style more consistent across platforms if it does not clearly violate
another language basic practice.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 3:27 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Den 2/17/2016 kl. 11:36 skrev Dalija Prasnikar:
And in some other languages you don't have out parameters (Java). Again, I like to
keep my coding style more consistent across platforms if it does not clearly violate
another language basic practice.

And it makes it possible for coding fluently.

Eg. using my TkbmMWScheduler thingy. Schedule returns a
IkbmMWScheduledEvent interface which is being passed on
as result from each property setting function:

FScheduler.Schedule(
function(const AScheduledEvent:IkbmMWScheduledEvent):boolean
begin
mData.Lines.Add('anonym:'+AScheduledEvent.Name);
Result:=true;
end)
.NamedAs('Relaxed event Every 2 secs')
.EverySecond(2)
.Synchronized
.Active:=true;

Which starts a scheduled event that runs every 2 seconds until its
either set to inactive or application shuts down. Its run synchronized
with the VCL main thread to allow for update of VCL controls.

or

FScheduler.Schedule(OnScheduledEvent)
.NamedAs('Relaxed event Every 250msecs')
.EveryMSecond(250)
.Relaxed
.StartingAt(TkbmMWDateTime.Now+(15/24/60/60))
.EndingAt(TkbmMWDateTime.Now+30/24/60/60)
.Active:=true;

Which starts a scheduled event that runs every 250msecs in relaxed mode
(shares a thread with other relaxed events), which starts 15 seconds
from now, and ends 30 seconds from now.

best regards
Kim/C4D
Per Larsen, Nex...

Posts: 28
Registered: 3/19/00
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 12:31 PM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:


FScheduler.Schedule(OnScheduledEvent)
.NamedAs('Relaxed event Every 250msecs')
.EveryMSecond(250)
.Relaxed
.StartingAt(TkbmMWDateTime.Now+(15/24/60/60))
.EndingAt(TkbmMWDateTime.Now+30/24/60/60)
.Active:=true;

You seem to have contracted Linq's Syndrome ;)
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 2:14 PM   in response to: Per Larsen, Nex... in response to: Per Larsen, Nex...
Per Larsen, NexusDB Larsen wrote:
You seem to have contracted Linq's Syndrome ;)

I switched to method chaining for a lot of stuff a while ago. Love it
for setting properties.
John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 4:01 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

I switched to method chaining for a lot of stuff a while ago. Love it
for setting properties.

Yes, it can make your code quite fluent ;)

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:40 AM   in response to: John Kaster in response to: John Kaster
John Kaster wrote:
Yes, it can make your code quite fluent ;)

My programs are now just one line long. ;)

You were being sincere, right? Not a little bit sarcastic, right? Just
checking. :)
(because I really like it and I'd be upset)
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 6:35 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

John Kaster wrote:
Yes, it can make your code quite fluent ;)

My programs are now just one line long. ;)

LOL!

--
Rudy Velthuis http://www.rvelthuis.de

Harrison's Postulate: For every action, there is an equal and
opposite criticism.

John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 12:07 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

My programs are now just one line long. ;)

Or one "statement" at least.

You were being sincere, right? Not a little bit sarcastic, right? Just
checking. :)

No, I've really liked fluent coding for a very long time. Even tried (a
lifetime ago) to get the VCL procs updated to functions returning Self
so fluency could be increased in the VCL

(because I really like it and I'd be upset)

No need to be upset :)

Besides, it would just be my opinion anyway. And if you disagree, who
cares? Programmers get their egos way too attached to their opinions,
IMO

(Irony intended)

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Van Swofford

Posts: 397
Registered: 6/28/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 12:31 PM   in response to: John Kaster in response to: John Kaster
John Kaster wrote:

Programmers get their egos way too attached to their opinions, IMO

But that could NEVER happen here. :-)

--
Cheers,
Van

"Good judgment comes from experience, and a lot of that comes from bad
judgment." - Will Rogers
John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 12:40 PM   in response to: Van Swofford in response to: Van Swofford
Van Swofford wrote:

But that could NEVER happen here. :-)

Of course not.

--
John Kaster http://johnkaster.wordpress.com
Software solutions

Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:15 PM   in response to: John Kaster in response to: John Kaster
John Kaster wrote:
No, I've really liked fluent coding for a very long time. Even tried
(a lifetime ago) to get the VCL procs updated to functions returning
Self so fluency could be increased in the VCL

That would have been phenomenal.

And, like Dalija suggested in a QC thing, extend the compiler to stop
the chain's execution after a NIL return.

Programmers get their egos way too attached to their opinions

If you used "if...goto" for forty years, I'm sure you'd be quite
proficient in it and not understand why others shun it. :) Others are
obsessed with patterns and writing five extra units to avoid typing
"nil." I generally like to bring both ends of that spectrum together in
a forum and fetch the popcorn.
John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 8:17 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

I generally like to bring both ends of that spectrum together in
a forum and fetch the popcorn.

This forum has always been good for fetching the popcorn.

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 12:10 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Others are obsessed with patterns and writing five extra units to
avoid typing "nil".

You make it seem as if it is more work to avoid nil. It isn't. The code
gets simpler, not more complicated or longer.

I found out because I am lazy and tried to simplify my code. The fact
you can avoid nil checks makes the code a lot simpler.

I also noticed that all code (often assembler) accessing strings starts
out with checking for nil. I would rather set unassigned strings to an
actual string with a payload of #0 and a length of 0, and not to nil,
so many of the extra nil checks can be avoided. It would make the
string code of the RTL probably a LOT simpler.

Note that a PChar cast actually does something like that: it points
PChar(nil) to a zero length string, so function calls that do not
accept nil won't go berzerk.

--
Rudy Velthuis http://www.rvelthuis.de

"War doesn't make boys men, it makes men dead." -- Ken Gillespie
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 3:19 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
You make it seem as if it is more work to avoid nil. It isn't. The
code gets simpler, not more complicated or longer.

Of course. The code gets very simple, and a in a one-million-iteration
loop, you are calling five million procedures with absolutely bullshit
parameters, instead of just three million, on average (and zero at
worst).

I'll put your solution in a frame and hang it on the wall to admire.
I'll use mine in the real world.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:29 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
You make it seem as if it is more work to avoid nil. It isn't. The
code gets simpler, not more complicated or longer.

Of course. The code gets very simple, and a in a one-million-iteration
loop, you are calling five million procedures with absolutely bullshit
parameters

Not at all. Why should I do that? What extra code is required? What
"extra methods" and what "absolutely bullshit parameters" do you mean?
I really don't get what you mean.

Avoiding nil makes my code simpler (and smaller and probably slightly
FASTER, although, to me, improved speed is just a byproduct). That is
my main reason for doing it. It does not require extra code or calling
some extra mystery methods with bullshit parameters. On the contrary.

I have no idea what you have in mind, but you seem to be way off.
--
Rudy Velthuis http://www.rvelthuis.de

"Men who believe absurdities will commit atrocities."
-- Voltaire
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:58 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
What extra code is required? What
"extra methods" and what "absolutely bullshit parameters" do you mean?
I really don't get what you mean.

Object.GetArm.RotateIt(90).SetTransparency(0.5)

for instance. What if GetArm returns nil?
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 6:12 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
What extra code is required? What
"extra methods" and what "absolutely bullshit parameters" do you
mean? I really don't get what you mean.

Object.GetArm.RotateIt(90).SetTransparency(0.5)

for instance. What if GetArm returns nil?

I already said I avoid nil as a flag. Now you give an example of a
method that returns nil, i.e. something I absolutely avoid.

I still don't get what you mean with "extra methods" and "bullshit
parameters", sorry.

--
Rudy Velthuis http://www.rvelthuis.de

"If you were plowing a field, which would you rather use? Two
strong oxen or 1024 chickens?"
-- Seymour Cray (1925-1996), father of supercomputing
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 6:47 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
I still don't get what you mean with "extra methods" and "bullshit
parameters", sorry.

Thought we were discussing fluency, but we must have inadvertently
fallen into a parallel universe in which it's all about nil flags
again. Happens all the time, don't worry about it. Let me re-align the
flux capacitors.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 7:09 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
I still don't get what you mean with "extra methods" and "bullshit
parameters", sorry.

Thought we were discussing fluency,

No matter what we were discussing. You wrote:

<<
Others are obsessed with patterns and writing five extra units to avoid
typing "nil."

I reacted to that.

Actually, ISTM that writing chained methods is extra work. And
returning nil is a no-no, exactly for the reason you gave.

So don't return nil. IOW, avoid nil -- as I have been saying all the
time -- and your code runs fine, without extra work, even when you are
chaining. No "five extra units" or "bullshit parameters". On the
contrary.

But my advice: don't do it that way (chaining) at all, and you avoid a
lot of trouble. It may look gorgeous to you, but it seems to have its
problems. Functions should return proper function values, or otherwsie
be procedures, and not just be made functions returning (most of the
time) Self so they can be chained, IMO.

IMO, programming is not a matter of cool syntax or avoiding having to
type. ISTM that for many, chaining is no more than a replacement for
"with". And it is extremely hard to debug.

--
Rudy Velthuis http://www.rvelthuis.de

"I was raised in the West. The west of Texas. It's pretty close
to California. In more ways than Washington, D.C., is close to
California." -- George W. Bush
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 7:54 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
I reacted to that.

Yes, and wrongly.

Actually, ISTM that writing chained methods is extra work. And
returning nil is a no-no, exactly for the reason you gave.

No to both counts.

So don't return nil.

Why not. Now I can do it safely. I'll be using nil absolutely
everywhere now.

But my advice: don't do it that way (chaining) at all, and you avoid a
lot of trouble.

Been doing it 100% trouble-free for a while now. It's a dream.

it seems to have its
problems.

Reality is not all what it seems to be.

IMO.

Yes. And MO is the opposite of everything you wrote. ;)

IMO, programming is not a matter of cool syntax or avoiding having to
type. ISTM that for many, chaining is no more than a replacement for
"with". And it is extremely hard to debug.

Nope, it's a gorgeous construct to get trivial jobs done in a nice
encapsulated and readable fashion. Of course, you'd need to be
protected against it since you'd go wild, but I wouldn't touch
programming if I were you.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 9:22 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
I reacted to that.

Yes, and wrongly.

Not at all. It was exactly what I wanted to say and it exactly answered
to what you wrote. It may not have answered to what you intended,
though, but then you should have written it differently.

Actually, ISTM that writing chained methods is extra work. And
returning nil is a no-no, exactly for the reason you gave.

No to both counts.

So don't return nil.

Why not. Now I can do it safely.

Oh? So what happens if you return nil in your example? Probably (very
likely): KA-BOOM!

ISTM that you can't safely return nil when chaining. This new operator
might make it possible, but now, that does not exist.

Fact is that those who want to avoid nil, as you claimed, don't have to
write extra units or classes or methods and don't have to pass silly
parameters, not even when chaining. Avoiding nil makes many things
easier, even now, even without that suggested operator.

Are you against making things easier?

--
Rudy Velthuis http://www.rvelthuis.de

"Object-oriented programming is a style of programming designed
to teach students about stacks." -- Edsger Dijkstra
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 3:51 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Not at all. It was exactly what I wanted to say and it exactly
answered to what you wrote.

I am sure everything is exactly what you wanted to write and it never
answers what anyone writes. Except, of course, in your frolicky little
mind. ;)

you should have written it differently.

I should do nothing of the sort. You should learn how to read.

Oh? So what happens if you return nil in your example? Probably (very
likely): KA-BOOM!

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always its
object. I don't use chaining with multiple objects, but the "?." would
allow to do that safely. That'd be excellent. On the other hand, if I
had an object function that would, by my own definition, always return
a valid object, of course I'd use it.

ISTM that you can't safely return nil when chaining. This new operator
might make it possible, but now, that does not exist.

What I wrote.

Fact is that those who want to avoid nil, as you claimed, don't have
to write extra units or classes or methods and don't have to pass
silly parameters, not even when chaining. Avoiding nil makes many
things easier, even now, even without that suggested operator.

You keep repeating that but it never sticks. Crazy uh? ;)

Are you against making things easier?

Show me one example in which your machinations make things easier.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:19 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
Not at all. It was exactly what I wanted to say and it exactly
answered to what you wrote.

I am sure everything is exactly what you wanted to write and it never
answers what anyone writes. Except, of course, in your frolicky little
mind. ;)

No need to get rude.

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always its
object.

So why would you need the new operator? If you can return a valid
object, why return nil?

--
Rudy Velthuis http://www.rvelthuis.de

"A good bookshop is just a genteel Black Hole that knows
how to read."
-- Terry Pratchett (Guards! Guards!)
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:22 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
So why would you need the new operator? If you can return a valid
object, why return nil?

Why don't you ever grasp a thread? I don't WANT to return valid
objects. :)
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:27 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
So why would you need the new operator? If you can return a valid
object, why return nil?

Why don't you ever grasp a thread? I don't WANT to return valid
objects. :)

Why not? Again: why would you return nil if you can return a valid
object?

--
Rudy Velthuis http://www.rvelthuis.de

Deadline-Dan's Demon: Every task takes twice as long as you think
it will take. If you double the time you think it will take, it
will actually take four times as long.
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:56 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Am 21.02.2016 um 13:27 schrieb Rudy Velthuis (TeamB):
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
So why would you need the new operator? If you can return a valid
object, why return nil?

Why don't you ever grasp a thread? I don't WANT to return valid
objects. :)

Why not? Again: why would you return nil if you can return a valid
object?

Because in some situations there isn't anything meaningful to return and
just returning a mock/stub object halps not much in such a case.

Greetings

Markus
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:31 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Why not? Again: why would you return nil if you can return a valid
object?

Because in some situations there isn't anything meaningful to return

Obviously there is, since he does it now.
--
Rudy Velthuis http://www.rvelthuis.de

"If god created us in his image we have certainly returned the
compliment."
-- Voltaire
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:23 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always its
object.

So why would you need the new operator? If you can return a valid
object, why return nil?

You can always return object. But it is not always desirable to return object.

Depending on the class in question, implementing null object pattern may
be too much trouble. It is not suitable for each and every purpose. In many
cases nil fits better.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:27 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always
its object.

So why would you need the new operator? If you can return a valid
object, why return nil?

You can always return object. But it is not always desirable to
return object.

Why not? Oh, this "nil as a flag" thing again?

--
Rudy Velthuis http://www.rvelthuis.de

"Every great advance in natural knowledge has involved the
absolute rejection of authority."
-- Thomas Huxley
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:35 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always
its object.

So why would you need the new operator? If you can return a valid
object, why return nil?

You can always return object. But it is not always desirable to
return object.

Why not? Oh, this "nil as a flag" thing again?

In context of fluent. Now you cannot use fluent chaining in Delphi for
such functions. You could if we would have proper operator.

Is that so hard to understand.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:32 PM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil,
always its object.

So why would you need the new operator? If you can return a
valid object, why return nil?

You can always return object. But it is not always desirable to
return object.

Why not? Oh, this "nil as a flag" thing again?

In context of fluent. Now you cannot use fluent chaining in Delphi for
such functions.

Or those functions don't return nil and you can chain to your heart's
desire.

--
Rudy Velthuis http://www.rvelthuis.de

"If Al Gore invented the Internet, I invented spell check."
-- Dan Quayle
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 3:34 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Why not? Oh, this "nil as a flag" thing again?

The problem with dummy/mock objects is that you have to recognize them as such in order to avoid using them as "real" objects. And checking for "if object.isdummy()" is exactly the same amount of work as checking for "if assigned(object)", you're just trading one flag for another.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 5:35 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

Why not? Oh, this "nil as a flag" thing again?

The problem with dummy/mock objects is that you have to recognize
them as such in order to avoid using them as "real" objects.

Actually, I though the purpose of mock objects is that they are treated
the same way as the real ones. If you treat them differently, you
defeat their entire purpose.

--
Rudy Velthuis http://www.rvelthuis.de

"It is forbidden to kill; therefore all murderers are punished
unless they kill in large numbers and to the sound of
trumpets."
-- Voltaire
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 1, 2016 6:00 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Actually, I though the purpose of mock objects is that they are treated
the same way as the real ones. If you treat them differently, you
defeat their entire purpose.

in unit testing, certainly. But actually using the data generated by a mock object may not be so desirable in a productive system.

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 1, 2016 9:35 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

Rudy Velthuis (TeamB) wrote:

Actually, I though the purpose of mock objects is that they are
treated the same way as the real ones. If you treat them
differently, you defeat their entire purpose.

in unit testing, certainly. But actually using the data generated by
a mock object may not be so desirable in a productive system.


Who would seriously use data generated by a mock object in a productive
system?

--
Rudy Velthuis http://www.rvelthuis.de

"Two things should be cut - the second act and the child's
throat." -- Noel Coward on a dull play with an annoying
child star
Asbjørn Heid

Posts: 267
Registered: 11/12/12
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 1:50 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always its
object.

So why would you need the new operator? If you can return a valid
object, why return nil?

So in a binary tree, you would return some special object for parent and non-existing child nodes, rather than nil?

If yes, how would you handle the case when someone asks for the grandparent of the root node, for example? Have a virtual getter which raises an exception in your special "non-existing" node class? Something else?

- Asbjørn
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:16 AM   in response to: Asbjørn Heid in response to: Asbjørn Heid
Asbjørn Heid wrote:

Rudy Velthuis (TeamB) wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always
its object.

So why would you need the new operator? If you can return a valid
object, why return nil?

So in a binary tree, you would return some special object for parent
and non-existing child nodes, rather than nil?

I would not return nil.

--
Rudy Velthuis http://www.rvelthuis.de

Weiler's Law: Nothing is impossible for the man who doesn't have
to do the work.
Asbjørn Heid

Posts: 267
Registered: 11/12/12
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:17 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Asbjørn Heid wrote:

Rudy Velthuis (TeamB) wrote:

It's all about the brand new "?." No kaboom.

Without the"?." I would never have a function return nil, always
its object.

So why would you need the new operator? If you can return a valid
object, why return nil?

So in a binary tree, you would return some special object for parent
and non-existing child nodes, rather than nil?

I would not return nil.

Yes I get that, that's why I specifically asked what you would return instead, and how you would handle the cases which is typically handled by returning nil.

I'm trying to understand how your code would look.

- Asbjørn
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:28 AM   in response to: Asbjørn Heid in response to: Asbjørn Heid
Asbjørn Heid wrote:

Yes I get that, that's why I specifically asked what you would return
instead

What people return now when they want to be able to chain. Obviously
they return valid objects, usually Self.

--
Rudy Velthuis http://www.rvelthuis.de

Lady Astor: "Mr. Churchill, you're drunk!"
Winston Churchill: "Yes, and you, Madam, are ugly. But tomorrow,
I shall be sober."
Asbjørn Heid

Posts: 267
Registered: 11/12/12
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:31 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Asbjørn Heid wrote:

Yes I get that, that's why I specifically asked what you would return
instead

What people return now when they want to be able to chain. Obviously
they return valid objects, usually Self.

I specifically said a binary tree. People usually return nil for the parent of the root, or the children of a leaf. You said you wouldn't return nil. That's why I ask what you'd do instead. So I can get an understanding of what your code would look like.

- Asbjørn
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 6:34 AM   in response to: Asbjørn Heid in response to: Asbjørn Heid
Asbjørn Heid wrote:

Rudy Velthuis (TeamB) wrote:
Asbjørn Heid wrote:

Yes I get that, that's why I specifically asked what you would
return instead

What people return now when they want to be able to chain. Obviously
they return valid objects, usually Self.

I specifically said a binary tree.

Oh sorry, I was still in the chaining thread, mentally. Return from
what?

--
Rudy Velthuis http://www.rvelthuis.de

"They always say time changes things, but you actually have to
change them yourself." -- Andy Warhol
Asbjørn Heid

Posts: 267
Registered: 11/12/12
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 7:07 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Asbjørn Heid wrote:

Rudy Velthuis (TeamB) wrote:
Asbjørn Heid wrote:

Yes I get that, that's why I specifically asked what you would
return instead

What people return now when they want to be able to chain. Obviously
they return valid objects, usually Self.

I specifically said a binary tree.

Oh sorry, I was still in the chaining thread, mentally. Return from
what?

Fair enough. The getter for the ParentNode and LeftChildNode/RightChildNode properties, in the case that the node is a root, or one or both children do not exist (for example for a leaf node).

This is typically a scenario where one returns nil to signal the non-existence of the respective nodes. A root node is thus defined by having no (nil) parent. A leaf node is defined by having no child nodes (both left/right child nodes are nil).

I can certainly envision doing this without returning nil, but I'd like to know what you have in mind.

- Asbjørn
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 11:08 AM   in response to: Asbjørn Heid in response to: Asbjørn Heid
Asbjørn,

| I can certainly envision doing this without returning nil, but I'd
| like to know what you have in mind.

So would I. <g>

--

Q -- XanaNews 1.19.1.372 - 2016-02-22 11:08:03
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 4:23 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Fact is that those who want to avoid nil, as you claimed, don't have
to write extra units or classes or methods and don't have to pass
silly parameters, not even when chaining. Avoiding nil makes many
things easier, even now, even without that suggested operator.

You keep repeating that but it never sticks. Crazy uh? ;)

I don't know why it never sticks. It is the truth. Apparently you are
not much interested in the truth.

--
Rudy Velthuis http://www.rvelthuis.de

"Programming is one of the most difficult branches of applied
mathematics; the poorer mathematicians had better remain pure
mathematicians." -- Edsger Dijkstra
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 8:14 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
I don't know why it never sticks. It is the truth. Apparently you are
not much interested in the truth.

Have you considered a career on God TV? ;)
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:32 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
I don't know why it never sticks. It is the truth. Apparently you
are not much interested in the truth.

Have you considered a career on God TV? ;)

I didn't know it existed. <g>

--
Rudy Velthuis http://www.rvelthuis.de

"The injury we do and the one we suffer are not weighed in the
same scale."
-- Aesop
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 1:56 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
I didn't know

That is utterly impossible.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 5:17 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
I didn't know

That is utterly impossible.

Yes, it sounds weird, coming from me, I know.

--
Rudy Velthuis http://www.rvelthuis.de

"Science is what people understand well enough to explain to a
computer. All else is art." -- Donald Knuth
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 7:33 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

I still don't get what you mean with "extra methods" and "bullshit
parameters", sorry.

Neither does he.

--
Nick
Delphi Programming is Fun
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 7:33 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

What if GetArm returns nil?

Hah! Exactly my point! If it never can, then it's no problem.

--
Nick
Delphi Programming is Fun
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 7:48 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
What if GetArm returns nil?

Hah! Exactly my point! If it never can, then it's no problem.

No, I think you're not up to date in this discussion. It's about the
"?." suggestion by Dalija. Which is excellent, and solves this issue.

"Hah!"
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 8:28 AM   in response to: Dominique Willems in response to: Dominique Willems
SOrry.

But my point remains. ;-)

--
Nick
Delphi Programming is Fun
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 4:07 PM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
But my point remains. ;-)

The point that you never made doesn't burst into existence by
referencing the empty hole in space that ought to contain it. ;)

I kind of like the conversation analogy you just created with your
rhetoric, btw. No valid object, not nil but a bogus object, and handing
it out all over an application, as if it were a valid entity. ;)
=> no valid point but a vague claim to its existence, and pointing to
the claim on each occasion.

It's a beaut.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 9:28 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Nick Hodges wrote:
What if GetArm returns nil?

Hah! Exactly my point! If it never can, then it's no problem.

No, I think you're not up to date in this discussion. It's about the
"?." suggestion by Dalija. Which is excellent, and solves this issue.

Not entirely. It still does not make a construct like:

X := TY.Bla(doodle).IsNil(code1).IsNotNil(code2).WithAngle(30);

possible. It simply ends the chain if Bla returns nil, without
alternative, and, AFAICT, without you knowing that it happened. This
means: no one-liners (<g>) and no error checking.

This problem does not exist if you don't return nil at all.
--
Rudy Velthuis http://www.rvelthuis.de

"A model is done when nothing else can be taken out." -- Dyson
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 9:55 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

Nick Hodges wrote:
What if GetArm returns nil?

Hah! Exactly my point! If it never can, then it's no problem.

No, I think you're not up to date in this discussion. It's about the
"?." suggestion by Dalija. Which is excellent, and solves this issue.

Not entirely. It still does not make a construct like:

X := TY.Bla(doodle).IsNil(code1).IsNotNil(code2).WithAngle(30);

possible. It simply ends the chain if Bla returns nil, without
alternative, and, AFAICT, without you knowing that it happened. This
means: no one-liners (<g>) and no error checking.

This problem does not exist if you don't return nil at all.

I am not sure what is your point. Of course, if you deal with functions
that return nil, you cannot do fluent chaining with them (unless you
have operator that allows safe calls on nil).

But that does not in any way mean that you should not ever return nil
from any function.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 9:59 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

I am not sure what is your point. Of course, if you deal with
functions that return nil, you cannot do fluent chaining with them

Then why the need for the ?. (or :) operator?

--
Rudy Velthuis http://www.rvelthuis.de

"In any contest between power and patience, bet on patience."
-- W.B. Prescott
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 10:03 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

I am not sure what is your point. Of course, if you deal with
functions that return nil, you cannot do fluent chaining with them

Then why the need for the ?. (or :) operator?

You do get that you don't have to return nil from every damn function you
write, but you may return nil from some?

?. operator would be helpful in cases where you deal with functions
that can return nil by design.

I have plenty of code that does not return nil and I have plenty of
code that does. I don't use fluent chaining with nil returning functions.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 10:16 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

I am not sure what is your point. Of course, if you deal with
functions that return nil, you cannot do fluent chaining with them

Then why the need for the ?. (or :) operator?

You do get that you don't have to return nil from every damn function
you write, but you may return nil from some?

Sure. I wouldn't, but hey, you can, if you want to. Just don't use
those for chaining.


?. operator would be helpful in cases where you deal with functions
that can return nil by design.

But they shouldn't, even in non-chaining scenarios, IMO.

I have plenty of code that does not return nil and I have plenty of
code that does. I don't use fluent chaining with nil returning
functions.

So why the need for the operator?

--
Rudy Velthuis http://www.rvelthuis.de

"If the automobile had followed the same development cycle as
the computer, a Rolls-Royce would today cost $100, get a
million miles per gallon, and explode once a year, killing
everyone inside." -- Robert X. Cringely.
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 10:28 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

I have plenty of code that does not return nil and I have plenty of
code that does. I don't use fluent chaining with nil returning
functions.

So why the need for the operator?

So I can chain functions that may return nil, too. Right now chaining
them would be downright stupid so I don't chain them in my current code.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 10:42 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

Rudy Velthuis (TeamB) wrote:
Dalija Prasnikar wrote:

I have plenty of code that does not return nil and I have plenty
of code that does. I don't use fluent chaining with nil returning
functions.

So why the need for the operator?

So I can chain functions that may return nil, too.

Ok, if you want that.

I'll maintain that simply not returning nil, or generally not using nil
as a flag, is the much better option.

--
Rudy Velthuis http://www.rvelthuis.de

"Wherever there is great property, there is great inequality,
for one very rich man; there must be at least five hundred
poor."
-- Adam Smith
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 3:48 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

I am not sure what is your point. Of course, if you deal with functions
that return nil, you cannot do fluent chaining with them (unless you
have operator that allows safe calls on nil).

Even in fluent interfaces that never return NIL there's the problem that you sometimes need to abort the processing if an error occurs. I think it can be done only if the methods are allowed to raise an exception but it completely kills the fluency, and exceptions are costly in terms of cpu time:

Try
  MyFamily.Find('Robert').SendEmail('Hello Robert, dinner at 18:00?').MakeAppointment(...);
Except
    on eSearcherror do....
    on eSendMailError do...
    on eAppointmentError do...
End;
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 3:54 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:
Even in fluent interfaces that never return NIL there's the problem
that you sometimes need to abort the processing if an error occurs.

To be honest, I almost exclusively use it as a property setter. Just
nicer to sometimes put heavily related object initialization on one
line.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 29, 2016 8:51 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Arthur Hoornweg wrote:
Even in fluent interfaces that never return NIL there's the problem
that you sometimes need to abort the processing if an error occurs.

To be honest, I almost exclusively use it as a property setter. Just
nicer to sometimes put heavily related object initialization on one
line.

ISTM that having a constructor that requires all necessary parameters
is safer. You can forget to set a property (or call a chaining function
that does the same), but you can't forget to pass a parameter without
the compiler flagging an error.

--
Rudy Velthuis http://www.rvelthuis.de

"When you are content to be simply yourself and don't compare
or compete, everybody will respect you."
-- Lao tzu
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2016 11:46 PM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:

And it makes it possible for coding fluently.

Not if a search function uses a NIL result to indicate "no match" as in Dalija's example.

guests.findname('John Smith').WakeupAt(Now+8/24);


would crash with a GPF if there is no "John Smith" in the collection and you'd better make sure that your unit testing catches that eventuality (-> more work, more lines of code).

However,

If guests.HaveName('John Smith',aguest) then   
   aguest.WakeupAt(...)


avoids that pitfall, is just as legible and doesn't require you to invest more work in unit testing.
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:31 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:
Kim Madsen wrote:

And it makes it possible for coding fluently.

Not if a search function uses a NIL result to indicate "no match" as in Dalija's example.

guests.findname('John Smith').WakeupAt(Now+8/24);


would crash with a GPF if there is no "John Smith" in the collection and you'd better make sure that your unit testing catches that eventuality (-> more work, more lines of code).

It wouldn't crash if we would have optional chaining like Swift has.

guests.findname('John Smith')?.WakeupAt(Now+8/24);


If "John Smith" cannot be found (and is nil) then WakeupAt would never be called.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:20 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Den 2/18/2016 kl. 11:31 skrev Dalija Prasnikar:
guests.findname('John Smith')?.WakeupAt(Now+8/24);


If "John Smith" cannot be found (and is nil) then WakeupAt would never be called.

Hi,

What if one wants to react on the nil.
Then perhaps something like this instead.

guest.findname('John Smith')
.IsNil(dosomething)
.IsNotNil(do something else)

or in a C ternary like way:

guest.findname('John Smith')
?.IsNotNilOperation(xx)
:.OptionalIsNilOperation(xx)

or perhaps more Pascal like:

When guest.findname('John Smith') is Nil then
.IsNotNilOperation(xx)
else
.OptionalIsNilOperation(xx)

and optional automatic variable scope:

When g:=guest.findname('John Smith') is Nil then
g.IsNotNilOperation(xx)
else
g.OptionalIsNilOperation(xx)

Just some ideas.

best regards
Kim Bo
C4D

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 6:39 AM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:

Den 2/18/2016 kl. 11:31 skrev Dalija Prasnikar:
guests.findname('John Smith')?.WakeupAt(Now+8/24);


If "John Smith" cannot be found (and is nil) then WakeupAt would
never be called.

Hi,

What if one wants to react on the nil.
Then perhaps something like this instead.

guest.findname('John Smith')
.IsNil(dosomething)
.IsNotNil(do something else)

What is the return type of IsNil? Assuming it is the object, then how
does IsNotNil know what to check? And DoSomething is not chained, so is
it an anonymous function?

Looks complicated to implement.

--
Rudy Velthuis http://www.rvelthuis.de

"When the water starts boiling it is foolish to turn off the
heat."
-- Nelson Mandela
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:54 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Den 2/18/2016 kl. 15:39 skrev Rudy Velthuis (TeamB):
guest.findname('John Smith')
.IsNil(dosomething)
.IsNotNil(do something else)

What is the return type of IsNil? Assuming it is the object, then how
does IsNotNil know what to check? And DoSomething is not chained, so is
it an anonymous function?

Its compiler magic :)

Ie.. if IsNil executes, then only that part is executed, and the rest of
the statement is shortcircuited.
The argument could be any function/event/anonymous function.
If IsNotNil executes, then that part is executed. The argument could
(with compiler magic) start with a . (dot) to indicate that we continue
the fluent access to the object/interface on which .IsNotNil is called on.

Looks complicated to implement.

Didnt say it was easy ;)
The compiler guys/girls should also have something to think about ;)

best regards
Kim/C4D
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:30 PM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:

Den 2/18/2016 kl. 15:39 skrev Rudy Velthuis (TeamB):
guest.findname('John Smith')
.IsNil(dosomething)
.IsNotNil(do something else)

What is the return type of IsNil? Assuming it is the object, then
how does IsNotNil know what to check? And DoSomething is not
chained, so is it an anonymous function?

Its compiler magic :)

Ie.. if IsNil executes, then only that part is executed, and the rest
of the statement is shortcircuited.

That would indeed require compiler magic.
--
Rudy Velthuis http://www.rvelthuis.de

"To be wronged is nothing unless you continue to remember it."
-- Confucius
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 1:45 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy,

| What is the return type of IsNil?

It better be Boolean True or False. <g>

--

Q -- XanaNews 1.19.1.372 - 2016-02-18 13:44:57
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:33 PM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:

Rudy,

What is the return type of IsNil?

It better be Boolean True or False. <g>

So how does bla.blop.IsNil(params).IsNotNil(params) work then? You
can't call IsNotNil(params) on True or False.

You can only chain such methods if they all return a valid object (or
interface) on which the next method can be called. That can either be
Self, or something new.

--
Rudy Velthuis http://www.rvelthuis.de

"But at my back I always hear Time's winged chariot hurrying
near." -- Andrew Marvell (1621-1678)
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 4:01 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy,

| | > What is the return type of IsNil?
| |
| | It better be Boolean True or False. <g>
|
| So how does bla.blop.IsNil(params).IsNotNil(params) work then? You
| can't call IsNotNil(params) on True or False.

| You can only chain such methods if they all return a valid object (or
| interface) on which the next method can be called. That can either be

| Self, or something new.

Now I'm confused. ...

--

Q -- XanaNews 1.19.1.372 - 2016-02-18 16:00:30
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 11:26 PM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:

Rudy,

| | > What is the return type of IsNil?
|
| | It better be Boolean True or False. <g>

So how does bla.blop.IsNil(params).IsNotNil(params) work then? You
can't call IsNotNil(params) on True or False.

You can only chain such methods if they all return a valid object
(or interface) on which the next method can be called. That can
either be Self, or something new.

Now I'm confused. ...

Look at how method chaining works: every method in the chain returns a
reference to an existing object or interface (often just Self), on
which you then call the next method of the chain.

--
Rudy Velthuis http://www.rvelthuis.de

Hind's Law of Computer Programming:

1. Any given program, when running, is obsolete.
2. If a program is useful, it will have to be changed.
3. If a program is useless, it will have to be documented.
4. Any given program will expand to fill all available memory.
5. The value of a program is proportional to the weight of its
output.
6. Program complexity grows until it exceeds the capability of
the programmer who must maintain it.
7. Make it possible for programmers to write programs in
English, and you will find that programmers cannot write in
English.
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 10:48 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy,

| | Now I'm confused. ...
|
| Look at how method chaining works: every method in the chain returns a
| reference to an existing object or interface (often just Self), on
| which you then call the next method of the chain.

Ah,... Hmmm,... I don't write code like that. <g>

--

Q -- XanaNews 1.19.1.372 - 2016-02-21 10:47:37
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2016 11:33 PM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:

Rudy,

| Now I'm confused. ...

Look at how method chaining works: every method in the chain
returns a reference to an existing object or interface (often just
Self), on which you then call the next method of the chain.

Ah,... Hmmm,... I don't write code like that. <g>

Neither do I, but some here seem to think it is the best thing since
sliced bread.

--
Rudy Velthuis http://www.rvelthuis.de

"Because I do it with one small ship, I am called a terrorist.
You do it with a whole fleet and are called an emperor."
-- A pirate, from St. Augustine's "City of God"
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 2:00 AM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:
Ah,... Hmmm,... I don't write code like that. <g>

I don't think they have pointers in Flow-Matic, so sit down.
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 22, 2016 11:09 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique,

| I don't think they have pointers in Flow-Matic, so sit down.

<giggle>

--

Q -- XanaNews 1.19.1.372 - 2016-02-22 11:09:16
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 5:01 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:
guests.findname('John Smith')?.WakeupAt(Now+8/24);

Whoa, I need that. Can you have that on my desk by Monday?
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 5:20 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:
Dalija Prasnikar wrote:
guests.findname('John Smith')?.WakeupAt(Now+8/24);

Whoa, I need that. Can you have that on my desk by Monday?

Just use Swift or .NET ;-)

Or vote for

Implement Safe Navigation Operator
http://qc.embarcadero.com/wc/qcmain.aspx?d=122858

Nullable Types and Null Propagation
https://quality.embarcadero.com/browse/RSP-13305

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 6:10 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:
Just use Swift or .NET ;-)

Behave.

Or vote for

Implement Safe Navigation Operator
http://qc.embarcadero.com/wc/qcmain.aspx?d=122858

Done.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 8:57 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Dalija Prasnikar wrote:
Just use Swift or .NET ;-)

Behave.

Or vote for

Implement Safe Navigation Operator
http://qc.embarcadero.com/wc/qcmain.aspx?d=122858

Done.

FWIW, Objective-C simply ignores messages sent to a nil object. That
works fine because every method is "called" through a real message send
mechanism in the RTL, not through a direct call to code.

This can run wild too, as I once noted, because a message is only
selected by its selector, not checking the parameters:

http://stackoverflow.com/questions/6881607/overriding-methods-in-objective-c

But if you never return nil, which is a good idea anyway, I see no need
for such an operator or construct.


--
Rudy Velthuis http://www.rvelthuis.de

"Rules of Optimization:"
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet."
-- M.A. Jackson

Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 9:05 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
But if you never return nil, which is a good idea anyway, I see no
need for such an operator or construct.

People who program return nils. The need is great.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:35 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
But if you never return nil, which is a good idea anyway, I see no
need for such an operator or construct.

People who program return nils. The need is great.

Not all do. The sane ones don't need such an operator (nor method
chaining, actually). IMO, method chaining is a nice gimmick to show
what you can do with some cleverness, but one that has, unfortunately,
been abused a little too much.

--
Rudy Velthuis http://www.rvelthuis.de

"I'm Jewish. I don't work out. If God had wanted us to bend over,
He would have put diamonds on the floor." -- Joan Rivers.
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:16 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
abused a little too much.

LOL!
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:32 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
abused a little too much.

LOL!

Huh? I find the code that, IIRC, Kim Madsen showed terrible:

FScheduler.Schedule(OnScheduledEvent)
.NamedAs('Relaxed event Every 250msecs')
.EveryMSecond(250)
.Relaxed
.StartingAt(TkbmMWDateTime.Now+(15/24/60/60))
.EndingAt(TkbmMWDateTime.Now+30/24/60/60)
.Active:=true;

I also don't see what makes it superior to simple property setting. It
is not even obvious what the above code does. What is named as such?
The event, the schduler or the schedule?

--
Rudy Velthuis http://www.rvelthuis.de

"I invented the term Object-Oriented, and I can tell you I did
not have C++ in mind." -- Alan Kay
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:41 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
abused a little too much.

LOL!

Huh? I find the code that, IIRC, Kim Madsen showed terrible:

FScheduler.Schedule(OnScheduledEvent)
.NamedAs('Relaxed event Every 250msecs')
.EveryMSecond(250)
.Relaxed
.StartingAt(TkbmMWDateTime.Now+(15/24/60/60))
.EndingAt(TkbmMWDateTime.Now+30/24/60/60)
.Active:=true;

I also don't see what makes it superior to simple property setting. It
is not even obvious what the above code does. What is named as such?
The event, the schduler or the schedule?

And why not

.Active(True);

--
Rudy Velthuis http://www.rvelthuis.de

"If women didn't exist, all the money in the world would have no
meaning." -- Aristotle Onassis (1906-1975)
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:45 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
And why not

.Active(True);

I would have used .Activate, but that's a matter of taste.
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:50 PM   in response to: Dominique Willems in response to: Dominique Willems
Den 2/19/2016 kl. 00:45 skrev Dominique Willems:
Rudy Velthuis (TeamB) wrote:
And why not

.Active(True);

I would have used .Activate, but that's a matter of taste.

Thats also supported. However as it ends the statement, setting a
property imo seems appropriate.

best regards
Kim/C4D
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:53 PM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:
Thats also supported.

That's because it's awesome. :)

However as it ends the statement, setting a
property imo seems appropriate.

Absolutely. I often use an obvious verb (like .Start or .Execute) to
end it all, but that's just a matter of preference.
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:43 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Huh? I find the code that, IIRC, Kim Madsen showed terrible:

I find it gorgeous.

I also don't see what makes it superior to simple property setting.

Doesn't need to be. It's gorgeous.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 11:27 PM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
Huh? I find the code that, IIRC, Kim Madsen showed terrible:

I find it gorgeous.

Yeah, but you're a Plutonian.

--
Rudy Velthuis http://www.rvelthuis.de

Albrecht's Law: Social innovations tend to the level of minimum
tolerable well-being.

Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 3:20 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
I find it gorgeous.

Yeah, but you're a Plutonian.

It's true. Our tastes are exquisite.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:30 AM   in response to: Dominique Willems in response to: Dominique Willems
Dominique Willems wrote:

Rudy Velthuis (TeamB) wrote:
I find it gorgeous.

Yeah, but you're a Plutonian.

It's true. Our tastes are exquisite.

You mean you taste exquisitely. Especially the 8 tentacle kind.

--
Rudy Velthuis http://www.rvelthuis.de

"Cancel the kitchen scraps for lepers and orphans! No more
merciful beheadings! And call off Christmas!"
-- The Sheriff of Nottingham
Dominique Willems

Posts: 591
Registered: 10/26/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2016 5:56 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
You mean you taste exquisitely. Especially the 8 tentacle kind.

That too, of course. Naturally.
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:49 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Den 2/19/2016 kl. 00:32 skrev Rudy Velthuis (TeamB):
Huh? I find the code that, IIRC, Kim Madsen showed terrible:

Thanks. Much appreciated ;)


FScheduler.Schedule(OnScheduledEvent)
.NamedAs('Relaxed event Every 250msecs')
.EveryMSecond(250)
.Relaxed
.StartingAt(TkbmMWDateTime.Now+(15/24/60/60))
.EndingAt(TkbmMWDateTime.Now+30/24/60/60)
.Active:=true;

I also don't see what makes it superior to simple property setting. It
is not even obvious what the above code does. What is named as such?
The event, the schduler or the schedule?

You can choose to use properties as usual. Both ways are supported.
However since people dont like 'with', then its rather tedious to write:

myscheduledevent:=FScheduler.Schedule(OnScheduledEvent);
myscheduledevent.Name:='Relaxed event Every 250msecs';
myscheduledevent.Interval.MilliSeconds:=250;
myscheduledevent.Options:=[mwseoRelaxed];
myscheduledevent.Starting:=TkbmMWDateTime.Now+(15/24/60/60);
myscheduledevent.Ending:=TkbmMWDateTime.Now+30/24/60/60);
myscheduledevent.Active:=true;

Thus they have the option to write fluently instead if they want.
Basically one gets a one line async one time or repeatable code
execution with lots of bells and whistles to control its execution.
Right up the alley for Go people ;)

best regards
Kim/C4D

Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 11:28 PM   in response to: Kim Madsen in response to: Kim Madsen
Kim Madsen wrote:

You can choose to use properties as usual. Both ways are supported.
However since people dont like 'with', then its rather tedious to
write:

myscheduledevent:=FScheduler.Schedule(OnScheduledEvent);
myscheduledevent.Name:='Relaxed event Every 250msecs';
myscheduledevent.Interval.MilliSeconds:=250;
myscheduledevent.Options:=[mwseoRelaxed];
myscheduledevent.Starting:=TkbmMWDateTime.Now+(15/24/60/60);
myscheduledevent.Ending:=TkbmMWDateTime.Now+30/24/60/60);
myscheduledevent.Active:=true;

I would use a shorter name, like E. <g>

--
Rudy Velthuis http://www.rvelthuis.de

"My opinions may have changed, but not the fact that I am
right."
-- Ashleigh Brilliant
John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 8:19 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

IMO, method chaining is a nice gimmick to show
what you can do with some cleverness, but one that has, unfortunately,
been abused a little too much.

Have you ever used LINQ?

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 11:30 PM   in response to: John Kaster in response to: John Kaster
John Kaster wrote:

Rudy Velthuis (TeamB) wrote:

IMO, method chaining is a nice gimmick to show
what you can do with some cleverness, but one that has,
unfortunately, been abused a little too much.

Have you ever used LINQ?

No. I assume LINQ uses it a lot? If so, that doesn't change my opinion:
it is a gimmick (a very old one BTW, it was used in Smalltalk, but
fortunately not to such an extent) that has been abused.

--
Rudy Velthuis http://www.rvelthuis.de

"The only rules comedy can tolerate are those of taste, and the
only limitations those of libel." -- James Thurber (1894-1961)
John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 19, 2016 9:45 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:

I assume LINQ uses it a lot? If so, that doesn't change my opinion:
it is a gimmick

Yes, LINQ takes great advantage of it. It is a very powerful piece of
functionality I wish Delphi had.

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 11:09 AM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Rudy Velthuis (TeamB) wrote:
Dominique Willems wrote:

Dalija Prasnikar wrote:
Just use Swift or .NET ;-)

Behave.

Or vote for

Implement Safe Navigation Operator
http://qc.embarcadero.com/wc/qcmain.aspx?d=122858

Done.

FWIW, Objective-C simply ignores messages sent to a nil object. That
works fine because every method is "called" through a real message send
mechanism in the RTL, not through a direct call to code.

You can also directly call method instead of sending message so again
you can access nil object by mistake. And if you send message to nil object
where you don't expect it to be nil, you will not have app crash, just nasty bug
you may have trouble pinpointing.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:38 PM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

FWIW, Objective-C simply ignores messages sent to a nil object. That
works fine because every method is "called" through a real message
send mechanism in the RTL, not through a direct call to code.

You can also directly call method instead of sending message

In Objective-C? No, you can't. EVERY method invokation (inside the [
and ] delimiters) is a message send. Oh, you can call functions in
plain C, but not invoke methods.

--
Rudy Velthuis http://www.rvelthuis.de

"Finagle's Law of Dynamic Negatives: Anything that can go wrong,
will -- at the worst possible moment."
Kim Madsen

Posts: 362
Registered: 12/13/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 3:10 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Den 2/18/2016 kl. 08:46 skrev Arthur Hoornweg:
Kim Madsen wrote:

And it makes it possible for coding fluently.

Not if a search function uses a NIL result to indicate "no match" as in Dalija's example.

guests.findname('John Smith').WakeupAt(Now+8/24);


would crash with a GPF if there is no "John Smith" in the collection and you'd better make sure that your unit testing catches that eventuality (-> more work, more lines of code).

However,

If guests.HaveName('John Smith',aguest) then   
   aguest.WakeupAt(...)


avoids that pitfall, is just as legible and doesn't require you to invest more work in unit testing.

Hi,

In the case of fluent, you always need to return a valid instance of an
interface. So in this specific case one would need to have instantiated
interfaced objects which are not nil, but which have a property that can
be checked if its nil... more or less like Rudy and Nick argues.

IMO only in fluently programming this is a requirement. In all other
cases I would prefer a nil value, or your way with an additional boolean
(I presume that aguest also would be nil when HaveName failed.

best regards
Kim Bo
C4D
Arthur Hoornweg

Posts: 414
Registered: 6/2/98
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:28 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

First, I prefer function returning actual result rather than moving most
important part into out parameter.

Then you have to decide what the "actual result" is. For a search function, found or not found is a highly interesting result as well. And how about duplicates?

I am reserving out parameters for
cases where there is no simple alternative and I need to return two
or more complex variables. In above case nil is non-ambiguous flag
and I don't see the reason for separating it.

The boolean return does not need a variable to be stored in so it doesn't cost anything. And you need the variable "item" anyway, no matter which solution you prefer.

FindName('John Smith',item);
IF Assigned(item) Then...
 
// reads less fluently than the following, IMHO:
 
If HaveName('John Smith',item) then...

My code can also be extended to work with generics adding additional
type safety.

Sure, but hey, you just said you try to keep the same coding style across languages. Many languages don't support generics.

Also with out parameters, if found item needs to be assigned to other class property,
that accepts nil as valid value, I would have to introduce additional variable
to make that code work.

And if the property doesn't accepts NILs, you'd need the additional variable also, to test for that case.

There are some cases where your approach would not suffer from mentioned
limitations, but I like to be consistent in my coding style. Using boolean approach
in some cases and out parameter in other would be confusing.

My preferred solution would be the following:

  For item in coll.FindNames('John Smith') do  
        item.dosomething();
  
 


because it handles all possible cases: found, not found and duplicates... and there's not even a NIL for Rudy to get upset about.
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 2:38 AM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:
Dalija Prasnikar wrote:

First, I prefer function returning actual result rather than moving most
important part into out parameter.

Then you have to decide what the "actual result" is. For a search function, found or not found is a highly interesting result as well. And how about duplicates?

What if list itself does not allow adding duplicates?

Now you are going into specification of Find function and you are trying
to reimplement its logic so it would no longer fit in my way of returning
nil.

I am not saying that your way is wrong or mine is better. I am saying I don't
write code like that unless I have no other options. I rarely use out parameters.

This is my coding style. You are free to dislike it ;-)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Van Swofford

Posts: 397
Registered: 6/28/03
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 7:23 AM   in response to: Dalija Prasnikar in response to: Dalija Prasnikar
Dalija Prasnikar wrote:

I am not saying that your way is wrong or mine is better. I am saying
I don't write code like that unless I have no other options. I rarely
use out parameters.

Would you use tuples if they were available in Delphi? I have in the
past created records just so I could return multiple values from a
function, but tuples seems like a much cleaner way to do that.

--
Cheers,
Van

"Good judgment comes from experience, and a lot of that comes from bad
judgment." - Will Rogers
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 7:40 AM   in response to: Van Swofford in response to: Van Swofford
Van Swofford wrote:
Dalija Prasnikar wrote:

I am not saying that your way is wrong or mine is better. I am saying
I don't write code like that unless I have no other options. I rarely
use out parameters.

Would you use tuples if they were available in Delphi? I have in the
past created records just so I could return multiple values from a
function, but tuples seems like a much cleaner way to do that.

I would use tuples instead of out parameters.

But that does not mean I would use tuples in this case. I just don't see a point.

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar

John Kaster


Posts: 913
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 18, 2016 12:17 PM   in response to: Arthur Hoornweg in response to: Arthur Hoornweg
Arthur Hoornweg wrote:

My preferred solution would be the following:

You might find GO's implementation of if somewhat interesting

https://tour.golang.org/flowcontrol/7

--
John Kaster http://johnkaster.wordpress.com
Software solutions
Arnaud Bouchez

Posts: 137
Registered: 8/2/15
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 6:03 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Below is a section of my book "More Coding in Delphi" discussing the
issue of 'nil' in code.

Remember me previous thread(s) about FreeAndNil() in here...

Most of the time, I agree that encapsulation of objects would imply that all nested objects ARE instantiated.
So checking "if Assigned(...)" or "if ...<>nil" should never be necessary.
Just like FreeAndNil() should never be used on such objects.
For instance, value objects (i.e. objects which contain data per representation) should have such a behavior.

In mORMot, we defined some T*AutoCreate classes which auto-instantiate and auto-finalize nested published class properties (and dynamic arrays of class instance).
See http://synopse.info/files/html/Synopse%20mORMot%20Framework%20SAD%201.18.html#TITLE_580
This TSynAutoCreateFields would **force** the class instance to behave as you describe.
And it would avoid overriding both constructor + destructor.

But some meta-classes may gather several class instances, depending on the current state of the application.
In this case, I do not mind especially checking for nil before accessing those properties.
If properly documented, I do not find this unsafe at all.
On a server, or within a complex process, it would help reduce the memory and resource consumption.
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:03 AM   in response to: Nick Hodges in response to: Nick Hodges
"Nick Hodges" wrote on Sun, 14 Feb 2016 08:03:05 -0800:

I still stand by my statements that nil should never be accepted by a
method as an argument and that nil should never be exposed by an API or
returned by a function.

Both are completely valid as long as the method is clearly documented
to use nil, or that it's use is easily inferred. You've not presented
any kind of case that explains what is actually wrong with it. You
may as well argue that nobody should ever eat vanilla ice cream
because you think chocolate is so much better.

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Nick Hodges

Posts: 2,414
Registered: 9/22/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:13 AM   in response to: Brandon Staggs in response to: Brandon Staggs
Brandon Staggs wrote:

You've not presented
any kind of case that explains what is actually wrong with it.

Hmm, I thought I had.

Accessing a nil variable causes an access violation.

That's bad, right?

--
Nick
Delphi Programming is Fun
Dalija Prasnikar

Posts: 2,325
Registered: 11/9/99
Re: Never Let a Bad State Happen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 15, 2016 8:14 AM   in response to: Nick Hodges in response to: Nick Hodges
Nick Hodges wrote:
Brandon Staggs wrote:

You've not presented
any kind of case that explains what is actually wrong with it.

Hmm, I thought I had.

Accessing a nil variable causes an access violation.

That's bad, right?

So is division by zero... that is not a proof ;-)

--
Dalija Prasnikar
https://twitter.com/dalijap
https://plus.google.com/+DalijaPrasnikar
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/9