Comments about noop features and blur thoughts

3 views
Skip to first unread message

ENRIQUE

unread,
Sep 18, 2009, 3:37:27 PM9/18/09
to noop
Hi all,

I read about noop in Linuxtoday.com (http://www.linuxtoday.com/
developer/2009091802135NWSW) and found the project quite interesting.

Just some comments about the planned/proposed features (http://
code.google.com/p/noop/wiki/Features)

- " Avoid null, Types shouldn't allow null value by default "

Certainly, that's the think I hate most when programming with an
external API that insist in returning nulls. To cope with the problem
I try to add the prefix "nullable" to a function to indicate/advice/
warn it can return nulls.
My opinion is that noop could by default forbid the "null" token and
just let it exists if explicitely the function/code is tagged as
nullable. And, still, to avoid lazy developers use the tag
automatically instead of thinking how to avoid the null trap, allow
its use only when detecting the code block is using an external
library that lets null be returned, never in native noop code.

- "Prefer Unchecked exceptions"
In my own experience checked exceptions can be useful if used properly
(http://code.google.com/p/recipientexceptions/wiki/
RecipientExceptionsIntroduction)

but most of the time checking is disturbing and does not improve code
quality. Using my "recipient Exceptions" nomenclature, I think that by
dividing between
context-free exceptions(unchecked) and context-aware exceptions
(checked) could be a pragmatical solution.

Some other blur thoughts not reflected in the planned/proposed
features:


BLUR thought 1:

- !!exception scope and visibility scope are completly different
things!!. Don't use "{" "}" to delimit exception scope. Don't force
visibility scope inside the exception scope. That forces undefined
values. A Java Example:

= = = = = = = = = = = = = = = = = = = = = = = = =
Connection objCon;
try {
String jndiCon = getConFromJNDI(....);
objCon = getConnection(....);
....
}catch(Exception e){
objCon.close();
}
= = = = = = = = = = = = = = = = = = = = = = = = = =

the visibility scope '{' '}' used for the try-catch blocks force
objCon to get an undefined value if an exception is thrown before
objCon beeing created. A possible solution is to initialize the objCon
with a fake object by that goes against software performance.

By not forcing exception blocks to relate to visibility scope the
problem dissapears:

= = = = = = = = = = = = = = = = = = = = = = = = =

:try
String jndiCon = getConFromJNDI(....);
Connection objCon = getConnection(....);
....

:catch
(Exception e)
objCon.close();
:
= = = = = = = = = = = = = = = = = = = = = = = = = =
Notice that if getConnection raises and exception objCon will still
be undefined. That would force functions raising exceptions in noop to
explicitely declare a default fake return value that will be assigned
just in case the function exits throught an exception. I thinks that's
a needed to avoid using null/undefined objects. To avoid the software
developer extra typing, the fake exception object could be indicated
during the class definition so that functions using the class will not
need to declare it when needed.

Notice also, I counter-tabulate exceptions and use the
invented :try :catch syntax just to make clear that visility scope has
nothing to do with exception scope.



BLUR thought 2:
- Discourage inheritance: There is much marketingware about OOP and
the miracles of inheritance and polimofirsm. Still most of the time
inheritance is not used properly and promotes wrong and unsustainable
APIs. Unfortunately inheritance works pretty well with UIs (surfaces
inside surfaces) and since many people learn OOP by using OOP UIs they
grow with the idea that inheritance is their friend.


Ajay

unread,
Sep 21, 2009, 5:04:20 AM9/21/09
to noop
On Sep 18, 3:37 pm, ENRIQUE <enrique.arizonben...@gmail.com> wrote:
[...]
>
> - " Avoid null, Types shouldn't allow null value by default "
>
>  Certainly, that's the think I hate most when programming with an
> external API that insist in returning nulls. To cope with the problem
> I try to add the prefix "nullable" to a function to indicate/advice/
> warn it can return nulls.
>  My opinion is that noop could by default forbid the "null" token and
> just let it exists if explicitely the function/code is tagged as
> nullable. And, still, to avoid lazy developers use the tag
> automatically instead of thinking how to avoid the null trap, allow
> its use only when detecting the code block is using an external
> library that lets null be returned, never in native noop code.
>
[...]

I like how Object C deals with null. i.e. does not throw a NPE. Any
method call on a null object will return null too.

Example:
String x = null;
String y = x.substring(0,3); // will *NOT* throw a NPE
// y is null.

This save the litter of (mostly) unnecessary null checks throughout
the code.

Just my 2 cents.

Ajay

Ajay

unread,
Sep 21, 2009, 5:14:40 AM9/21/09
to noop

Nicolas Dasriaux

unread,
Sep 21, 2009, 8:45:06 AM9/21/09
to no...@googlegroups.com
PROPOSALS for nullable and non-nullable references and graceful null handling

MOTIVATIONS

Nullable and non-null

You don't have to check for null when it is absolutely sure it cannot be null.

Most of the time, it shouldn't be null.
In most cases, fields, parameters, and variables are not expected to be null.
Fields may temporarily be null before the constructor has initialized the fields. This state is only transient.

Sometimes, it might be null.
Some fields may be null, for example in the case of lazy loading or lazy computation.
Null may also represent the 'not-assigned' value for an optional field.

Typing a reference as non-null reference should require no additional effort.
Typing a reference as nullable should be explicit and non-default. It should require minimal effort in terms of typing, but should be intentional.

Gracefull null handling

Dereferencing a nullable reference should not require boiler plate code in simple cases.

Graceful null handling is especially desired in the presentation layer.
This may be a personal view, but I see overuse of gracefull null handling in business layer as a serious anti-pattern.
It leads to very late failure, and difficult to diagnose bugs. The code fails much later after the unexpected null has appeared. I call that the 'null tunnel'.
General overuse of graceful null handling leads to code that do not fail when it doesn't work as expected.
This kind of code do not comply with the 'fail early' principle.

Many UI and web frameworks, such as JSF and JSP EL (expression language), have been providing gracefull handling of null for a long time.
This is especially useful when chaining properties such as :

customer.address.city

Null Object Pattern

The null object pattern is very difficult to understand for a vast majority of developpers.
I don't see that as a desirable feature, but it may reflect only my personal opinion).

NULLABLE AND NON-NULLABLE REFERENCES

All references (fields, parameters, and variables) are typed as non-null by default.
Typing as nullable is performed with a specific syntax.

I see two possible syntaxes :
- a 'nullable' keyword
- a '?' symbol posfixing the reference type

The '?' symbol would be much more consistent with the proposed null-safe operator '?.' and is also much shorter to type.

// Typed as non-null Customer references
Customer customer, otherCustomer;

// Typed as nullable Customer reference
nullable Customer nullableCustomer, otherNullableCustomer;

// Typed as nullable Customer reference (alternative syntax)
Customer? nullableCustomer, otherNullableCustomer;

// ---------- Assignment to non-null reference ----------

// Should NOT compile. CANNOT assign null to non-null reference
customer = null;

//Should compile. Can assign non-null reference to non-null reference
customer = otherCustomer;

// Should NOT compile. CANNOT assign nullable reference to non-null reference
customer = nullableCustomer;

// ---------- Derefencing non-null reference (calling method, accessing field or property) ----------

// Should compile. Can derefence non-null reference without checking null
customer.addOrder(order);

// Should NOT compile (or is it a WARNING). Useless to check for null on non-null reference
// (for general case, compiler should use control flow analysis to check this)

if (customer != null) {
    customer.addOrder(order);
}

// Should NOT compile (or is it a WARNING). Useless to check for null on non-null reference
customer?.addOrder(order);

// ---------- Assignment to nullable reference ----------

//Should compile. Can assign null to nullable reference
nullableCustomer = null;

//Should compile. Can assign nullable reference to nullable reference
nullableCustomer = otherNullableCustomer;

//Should compile. Can assign non-null reference to nullable reference
nullableCustomer = customer;

// ---------- Derefencing nullable reference (calling method, accessing field or property) ----------

// Should NOT compile. CANNOT derefence null reference without checking null
nullableCustomer.addOrder(order);

// Should compile. Can dereference a null reference, when it has been checked for null
// (for general case, compiler should use control flow analysis to check this)

if (nullableCustomer != null) {
    nullableCustomer.addOrder(order);
}

// Should compile. Can dereference a non-null reference, when using null safe derefencing operator (?.)
nullableCustomer?.addOrder(order);

GRACEFULL NULL HANDLING


The '?.' (AKA elvis) operator allows to handle nullable references gracefully, without boilerplate.

Customer? nullableCustomer = null;

// Do nothing when calling a method on null reference
nullableCustomer?.addOrder(order);

// Do nothing and return null when calling a method with a result on null reference (even if return type is non-null ?)
nullableCustomer?.getPastOrders();

// Non null property accesse on null reference returns null (even if property type is non-null ?)
nullableCustomer?.firstName

WARNING : The behaviour of the '?.' should be much further specified


2009/9/21 Ajay <aja...@gmail.com>

ENRIQUE ARIZON BENITO

unread,
Sep 21, 2009, 1:28:54 PM9/21/09
to no...@googlegroups.com
Hi,

The null Object pattern proposal claims " There are many situations where an object reference may be null.".

Well, for the last 15 years I have worked with webapps, comunication software, simulation software, statistic software, ... and I have never found a simple example where an object reference ought to be null. I doubt that claim can be sustained.

 The most similar to a null object could be that of a "non defined object" or "non applicable object". Still that makes only sense in the field of fuzzy logic or artificial inteligence. In a general purpose language like noop (or Java, or C,...) a null object means nothing (which is quite different to not defined/not applicable). There is no way for the language to known *why* the object is null or how to react to such event. I think a null
object must always raise an exception since it means a failure, a non-planed state. It's a completly random state, as random as a hardware failure in a RAM module. It's up to the software developer how to react to such exception. But keeping a null object around means, from my point of view, hidding an error (I think a good mathematician could probe that, in fact, it ougth to be considered an error).
When a null pointer exception is thrown the software developer will basically choose one of the next two options:
- Assign a default value, that makes sense in the context of the application.
- Stop normal execution and rollback to an stable state.

(A inexperienced software developer will also choose a third option. Ignore it  ;) )

Since the first option (assigning a default value to the object) is quite common I speak about a default value in my first mail. That's looks me vaguely similar to the Null Object Pattern. Still it must be considered a utility to avoid typing code. Without a running context that limits the semantics of a type or object instance it's mathematically impossible to known whether the default value (something like similar to the Null Object value) makes sense or not. For example, using one of the most widely used classes in Java, an String:
 In a running context it could make
sense to default a surname to an empty string (""). In another context it can make sense to assign to a default file system path (the /home/user directory) or a default country ("US"). But in a bank transaction an String associated to the recipient of a 1Million$ transfer can not be left empty. It must raise an exception, leave up the stack and finally "advice" the Oracle database to rollback the transaction.
So a default value must be considered just an utility for the most simple and less risky cases as a way to avoid typing code.

Also is quite clear from the previous String example that the default value has to be changed depending where we are in the code (the running context/application state), so the idea of assigning a default object based just merely on its type can't be a pratical approach unless it's value can be reasigned with easy. In the previous paragraph that would force to implement a new SurnameString Class, a fileSystemPathString Class, a CountryString class and a recipientString class just to allow a new default value (null object value) for each one. A more practical approach would be to indicate the compiler what  the default value is when declaring the variable. For example:

String surname = "surname" defaults "";
String path = "path" defaults "/home/";
...
Then a code like:

  surname = input.getSurname();

would assign "" to surname and still raise and exception. The language can not guess in advance the consecuences of an empty String. It could means nothing ... or 1 millon dolar loose.

Regards!

Enrique




Reply all
Reply to author
Forward
0 new messages