Null object: Difference between revisions
LalaithMeren (talk | contribs) |
|||
(130 intermediate revisions by 73 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Basic language learning}} |
{{task|Basic language learning}} |
||
[[Category:Simple]] |
|||
'''Null''' (or '''nil''') is the computer science concept of an undefined or unbound object. Some languages have an explicit way to access the null object, and some don't. Some languages distinguish the null object from [[undefined values]], and some don't. |
|||
'''Null''' (or '''nil''') is the computer science concept of an undefined or unbound object. |
|||
Some languages have an explicit way to access the null object, and some don't. |
|||
Some languages distinguish the null object from [[undefined values]], and some don't. |
|||
;Task: |
|||
Show how to access null in your language by checking to see if an object is equivalent to the null object. |
Show how to access null in your language by checking to see if an object is equivalent to the null object. |
||
''This task is not about whether a variable is defined. The task is about "null"-like values in various languages, which may or may not be related to the defined-ness of variables in your language.'' |
''This task is not about whether a variable is defined. The task is about "null"-like values in various languages, which may or may not be related to the defined-ness of variables in your language.'' |
||
<br><br> |
|||
=={{header|11l}}== |
|||
<syntaxhighlight lang="11l">F f([Int]? &a) |
|||
I a != N |
|||
a.append(1) |
|||
f(N) |
|||
[Int] arr |
|||
f(&arr) |
|||
print(arr)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1] |
|||
</pre> |
|||
=={{header|6502 Assembly}}== |
|||
{{trans|Z80 Assembly}} |
|||
Technically there is no such thing as a null pointer; all pointers point to ''something.'' It's a matter of what you're willing to give up. Often the null pointer is thought of as memory address 0, and on many CPUs this is the case - however this is most assuredly '''not''' the case on the 6502. Reason being, zero page RAM is limited and quite valuable, given that there are only 256 bytes of it and it is much more efficient to access than regular memory. As such, declaring <code>$0000</code> to be the null pointer would be a very poor choice. Ideally, the null pointer on a 6502 should: |
|||
* Be somewhere that isn't zero page RAM |
|||
* Be somewhere that we cannot change at runtime (e.g. read-only memory) or doing so would cause major problems (the vector table) |
|||
* Point to something that has no value to the programmer. |
|||
We can choose quite a few places, the easiest one I can think of is <code>$FFFF</code>. Although it sort of breaks our first rule, as when dereferenced as a 16-bit value, you get the value stored at <code>$0000</code> as the high byte, we still can access <code>$0000</code> normally anyway. Since it points to the high byte of the interrupt request vector, it's something we don't want to (or most likely can't) modify at runtime, and is of no use to us (if we really wanted the IRQ handler's address we'd dereference <code>$FFFE</code> instead.) |
|||
How a null pointer is implemented is very simple. You decide beforehand what your null pointer will be, and before you dereference a pointer variable, compare it to the null pointer, and if they're equal, don't dereference it. That's all there is to it. |
|||
<syntaxhighlight lang="6502asm">lda pointer ;a zero-page address that holds the low byte of a pointer variable. |
|||
CMP #$FF |
|||
BNE .continue |
|||
lda pointer+1 |
|||
CMP #$FF |
|||
BNE .continue |
|||
RTS ;return without doing anything |
|||
.continue</syntaxhighlight> |
|||
=={{header|8th}}== |
|||
<syntaxhighlight lang="forth"> |
|||
null? if "item was null" . then |
|||
</syntaxhighlight> |
|||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
|||
<syntaxhighlight lang="aarch64 assembly"> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
|||
/* program nullobj64.s */ |
|||
/*******************************************/ |
|||
/* Constantes file */ |
|||
/*******************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly*/ |
|||
.include "../includeConstantesARM64.inc" |
|||
/*******************************************/ |
|||
/* Initialized data */ |
|||
/*******************************************/ |
|||
.data |
|||
szCarriageReturn: .asciz "\n" |
|||
szMessResult: .asciz "Value is null.\n" // message result |
|||
qPtrObjet: .quad 0 // objet pointer |
|||
/*******************************************/ |
|||
/* UnInitialized data */ |
|||
/*******************************************/ |
|||
.bss |
|||
/*******************************************/ |
|||
/* code section */ |
|||
/*******************************************/ |
|||
.text |
|||
.global main |
|||
main: // entry of program |
|||
ldr x0,qAdrqPtrObjet // load pointer address |
|||
ldr x0,[x0] // load pointer value |
|||
cbnz x0,100f // is null ? |
|||
ldr x0,qAdrszMessResult // yes -> display message |
|||
bl affichageMess |
|||
100: // standard end of the program |
|||
mov x0,0 // return code |
|||
mov x8,EXIT // request to exit program |
|||
svc 0 // perform the system call |
|||
qAdrszMessResult: .quad szMessResult |
|||
qAdrszCarriageReturn: .quad szCarriageReturn |
|||
qAdrqPtrObjet: .quad qPtrObjet |
|||
/********************************************************/ |
|||
/* File Include fonctions */ |
|||
/********************************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly */ |
|||
.include "../includeARM64.inc" |
|||
</syntaxhighlight> |
|||
=={{header|Action!}}== |
|||
<syntaxhighlight lang="action!">TYPE Object=[ |
|||
BYTE byteData |
|||
INT intData |
|||
CARD cardData] |
|||
PROC IsNull(Object POINTER ptr) |
|||
IF ptr=0 THEN |
|||
PrintE("Object is null") |
|||
ELSE |
|||
PrintE("Object is not null") |
|||
FI |
|||
RETURN |
|||
PROC Main() |
|||
Object a |
|||
Object POINTER ptr1=a,ptr2=0 |
|||
IsNull(ptr1) |
|||
IsNull(ptr2) |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Null_object.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
Object is not null |
|||
Object is null |
|||
</pre> |
|||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
< |
<syntaxhighlight lang="actionscript">if (object == null) |
||
trace("object is null");</ |
trace("object is null");</syntaxhighlight> |
||
ActionScript also has an '''undefined''' value: see [[Undefined values#ActionScript]]. |
ActionScript also has an '''undefined''' value: see [[Undefined values#ActionScript]]. |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_Io; |
||
if Object = null then |
if Object = null then |
||
Ada.Text_Io.Put_line("object is null"); |
Ada.Text_Io.Put_line("object is null"); |
||
end if;</ |
end if;</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 26: | Line 154: | ||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}} |
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}} |
||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}} |
||
< |
<syntaxhighlight lang="algol68">REF STRING no result = NIL; |
||
STRING result := ""; |
STRING result := ""; |
||
Line 44: | Line 172: | ||
REF STRING var := NIL; |
REF STRING var := NIL; |
||
IF var ISNT NIL THEN print(("The address of var ISNT NIL",new line)) FI; |
IF var ISNT NIL THEN print(("The address of var ISNT NIL",new line)) FI; |
||
IF var IS REF STRING(NIL) THEN print(("The address of var IS REF STRING(NIL)",new line)) FI</ |
IF var IS REF STRING(NIL) THEN print(("The address of var IS REF STRING(NIL)",new line)) FI</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 67: | Line 195: | ||
* ALGOL 68's '''void''' is python's <code>NoneType</code>, and |
* ALGOL 68's '''void''' is python's <code>NoneType</code>, and |
||
* ALGOL 68's '''nil''' is python's <code>hash(None)</code> |
* ALGOL 68's '''nil''' is python's <code>hash(None)</code> |
||
=={{header|ALGOL W}}== |
|||
<syntaxhighlight lang="algolw">begin |
|||
% declare a record type - will be accessed via references % |
|||
record R( integer f1, f2, f3 ); |
|||
% declare a reference to a R instance % |
|||
reference(R) refR; |
|||
% assign null to the reference % |
|||
refR := null; |
|||
% test for a null reference - will write "refR is null" % |
|||
if refR = null then write( "refR is null" ) else write( "not null" ); |
|||
end.</syntaxhighlight> |
|||
=={{header|AmigaE}}== |
=={{header|AmigaE}}== |
||
< |
<syntaxhighlight lang="amigae">DEF x : PTR TO object |
||
-> ... |
-> ... |
||
IF object <> NIL |
IF object <> NIL |
||
-> ... |
-> ... |
||
ENDIF</ |
ENDIF</syntaxhighlight> |
||
=={{header|APL}}== |
|||
APL is a vector/array-based language, so rather than a 'null pointer' or 'null value' there is the 'null vector'. |
|||
<syntaxhighlight lang="apl"> |
|||
⍝⍝ GNU APL |
|||
]help ⍬ |
|||
niladic function: Z ← ⍬ (Zilde) |
|||
Zilde is the empty numeric vector (aka. ⍳0) |
|||
Not a function but rather an alias for the empty |
|||
vector: |
|||
⍬≡⍳0 |
|||
1 |
|||
</syntaxhighlight> |
|||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
Many applications will return <code>missing value</code>, but <code>null</code> is also available. |
Many applications will return <code>missing value</code>, but <code>null</code> is also available. |
||
< |
<syntaxhighlight lang="applescript">if x is missing value then |
||
display dialog "x is missing value" |
display dialog "x is missing value" |
||
end if |
end if |
||
Line 83: | Line 236: | ||
if x is null then |
if x is null then |
||
display dialog "x is null" |
display dialog "x is null" |
||
end if</ |
end if</syntaxhighlight> |
||
=={{header|ARM Assembly}}== |
|||
{{works with|as|Raspberry Pi}} |
|||
<syntaxhighlight lang="arm assembly"> |
|||
/* ARM assembly Raspberry PI */ |
|||
/* program nullobj.s */ |
|||
/* Constantes */ |
|||
.equ STDIN, 0 @ Linux input console |
|||
.equ STDOUT, 1 @ Linux output console |
|||
.equ EXIT, 1 @ Linux syscall |
|||
.equ READ, 3 @ Linux syscall |
|||
.equ WRITE, 4 @ Linux syscall |
|||
/* Initialized data */ |
|||
.data |
|||
szCarriageReturn: .asciz "\n" |
|||
szMessResult: .asciz "Value is null.\n" @ message result |
|||
iPtrObjet: .int 0 @ objet pointer |
|||
/* UnInitialized data */ |
|||
.bss |
|||
/* code section */ |
|||
.text |
|||
.global main |
|||
main: @ entry of program |
|||
ldr r0,iAdriPtrObjet @ load pointer address |
|||
ldr r0,[r0] @ load pointer value |
|||
cmp r0,#0 @ is null ? |
|||
ldreq r0,iAdrszMessResult @ yes -> display message |
|||
bleq affichageMess |
|||
100: @ standard end of the program |
|||
mov r0, #0 @ return code |
|||
pop {fp,lr} @ restaur 2 registers |
|||
mov r7, #EXIT @ request to exit program |
|||
svc 0 @ perform the system call |
|||
iAdrszMessResult: .int szMessResult |
|||
iAdrszCarriageReturn: .int szCarriageReturn |
|||
iAdriPtrObjet: .int iPtrObjet |
|||
/******************************************************************/ |
|||
/* display text with size calculation */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the message */ |
|||
affichageMess: |
|||
push {r0,r1,r2,r7,lr} @ save registres |
|||
mov r2,#0 @ counter length |
|||
1: @ loop length calculation |
|||
ldrb r1,[r0,r2] @ read octet start position + index |
|||
cmp r1,#0 @ if 0 its over |
|||
addne r2,r2,#1 @ else add 1 in the length |
|||
bne 1b @ and loop |
|||
@ so here r2 contains the length of the message |
|||
mov r1,r0 @ address message in r1 |
|||
mov r0,#STDOUT @ code to write to the standard output Linux |
|||
mov r7, #WRITE @ code call system "write" |
|||
svc #0 @ call systeme |
|||
pop {r0,r1,r2,r7,lr} @ restaur des 2 registres */ |
|||
bx lr @ return |
|||
</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">v: null |
|||
if v=null -> print "got NULL!"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>got NULL!</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">If (object == null) |
||
MsgBox, object is null</ |
MsgBox, object is null</syntaxhighlight> |
||
=={{header|AutoIt}}== |
|||
<syntaxhighlight lang="autoit">Local $object = Null |
|||
If $object = Null Then MsgBox(0, "NULL", "Object is null")</syntaxhighlight> |
|||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
Undefined elements correspond to an empty string; when converted to a numerical value, it evaluates to 0. In order to distinguish a undefined value from a value of 0, length(var) need to be used. |
Undefined elements correspond to an empty string; when converted to a numerical value, it evaluates to 0. In order to distinguish a undefined value from a value of 0, length(var) need to be used. |
||
< |
<syntaxhighlight lang="awk">#!/usr/bin/awk -f |
||
BEGIN { |
BEGIN { |
||
b=0; |
b=0; |
||
Line 97: | Line 330: | ||
print "<"u,length(u)">" |
print "<"u,length(u)">" |
||
print "<"u+0,length(u+0)">"; |
print "<"u+0,length(u+0)">"; |
||
}</ |
}</syntaxhighlight> |
||
Output |
Output |
||
<pre><0 1> |
<pre><0 1> |
||
< 0> |
< 0> |
||
<0 1></pre> |
<0 1></pre> |
||
=={{header|Axe}}== |
|||
Null pointers can be checked by simply comparing the pointer with 0. |
|||
<syntaxhighlight lang="axe">If P=0 |
|||
Disp "NULL PTR",i |
|||
End</syntaxhighlight> |
|||
=={{header|Babel}}== |
=={{header|Babel}}== |
||
In this example, we place nil on the stack, then perform an if-then-else (ifte) based on the value returned by the 'nil?' operator which returns true if top-of-stack (TOS) is nil. If TOS is nil, then we can be relieved, otherwise, the interpreter has gone absolutely haywire. The '<<' operator prints the selected string to STDOUT. |
In this example, we place nil on the stack, then perform an if-then-else (ifte) based on the value returned by the 'nil?' operator which returns true if top-of-stack (TOS) is nil. If TOS is nil, then we can be relieved, otherwise, the interpreter has gone absolutely haywire. The '<<' operator prints the selected string to STDOUT. |
||
< |
<syntaxhighlight lang="babel">{ nil { nil? } { "Whew!\n" } { "Something is terribly wrong!\n" } ifte << }</syntaxhighlight> |
||
=={{header|BASIC}}== |
|||
==={{header|Applesoft BASIC}}=== |
|||
caveat: http://qconlondon.com/london-2009/presentation/Null+References%3A+The+Billion+Dollar+Mistake |
|||
Applesoft has no built-in object system. The closest values to NULL or nil for each of the types are 0 for integers and floating point numbers, and "" for strings. There is also the NUL character: CHR$(0). One could create an object system using global variables and include a special value for NULL, but this is probably a mistake. |
|||
<syntaxhighlight lang="applesoftbasic">TRUE = 1 : FALSE = 0 |
|||
NULL = TRUE |
|||
IF NULL THEN PRINT "NULL" |
|||
NULL = FALSE |
|||
IF NOT NULL THEN PRINT "NOT NULL"</syntaxhighlight>'''Output:'''<pre>NULL |
|||
NOT NULL</pre> |
|||
=={{header|BBC BASIC}}== |
==={{header|BBC BASIC}}=== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
A null object has a pointer with a value of zero or one. |
A null object has a pointer with a value of zero or one. |
||
< |
<syntaxhighlight lang="bbcbasic"> PROCtestobjects |
||
END |
END |
||
Line 122: | Line 375: | ||
IF !^s{} <= 1 PRINT "s{} is null" ELSE PRINT "s{} is not null" |
IF !^s{} <= 1 PRINT "s{} is null" ELSE PRINT "s{} is not null" |
||
IF !^t{} <= 1 PRINT "t{} is null" ELSE PRINT "t{} is not null" |
IF !^t{} <= 1 PRINT "t{} is null" ELSE PRINT "t{} is not null" |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 130: | Line 383: | ||
t{} is null |
t{} is null |
||
</pre> |
</pre> |
||
==={{header|GWBASIC/QBasic/QB/VBDOS}}=== |
|||
These dialects of BASIC have no built-in object system. One STRING variable can have a default empty ("") value and a numeric one a default zero (0) value. A STRING variable can be assigned with the NULL (Chr$(0)) value if needed and can be assesed with the instruction. |
|||
<syntaxhighlight lang="basic"> |
|||
IF VAR$ = CHR$(0) THEN PRINT "Variable has a null value." |
|||
</syntaxhighlight> |
|||
=={{header|Bracmat}}== |
|||
Bracmat has no null objects. |
|||
The operators for multiplication, addition and concatenation have neutral elements, which are <code>1</code>, <code>0</code> and the empty string, respectively, but these are values like any other string. |
|||
<syntaxhighlight lang="bracmat"> |
|||
a:?x*a*?z {assigns 1 to x and to z} |
|||
a:?x+a+?z {assigns 0 to x and to z} |
|||
a:?x a ?z {assigns "" (or (), which is equivalent) to x and to z} |
|||
</syntaxhighlight> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Line 138: | Line 409: | ||
The standard library defines NULL in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h and wchar.h. [[POSIX]] systems also define NULL in dirent.h and unistd.h. Many C files include at least one of these headers, so NULL is almost always available. |
The standard library defines NULL in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h and wchar.h. [[POSIX]] systems also define NULL in dirent.h and unistd.h. Many C files include at least one of these headers, so NULL is almost always available. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
int main() |
int main() |
||
Line 148: | Line 419: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
|||
As with Java, any reference type may be null, and testing for nullity uses ordinary boolean operators. |
|||
<syntaxhighlight lang="csharp">if (foo == null) |
|||
Console.WriteLine("foo is null");</syntaxhighlight> |
|||
C# 2.0 introduced nullable types for situations in which even primitive value types may have undefined or unknown values (for example, when reading from a database). Prior to the introduction of nullable types, these situations would require writing wrapper classes or casting to a reference type (e.g., object), incurring the penalties of boxing and reduced type safety. A variable with nullable type can be declared simply by adding the '?' operator after the type. |
|||
{{works with|C sharp|C#|2.0+}} |
|||
<syntaxhighlight lang="csharp">int? x = 12; |
|||
x = null;</syntaxhighlight> |
|||
Also new in C# 2.0 was the null coalescing operator, '??', which is simply syntactic sugar allowing a default value to replace an operand if the operand is null: |
|||
{{works with|C sharp|C#|2.0+}} |
|||
<syntaxhighlight lang="csharp">Console.WriteLine(name ?? "Name not specified"); |
|||
//Without the null coalescing operator, this would instead be written as: |
|||
//if(name == null){ |
|||
// Console.WriteLine("Name not specified"); |
|||
//}else{ |
|||
// Console.WriteLine(name); |
|||
//}</syntaxhighlight> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
In C++ non-pointer types do not support null. (C++ provides value semantics rather than reference semantics). When using pointers C++ permits checking for null by comparing the pointer to a literal of 0, or (as in C) by way of a macro (NULL) which simply expands to 0. |
In C++ non-pointer types do not support null. (C++ provides value semantics rather than reference semantics). When using pointers C++ permits checking for null by comparing the pointer to a literal of 0, or (as in C) by way of a macro (NULL) which simply expands to 0. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <cstdlib> |
#include <cstdlib> |
||
if (object == 0) { |
if (object == 0) { |
||
std::cout << "object is null"; |
std::cout << "object is null"; |
||
}</ |
}</syntaxhighlight> |
||
std::optional is available since C++17 (or Boost's boost::optional via boost/optional.hpp for earlier standards) for cases where the programmer wishes to pass by value, but still support a null value. |
|||
< |
<syntaxhighlight lang="cpp"> |
||
#include <boost/optional.hpp> |
|||
#include <iostream> |
#include <iostream> |
||
#include <optional> |
|||
std::optional<int> maybeInt() |
|||
int main() |
int main() |
||
{ |
{ |
||
std::optional<int> maybe = maybeInt(); |
|||
if(!maybe) |
if(!maybe) |
||
std::cout << "object is null\n"; |
std::cout << "object is null\n"; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C sharp|C#}}== |
|||
As with Java, any reference type may be null, and testing for nullity uses ordinary boolean operators. |
|||
<lang csharp>if (foo == null) |
|||
Console.WriteLine("foo is null");</lang> |
|||
===C++11=== |
|||
C# 2.0 introduced nullable types for situations in which even primitive value types may have undefined or unknown values (for example, when reading from a database). Prior to the introduction of nullable types, these situations would require writing wrapper classes or casting to a reference type (e.g., object), incurring the penalties of boxing and reduced type safety. A variable with nullable type can be declared simply by adding the '?' operator after the type. |
|||
In C++11 there is <code>nullptr</code> of type <code>nullptr_t</code> which represents a pointer to an invalid place. You can use it like |
|||
{{works with|C sharp|C#|2.0+}} |
|||
<syntaxhighlight lang="cpp"> |
|||
<lang csharp>int? x = 12; |
|||
int *p = nullptr; |
|||
x = null;</lang> |
|||
... |
|||
if (p == nullptr){ |
|||
Also new in C# 2.0 was the null coalescing operator, '??', which is simply syntactic sugar allowing a default value to replace an operand if the operand is null: |
|||
// do some thing |
|||
} |
|||
{{works with|C sharp|C#|2.0+}} |
|||
//or just |
|||
<lang csharp>Console.WriteLine(name ?? "Name not specified"); |
|||
if (p){ |
|||
// do some thing |
|||
//Without the null coalescing operator, this would instead be written as: |
|||
} |
|||
//if(name == null){ |
|||
</syntaxhighlight> |
|||
// Console.WriteLine("Name not specified"); |
|||
//}else{ |
|||
// Console.WriteLine(name); |
|||
//}</lang> |
|||
=={{header|Chapel}}== |
=={{header|Chapel}}== |
||
Class variables can be declared as nil if and only if they have nilable class type, declared with postfix ?, alongside memory management technique owned, borrowed, shared, or unmanaged. A nilable class type is default initialized to nil. |
|||
Objects variables without an initializer expression will be initiallized to nil: |
|||
<lang |
<syntaxhighlight lang="chapel"> |
||
class C { }; |
|||
var c:C; // is nil |
|||
var c : owned C?; // is nil |
|||
writeln(if c == nil then "nil" else "something");</lang> |
|||
writeln(if c == nil then "nil" else "something"); |
|||
</syntaxhighlight> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Clojure's <code>nil</code> is equivalent to Java's <code>null</code>. |
Clojure's <code>nil</code> is equivalent to Java's <code>null</code>. |
||
< |
<syntaxhighlight lang="lisp">(let [x nil] |
||
(println "Object is" (if (nil? x) "nil" "not nil")))</ |
(println "Object is" (if (nil? x) "nil" "not nil")))</syntaxhighlight> |
||
Test wether symbol <code>foo</code> is defined: |
Test wether symbol <code>foo</code> is defined: |
||
< |
<syntaxhighlight lang="lisp">(find (ns-interns *ns*) 'foo)</syntaxhighlight> |
||
Undefining <code>foo</code>: |
Undefining <code>foo</code>: |
||
< |
<syntaxhighlight lang="lisp">(ns-unmap *ns* 'foo)</syntaxhighlight> |
||
=={{header|COBOL}}== |
|||
Works with GnuCOBOL 2.0 |
|||
<syntaxhighlight lang="cobol"> identification division. |
|||
program-id. null-objects. |
|||
remarks. test with cobc -x -j null-objects.cob |
|||
data division. |
|||
working-storage section. |
|||
01 thing-not-thing usage pointer. |
|||
*> call a subprogram |
|||
*> with one null pointer |
|||
*> an omitted parameter |
|||
*> and expect void return (callee returning omitted) |
|||
*> and do not touch default return-code (returning nothing) |
|||
procedure division. |
|||
call "test-null" using thing-not-thing omitted returning nothing |
|||
goback. |
|||
end program null-objects. |
|||
*> Test for pointer to null (still a real thing that takes space) |
|||
*> and an omitted parameter, (call frame has placeholder) |
|||
*> and finally, return void, (omitted) |
|||
identification division. |
|||
program-id. test-null. |
|||
data division. |
|||
linkage section. |
|||
01 thing-one usage pointer. |
|||
01 thing-two pic x. |
|||
procedure division using |
|||
thing-one |
|||
optional thing-two |
|||
returning omitted. |
|||
if thing-one equal null then |
|||
display "thing-one pointer to null" upon syserr |
|||
end-if |
|||
if thing-two omitted then |
|||
display "no thing-two was passed" upon syserr |
|||
end-if |
|||
goback. |
|||
end program test-null.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
prompt$ cobc -x -j null-objects.cob |
|||
thing-one pointer to null |
|||
no thing-two was passed |
|||
</pre> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 224: | Line 567: | ||
Common Lisp has an object denoted by the symbol <code>nil</code>. When the symbol <code>nil</code> is evaluated as an expression, it evaluates to itself. |
Common Lisp has an object denoted by the symbol <code>nil</code>. When the symbol <code>nil</code> is evaluated as an expression, it evaluates to itself. |
||
<code>nil</code> uniquely represents boolean false, and so code like < |
<code>nil</code> uniquely represents boolean false, and so code like <syntaxhighlight lang="lisp">(if (condition) (do-this))</syntaxhighlight> is actually testing whether <code>(condition)</code> returns the value <code>nil</code>. The object <code>nil</code> is also used to denote the empty list which also terminates other lists. The value is also used as a default when some function returns fewer values than expected. <code>(list (values))</code> produces <code>(nil)</code> (list containing one element, which is the empty list), because <code>(values)</code> produces no value, but the function call <code>(list ...)</code> needs to reduce the expression to a single argument value, and so <code>nil</code> is supplied. |
||
====Beginnings of Null Object==== |
====Beginnings of Null Object==== |
||
Line 243: | Line 586: | ||
Suppose that the <code>car</code> function did not have a safe defaulting behavior for <code>nil</code>. We could use the methods of the object system to define a <code>car*</code> which does have the safe behavior: |
Suppose that the <code>car</code> function did not have a safe defaulting behavior for <code>nil</code>. We could use the methods of the object system to define a <code>car*</code> which does have the safe behavior: |
||
< |
<syntaxhighlight lang="lisp">(defmethod car* ((arg cons)) |
||
(car arg)) |
(car arg)) |
||
(defmethod car* ((arg null)) |
(defmethod car* ((arg null)) |
||
nil)</ |
nil)</syntaxhighlight> |
||
Now if we invoke <code>car*</code> on something which is neither a cons, nor <code>nil</code>, we get an error about no applicable method being found. |
Now if we invoke <code>car*</code> on something which is neither a cons, nor <code>nil</code>, we get an error about no applicable method being found. |
||
Line 253: | Line 596: | ||
We can handle that ourselves by writing a method specialized to the master supertype <code>t</code>: |
We can handle that ourselves by writing a method specialized to the master supertype <code>t</code>: |
||
< |
<syntaxhighlight lang="lisp">(defmethod car* ((arg t)) ;; can just be written (defmethod car* (arg) ...) |
||
(error "CAR*: ~s is neither a cons nor nil" arg))</ |
(error "CAR*: ~s is neither a cons nor nil" arg))</syntaxhighlight> |
||
The classes <code>t</code> and <code>null</code> are widely exploited in Lisp OO programming. |
The classes <code>t</code> and <code>null</code> are widely exploited in Lisp OO programming. |
||
=={{header|Component Pascal}}== |
=={{header|Component Pascal}}== |
||
<syntaxhighlight lang="oberon2"> |
|||
<lang Oberon2> |
|||
MODULE ObjectNil; |
MODULE ObjectNil; |
||
IMPORT StdLog; |
IMPORT StdLog; |
||
Line 277: | Line 620: | ||
END ObjectNil. |
END ObjectNil. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Crystal}}== |
|||
In Crystal, nil is represented by an instance of the Nil type, accessed by the identifier <code>nil</code>. A variable can only become nil if Nil is one of its possible types. All objects inheriting from the base Object class implement the method <code>.nil?</code> which returns true if the object is nil and false if it isn't. The equality and case equality operators can also be used to check for nil. The compiler returns an error if an object may be nil but is not treated as such. This can be suppressed with the <code>.not_nil!</code> method, which throws an exception at runtime if the object is in fact nil. |
|||
<syntaxhighlight lang="crystal">foo : Int32 | Nil = 5 # this variable's type can be Int32 or Nil |
|||
bar : Int32? = nil # equivalent type to above, but shorter syntax |
|||
baz : Int32 = 5 # this variable can never be nil |
|||
foo.not_nil! # nothing happens, since 5 is not nil |
|||
puts "Is foo nil? #{foo.nil?}" |
|||
foo = nil |
|||
puts "Now is foo nil? #{foo.nil?}" |
|||
puts "Does bar equal nil? #{bar == nil}" |
|||
puts "Is bar equivalent to nil? #{bar === nil}" |
|||
bar.not_nil! # bar is nil, so an exception is thrown</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Is foo nil? false |
|||
Now is foo nil? true |
|||
Does bar equal nil? true |
|||
Is bar equivalent to nil? true |
|||
Unhandled exception: Nil assertion failed (NilAssertionError) |
|||
...</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
In D ''is'' is used to perform bitwise identity, like to compare an object reference against null. |
In D ''is'' is used to perform bitwise identity, like to compare an object reference against null. |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
class K {} |
class K {} |
||
Line 292: | Line 660: | ||
if (k !is null) |
if (k !is null) |
||
writeln("Now k is not null"); |
writeln("Now k is not null"); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>k is null |
<pre>k is null |
||
Line 298: | Line 666: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi"> // the following are equivalent |
||
if lObject = nil then |
if lObject = nil then |
||
... |
... |
||
if not Assigned(lObject) then |
if not Assigned(lObject) then |
||
...</ |
...</syntaxhighlight> |
||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
See [[#Delphi | Delphi]] |
See [[#Delphi | Delphi]] |
||
=={{header|Dyalect}}== |
|||
Dyalect has a notion of <code>nil</code> - a special sigleton value which can be used in the cases when no other meaningful value can be provided. |
|||
<syntaxhighlight lang="dyalect">var x = nil |
|||
if x == nil { |
|||
//Do something |
|||
}</syntaxhighlight> |
|||
=={{header|Déjà Vu}}== |
|||
There isn't an actual null object, so generally falsy objects are used to indicate a missing value, or when that's impractical a specific ident: |
|||
<syntaxhighlight lang="dejavu">if not obj: |
|||
pass #obj is seen as null |
|||
if = :nil obj: |
|||
pass #obj is seen as null</syntaxhighlight> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">object == null</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
|||
The null object - '''null''' - is the same as the empty list (). It may be tested with the '''null?''' or '''!null?''' predicates. NB : null is not the same as the boolean #f (false). null evaluates to #t (true) in logical operations. |
|||
<syntaxhighlight lang="lisp"> |
|||
null → null |
|||
() → null |
|||
(null? 3) → #f |
|||
(!null? 4) → #t |
|||
(null? null) → #t |
|||
;; careful - null is not false : |
|||
(if null 'OUI 'NON) → OUI |
|||
;; usual usage : recursion on lists until (null? list) |
|||
(define (f list) |
|||
(when (!null? list) |
|||
(write (first list)) (f (rest list)))) |
|||
(f '( a b c)) → a b c |
|||
</syntaxhighlight> |
|||
=={{header|Ecstasy}}== |
|||
In Ecstasy, everything is an object, including the <span style="background-color: #e5e4e2"><tt> Null </tt></span> value. <span style="background-color: #e5e4e2"><tt> Null </tt></span> is the only value in the [https://github.com/xtclang/xvm/blob/dd32c2eba0930c4a59f4ba7507c6af37818d255c/lib_ecstasy/src/main/x/ecstasy.x#L21 <span style="background-color: #e5e4e2"><tt> Nullable </tt></span> enumeration defined in the "<tt>ecstasy</tt>" core module]. As a regular old object, the <span style="background-color: #e5e4e2"><tt> Null </tt></span> value has a regular old class, a regular old type, and it implements regular old methods such as <span style="background-color: #e5e4e2"><tt> toString() </tt></span>. There are, however, a few specific ways in the language (both the compiler and runtime) that <span style="background-color: #e5e4e2"><tt> Null </tt></span> is treated specially: |
|||
<ul><li>Syntax support: A type union with <span style="background-color: #e5e4e2"><tt> Nullable </tt></span> can be indicated with the postfix "?"; for example, the long-hand type union syntax <span style="background-color: #e5e4e2"><tt> Nullable|String s </tt></span> can be replaced using the short-hand notation <span style="background-color: #e5e4e2"><tt> String? s </tt></span>. |
|||
</li><li>Syntax support: The postfix "?" operator is a short-circuiting null value test, allowing a cascading sequence of null tests to replace a series of nested if statements; for example, <span style="background-color: #e5e4e2"><tt> Int x = a?.b()?.c?[i?].d? : e; </tt></span> will result in the value of <span style="background-color: #e5e4e2"><tt> e </tt></span> if any of the expressions <span style="background-color: #e5e4e2"><tt> a </tt></span>, <span style="background-color: #e5e4e2"><tt> a.b() </tt></span>, <span style="background-color: #e5e4e2"><tt> a.b().c </tt></span>, <span style="background-color: #e5e4e2"><tt> i </tt></span>, or <span style="background-color: #e5e4e2"><tt> a.b().c[i].d </tt></span> are <span style="background-color: #e5e4e2"><tt> Null </tt></span>. |
|||
</li><li>Syntax support: The expression <span style="background-color: #e5e4e2"><tt> x ?: y </tt></span> will use the value <span style="background-color: #e5e4e2"><tt> y </tt></span> iff <span style="background-color: #e5e4e2"><tt> x </tt></span> is <span style="background-color: #e5e4e2"><tt> Null </tt></span>, and the corresponding assignment statement <span style="background-color: #e5e4e2"><tt> x ?:= y </tt></span> will assign <span style="background-color: #e5e4e2"><tt> y </tt></span> to <span style="background-color: #e5e4e2"><tt> x </tt></span> iff <span style="background-color: #e5e4e2"><tt> x </tt></span> is <span style="background-color: #e5e4e2"><tt> Null </tt></span>. |
|||
</li><li>Syntax support: The assignment statement <span style="background-color: #e5e4e2"><tt> x ?= y </tt></span> will assign <span style="background-color: #e5e4e2"><tt> y </tt></span> to <span style="background-color: #e5e4e2"><tt> x </tt></span> iff <span style="background-color: #e5e4e2"><tt> y </tt></span> is <b>not</b> <span style="background-color: #e5e4e2"><tt> Null </tt></span>. |
|||
</li><li>The assignment operator <span style="background-color: #e5e4e2"><tt> ?= </tt></span> also yields a <span style="background-color: #e5e4e2"><tt> Boolean </tt></span> value indicating the <b>non-</b>null-ness the right hand side value, which can be used in an <span style="background-color: #e5e4e2"><tt> if </tt></span> condition, <span style="background-color: #e5e4e2"><tt> while </tt></span> condition, etc.; for example, <span style="background-color: #e5e4e2"><tt> if (x ?= y) ... </tt></span> will take the "then" branch if <span style="background-color: #e5e4e2"><tt> y </tt></span> is non-null and therefore <span style="background-color: #e5e4e2"><tt> x </tt></span> is definitely assigned, otherwise it will take the "else" branch and <span style="background-color: #e5e4e2"><tt> x </tt></span> will not be definitely assigned. |
|||
</li><li><span style="background-color: #e5e4e2"><tt> Null </tt></span> values are treated specially by equality comparisons: Normally, the compiler prevents two references of different compile-time types from being compared (such as <span style="background-color: #e5e4e2"><tt> Int </tt></span> and <span style="background-color: #e5e4e2"><tt> String </tt></span>), but an explicit exception is made that allows a nullable type to be compared with a non-nullable type (such as <span style="background-color: #e5e4e2"><tt> String? </tt></span> and <span style="background-color: #e5e4e2"><tt> String </tt></span>). |
|||
</li></ul> |
|||
Other than these specific compiler and runtime features, <span style="background-color: #e5e4e2"><tt> Null </tt></span> is treated exactly like every other object. |
|||
<syntaxhighlight lang="java"> |
|||
module NullObject { |
|||
void run() { |
|||
@Inject Console console; |
|||
console.print($"Null value={Null}, Null.toString()={Null.toString()}"); |
|||
// String s = Null; // <-- compiler error: cannot assign Null to a String type |
|||
String? s = Null; // "String?" is shorthand for the union "Nullable|String" |
|||
String s2 = "test"; |
|||
console.print($"{s=}, {s2=}, {s==s2=}"); |
|||
// Int len = s.size; // <-- compiler error: String? does not have a "size" property |
|||
Int len = s?.size : 0; |
|||
console.print($"{len=}"); |
|||
if (String test ?= s) { |
|||
// "s" is still Null in this test, we never get here |
|||
} else { |
|||
s = "a non-null value"; |
|||
} |
|||
// if (String test ?= s){} // <-- compiler error: The expression type is not nullable |
|||
s2 = s; // at this point, s is known to be a non-null String |
|||
console.print($"{s=}, {s2=}, {s==s2=}"); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Null value=Null, Null.toString()=Null |
|||
s=Null, s2=test, s==s2=False |
|||
len=0 |
|||
s=a non-null value, s2=a non-null value, s==s2=True |
|||
</pre> |
|||
=={{header|Eiffel}}== |
|||
Any reference type variable can be Void. In the following example, STRING is a reference type, while INTEGER is an expanded type. The keyword "detachable" (as opposed to "attached") is used to indicate that the variable "s" may be Void. The default interpretation when neither of these two keywords is used depends on a compiler option. The first if statement will cause a compiler warning because an expanded type variable such as i will never be Void. |
|||
<syntaxhighlight lang="eiffel"> |
|||
class |
|||
APPLICATION |
|||
inherit |
|||
ARGUMENTS |
|||
create |
|||
make |
|||
feature {NONE} -- Initialization |
|||
make |
|||
local |
|||
i: INTEGER |
|||
s: detachable STRING |
|||
do |
|||
if i = Void then |
|||
print("i = Void") |
|||
end |
|||
if s = Void then |
|||
print("s = Void") |
|||
end |
|||
end |
|||
end</syntaxhighlight> |
|||
{{out}}<pre>s = Void</pre> |
|||
=={{header|Elixir}}== |
|||
<code>nil</code> is atom in fact: |
|||
<syntaxhighlight lang="elixir">iex(1)> nil == :nil |
|||
true |
|||
iex(2)> is_nil(nil) |
|||
true</syntaxhighlight> |
|||
<code>nil</code> is thought of as being <code>false</code> in the conditional expression. |
|||
If the condition given to <code>if/2</code> returns <code>false</code> or <code>nil</code>, the body given between <code>do</code>/<code>end</code> is not executed and it simply returns <code>nil</code>. |
|||
<syntaxhighlight lang="elixir">iex(3)> if nil, do: "not execute" |
|||
nil</syntaxhighlight> |
|||
=={{header|EMal}}== |
|||
<syntaxhighlight lang="emal"> |
|||
^| |
|||
| EMal has the Variable type (and its keyword var) that is the nullable universal supertype. |
|||
| EMal has the Void type (and its keyword void) that holds only one value: null. |
|||
| EMal has not nullable types (logic, int, real, text, blob), but null equality is always allowed. |
|||
|^ |
|||
var a # defaults to null |
|||
int b # defaults to 0 |
|||
void c # only one allowed value: null |
|||
writeLine("nullable var equals to not nullable int: " + (a == b)) # allowed, false |
|||
^| if the data type of a is void we are sure that a is null |^ |
|||
writeLine("type of a equals to Void data type: " + (generic!a == void)) # true |
|||
writeLine("integer value " + b + " equals to null: " + (b == null)) # allowed, always false |
|||
writeLine("a void value equals to null: " + (c == null)) # always true</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
nullable var equals to not nullable int: ⊥ |
|||
type of a equals to Void data type: ⊤ |
|||
integer value 0 equals to null: ⊥ |
|||
a void value equals to null: ⊤ |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Line 331: | Line 848: | ||
Atoms are erlang's user-defined constants that always evaluates to is itself. It is also equal to no other value else but itself. |
Atoms are erlang's user-defined constants that always evaluates to is itself. It is also equal to no other value else but itself. |
||
=={{header|F_Sharp|F#}}== |
|||
As a .Net languages F# inherits the null as a potential value for object variables. |
|||
Other than in interfacing assemblies written in other .Net languages, null rarely serves a purpose in F# code. |
|||
Contrived code, to show using null, as per task description: |
|||
<syntaxhighlight lang="fsharp">let sl : string list = [null; "abc"] |
|||
let f s = |
|||
match s with |
|||
| null -> "It is null!" |
|||
| _ -> "It's non-null: " + s |
|||
for s in sl do printfn "%s" (f s)</syntaxhighlight> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
< |
<syntaxhighlight lang="factor">: is-f? ( obj -- ? ) f = ;</syntaxhighlight> |
||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
Line 339: | Line 869: | ||
Test for equality with 'null', which is the null value. |
Test for equality with 'null', which is the null value. |
||
< |
<syntaxhighlight lang="fantom"> |
||
fansh> x := null |
fansh> x := null |
||
fansh> x == null |
fansh> x == null |
||
Line 347: | Line 877: | ||
fansh> x == null |
fansh> x == null |
||
false |
false |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note, nullable objects have a type ending in a question mark, for example: |
Note, nullable objects have a type ending in a question mark, for example: |
||
Line 359: | Line 889: | ||
In practice, all notable hosted implementations follow the C practice of being able to treat a zero address (i.e. FALSE) as a null address for the purpose of list termination. |
In practice, all notable hosted implementations follow the C practice of being able to treat a zero address (i.e. FALSE) as a null address for the purpose of list termination. |
||
=={{header|FreeBASIC}}== |
|||
<syntaxhighlight lang="freebasic">'FB 1.05.0 Win64 |
|||
' FreeBASIC does not have a NULL keyword but it's possible to create one using a macro |
|||
#Define NULL CPtr(Any Ptr, 0) '' Any Ptr is implicitly convertible to pointers of other types |
|||
Type Dog |
|||
name As String |
|||
age As Integer |
|||
End Type |
|||
Dim d As Dog Ptr = New Dog |
|||
d->Name = "Rover" |
|||
d->Age = 5 |
|||
Print d->Name, d->Age |
|||
Delete d |
|||
d = NULL '' guard against 'd' being used accidentally in future |
|||
' in practice many FB developers would simply have written: d = 0 above |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Rover 5 |
|||
</pre> |
|||
=={{header|FutureBasic}}== |
|||
While objects such as strings can be NULL in FB, arrays, dictionaries and other collections cannot contain NULL objects. |
|||
<syntaxhighlight lang="futurebasic"> |
|||
// Object dimensioned, but not assigned |
|||
CFStringRef object |
|||
if ( object == NULL ) |
|||
print "object is NULL" |
|||
end if |
|||
HandleEvents |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
object is NULL |
|||
</pre> |
|||
=={{header|GDScript}}== |
|||
Godot has a null value. Here is an example of dealing with null. |
|||
<syntaxhighlight lang="gdscript"> |
|||
extends Node2D |
|||
func _ready() -> void: |
|||
var empty : Object |
|||
var not_empty = Object.new() |
|||
# Compare with null. |
|||
if empty == null: |
|||
print("empty is null") |
|||
else: |
|||
print("empty is not null") |
|||
# C-like comparation. |
|||
if not_empty: |
|||
print("not_empty is not null") |
|||
else: |
|||
print("not_empty is null") |
|||
return |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
empty is null |
|||
not_empty is not null |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Nil is a predefined identifier, defined for six types in Go. In each case, it represents the zero value for the type, that is, the memory representation of all zero bytes. This is the value of a newly created object. In the cases of these six types, an object must be subsequently initialized in some way before it has much use. Examples of initialization are given in the [[Undefined values#Go|Go solution]] of task [[Undefined values]]. |
Nil is a predefined identifier, defined for six types in Go. In each case, it represents the zero value for the type, that is, the memory representation of all zero bytes. This is the value of a newly created object. In the cases of these six types, an object must be subsequently initialized in some way before it has much use. Examples of initialization are given in the [[Undefined values#Go|Go solution]] of task [[Undefined values]]. |
||
<syntaxhighlight lang="go"> |
|||
<lang go> |
|||
package main |
package main |
||
Line 383: | Line 988: | ||
fmt.Println(c == nil) |
fmt.Println(c == nil) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output is "true" in each case. |
Output is "true" in each case. |
||
Line 390: | Line 995: | ||
Haskell does not have a universal null value. There is a 'value of every type', the undefined value (sometimes written ⊥, 'bottom'), but it is essentially a sort of exception — any attempt to use it is an error. |
Haskell does not have a universal null value. There is a 'value of every type', the undefined value (sometimes written ⊥, 'bottom'), but it is essentially a sort of exception — any attempt to use it is an error. |
||
< |
<syntaxhighlight lang="haskell">undefined -- undefined value provided by the standard library |
||
error "oops" -- another undefined value |
error "oops" -- another undefined value |
||
head [] -- undefined, you can't take the head of an empty list</ |
head [] -- undefined, you can't take the head of an empty list</syntaxhighlight> |
||
When one would use "null" as a marker for "there is no normal value here" (e.g. a field which is either an integer or null), one uses the Maybe type instead. The definition of Maybe is: |
When one would use "null" as a marker for "there is no normal value here" (e.g. a field which is either an integer or null), one uses the Maybe type instead. The definition of Maybe is: |
||
< |
<syntaxhighlight lang="haskell"> data Maybe a = Nothing | Just a</syntaxhighlight> |
||
That is, a <tt>Maybe Integer</tt> is either <tt>Nothing</tt> or <tt>Just </tt><some integer>. |
That is, a <tt>Maybe Integer</tt> is either <tt>Nothing</tt> or <tt>Just </tt><some integer>. |
||
Line 402: | Line 1,007: | ||
There are many ways to work with Maybe, but here's a basic case expression: |
There are many ways to work with Maybe, but here's a basic case expression: |
||
< |
<syntaxhighlight lang="haskell">case thing of |
||
Nothing -> "It's Nothing. Or null, whatever." |
Nothing -> "It's Nothing. Or null, whatever." |
||
Just v -> "It's not Nothing; it is " ++ show v ++ "."</ |
Just v -> "It's not Nothing; it is " ++ show v ++ "."</syntaxhighlight> |
||
It is easy to work with Maybe type using do-notation (since Maybe is a monad): |
|||
<syntaxhighlight lang="haskell">add_two_maybe_numbers x y do |
|||
a <- x |
|||
b <- y |
|||
return (a+b)</syntaxhighlight> |
|||
Then |
|||
<syntaxhighlight lang="haskell">*Main> add_two_maybe_numbers (Just 2) (Just 3) |
|||
Just 5 |
|||
*Main> add_two_maybe_numbers (Just 2) Nothing |
|||
Nothing</syntaxhighlight> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Icon/Unicon have a [[Icon%2BUnicon/Intro#null|null value/datatype]]. It isn't possible to undefine a variable. |
Icon/Unicon have a [[Icon%2BUnicon/Intro#null|null value/datatype]]. It isn't possible to undefine a variable. |
||
< |
<syntaxhighlight lang="icon">procedure main() |
||
nulltest("a",a) # unassigned variables are null by default |
nulltest("a",a) # unassigned variables are null by default |
||
nulltest("b",b := &null) # explicit assignment is possible |
nulltest("b",b := &null) # explicit assignment is possible |
||
Line 418: | Line 1,034: | ||
procedure nulltest(name,var) |
procedure nulltest(name,var) |
||
return write(name, if /var then " is" else " is not"," null.") |
return write(name, if /var then " is" else " is not"," null.") |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Io}}== |
=={{header|Io}}== |
||
< |
<syntaxhighlight lang="io">if(object == nil, "object is nil" println)</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
J doesn't have an untyped NULL. Instead, it has a concept of "fill". Numeric fill is 0, character fill is the space character, and boxed fill is the ace (a:) which is an empty box. Fill is what is used to pad an array structure when that is needed. (And some operations support using a user specified value in place of the default fill.) |
|||
J doesn't have NULL. To indicate "missing data", "normal" data is usually pressed into service (e.g. <tt>0</tt> or <tt>_1</tt> in a numeric context, <tt>' '</tt> in a literal context, <tt>a:</tt> in a boxed context, etc). Frequently, missing data is represented by the empty vector <tt><nowiki>''</nowiki></tt>, or other arrays without any elements. |
|||
To indicate "missing data", "normal" data is usually pressed into service (e.g. <tt>0</tt> or <tt>_1</tt> in a numeric context, <tt>' '</tt> in a literal context, <tt>a:</tt> in a boxed context, etc). Frequently, missing data is represented by the empty vector <tt><nowiki>''</nowiki></tt>, or other arrays without any elements. |
|||
However, undefined names in J can be identified: |
|||
That said, undefined names in J are not associated with any data of any type. Furthermore, any attempt to use the value of an undefined is treated as an error (this is distinct from the concept of an empty array, which contains no data but which is not an error to use). However, it is possible to check if a name is defined before attempting to use it: |
|||
<lang J>isUndefined=: _1 = nc@boxxopen</lang> |
|||
<syntaxhighlight lang="j">isUndefined=: _1 = nc@boxxopen</syntaxhighlight> |
|||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> isUndefined 'foo' |
||
1 |
1 |
||
foo=:9 |
foo=:9 |
||
isUndefined 'foo' |
isUndefined 'foo' |
||
0</ |
0</syntaxhighlight> |
||
Note, |
Note, of course, that this "name is not defined" state is not a first class value in J -- you can not create a list of "undefineds". |
||
Finally, note: the concept of an empty array can be natural in J (and APL) for representing data which is not there -- it is the structural equivalent of the number zero. That said, its implications can sometimes be non-obvious for people coming from a languages which requires that arrays have content. As a result, you will sometimes encounter empty array jokes... |
|||
:Marie Pennysworth, having spent a productive day shopping, stopped by Robert Cuttingham's butcher shop. |
:Marie Pennysworth, having spent a productive day shopping, stopped by Robert Cuttingham's butcher shop. |
||
:"How much for your t-bones |
:"How much for your t-bones?" she asked. |
||
:"Eleven dollars per pound," he responded. |
:"Eleven dollars per pound," he responded. |
||
:"How about for your sirloin?" she continued. |
:"How about for your sirloin?" she continued. |
||
Line 452: | Line 1,070: | ||
:He smiled, "When I am out, I only charge seven dollars a pound." |
:He smiled, "When I am out, I only charge seven dollars a pound." |
||
That said, note that |
That said, note that a typical way to indicate missing or invalid data, in J, is to have a parallel array which is a bit mask (which selects the desired or valid values and, by implication, does not select the invalid values). Or, as a logical equivalent: a list of indices which select the desired and/or valid values. Alternatively, you can have an array without the invalid values and a bit mask which demonstrates how the data would be populated on a larger array -- in other words instead of 3,4,null,5 you could have (3 4 5) and (1 1 0 1). And you can transform between some of these representations: |
||
< |
<syntaxhighlight lang="j"> 1 1 0 1#3 4 _ 5 NB. use bitmask to select numbers |
||
3 4 5 |
3 4 5 |
||
I.1 1 0 1 |
I.1 1 0 1 NB. get indices for bitmask |
||
0 1 3 |
0 1 3 |
||
0 1 3 { 3 4 _ 5 |
0 1 3 { 3 4 _ 5 NB. use indices to select numbers |
||
3 4 5 |
3 4 5 |
||
1 1 0 1 #inv 3 4 5 |
1 1 0 1 #inv 3 4 5 NB. use bitmask to restore original positions |
||
3 4 0 5 |
3 4 0 5 |
||
1 1 0 1 #!._ inv 3 4 5 |
1 1 0 1 #!._ inv 3 4 5 NB. specify different fill element |
||
3 4 _ 5 |
3 4 _ 5 |
||
3 4 5 (0 1 3}) _ _ _ _ NB. use indices to restore original positions |
|||
3 4 _ 5</syntaxhighlight> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
In Java, "null" is a value of every reference type. |
In Java, "null" is a value of every reference type. |
||
< |
<syntaxhighlight lang="java">// here "object" is a reference |
||
if (object == null) { |
if (object == null) { |
||
System.out.println("object is null"); |
System.out.println("object is null"); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
In Javascript <tt>null</tt> is the value that isn't anything. <tt>null</tt> is not an object, but because of a bug <tt>typeof null</tt> will return "object". |
In Javascript <tt>null</tt> is the value that isn't anything. <tt>null</tt> is not an object, but because of a bug <tt>typeof null</tt> will return "object". |
||
< |
<syntaxhighlight lang="javascript">if (object === null) { |
||
alert("object is null"); |
alert("object is null"); |
||
// The object is nothing |
// The object is nothing |
||
} |
} |
||
typeof null === "object"; // This stands since the beginning of JavaScript</ |
typeof null === "object"; // This stands since the beginning of JavaScript</syntaxhighlight> |
||
=={{header|jq}}== |
|||
jq has <tt>null</tt> as a value, but while on the subject of nothing, it may be worth mentioning that jq also has a filter, <tt>empty</tt>, for producing an empty sequence, a.k.a. nothing. |
|||
<tt>null</tt> is distinct from <tt>false</tt>. |
|||
Here are some examples: |
|||
<syntaxhighlight lang="jq">null|type # => "null" |
|||
null == false # => false |
|||
null == null # => true |
|||
empty|type # => # i.e. nothing (as in, nada) |
|||
empty == empty # => # niente |
|||
empty == "black hole" # => # Ничего</syntaxhighlight> |
|||
=={{header|Jsish}}== |
|||
Like Javascript, Jsish has '''undefined''' and '''null'''. Unlike Javascript, null is not typed as '''object''', but '''null'''. |
|||
Jsish, with parameter typed functions, also allows '''void''' as a type spec, to indicate the parameter (of whatever type) may be omitted by a caller. |
|||
<syntaxhighlight lang="javascript">/* null non value */ |
|||
if (thing == null) { puts("thing tests as null"); } |
|||
if (thing === undefined) { puts("thing strictly tests as undefined"); } |
|||
puts(typeof thing); |
|||
puts(typeof null); |
|||
puts(typeof undefined);</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ jsish nulling.jsi |
|||
thing tests as null |
|||
thing strictly tests as undefined |
|||
undefined |
|||
null |
|||
undefined |
|||
</pre> |
|||
=={{header|Julia}}== |
|||
See language reference: https://docs.julialang.org/en/v1/manual/faq/#Nothingness-and-missing-values |
|||
=={{header|K}}== |
=={{header|K}}== |
||
Line 488: | Line 1,150: | ||
and and missing value ''nil'' : |
and and missing value ''nil'' : |
||
: Empty expressions in both list expressions and function expressions actually represent a special atomic value called ''nil''. ... A list may contain one or more empty items (i.e. the nil value _n), which are typically indicated by omission: |
: Empty expressions in both list expressions and function expressions actually represent a special atomic value called ''nil''. ... A list may contain one or more empty items (i.e. the nil value _n), which are typically indicated by omission: |
||
<syntaxhighlight lang="k"> |
|||
<lang k> |
|||
(1;;2) ~ (1 ; _n ; 2) / ~ is ''identical to'' or ''match'' . |
(1;;2) ~ (1 ; _n ; 2) / ~ is ''identical to'' or ''match'' . |
||
1 |
1 |
||
Line 495: | Line 1,157: | ||
additional properties : _n@i and _n?i are i; _n`v is _n |
additional properties : _n@i and _n?i are i; _n`v is _n |
||
</syntaxhighlight> |
|||
</lang> |
|||
For more detail on K's concept of typed nulls, see http://code.kx.com/wiki/Reference/Datatypes#Primitive_Types |
|||
=={{header|Klingphix}}== |
|||
<syntaxhighlight lang="klingphix">%t nan !t |
|||
$t nan == ?</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1</pre> |
|||
=={{header|Kotlin}}== |
|||
Kotlin distinguishes between non-nullable types and nullable types. The latter are distinguished from the former by a '?' suffix. Only nullable types have a 'null' value indicating that they don't currently refer to an object of their non-nullable equivalent. |
|||
In addition, Kotlin has a Nothing type which has no instances and is a sub-type of every other type. There is also a nullable Nothing? type whose only value is 'null' and so, technically, this is the type of 'null' itself. |
|||
Here are some examples: |
|||
<syntaxhighlight lang="scala">// version 1.1.0 |
|||
fun main(args: Array<String>) { |
|||
val i: Int = 3 // non-nullable Int type - can't be assigned null |
|||
println(i) |
|||
val j: Int? = null // nullable Int type - can be assigned null |
|||
println(j) |
|||
println(null is Nothing?) // test that null is indeed of type Nothing? |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
3 |
|||
null |
|||
true |
|||
</pre> |
|||
=={{header|langur}}== |
|||
Null can be compared for directly, using equality operators. Operators ending with a ? mark propagate null. A null in an expression test is a non-truthy result. |
|||
<syntaxhighlight lang="langur">val .x, .y = true, null |
|||
writeln .x == null |
|||
writeln .y == null |
|||
writeln .x ==? null |
|||
writeln .y ==? null |
|||
# null not a "truthy" result |
|||
writeln if(null: 0; 1)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>false |
|||
true |
|||
null |
|||
null |
|||
1</pre> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso">local(x = string, y = null) |
|||
#x->isA(::null) |
|||
// 0 (false) |
|||
#y->isA(::null) |
|||
// 1 (true) |
|||
#x == null |
|||
// false |
|||
#y == null |
|||
//true |
|||
#x->type == 'null' |
|||
// false |
|||
#y->type == 'null' |
|||
//true</syntaxhighlight> |
|||
=={{header|Latitude}}== |
|||
Nil is an object in Latitude, like any other. |
|||
<syntaxhighlight lang="latitude">foo := Nil. |
|||
if { foo nil?. } then { |
|||
putln: "Foo is nil". |
|||
} else { |
|||
putln: "Foo is not nil". |
|||
}.</syntaxhighlight> |
|||
In particular, Nil satisfies the Collection mixin, so it can be treated as an (immutable) collection. |
|||
<syntaxhighlight lang="latitude">Nil to (Array). ;; []</syntaxhighlight> |
|||
Nil is the default value returned if a method body is empty. |
|||
<syntaxhighlight lang="latitude">func := {}. |
|||
func. ;; Nil</syntaxhighlight> |
|||
=={{header|Lily}}== |
|||
Lily doesn't provide a built-in nothing type, but allows one to be created using enum class: |
|||
<syntaxhighlight lang="lily">enum class Option[A] { |
|||
Some(A) |
|||
None |
|||
} |
|||
# Only variables of class Option can be assigned to None. |
|||
# Type: Option[integer] |
|||
var v = Some(10) |
|||
# Valid: v is an Option, and any Option can be assigned to None |
|||
v = None |
|||
# Invalid! v is an Option[integer], not just a plain integer. |
|||
v = 10 |
|||
# Type: integer |
|||
var w = 10 |
|||
# Invalid! Likewise, w is an integer, not an Option. |
|||
w = None</syntaxhighlight> |
|||
=={{header|Lingo}}== |
|||
Null/nil is called "<Void>" in Lingo. Lingo doesn't distinguish undefined variables from <Void> objects, and by using the constant VOID you can even assign <Void> to variables. Functions that don't return anything, return <Void>. Checking for <Void> (e.g. by using built-in function voidP) can be used to implement optional function arguments: if voidP() returns TRUE (1) for some argument, a default value can be assigned in the function body. |
|||
<syntaxhighlight lang="lingo">put _global.doesNotExist |
|||
-- <Void> |
|||
put voidP(_global.doesNotExist) |
|||
-- 1 |
|||
x = VOID |
|||
put x |
|||
-- <Void> |
|||
put voidP(x) |
|||
-- 1</syntaxhighlight> |
|||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
< |
<syntaxhighlight lang="logo">to test :thing |
||
if empty? :thing [print [list or word is empty]] |
if empty? :thing [print [list or word is empty]] |
||
end |
end |
||
print empty? [] ; true |
print empty? [] ; true |
||
print empty? "|| ; true</ |
print empty? "|| ; true</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua"> |
||
isnil = (object == nil) |
isnil = (object == nil) |
||
print(isnil) |
print(isnil) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
=={{header|M2000 Interpreter}}== |
||
===For Com Objects=== |
|||
There is a Nothing to assign to a COM object to released (but time to actually released depends from system). A com pointer can't get another value (only the first value, and the Nothing at the end). |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module CheckWord { |
|||
Declare Alfa "WORD.APPLICATION" |
|||
Declare Alfa Nothing |
|||
Print Type$(Alfa)="Nothing" |
|||
Try ok { |
|||
Declare Alfa "WORD.APPLICATION" |
|||
\\ we can't declare again Alfa |
|||
} |
|||
If Not Ok Then Print Error$ ' return Bad Object declaration |
|||
} |
|||
CheckWord |
|||
</syntaxhighlight> |
|||
===For Containers=== |
|||
Container's pointers (for arrays, inventories, stack) we have to assign an empty container, there is not a null one. |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module CheckContainers { |
|||
\\ Arrays (A() and B() are value types) |
|||
Dim A(10)=1, B() |
|||
\\ B() get a copy of A(), is not a reference type |
|||
B()=A() |
|||
\\ we make a pointer to Array |
|||
B=A() |
|||
\\ now B is a reference type object |
|||
Print Len(B)=10 ' ten items |
|||
B+=10 |
|||
Print A(3)=11, A(7)=11 |
|||
\\ we can change pointer using a pointer to an empty array |
|||
B=(,) |
|||
\\ we can erase A() and B() |
|||
Dim A(0), B(0) |
|||
Print Len(A())=0, Len(B())=0 |
|||
Print Len(B)=0 |
|||
B=(123,) |
|||
\\ B() is a value type so get a copy |
|||
B()=B |
|||
Print Len(B)=1, B(0)=123 |
|||
\\ Using Clear we pass a new empty array |
|||
Clear B |
|||
Print Type$(B)="mArray" |
|||
Print Len(B)=1, B(0)=123 |
|||
\\ Inventrories. Keys must be unique (for normal inventories) |
|||
Inventory M=1,2,3,4:=400,5 |
|||
Print M |
|||
Clear M |
|||
Inventory M=1,2,3,4,5 |
|||
Print M |
|||
\\ Inventory Queue can have same keys. |
|||
Inventory Queue N=1,1,2:="old",2:="ok",3 |
|||
If Exist(N,2) Then Print Eval$(N)="ok", Eval(N!)=3 ' 4th item |
|||
Clear N |
|||
Print Len(N)=0, Type$(N)="Inventory" |
|||
\\ Stack Object |
|||
Z=Stack:=1,2,3 |
|||
Stack Z { |
|||
While not empty {Print Number} |
|||
} |
|||
Print Len(Z)=0 |
|||
Z=Stack((Stack:=1,2,3,4),Stack:=20,30,40 ) |
|||
Print Len(Z)=7 |
|||
Print Z ' 1 2 3 4 20 30 49 |
|||
Z=Stack ' This is an empty stacl |
|||
Print Len(Z)=0 |
|||
Print Type$(Z)="mStiva" |
|||
} |
|||
CheckContainers |
|||
</syntaxhighlight> |
|||
===For Groups=== |
|||
Groups are value types, but we can make reference to them,or pointer to them |
|||
A Named referenced can't get a new reference |
|||
A pointer to a named group is actual a reference, and can change type and reference |
|||
A pointer to a copy of group (as float group) is actually a pointer to group. |
|||
Pointers to groups can be point to an Null Group, assigning a 0& value (a long type) |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
class something { |
|||
} |
|||
class alfa as something { |
|||
x=10, y=20 |
|||
} |
|||
a->alfa() |
|||
Print a is type alfa = true |
|||
Print a is type something = true |
|||
a->0& |
|||
Print a is type null = true |
|||
\\ beta is a named object, is static |
|||
group beta { |
|||
type: something, alfa |
|||
x=10, y=20 |
|||
} |
|||
Print beta is type alfa = true |
|||
Print beta is type something = true |
|||
\\ now a is a pointer as a weak reference to beta |
|||
a->beta |
|||
print a is type alfa = true |
|||
print a is type something = true |
|||
a=pointer() ' same as a->0& |
|||
Print a is type null = true |
|||
\\ now a is a pointer of a copy of beta |
|||
a->(beta) |
|||
print a is type alfa = true |
|||
print a is type something = true |
|||
a=pointer() ' same as a->0& |
|||
Print a is type null = true |
|||
</syntaxhighlight> |
|||
=={{header|Maple}}== |
|||
In Maple, NULL and () represent the null object. |
|||
<syntaxhighlight lang="maple">a := NULL; |
|||
a := |
|||
is (NULL = ()); |
|||
true |
|||
if a = NULL then |
|||
print (NULL); |
|||
end if; |
|||
</syntaxhighlight> |
|||
A null object is different from an undefined value. |
|||
<syntaxhighlight lang="maple">b := Array([1, 2, 3, Integer(undefined), 5]); |
|||
b := [ 1 2 3 undefined 5 ] |
|||
numelems(b); |
|||
5 |
|||
b := Array([1, 2, 3, Float(undefined), 5]); |
|||
b := [ 1 2 3 Float(undefined) 5 ] |
|||
numelems(b); |
|||
5 |
|||
b := Array([1, 2, 3, NULL, 5]); |
|||
b := [ 1 2 3 5 ] |
|||
numelems(b); |
|||
4 |
|||
</syntaxhighlight> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
Mathematica can assign a Null value to a symbol, two examples: |
Mathematica can assign a Null value to a symbol, two examples: |
||
< |
<syntaxhighlight lang="mathematica">x=Null;</syntaxhighlight> |
||
<syntaxhighlight lang="mathematica">x =. |
|||
<lang Mathematica>x =. |
|||
x = (1 + 2;) |
x = (1 + 2;) |
||
FullForm[x]</ |
FullForm[x]</syntaxhighlight> |
||
Both set x to be Null. To specifically test is something is Null one can use the SameQ function (with infix operator: ===): |
Both set x to be Null. To specifically test is something is Null one can use the SameQ function (with infix operator: ===): |
||
<lang |
<syntaxhighlight lang="mathematica">SameQ[x,Null]</syntaxhighlight> |
||
Or equivalent: |
Or equivalent: |
||
< |
<syntaxhighlight lang="mathematica">x===Null</syntaxhighlight> |
||
will give back True if and only if x is assigned to be Null. If x is empty (nothing assigned) this will return False. |
will give back True if and only if x is assigned to be Null. If x is empty (nothing assigned) this will return False. |
||
To test if an object has something assigned (number, list, graphics, null, infinity, symbol, equation, pattern, whatever) one uses ValueQ: |
To test if an object has something assigned (number, list, graphics, null, infinity, symbol, equation, pattern, whatever) one uses ValueQ: |
||
<syntaxhighlight lang="mathematica">x =.; |
|||
<lang Mathematica>x =.; |
|||
ValueQ[x] |
ValueQ[x] |
||
x = 3; |
x = 3; |
||
ValueQ[x]</ |
ValueQ[x]</syntaxhighlight> |
||
gives: |
gives: |
||
<syntaxhighlight lang="mathematica">False |
|||
<lang Mathematica>False |
|||
True</ |
True</syntaxhighlight> |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
The closest think to a NULL element in Matlab/Octave is an empty field or empty string; empty fields in a conditional expression evaluate to false. |
The closest think to a NULL element in Matlab/Octave is an empty field or empty string; empty fields in a conditional expression evaluate to false. |
||
< |
<syntaxhighlight lang="matlab">a = []; b=''; |
||
isempty(a) |
isempty(a) |
||
isempty(b) |
isempty(b) |
||
Line 540: | Line 1,475: | ||
else, |
else, |
||
0 |
0 |
||
end;</ |
end;</syntaxhighlight> |
||
<pre>octave:4> a = []; b=''; |
<pre>octave:4> a = []; b=''; |
||
Line 549: | Line 1,484: | ||
octave:7> if (a) 1, else, 0, end; |
octave:7> if (a) 1, else, 0, end; |
||
ans = 0</pre> |
ans = 0</pre> |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
Line 555: | Line 1,489: | ||
=={{header|MAXScript}}== |
=={{header|MAXScript}}== |
||
< |
<syntaxhighlight lang="maxscript">if obj == undefined then print "Obj is undefined"</syntaxhighlight> |
||
=={{header|min}}== |
|||
<syntaxhighlight lang="min">null null? puts!</syntaxhighlight> |
|||
{{out}} |
|||
<pre>true</pre> |
|||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
Line 561: | Line 1,500: | ||
This can lead to errors, if for example you write: |
This can lead to errors, if for example you write: |
||
< |
<syntaxhighlight lang="modula3">VAR foo := NIL</syntaxhighlight> |
||
This (most likely incorrectly) gives foo the type <code>NULL</code>, which can only have the value <code>NIL</code>, so trying to assign it anything else will not work. To overcome this problem, you must specify the reference type when declaring foo: |
This (most likely incorrectly) gives foo the type <code>NULL</code>, which can only have the value <code>NIL</code>, so trying to assign it anything else will not work. To overcome this problem, you must specify the reference type when declaring foo: |
||
< |
<syntaxhighlight lang="modula3">VAR foo: REF INTEGER := NIL;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="modula3">IF foo = NIL THEN |
||
IO.Put("Object is nil.\n"); |
IO.Put("Object is nil.\n"); |
||
END;</ |
END;</syntaxhighlight> |
||
=={{header|MUMPS}}== |
=={{header|MUMPS}}== |
||
Line 594: | Line 1,533: | ||
</table> |
</table> |
||
<p>Or, by examples (in immediate mode):</p> |
<p>Or, by examples (in immediate mode):</p> |
||
<syntaxhighlight lang="mumps"> |
|||
<lang MUMPS> |
|||
CACHE>WRITE $DATA(VARI) |
CACHE>WRITE $DATA(VARI) |
||
0 |
0 |
||
Line 613: | Line 1,552: | ||
<CACHE>W $DATA(VARI)," ",VARI |
<CACHE>W $DATA(VARI)," ",VARI |
||
1 HELLO |
1 HELLO |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Nanoquery}}== |
|||
{{trans|Ursa}} |
|||
<syntaxhighlight lang="nanoquery">$x = $null |
|||
if ($x = $null) |
|||
println "x is null" |
|||
else |
|||
println "x is not null" |
|||
end if</syntaxhighlight> |
|||
=={{header|Neko}}== |
|||
<syntaxhighlight lang="actionscript">/** |
|||
<doc> |
|||
<p>Neko uses <i>null</i> for undefined variables, |
|||
and also as a programmer accessible value.</p> |
|||
<p>The <i>null</i> value can be treated as a boolean value with the |
|||
builtin $istrue, and tests as false.</p> |
|||
</doc> |
|||
*/ |
|||
var n = null |
|||
if n == null $print("n is null\n") |
|||
if $not($istrue(n)) $print("and tests as boolean false\n")</syntaxhighlight> |
|||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
In NetRexx as in Java, "null" is a value of every reference type. |
In NetRexx as in Java, "null" is a value of every reference type. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols binary |
options replace format comments java crossref symbols binary |
||
Line 624: | Line 1,587: | ||
say String.valueOf(robject) -- will report the text "null" |
say String.valueOf(robject) -- will report the text "null" |
||
if robject = null then say 'Really, it''s "null"!' |
if robject = null then say 'Really, it''s "null"!' |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 630: | Line 1,593: | ||
Really, it's "null"! |
Really, it's "null"! |
||
</pre> |
</pre> |
||
=={{header|NewLISP}}== |
|||
<syntaxhighlight lang="newlisp"> |
|||
#! /usr/local/bin/newlisp |
|||
(setq myobject nil) |
|||
(println (nil? myobject)) |
|||
(exit) |
|||
</syntaxhighlight> |
|||
<pre> |
|||
true |
|||
</pre> |
|||
=={{header|Nim}}== |
|||
There is a <code>nil</code> value in Nim, which is the same as a 0. It can be explicitly forbidden as a value: |
|||
<syntaxhighlight lang="nim">let s: pointer = nil |
|||
{.experimental: "notnil".} |
|||
let ns: pointer not nil = nil # Compile time error</syntaxhighlight> |
|||
The value "nil" can be used for pointers, references (i.e. pointers managed by the garbage collector) and procedures. It was also used for strings and sequences, but this is no longer the case (option <code>--nilseqs:on</code> allows to retrieve the old behavior). |
|||
Testing if a pointer “p” is <code>nil</code> can be done either by using <code>==</code> or using the procedure <code>isNil</code>. |
|||
<syntaxhighlight lang="nim">var p: ptr int |
|||
if p == nil: echo "it is nil" |
|||
if p != nil: echo "it is not nil" |
|||
if p.isNil: echo "it is nil"</syntaxhighlight> |
|||
=={{header|Oberon-2}}== |
|||
{{works with|oo2c}} |
|||
<syntaxhighlight lang="oberon2"> |
|||
MODULE Null; |
|||
IMPORT |
|||
Out; |
|||
TYPE |
|||
Object = POINTER TO ObjectDesc; |
|||
ObjectDesc = RECORD |
|||
END; |
|||
VAR |
|||
o: Object; (* default initialization to NIL *) |
|||
BEGIN |
|||
IF o = NIL THEN Out.String("o is NIL"); Out.Ln END |
|||
END Null. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
o is NIL |
|||
</pre> |
|||
=={{header|Objeck}}== |
|||
In Objeck, "Nil" is a value of every reference type. |
|||
<syntaxhighlight lang="objeck"> |
|||
# here "object" is a reference |
|||
if(object = Nil) { |
|||
"object is null"->PrintLine(); |
|||
}; |
|||
</syntaxhighlight> |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
The value <code>nil</code> is used to indicate that an object pointer (variable of type <code>id</code>) doesn't point to a valid object. |
The value <code>nil</code> is used to indicate that an object pointer (variable of type <code>id</code>) doesn't point to a valid object. |
||
< |
<syntaxhighlight lang="objc">// here "object" is an object pointer |
||
if (object == nil) { |
if (object == nil) { |
||
NSLog("object is nil"); |
NSLog("object is nil"); |
||
}</ |
}</syntaxhighlight> |
||
An interesting thing is that in Objective-C, it is possible to send a message to <code>nil</code>, and the program will not crash or raise an exception (nothing will be executed and <code>nil</code> will be returned in place of the usual return value). |
An interesting thing is that in Objective-C, it is possible to send a message to <code>nil</code>, and the program will not crash or raise an exception (nothing will be executed and <code>nil</code> will be returned in place of the usual return value). |
||
<lang |
<syntaxhighlight lang="objc">[nil fooBar];</syntaxhighlight> |
||
Note that <code>nil</code> is distinct from <code>NULL</code>, which is only used for regular C pointers. |
Note that <code>nil</code> is distinct from <code>NULL</code>, which is only used for regular C pointers. |
||
Line 645: | Line 1,667: | ||
Confusingly, there is also <code>NSNull</code>, a singleton class with one value, <code>[NSNull null]</code>, used as a dummy object to represent the lack of a useful object. This is needed in collections like arrays and dictionaries, etc., because they do not allow <code>nil</code> elements, so if you want to represent some "empty" slots in the array you would use this. |
Confusingly, there is also <code>NSNull</code>, a singleton class with one value, <code>[NSNull null]</code>, used as a dummy object to represent the lack of a useful object. This is needed in collections like arrays and dictionaries, etc., because they do not allow <code>nil</code> elements, so if you want to represent some "empty" slots in the array you would use this. |
||
=={{header|Objeck}}== |
|||
In Objeck, "Nil" is a value of every reference type. |
|||
<lang Objeck> |
|||
# here "object" is a reference |
|||
if(object = Nil) { |
|||
"object is null"->PrintLine(); |
|||
}; |
|||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Maybe the closest type of OCaml would be the type option, which is defined like this in the standard library: |
Maybe the closest type of OCaml would be the type option, which is defined like this in the standard library: |
||
< |
<syntaxhighlight lang="ocaml">type 'a option = None | Some of 'a</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ocaml">match v with |
||
| None -> "unbound value" |
| None -> "unbound value" |
||
| Some _ -> "bounded value"</ |
| Some _ -> "bounded value"</syntaxhighlight> |
||
=={{header|Oforth}}== |
|||
null is an object, the only instance of Null class. |
|||
When an object is created, all attributes are initiallized to null value. |
|||
When a method or function is called, all local variables begin with null value. |
|||
<syntaxhighlight lang="oforth">null isNull |
|||
"abcd" isNull |
|||
: testNull { | a | a ifNull: [ "Variable value is null" println ] ;</syntaxhighlight> |
|||
=={{header|Ol}}== |
|||
Ol has no null object in task meaning sense. To indicate the "unassigned" variable state typically used #false because this is only value that triggers the 'unless' and 'if not'. |
|||
The builtin null and #null (that a same) means "an empty list". Important note: in contrast with CL the null means #true in 'if' statement! |
|||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
ooRexx has a special singleton object |
ooRexx has a special singleton object called .nil that is used to indicate the absence of values in some situations (such as the default values returned from collection objects). |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
if a[i] == .nil then say "Item" i "is missing" |
if a[i] == .nil then say "Item" i "is missing" |
||
</syntaxhighlight> |
|||
</lang> |
|||
Uninitialized ooRexx variables do not evaluate to .nil, but rather the character string name of the variable (all uppercase). The var() built-in function allows variable validity to be tested: |
Uninitialized ooRexx variables do not evaluate to .nil, but rather the character string name of the variable (all uppercase). The var() built-in function allows variable validity to be tested: |
||
<syntaxhighlight lang="oorexx">a=.array~of('A','B') |
|||
<lang ooRexx> |
|||
i=3 |
|||
if \var("INPUT") then say "Variable INPUT is not assigned". |
|||
if a[i] == .nil then say "Item" i "of array A is missing" |
|||
</lang> |
|||
if \var("INPUT") then say "Variable INPUT is not assigned" |
|||
if \var("var") then say "Variable" var "is not assigned"</syntaxhighlight> |
|||
Output: |
|||
<pre>Item 3 of array A is missing |
|||
Variable INPUT is not assigned |
|||
Variable VAR is not assigned</pre> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Line 676: | Line 1,710: | ||
===Unbound variables=== |
===Unbound variables=== |
||
If an unbound variable is accessed, the current thread will be suspended: |
If an unbound variable is accessed, the current thread will be suspended: |
||
< |
<syntaxhighlight lang="oz">declare |
||
X |
X |
||
in |
in |
||
{Show X+2} %% blocks</ |
{Show X+2} %% blocks</syntaxhighlight> |
||
If you later assign a value to X in another thread, the original thread will resume and print the result of the addition. This is the basic building block of Oz' [http://c2.com/cgi/wiki?DeclarativeConcurrency declarative concurrency]. |
If you later assign a value to X in another thread, the original thread will resume and print the result of the addition. This is the basic building block of Oz' [http://c2.com/cgi/wiki?DeclarativeConcurrency declarative concurrency]. |
||
===Undefined values=== |
===Undefined values=== |
||
Line 685: | Line 1,719: | ||
It is also possible to assign a unique "failed" value to a variable. Such a failed value encapsulates an exception. This can be useful in concurrent programming to propagate exceptions across thread boundaries. |
It is also possible to assign a unique "failed" value to a variable. Such a failed value encapsulates an exception. This can be useful in concurrent programming to propagate exceptions across thread boundaries. |
||
< |
<syntaxhighlight lang="oz">declare |
||
X = {Value.failed dontTouchMe} |
X = {Value.failed dontTouchMe} |
||
in |
in |
||
{Wait X} %% throws dontTouchMe</ |
{Wait X} %% throws dontTouchMe</syntaxhighlight> |
||
Sometimes algebraic data types like Haskell's Maybe are simulated using records. |
Sometimes algebraic data types like Haskell's Maybe are simulated using records. |
||
< |
<syntaxhighlight lang="oz">declare |
||
X = just("Data") |
X = just("Data") |
||
in |
in |
||
case X of nothing then skip |
case X of nothing then skip |
||
[] just(Result) then {Show Result} |
[] just(Result) then {Show Result} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
GP does not have good facilities for this, but this test suffices for most purposes: |
GP does not have good facilities for this, but this test suffices for most purposes: |
||
< |
<syntaxhighlight lang="parigp">foo!='foo</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 713: | Line 1,747: | ||
You can check to see if a value is <code>undef</code> by using the <code>defined</code> operator: |
You can check to see if a value is <code>undef</code> by using the <code>defined</code> operator: |
||
< |
<syntaxhighlight lang="perl">print defined($x) ? 'Defined' : 'Undefined', ".\n";</syntaxhighlight> |
||
From the above discussion, it should be clear that if <code>defined</code> returns false, it does not mean that the variable has not been set; rather, it could be that it was explicitly set to <code>undef</code>. |
From the above discussion, it should be clear that if <code>defined</code> returns false, it does not mean that the variable has not been set; rather, it could be that it was explicitly set to <code>undef</code>. |
||
Starting in Perl 5.10, there is also a [http://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or defined-or] operator in Perl. For example: |
Starting in Perl 5.10, there is also a [http://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or defined-or] operator in Perl. For example: |
||
< |
<syntaxhighlight lang="perl">say $number // "unknown";</syntaxhighlight> |
||
prints $number if it is defined (even if it is false) or the string "unknown" otherwise. |
prints $number if it is defined (even if it is false) or the string "unknown" otherwise. |
||
=={{header| |
=={{header|Phix}}== |
||
There is a builtin NULL, however it is equivalent to the integer 0 and will trigger a type check if assigned to a variable declared as string or sequence. In most programs the zero-length string/sequence (""/{}) suffices, |
|||
{{trans|Haskell}} (as it were...) |
|||
but if you want a variable that can be a string/sequence or NULL, but not other arbitrary integer/float values, use something like the following user-defined types: |
|||
<!--<syntaxhighlight lang="phix">--> |
|||
In Perl 6 you can name the concept of <tt>Nil</tt>, but it not considered an object, but rather the <i>absence</i> of an object, more of a "bottom" type. The closest analog in real objects is an empty list, but an empty list is considered defined, while <tt>Nil.defined</tt> always returns false. <tt>Nil</tt> is what you get if you try to read off the end of a list, and <tt>()</tt> is just very easy to read off the end of... <tt>:-)</tt> |
|||
<span style="color: #008080;">type</span> <span style="color: #000000;">nullableString</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span> |
|||
<span style="color: #000000;">nullableString</span> <span style="color: #000000;">s</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"hello"</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span> |
|||
<span style="color: #000080;font-style:italic;">--s = 1 -- error |
|||
--s = {1,2,3} -- error</span> |
|||
<span style="color: #008080;">type</span> <span style="color: #000000;">nullableSequence</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span> |
|||
<span style="color: #000000;">nullableSequence</span> <span style="color: #000000;">q</span> |
|||
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">}</span> |
|||
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"string"</span> <span style="color: #000080;font-style:italic;">-- fine (strings are a subset of sequences)</span> |
|||
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span> |
|||
<span style="color: #000080;font-style:italic;">--q = 1 -- error</span> |
|||
<!--</syntaxhighlight>--> |
|||
See also [[Undefined_values#Phix|Undefined_values]] |
|||
If you try to put <tt>Nil</tt> into a container, you don't end up with a container that has <tt>Nil</tt> in it. Instead the container reverts to an uninitialized state that is consistent with the declared type. Hence, Perl 6 has the notion of typed undefined values, that are real objects in the sense of "being there", but are generic in the sense of representing type information without being instantiated as a real object. We call these <i>type objects</i> since they can stand in for real objects when one reasons about the types of objects. So type objects fit into the type hierarchy just as normal objects do. In physics terms, think of them as "type charge carriers" that are there for bookkeeping between the "real" particles. |
|||
All type objects derive from <tt>Mu</tt>, the most-undefined type |
|||
object, and the object most like "null" in many languages. All other object types derive from <tt>Mu</tt>, |
|||
so it is like <tt>Object</tt> in other languages as well, except <tt>Mu</tt> also encompasses various objects that are not discrete, such as junctions. So Perl 6 distinguishes <tt>Mu</tt> from <tt>Any</tt>, which is the type that functions the most like a discrete, mundane object. |
|||
Mostly the user doesn't have to think about it. All object containers behave like "Maybe" types in Haskell terms; they may either hold a valid value or a "nothing" of an appropriate type. |
|||
Most containers default to an object of type <tt>Any</tt> so you don't accidentally send quantum superpositions (junctions) around in your program. |
|||
<lang perl6>my $var; |
|||
say $var.WHAT; # Any() |
|||
$var = 42; |
|||
say $var.WHAT; # Int() |
|||
say $var.defined; # True |
|||
$var = Nil; |
|||
say $var.WHAT; # Any() |
|||
say $var.defined # False</lang> |
|||
You can declare a variable of type <tt>Mu</tt> if you wish to propagate superpositional types: |
|||
<lang perl6>my Mu $junction; |
|||
say $junction.WHAT; # Mu() |
|||
$junction = 1 | 2 | 3; |
|||
say $junction.WHAT; # Junction()</lang> |
|||
Or you can declare a more restricted type than <tt>Any</tt> |
|||
<lang perl6>my Str $str; |
|||
say $str.WHAT; # Str() |
|||
$str = "I am a string."; |
|||
say $str.WHAT; # Str() |
|||
$str = 42; # (fails)</lang> |
|||
But in the Perl 6 view of reality, it's completely bogus to ask |
|||
for a way "to see if an object is equivalent to the null object." |
|||
The whole point of such a non-object object is that it doesn't exist, |
|||
and can't participate in computations. If you think you mean the |
|||
null object in Perl 6, you really mean some kind of generic object |
|||
that is uninstantiated, and hence undefined. One of those is your "null object", |
|||
except there are many of them, so you can't just check for equivalence. Use the <tt>defined</tt> predicate (or match on a subclass of your type that forces recognition of abstraction or definedness). |
|||
Perl 6 also has <tt>Failure</tt> objects that, in addition to being |
|||
undefined carriers of type, are also carriers of the <i>reason</i> |
|||
for the value's undefinedness. We tend view them as lazily thrown |
|||
exceptions, at least until you try to use them as defined values, |
|||
in which case they're thrown for real. |
|||
=={{header|PHL}}== |
=={{header|PHL}}== |
||
< |
<syntaxhighlight lang="phl">if (obj == null) printf("obj is null!\n");</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
There is a special value <tt>NULL</tt>. You can test for it using <tt>is_null()</tt> or <tt>!isset()</tt> |
There is a special value <tt>NULL</tt>. You can test for it using <tt>is_null()</tt> or <tt>!isset()</tt> |
||
< |
<syntaxhighlight lang="php">$x = NULL; |
||
if (is_null($x)) |
if (is_null($x)) |
||
echo "\$x is null\n";</ |
echo "\$x is null\n";</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Line 787: | Line 1,795: | ||
'[http://software-lab.de/doc/refN.html#not not]' is the predicate to check for |
'[http://software-lab.de/doc/refN.html#not not]' is the predicate to check for |
||
NIL, but many other (typically flow control) functions can be used. |
NIL, but many other (typically flow control) functions can be used. |
||
< |
<syntaxhighlight lang="picolisp">(if (not MyNewVariable) |
||
(handle value-is-NIL) )</ |
(handle value-is-NIL) )</syntaxhighlight> |
||
or |
or |
||
< |
<syntaxhighlight lang="picolisp">(unless MyNewVariable |
||
(handle value-is-NIL) )</ |
(handle value-is-NIL) )</syntaxhighlight> |
||
=={{header|Pike}}== |
=={{header|Pike}}== |
||
In Pike all variables are initialized to <math>0</math>, regardless of their type. thus <math>0</math> functions as a <code>Null</code> value for all types except integer. |
In Pike all variables are initialized to <math>0</math>, regardless of their type. thus <math>0</math> functions as a <code>Null</code> value for all types except integer. |
||
Line 798: | Line 1,807: | ||
to tell the difference between a value <math>0</math> and absence of a key, <code>zero_type()</code> is used: |
to tell the difference between a value <math>0</math> and absence of a key, <code>zero_type()</code> is used: |
||
< |
<syntaxhighlight lang="pike">> mapping bar; |
||
> bar; |
> bar; |
||
Result: 0 |
Result: 0 |
||
Line 809: | Line 1,818: | ||
Result: 0 |
Result: 0 |
||
> zero_type(bar->baz); |
> zero_type(bar->baz); |
||
Result: 1</ |
Result: 1</syntaxhighlight> |
||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
declare x fixed decimal (10); |
declare x fixed decimal (10); |
||
... |
... |
||
Line 820: | Line 1,829: | ||
... |
... |
||
if ^valid(y) then signal error; |
if ^valid(y) then signal error; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Comment:- |
Comment:- |
||
In the picture specification, the content of variable y |
In the picture specification, the content of variable y |
||
Line 829: | Line 1,838: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
In PowerShell the automatic variable <code>$null</code> represents a null value. Comparisons are not left/right symmetrical which means placing <code>$null</code> on the left side greatly assists when comparing to an array. |
In PowerShell the automatic variable <code>$null</code> represents a null value. Comparisons are not left/right symmetrical which means placing <code>$null</code> on the left side greatly assists when comparing to an array. |
||
< |
<syntaxhighlight lang="powershell">if ($null -eq $object) { |
||
... |
... |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
All variables that has not yet been given any other value will be initiated to #Null |
All variables that has not yet been given any other value will be initiated to #Null |
||
< |
<syntaxhighlight lang="purebasic">If variable = #Null |
||
Debug "Variable has no value" |
Debug "Variable has no value" |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">x = None |
||
if x is None: |
if x is None: |
||
print "x is None" |
print "x is None" |
||
else: |
else: |
||
print "x is not None"</ |
print "x is not None"</syntaxhighlight> |
||
Output:<pre> |
Output:<pre> |
||
x is None |
x is None |
||
Line 851: | Line 1,860: | ||
=={{header|R}}== |
=={{header|R}}== |
||
R has the special value NULL to represent a null object. You can test for it using the function is.null. Note that R also has a special value NA to represent missing or unknown values. |
R has the special value NULL to represent a null object. You can test for it using the function is.null. Note that R also has a special value NA to represent missing or unknown values. |
||
< |
<syntaxhighlight lang="r">is.null(NULL) # TRUE |
||
is.null(123) # FALSE |
is.null(123) # FALSE |
||
is.null(NA) # FALSE |
is.null(NA) # FALSE |
||
123==NULL # Empty logical value, with a warning |
123==NULL # Empty logical value, with a warning |
||
foo <- function(){} # function that does nothing |
foo <- function(){} # function that does nothing |
||
foo() # returns NULL</ |
foo() # returns NULL</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 863: | Line 1,872: | ||
sometimes it is used as a generic null value. |
sometimes it is used as a generic null value. |
||
<syntaxhighlight lang="racket"> |
|||
<lang Racket> |
|||
-> null |
-> null |
||
'() |
'() |
||
Line 870: | Line 1,879: | ||
-> (null? 3) |
-> (null? 3) |
||
#f |
#f |
||
</syntaxhighlight> |
|||
</lang> |
|||
But a value that is more used as a generic "nothing" value is "#f", |
But a value that is more used as a generic "nothing" value is "#f", |
||
false. Racket also has a void value, mostly the result of side-effect |
false. Racket also has a void value, mostly the result of side-effect |
||
functions. (And an undefined value.) |
functions. (And an undefined value.) |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{trans|Haskell}} (as it were...) |
|||
In Raku you can name the concept of <tt>Nil</tt>, but it not considered an object, but rather the <i>absence</i> of an object, more of a "bottom" type. The closest analog in real objects is an empty list, but an empty list is considered defined, while <tt>Nil.defined</tt> always returns false. <tt>Nil</tt> is what you get if you try to read off the end of a list, and <tt>()</tt> is just very easy to read off the end of... <tt>:-)</tt> |
|||
If you try to put <tt>Nil</tt> into a container, you don't end up with a container that has <tt>Nil</tt> in it. Instead the container reverts to an uninitialized state that is consistent with the declared type. Hence, Raku has the notion of typed undefined values, that are real objects in the sense of "being there", but are generic in the sense of representing type information without being instantiated as a real object. We call these <i>type objects</i> since they can stand in for real objects when one reasons about the types of objects. So type objects fit into the type hierarchy just as normal objects do. In physics terms, think of them as "type charge carriers" that are there for bookkeeping between the "real" particles. |
|||
All type objects derive from <tt>Mu</tt>, the most-undefined type |
|||
object, and the object most like "null" in many languages. All other object types derive from <tt>Mu</tt>, |
|||
so it is like <tt>Object</tt> in other languages as well, except <tt>Mu</tt> also encompasses various objects that are not discrete, such as junctions. So Raku distinguishes <tt>Mu</tt> from <tt>Any</tt>, which is the type that functions the most like a discrete, mundane object. |
|||
Mostly the user doesn't have to think about it. All object containers behave like "Maybe" types in Haskell terms; they may either hold a valid value or a "nothing" of an appropriate type. |
|||
Most containers default to an object of type <tt>Any</tt> so you don't accidentally send quantum superpositions (junctions) around in your program. |
|||
<syntaxhighlight lang="raku" line>my $var; |
|||
say $var.WHAT; # Any() |
|||
$var = 42; |
|||
say $var.WHAT; # Int() |
|||
say $var.defined; # True |
|||
$var = Nil; |
|||
say $var.WHAT; # Any() |
|||
say $var.defined # False</syntaxhighlight> |
|||
You can declare a variable of type <tt>Mu</tt> if you wish to propagate superpositional types: |
|||
<syntaxhighlight lang="raku" line>my Mu $junction; |
|||
say $junction.WHAT; # Mu() |
|||
$junction = 1 | 2 | 3; |
|||
say $junction.WHAT; # Junction()</syntaxhighlight> |
|||
Or you can declare a more restricted type than <tt>Any</tt> |
|||
<syntaxhighlight lang="raku" line>my Str $str; |
|||
say $str.WHAT; # Str() |
|||
$str = "I am a string."; |
|||
say $str.WHAT; # Str() |
|||
$str = 42; # (fails)</syntaxhighlight> |
|||
But in the Raku view of reality, it's completely bogus to ask |
|||
for a way "to see if an object is equivalent to the null object." |
|||
The whole point of such a non-object object is that it doesn't exist, |
|||
and can't participate in computations. If you think you mean the |
|||
null object in Raku, you really mean some kind of generic object |
|||
that is uninstantiated, and hence undefined. One of those is your "null object", |
|||
except there are many of them, so you can't just check for equivalence. Use the <tt>defined</tt> predicate (or match on a subclass of your type that forces recognition of abstraction or definedness). |
|||
Raku also has <tt>Failure</tt> objects that, in addition to being |
|||
undefined carriers of type, are also carriers of the <i>reason</i> |
|||
for the value's undefinedness. We tend view them as lazily thrown |
|||
exceptions, at least until you try to use them as defined values, |
|||
in which case they're thrown for real. |
|||
=={{header|Raven}}== |
=={{header|Raven}}== |
||
{{improve|Raven|Add NULL handling with MySQL data.}} |
|||
<syntaxhighlight lang="raven">NULL as $v |
|||
$v NULL = # TRUE |
$v NULL = # TRUE |
||
$v NULL != # FALSE |
$v NULL != # FALSE |
||
Line 885: | Line 1,948: | ||
NULL as $v2 |
NULL as $v2 |
||
$v2 $v = # TRUE</ |
$v2 $v = # TRUE</syntaxhighlight> |
||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
< |
<syntaxhighlight lang="rebol">x: none |
||
print ["x" either none? x ["is"]["isn't"] "none."]</ |
print ["x" either none? x ["is"]["isn't"] "none."]</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>x is none.</pre> |
<pre>x is none.</pre> |
||
REBOL also has the concept of <code>unset</code> values, testable with <code>get/any</code> |
|||
<syntaxhighlight lang="rebol">unset? get/any 'some-var |
|||
unset? get 'some-var</syntaxhighlight> |
|||
{{out}} |
|||
<pre>true |
|||
** Script Error: some-var has no value |
|||
** Near: unset? get 'some-var</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
REXX can have variables with a null value. |
REXX can have variables with a null value. |
||
<br>With the '''symbol''' built-in function, it can be determined if a variable is defined (or not). |
<br>With the '''symbol''' built-in function, it can be determined if a variable is defined (or not). |
||
<br>The '''length''' built-in function can be used to see what the length of the value of a defined variable. |
<br>The '''length''' built-in function can be used to see what the length of the value of a defined variable. |
||
<br>A variable with a '''null''' value has a length of 0 (zero). |
<br>A variable with a '''null''' value has a length of '''0''' (zero). |
||
<br><br>The ''' |
<br><br>The '''drop''' statement can be used to "undefine" a REXX variable. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program demonstrates null strings, and also undefined values. */ |
||
if symbol('ABC')=="VAR" then say 'variable ABC is defined, value='abc"<<<" |
if symbol('ABC')=="VAR" then say 'variable ABC is defined, value='abc"<<<" |
||
Line 914: | Line 1,987: | ||
cat='' |
cat='' |
||
if symbol('CAT')=="VAR" then say 'variable CAT is defined, value='cat"<<<" |
if symbol('CAT')=="VAR" then say 'variable CAT is defined, value='cat"<<<" |
||
else say "variable CAT isn't defined."</ |
else say "variable CAT isn't defined."</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre style=overflow:scroll"> |
<pre style=overflow:scroll"> |
||
Line 922: | Line 1,995: | ||
variable CAT is defined, value=<<< |
variable CAT is defined, value=<<< |
||
</pre> |
</pre> |
||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
see isnull(5) + nl + # print 0 |
|||
isnull("hello") + nl + # print 0 |
|||
isnull([1,3,5]) + nl + # print 0 |
|||
isnull("") + nl + # print 1 |
|||
isnull("NULL") # print 1 |
|||
</syntaxhighlight> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
The value when referring to the instance variable which isn't initialized is nil. |
|||
<lang ruby> |
|||
<syntaxhighlight lang="ruby">puts "@object is nil" if @object.nil? # instance variable |
|||
</lang> |
|||
puts "$object is nil" if $object.nil? # global variable, too |
|||
# It recognizes as the local variable even if it isn't executed. |
|||
object = 1 if false |
|||
puts "object is nil" if object.nil? |
|||
# nil itself is an object: |
|||
puts nil.class # => NilClass</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
@object is nil |
|||
$object is nil |
|||
object is nil |
|||
NilClass |
|||
</pre> |
|||
=={{header|Rust}}== |
|||
<syntaxhighlight lang="rust">// If an option may return null - or nothing - in Rust, it's wrapped |
|||
// in an Optional which may return either the type of object specified |
|||
// in <> or None. We can check this using .is_some() and .is_none() on |
|||
// the Option. |
|||
fn check_number(num: &Option<u8>) { |
|||
if num.is_none() { |
|||
println!("Number is: None"); |
|||
} else { |
|||
println!("Number is: {}", num.unwrap()); |
|||
} |
|||
} |
|||
fn main() { |
|||
let mut possible_number: Option<u8> = None; |
|||
check_number(&possible_number); |
|||
possible_number = Some(31); |
|||
check_number(&possible_number); |
|||
}</syntaxhighlight> |
|||
=={{header|S-lang}}== |
|||
S-Lang uses NULL; it is the only object of type Null_Type: |
|||
<syntaxhighlight lang="s-lang">variable foo = NULL; |
|||
print(foo); |
|||
if (foo == NULL) |
|||
print(typeof(foo)); |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>NULL |
|||
Null_Type |
|||
</pre> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
[http://blog.sanaulla.info/2009/07/12/nothingness/ This blog post] has a good explanations of the different types of null-like values. |
[http://blog.sanaulla.info/2009/07/12/nothingness/ This blog post] has a good explanations of the different types of null-like values. |
||
< |
<syntaxhighlight lang="scala"> |
||
scala> Nil |
scala> Nil |
||
res0: scala.collection.immutable.Nil.type = List() |
res0: scala.collection.immutable.Nil.type = List() |
||
Line 954: | Line 2,086: | ||
scala> val a = println() |
scala> val a = println() |
||
a: Unit = () |
a: Unit = () |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
<lang |
<syntaxhighlight lang="scheme">(null? object)</syntaxhighlight> |
||
Note: "null?" here tests whether a value is the empty list. |
Note: "null?" here tests whether a value is the empty list. |
||
=={{header|Sidef}}== |
|||
The absence of a value is represented by ''nil'' |
|||
<syntaxhighlight lang="ruby">var undefined; # initialized with an implicit nil |
|||
say undefined==nil; # true |
|||
say defined(nil) # false</syntaxhighlight> |
|||
However, ''nil'' is not an object, so we can't call methods on it. Alternatively, Sidef provides the ''null'' object: |
|||
<syntaxhighlight lang="ruby">var null_obj = null; # initialize with a null value |
|||
say null_obj.is_a(null); # true |
|||
say defined(null_obj); # true</syntaxhighlight> |
|||
=={{header|Slate}}== |
=={{header|Slate}}== |
||
< |
<syntaxhighlight lang="slate">Nil isNil = True.</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
< |
<syntaxhighlight lang="smalltalk">object isNil ifTrue: [ "true block" ] |
||
ifFalse: [ "false block" ]. |
ifFalse: [ "false block" ]. |
||
nil isNil ifTrue: [ 'true!' displayNl ]. "output: true!" |
nil isNil ifTrue: [ 'true!' displayNl ]. "output: true!" |
||
foo isNil ifTrue: [ 'ouch' displayNl ]. |
foo isNil ifTrue: [ 'ouch' displayNl ]. |
||
x := (foo == nil). |
x := (foo == nil). |
||
x := foo isNil</ |
x := foo isNil</syntaxhighlight> |
||
notice that nil is the singleton instance of the UndefinedObject class; i.e. it is a first class object. Thus we can do: |
notice that nil is the singleton instance of the UndefinedObject class; i.e. it is a first class object. Thus we can do: |
||
< |
<syntaxhighlight lang="smalltalk">foo := nil. |
||
foo class. "-> UndefinedObject" |
foo class. "-> UndefinedObject" |
||
foo respondsTo: #'bar'. "asking if a message is implemented" |
foo respondsTo: #'bar'. "asking if a message is implemented" |
||
foo class compile:'fancyOperation ^ 123'. |
foo class compile:'fancyOperation ^ 123'. |
||
foo fancyOperation "->123"</ |
foo fancyOperation "->123"</syntaxhighlight> |
||
the last example being for demonstration only - it is not considered well behaved to add arbitrary code that way, except for framework support, such as encoding, decoding marshalling etc.) |
the last example being for demonstration only - it is not considered well behaved to add arbitrary code that way, except for framework support, such as encoding, decoding marshalling etc.) |
||
Line 986: | Line 2,129: | ||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
Maybe the closest type of Standard ML would be the type option, which is defined like this in the standard library: |
Maybe the closest type of Standard ML would be the type option, which is defined like this in the standard library: |
||
< |
<syntaxhighlight lang="sml">datatype 'a option = NONE | SOME of 'a</syntaxhighlight> |
||
< |
<syntaxhighlight lang="sml">case v of NONE => "unbound value" |
||
| SOME _ => "bounded value"</ |
| SOME _ => "bounded value"</syntaxhighlight> |
||
=={{header|Swift}}== |
|||
Swift has <code>Optional<T></code> type, where <code>nil</code> means a lack of value. |
|||
<code>T?</code> is syntactic sugar for <code>Optional<T></code>. |
|||
<syntaxhighlight lang="swift">let maybeInt: Int? = nil</syntaxhighlight> |
|||
To just check if variable is nil, you can use <code>==</code> operator. |
|||
<syntaxhighlight lang="swift">if maybeInt == nil { |
|||
print("variable is nil") |
|||
} else { |
|||
print("variable has some value") |
|||
}</syntaxhighlight> |
|||
Usually you want to access the value after checking if it's nil. To do that you use <code>if let</code> |
|||
<syntaxhighlight lang="swift">if let certainlyInt = maybeInt { |
|||
print("variable has value \(certainlyInt)") |
|||
} else { |
|||
print("variable is nil") |
|||
}</syntaxhighlight> |
|||
=={{header|Tailspin}}== |
|||
Tailspin does not have a null value, but a transform is allowed to produce nothing at all, in which case that chain of computation simply stops. A templates transform can explicitly label cases as producing nothing by !VOID but also input values for which there is no matching branch will produce nothing. If you need computation to continue even in the event of nothing being produced, you can wrap the transform in an array/list to get an empty list. |
|||
<syntaxhighlight lang="tailspin"> |
|||
templates mightBeNothing |
|||
when <=0> do !VOID |
|||
when <=1> do 'something' ! |
|||
end mightBeNothing |
|||
1 -> mightBeNothing -> 'Produced $;. ' -> !OUT::write |
|||
0 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write |
|||
2 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write |
|||
// capture the transform in a list to continue computation when no result is emitted |
|||
[1 -> mightBeNothing] -> \( |
|||
when <=[]> 'Produced nothing. ' ! |
|||
otherwise 'Produced $(1);. ' ! |
|||
\) -> !OUT::write |
|||
[0 -> mightBeNothing] -> \( |
|||
when <=[]> 'Produced nothing. ' ! |
|||
otherwise 'Produced $(1);. ' ! |
|||
\) -> !OUT::write |
|||
[2 -> mightBeNothing] -> \( |
|||
when <=[]> 'Produced nothing. ' ! |
|||
otherwise 'Produced $(1);. ' ! |
|||
\) -> !OUT::write |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Produced something. Produced something. Produced nothing. Produced nothing. </pre> |
|||
It is an error to try to assign nothing to a symbol or field. |
|||
<syntaxhighlight lang="tailspin"> |
|||
// throws an error |
|||
def nothing: 0 -> mightBeNothing; |
|||
// throws an error |
|||
{ nothing: 0 -> mightBeNothing } |
|||
// OK, simply results in the empty structure without a field called 'nothing' |
|||
{ 0 -> mightBeNothing -> (nothing: $) } |
|||
</syntaxhighlight> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
In Tcl, where every value is a string, there is no out-of band value corresponding to NULL. In many cases, using the empty string is sufficient: |
In Tcl, where every value is a string, there is no out-of band value corresponding to NULL. In many cases, using the empty string is sufficient: |
||
< |
<syntaxhighlight lang="tcl">if {$value eq ""} ...</syntaxhighlight> |
||
A stricter approximation to NULL can be had with non-existing variables or elements of a dict or array: |
A stricter approximation to NULL can be had with non-existing variables or elements of a dict or array: |
||
< |
<syntaxhighlight lang="tcl">if {![info exist nullvar]} ... |
||
if {![info exists arr(nullval)]} ... |
if {![info exists arr(nullval)]} ... |
||
if {![dict exists $dic nullval]} ...</ |
if {![dict exists $dic nullval]} ...</syntaxhighlight> |
||
Note that lists do not support anything like nulls, since they are strictly sequences of values. |
Note that lists do not support anything like nulls, since they are strictly sequences of values. |
||
=={{header|TXR}}== |
|||
=={{trans|Common Lisp}}== |
|||
TXR Lisp has a <code>nil</code> symbol which serves as the empty list and Boolean false, like Common Lisp and similar dialects. It is a very important symbol which plays a central role. |
|||
Variable definitions, global and local, without initial value expressions take on the value <code>nil</code>. Elements of newly created vectors and structure slots are <code>nil</code> by default. Optional function parameters that don't receive arguments are given <code>nil</code> arguments by default. Many functions which search for something use <code>nil</code> for indicating not found. |
|||
Object-oriented programming in TXR Lisp is done with structures, which do not provide a CLOS-like object system. The <code>nil</code> object isn't a structure, and so it cannot take slot references, or method invocation. Only structures have methods, which means that it's not possible to define a null object method <code>m</code> such that <code>obj.(m)</code> can be invoked if <code>obj</code> is an expression evaluating to <code>nil</code>. |
|||
The Gang-of-Five Null Object Pattern can be employed: defining struct types that behave like null. This null object doesn't have to be related by inheritance to the structs in conjunction with which it is used. |
|||
<syntaxhighlight lang="txrlisp"> |
|||
(defstruct null-widget () |
|||
(:method popularity (me) 0)) |
|||
(defvarl null-widget (new null-widget)) |
|||
(defstruct real-widget () |
|||
pop |
|||
(:method popularity (me) me.pop))</syntaxhighlight> |
|||
In situations when a null object would be used simply to provide safe treatment of null without the verbosity of checks for its presence, and a default value of <code>nil</code> is acceptable, TXR Lisp has null-safe slot and method access: <code>obj.?slot</code>, <code>obj.?(method arg)</code>. |
|||
The expression <code>w.?(popularity)</code> will evaluate to <code>nil</code> if <code>w</code> is <code>nil</code>, being equivalent to <code>(if w w.(popularity))</code>, except that <code>w</code> is evaluated only once. |
|||
Like in Common Lisp, <code>nil</code> an instance of the type <code>null</code>, which is a unit type having only that instance. And <code>nil</code> is also the name of the bottom type of the type system: the <code>nil</code> type is the subtype of every type, including itself. |
|||
Like in Common Lisp, the expression <code>(or a b c ...)</code> evaluates the arguments from left to right, returning the value of the leftmost one which does not evaluate to <code>nil</code>. |
|||
<syntaxhighlight lang="txrlisp">;; Find widget in one of three places in order |
|||
(defun find-widget (name) |
|||
(or [%widget-hash% name] |
|||
(lookup-local-widget name) |
|||
(lookup-global-widget name)))</syntaxhighlight> |
|||
=={{header|Ursa}}== |
|||
<syntaxhighlight lang="ursa"># the type at declaration doesn't matter |
|||
decl int x |
|||
set x null |
|||
if (= x null) |
|||
out "x is null" endl console |
|||
else |
|||
out "x is not null" endl console |
|||
end if</syntaxhighlight> |
|||
=={{header|VBA}}== |
|||
<syntaxhighlight lang="vb">Public Sub Main() |
|||
Dim c As VBA.Collection |
|||
' initial state: Nothing |
|||
Debug.Print c Is Nothing |
|||
' create an instance |
|||
Set c = New VBA.Collection |
|||
Debug.Print Not c Is Nothing |
|||
' release the instance |
|||
Set c = Nothing |
|||
Debug.Print c Is Nothing |
|||
End Sub</syntaxhighlight> |
|||
=={{header|Visual Basic}}== |
|||
{{works with|VB6}} |
|||
Null by the definition of this task is called "Nothing" in VB6: |
|||
<syntaxhighlight lang="vb"> |
|||
Public Sub Main() |
|||
Dim c As VBA.Collection |
|||
' initial state: Nothing |
|||
Debug.Assert c Is Nothing |
|||
' create an instance |
|||
Set c = New VBA.Collection |
|||
Debug.Assert Not c Is Nothing |
|||
' release the instance |
|||
Set c = Nothing |
|||
Debug.Assert c Is Nothing |
|||
End Sub |
|||
</syntaxhighlight> |
|||
The Null keyword has a different meaning in VB6: it's one of the states that a Variant type variable can be in. Null means that a Variant doesn't hold valid (i.e.: defined) data. |
|||
<syntaxhighlight lang="vb"> |
|||
Public Sub Main() |
|||
Dim v As Variant |
|||
' initial state: Empty |
|||
Debug.Assert IsEmpty(v) |
|||
Debug.Assert VarType(v) = vbEmpty |
|||
v = 1& |
|||
Debug.Assert VarType(v) = vbLong |
|||
' assigning the Null state |
|||
v = Null |
|||
' checking for Null state |
|||
Debug.Assert IsNull(v) |
|||
Debug.Assert VarType(v) = vbNull |
|||
End Sub |
|||
</syntaxhighlight> |
|||
=={{header|V (Vlang)}}== |
|||
V (Vlang) does not have nor normally allow null or nil (also called "the billion dollar mistake"): |
|||
1) All primitive types/variables have default values. |
|||
2) For arrays and structs, default values are automatically assigned. |
|||
3) Usage of voidptr or nil, only done in unsafe, and is usually only for the purposes of interoperability with other languages. |
|||
<syntaxhighlight lang="v (vlang)"> |
|||
// Null or nil not used, default values for various primitive types/variables instead: |
|||
a_string :='' |
|||
a_bool := false |
|||
an_int := 0 |
|||
[3]string{} // ['', '', ''] |
|||
[3]bool{} // [false, false, false] |
|||
[3]int{} // [0, 0, 0] |
|||
</syntaxhighlight> |
|||
=={{header|Wart}}== |
|||
The null value <code>nil</code> is also the only false value. |
|||
<syntaxhighlight lang="wart">(not nil) |
|||
</syntaxhighlight> |
|||
=={{header|Wren}}== |
|||
In Wren, it is not technically possible for a variable to have no value at all. |
|||
If you define a variable without giving it a value, then it is given the special value ''null'' which is the only instance of the Null class and also a keyword. |
|||
Similarly, if you define a function but don't give it a return value, then it returns ''null''. In this particular respect, null is similar to ''void'' in C. |
|||
In boolean expressions, ''null'' is considered to be false whereas (apart from ''false'' itself) all other values (even 0) are considered to be true. For consistency the Null class therefore overrides the ''!'' operator, which it inherits from the Object class, so that ''!null'' returns true. |
|||
It is always easy to test for nullness either by querying a variable's type or checking the value of a boolean expression involving a potentially null variable. |
|||
<syntaxhighlight lang="wren">// Declare a variable without giving it an explicit value. |
|||
var s |
|||
// We can now check for nullness in one of these ways. |
|||
System.print(s) |
|||
System.print(s == null) |
|||
System.print(s is Null) |
|||
System.print(s.type == Null) |
|||
// Similarly, if we define this function without giving it a return value. |
|||
var f = Fn.new { |
|||
System.print("I'm a function with no explicit return value.") |
|||
} |
|||
// And now call it. |
|||
var g = f.call() |
|||
// We find that the return value is null. |
|||
System.print(g)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
null |
|||
true |
|||
true |
|||
true |
|||
I'm a function with no explicit return value. |
|||
null |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
In zkl, there isn't a C like 0/NULL, a value that, if referenced, causes bad things to happen. There is an Object, Void, that is used as generic NULL like thing but it is just another object. |
|||
<syntaxhighlight lang="zkl">if(Void == n) ... |
|||
return(Void)</syntaxhighlight> |
|||
=={{header|Z80 Assembly}}== |
|||
{{trans|ARM Assembly}} |
|||
Even though this doesn't really apply to assembly, as there is no "null pointer" per se (that is, all data is a number), it would be interesting to demystify what <code>NULL</code> really is. At the lowest level, the null pointer is just a pointer to a memory location that is of no use to the programmer. The Z80 does not segfault, so any memory address we read is fair game. So without the hardware enforcing <code>NULL</code>, we need to pick an address we don't mind losing. Typically, using <code>&0000</code> to equal [[C]]'s <code>NULL</code> is acceptable, as address <code>&0000</code> on any randomly chosen Z80-based hardware is typically a jump to the kernel's entry point (or the main program's entry point, depending on the implementation.) |
|||
<syntaxhighlight lang="z80">ld a,(&0000) ;dereference the null pointer as a uint8 |
|||
ld hl,(&0000) ;dereference the null pointer as a uint16</syntaxhighlight> |
|||
Typically, you would get 0xC3 when dereferencing as an 8-bit value and 0xC3nn when dereferencing as a 16-bit value, where nn is the low byte of the address of the aforementioned entry point. Neither of these are particularly useful, so having <code>&0000</code> as the null pointer is perfectly fine. Although there are technically other options, most CPUs can compare with zero more efficiently than most other numbers, and the Z80 is no exception. Of course, the Z80 will not check if a pointer is NULL for you, so you have to do it yourself: |
|||
<syntaxhighlight lang="z80">LD HL,myPointers |
|||
;there is no LD BC,(HL) so we have to do this: |
|||
LD c,(hl) |
|||
inc hl |
|||
LD b,(hl) |
|||
;and compare to null |
|||
LD a,b |
|||
or c ;compare BC to zero |
|||
JR z,isNull</syntaxhighlight> |
|||
{{omit from|GUISS}} |
{{omit from|GUISS}} |
||
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have a null value. --> |
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have a null value. --> |
||
{{omit from|6502 Assembly}} |
|||
{{omit from|68000 Assembly}} |
|||
{{omit from|8080 Assembly}} |
|||
{{omit from|8086 Assembly}} |
|||
{{omit from|MIPS Assembly}} |
|||
{{omit from|X86 Assembly}} |
|||
{{omit from|Z80 Assembly}} |
Revision as of 15:46, 6 May 2024
You are encouraged to solve this task according to the task description, using any language you may know.
Null (or nil) is the computer science concept of an undefined or unbound object. Some languages have an explicit way to access the null object, and some don't. Some languages distinguish the null object from undefined values, and some don't.
- Task
Show how to access null in your language by checking to see if an object is equivalent to the null object.
This task is not about whether a variable is defined. The task is about "null"-like values in various languages, which may or may not be related to the defined-ness of variables in your language.
11l
F f([Int]? &a)
I a != N
a.append(1)
f(N)
[Int] arr
f(&arr)
print(arr)
- Output:
[1]
6502 Assembly
Technically there is no such thing as a null pointer; all pointers point to something. It's a matter of what you're willing to give up. Often the null pointer is thought of as memory address 0, and on many CPUs this is the case - however this is most assuredly not the case on the 6502. Reason being, zero page RAM is limited and quite valuable, given that there are only 256 bytes of it and it is much more efficient to access than regular memory. As such, declaring $0000
to be the null pointer would be a very poor choice. Ideally, the null pointer on a 6502 should:
- Be somewhere that isn't zero page RAM
- Be somewhere that we cannot change at runtime (e.g. read-only memory) or doing so would cause major problems (the vector table)
- Point to something that has no value to the programmer.
We can choose quite a few places, the easiest one I can think of is $FFFF
. Although it sort of breaks our first rule, as when dereferenced as a 16-bit value, you get the value stored at $0000
as the high byte, we still can access $0000
normally anyway. Since it points to the high byte of the interrupt request vector, it's something we don't want to (or most likely can't) modify at runtime, and is of no use to us (if we really wanted the IRQ handler's address we'd dereference $FFFE
instead.)
How a null pointer is implemented is very simple. You decide beforehand what your null pointer will be, and before you dereference a pointer variable, compare it to the null pointer, and if they're equal, don't dereference it. That's all there is to it.
lda pointer ;a zero-page address that holds the low byte of a pointer variable.
CMP #$FF
BNE .continue
lda pointer+1
CMP #$FF
BNE .continue
RTS ;return without doing anything
.continue
8th
null? if "item was null" . then
AArch64 Assembly
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program nullobj64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
/*******************************************/
/* Initialized data */
/*******************************************/
.data
szCarriageReturn: .asciz "\n"
szMessResult: .asciz "Value is null.\n" // message result
qPtrObjet: .quad 0 // objet pointer
/*******************************************/
/* UnInitialized data */
/*******************************************/
.bss
/*******************************************/
/* code section */
/*******************************************/
.text
.global main
main: // entry of program
ldr x0,qAdrqPtrObjet // load pointer address
ldr x0,[x0] // load pointer value
cbnz x0,100f // is null ?
ldr x0,qAdrszMessResult // yes -> display message
bl affichageMess
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszMessResult: .quad szMessResult
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrqPtrObjet: .quad qPtrObjet
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
Action!
TYPE Object=[
BYTE byteData
INT intData
CARD cardData]
PROC IsNull(Object POINTER ptr)
IF ptr=0 THEN
PrintE("Object is null")
ELSE
PrintE("Object is not null")
FI
RETURN
PROC Main()
Object a
Object POINTER ptr1=a,ptr2=0
IsNull(ptr1)
IsNull(ptr2)
RETURN
- Output:
Screenshot from Atari 8-bit computer
Object is not null Object is null
ActionScript
if (object == null)
trace("object is null");
ActionScript also has an undefined value: see Undefined values#ActionScript.
Ada
with Ada.Text_Io;
if Object = null then
Ada.Text_Io.Put_line("object is null");
end if;
ALGOL 68
In ALGOL 68 the NIL yields a name that does not refer to any value. NIL can never be naturally coerced and can only appear where the context is strong.
REF STRING no result = NIL;
STRING result := "";
IF no result :=: NIL THEN print(("no result :=: NIL", new line)) FI;
IF result :/=: NIL THEN print(("result :/=: NIL", new line)) FI;
IF no result IS NIL THEN print(("no result IS NIL", new line)) FI;
IF result ISNT NIL THEN print(("result ISNT NIL", new line)) FI;
COMMENT using the UNESCO/IFIP/WG2.1 ALGOL 68 character set
result := °;
IF REF STRING(result) :≠: ° THEN print(("result ≠ °", new line)) FI;
END COMMENT
# Note the following gotcha: #
REF STRING var := NIL;
IF var ISNT NIL THEN print(("The address of var ISNT NIL",new line)) FI;
IF var IS REF STRING(NIL) THEN print(("The address of var IS REF STRING(NIL)",new line)) FI
Output:
no result :=: NIL result :/=: NIL no result IS NIL result ISNT NIL The address of var ISNT NIL The address of var IS REF STRING(NIL)
NIL basically is an untyped ref (pointer) that does not refer anywhere.
ALGOL 68 also has empty. This is a "constant" of size 0 and type void. c.f. Roots of a function for two different examples of usage.
- empty as an undefined argument to a routine.
- empty as a routine return if no result is found.
empty is typically used to refer to am empty leaf in a tree structure.
Basically:
- ALGOL 68's empty is python's
None
, - ALGOL 68's void is python's
NoneType
, and - ALGOL 68's nil is python's
hash(None)
ALGOL W
begin
% declare a record type - will be accessed via references %
record R( integer f1, f2, f3 );
% declare a reference to a R instance %
reference(R) refR;
% assign null to the reference %
refR := null;
% test for a null reference - will write "refR is null" %
if refR = null then write( "refR is null" ) else write( "not null" );
end.
AmigaE
DEF x : PTR TO object
-> ...
IF object <> NIL
-> ...
ENDIF
APL
APL is a vector/array-based language, so rather than a 'null pointer' or 'null value' there is the 'null vector'.
⍝⍝ GNU APL
]help ⍬
niladic function: Z ← ⍬ (Zilde)
Zilde is the empty numeric vector (aka. ⍳0)
Not a function but rather an alias for the empty
vector:
⍬≡⍳0
1
AppleScript
Many applications will return missing value
, but null
is also available.
if x is missing value then
display dialog "x is missing value"
end if
if x is null then
display dialog "x is null"
end if
ARM Assembly
/* ARM assembly Raspberry PI */
/* program nullobj.s */
/* Constantes */
.equ STDIN, 0 @ Linux input console
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
/* Initialized data */
.data
szCarriageReturn: .asciz "\n"
szMessResult: .asciz "Value is null.\n" @ message result
iPtrObjet: .int 0 @ objet pointer
/* UnInitialized data */
.bss
/* code section */
.text
.global main
main: @ entry of program
ldr r0,iAdriPtrObjet @ load pointer address
ldr r0,[r0] @ load pointer value
cmp r0,#0 @ is null ?
ldreq r0,iAdrszMessResult @ yes -> display message
bleq affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
pop {fp,lr} @ restaur 2 registers
mov r7, #EXIT @ request to exit program
svc 0 @ perform the system call
iAdrszMessResult: .int szMessResult
iAdrszCarriageReturn: .int szCarriageReturn
iAdriPtrObjet: .int iPtrObjet
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registres
mov r2,#0 @ counter length
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call systeme
pop {r0,r1,r2,r7,lr} @ restaur des 2 registres */
bx lr @ return
Arturo
v: null
if v=null -> print "got NULL!"
- Output:
got NULL!
AutoHotkey
If (object == null)
MsgBox, object is null
AutoIt
Local $object = Null
If $object = Null Then MsgBox(0, "NULL", "Object is null")
AWK
Undefined elements correspond to an empty string; when converted to a numerical value, it evaluates to 0. In order to distinguish a undefined value from a value of 0, length(var) need to be used.
#!/usr/bin/awk -f
BEGIN {
b=0;
print "<"b,length(b)">"
print "<"u,length(u)">"
print "<"u+0,length(u+0)">";
}
Output
<0 1> < 0> <0 1>
Axe
Null pointers can be checked by simply comparing the pointer with 0.
If P=0
Disp "NULL PTR",i
End
Babel
In this example, we place nil on the stack, then perform an if-then-else (ifte) based on the value returned by the 'nil?' operator which returns true if top-of-stack (TOS) is nil. If TOS is nil, then we can be relieved, otherwise, the interpreter has gone absolutely haywire. The '<<' operator prints the selected string to STDOUT.
{ nil { nil? } { "Whew!\n" } { "Something is terribly wrong!\n" } ifte << }
BASIC
Applesoft BASIC
caveat: http://qconlondon.com/london-2009/presentation/Null+References%3A+The+Billion+Dollar+Mistake
Applesoft has no built-in object system. The closest values to NULL or nil for each of the types are 0 for integers and floating point numbers, and "" for strings. There is also the NUL character: CHR$(0). One could create an object system using global variables and include a special value for NULL, but this is probably a mistake.
TRUE = 1 : FALSE = 0
NULL = TRUE
IF NULL THEN PRINT "NULL"
NULL = FALSE
IF NOT NULL THEN PRINT "NOT NULL"
Output:
NULL NOT NULL
BBC BASIC
A null object has a pointer with a value of zero or one.
PROCtestobjects
END
DEF PROCtestobjects
PRIVATE a(), b(), s{}, t{}
DIM a(123)
DIM s{a%, b#, c$}
IF !^a() <= 1 PRINT "a() is null" ELSE PRINT "a() is not null"
IF !^b() <= 1 PRINT "b() is null" ELSE PRINT "b() is not null"
IF !^s{} <= 1 PRINT "s{} is null" ELSE PRINT "s{} is not null"
IF !^t{} <= 1 PRINT "t{} is null" ELSE PRINT "t{} is not null"
ENDPROC
Output:
a() is not null b() is null s{} is not null t{} is null
GWBASIC/QBasic/QB/VBDOS
These dialects of BASIC have no built-in object system. One STRING variable can have a default empty ("") value and a numeric one a default zero (0) value. A STRING variable can be assigned with the NULL (Chr$(0)) value if needed and can be assesed with the instruction.
IF VAR$ = CHR$(0) THEN PRINT "Variable has a null value."
Bracmat
Bracmat has no null objects.
The operators for multiplication, addition and concatenation have neutral elements, which are 1
, 0
and the empty string, respectively, but these are values like any other string.
a:?x*a*?z {assigns 1 to x and to z}
a:?x+a+?z {assigns 0 to x and to z}
a:?x a ?z {assigns "" (or (), which is equivalent) to x and to z}
C
C has the null pointer, written as "0", whose internal representation is often, though not always, the same as integer zero. It is (supposedly) garanteed to be pointing to nothing, so receiving one of those likely means you are not looking at an object--but, there are occasions where changing content of a null pointer actually does something (say, on DOS); and a function that's supposed to return a pointer on success doesn't always return a 0 otherwise (e.g. mmap returns -1 for failure).
There is a very common macro, NULL
, which evaluates to (void*) 0
or an equivalent value. NULL is compatible with all pointer types, including both data pointers and function pointers.
The standard library defines NULL in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h and wchar.h. POSIX systems also define NULL in dirent.h and unistd.h. Many C files include at least one of these headers, so NULL is almost always available.
#include <stdio.h>
int main()
{
char *object = 0;
if (object == NULL) {
puts("object is null");
}
return 0;
}
C#
As with Java, any reference type may be null, and testing for nullity uses ordinary boolean operators.
if (foo == null)
Console.WriteLine("foo is null");
C# 2.0 introduced nullable types for situations in which even primitive value types may have undefined or unknown values (for example, when reading from a database). Prior to the introduction of nullable types, these situations would require writing wrapper classes or casting to a reference type (e.g., object), incurring the penalties of boxing and reduced type safety. A variable with nullable type can be declared simply by adding the '?' operator after the type.
int? x = 12;
x = null;
Also new in C# 2.0 was the null coalescing operator, '??', which is simply syntactic sugar allowing a default value to replace an operand if the operand is null:
Console.WriteLine(name ?? "Name not specified");
//Without the null coalescing operator, this would instead be written as:
//if(name == null){
// Console.WriteLine("Name not specified");
//}else{
// Console.WriteLine(name);
//}
C++
In C++ non-pointer types do not support null. (C++ provides value semantics rather than reference semantics). When using pointers C++ permits checking for null by comparing the pointer to a literal of 0, or (as in C) by way of a macro (NULL) which simply expands to 0.
#include <iostream>
#include <cstdlib>
if (object == 0) {
std::cout << "object is null";
}
std::optional is available since C++17 (or Boost's boost::optional via boost/optional.hpp for earlier standards) for cases where the programmer wishes to pass by value, but still support a null value.
#include <iostream>
#include <optional>
std::optional<int> maybeInt()
int main()
{
std::optional<int> maybe = maybeInt();
if(!maybe)
std::cout << "object is null\n";
}
C++11
In C++11 there is nullptr
of type nullptr_t
which represents a pointer to an invalid place. You can use it like
int *p = nullptr;
...
if (p == nullptr){
// do some thing
}
//or just
if (p){
// do some thing
}
Chapel
Class variables can be declared as nil if and only if they have nilable class type, declared with postfix ?, alongside memory management technique owned, borrowed, shared, or unmanaged. A nilable class type is default initialized to nil.
class C { };
var c : owned C?; // is nil
writeln(if c == nil then "nil" else "something");
Clojure
Clojure's nil
is equivalent to Java's null
.
(let [x nil]
(println "Object is" (if (nil? x) "nil" "not nil")))
Test wether symbol foo
is defined:
(find (ns-interns *ns*) 'foo)
Undefining foo
:
(ns-unmap *ns* 'foo)
COBOL
Works with GnuCOBOL 2.0
identification division.
program-id. null-objects.
remarks. test with cobc -x -j null-objects.cob
data division.
working-storage section.
01 thing-not-thing usage pointer.
*> call a subprogram
*> with one null pointer
*> an omitted parameter
*> and expect void return (callee returning omitted)
*> and do not touch default return-code (returning nothing)
procedure division.
call "test-null" using thing-not-thing omitted returning nothing
goback.
end program null-objects.
*> Test for pointer to null (still a real thing that takes space)
*> and an omitted parameter, (call frame has placeholder)
*> and finally, return void, (omitted)
identification division.
program-id. test-null.
data division.
linkage section.
01 thing-one usage pointer.
01 thing-two pic x.
procedure division using
thing-one
optional thing-two
returning omitted.
if thing-one equal null then
display "thing-one pointer to null" upon syserr
end-if
if thing-two omitted then
display "no thing-two was passed" upon syserr
end-if
goback.
end program test-null.
- Output:
prompt$ cobc -x -j null-objects.cob thing-one pointer to null no thing-two was passed
Common Lisp
Basics
Common Lisp has an object denoted by the symbol nil
. When the symbol nil
is evaluated as an expression, it evaluates to itself.
nil
uniquely represents boolean false, and so code like
(if (condition) (do-this))
is actually testing whether (condition)
returns the value nil
. The object nil
is also used to denote the empty list which also terminates other lists. The value is also used as a default when some function returns fewer values than expected. (list (values))
produces (nil)
(list containing one element, which is the empty list), because (values)
produces no value, but the function call (list ...)
needs to reduce the expression to a single argument value, and so nil
is supplied.
Beginnings of Null Object
The idea of making functions accept nil
without failing did not appear in early Lisps. For instance (car nil)
was erroneous: it was incorrect to try to access the first element of a non-list.
The defaulting behavior (car nil)
which Common Lisp programmers take for granted was introduced in InterLisp, and then copied into MacLisp. (InterLisp had other liberties that do not survive into Common Lisp: it was possible to call a function with insufficient arguments, and the missing ones defaulted to nil
. Likewise, excess arguments were ignored. CL has a disciplined syntax and semantics for default and variable arguments.)
This (car nil) -> nil
behavior shows nil
in an kind of new role: the role of a null object which takes methods that apply to other objects and provides some default non-failing behavior. It is the beginnings of the [null object design pattern].
Object-Oriented Null Object
In Common Lisp, in fact, there is a class called null
, of which the object nil
is understood to be the only instance. Furthermore, the null
class is at the bottom of the type spindle: it is a subclass of every class. This is in contrast with the type T
which is a superclass of every class.
Since null
is at the bottom of the class hierarchy, it is possible to write methods specialized to parameters of class null
which will only be applicable if the argument is the object nil
. No other object is a subtype of null
.
Some traditional Lisp functions could be expressed using the object system like this.
Suppose that the car
function did not have a safe defaulting behavior for nil
. We could use the methods of the object system to define a car*
which does have the safe behavior:
(defmethod car* ((arg cons))
(car arg))
(defmethod car* ((arg null))
nil)
Now if we invoke car*
on something which is neither a cons, nor nil
, we get an error about no applicable method being found.
We can handle that ourselves by writing a method specialized to the master supertype t
:
(defmethod car* ((arg t)) ;; can just be written (defmethod car* (arg) ...)
(error "CAR*: ~s is neither a cons nor nil" arg))
The classes t
and null
are widely exploited in Lisp OO programming.
Component Pascal
MODULE ObjectNil;
IMPORT StdLog;
TYPE
Object = POINTER TO ObjectDesc;
ObjectDesc = RECORD
END;
VAR
x: Object; (* default initialization to NIL *)
PROCEDURE DoIt*;
BEGIN
IF x = NIL THEN
StdLog.String("x is NIL");StdLog.Ln
END
END DoIt;
END ObjectNil.
Crystal
In Crystal, nil is represented by an instance of the Nil type, accessed by the identifier nil
. A variable can only become nil if Nil is one of its possible types. All objects inheriting from the base Object class implement the method .nil?
which returns true if the object is nil and false if it isn't. The equality and case equality operators can also be used to check for nil. The compiler returns an error if an object may be nil but is not treated as such. This can be suppressed with the .not_nil!
method, which throws an exception at runtime if the object is in fact nil.
foo : Int32 | Nil = 5 # this variable's type can be Int32 or Nil
bar : Int32? = nil # equivalent type to above, but shorter syntax
baz : Int32 = 5 # this variable can never be nil
foo.not_nil! # nothing happens, since 5 is not nil
puts "Is foo nil? #{foo.nil?}"
foo = nil
puts "Now is foo nil? #{foo.nil?}"
puts "Does bar equal nil? #{bar == nil}"
puts "Is bar equivalent to nil? #{bar === nil}"
bar.not_nil! # bar is nil, so an exception is thrown
- Output:
Is foo nil? false Now is foo nil? true Does bar equal nil? true Is bar equivalent to nil? true Unhandled exception: Nil assertion failed (NilAssertionError) ...
D
In D is is used to perform bitwise identity, like to compare an object reference against null.
import std.stdio;
class K {}
void main() {
K k;
if (k is null)
writeln("k is null");
k = new K;
if (k !is null)
writeln("Now k is not null");
}
- Output:
k is null Now k is not null
Delphi
// the following are equivalent
if lObject = nil then
...
if not Assigned(lObject) then
...
DWScript
See Delphi
Dyalect
Dyalect has a notion of nil
- a special sigleton value which can be used in the cases when no other meaningful value can be provided.
var x = nil
if x == nil {
//Do something
}
Déjà Vu
There isn't an actual null object, so generally falsy objects are used to indicate a missing value, or when that's impractical a specific ident:
if not obj:
pass #obj is seen as null
if = :nil obj:
pass #obj is seen as null
E
object == null
EchoLisp
The null object - null - is the same as the empty list (). It may be tested with the null? or !null? predicates. NB : null is not the same as the boolean #f (false). null evaluates to #t (true) in logical operations.
null → null
() → null
(null? 3) → #f
(!null? 4) → #t
(null? null) → #t
;; careful - null is not false :
(if null 'OUI 'NON) → OUI
;; usual usage : recursion on lists until (null? list)
(define (f list)
(when (!null? list)
(write (first list)) (f (rest list))))
(f '( a b c)) → a b c
Ecstasy
In Ecstasy, everything is an object, including the Null value. Null is the only value in the Nullable enumeration defined in the "ecstasy" core module. As a regular old object, the Null value has a regular old class, a regular old type, and it implements regular old methods such as toString() . There are, however, a few specific ways in the language (both the compiler and runtime) that Null is treated specially:
- Syntax support: A type union with Nullable can be indicated with the postfix "?"; for example, the long-hand type union syntax Nullable|String s can be replaced using the short-hand notation String? s .
- Syntax support: The postfix "?" operator is a short-circuiting null value test, allowing a cascading sequence of null tests to replace a series of nested if statements; for example, Int x = a?.b()?.c?[i?].d? : e; will result in the value of e if any of the expressions a , a.b() , a.b().c , i , or a.b().c[i].d are Null .
- Syntax support: The expression x ?: y will use the value y iff x is Null , and the corresponding assignment statement x ?:= y will assign y to x iff x is Null .
- Syntax support: The assignment statement x ?= y will assign y to x iff y is not Null .
- The assignment operator ?= also yields a Boolean value indicating the non-null-ness the right hand side value, which can be used in an if condition, while condition, etc.; for example, if (x ?= y) ... will take the "then" branch if y is non-null and therefore x is definitely assigned, otherwise it will take the "else" branch and x will not be definitely assigned.
- Null values are treated specially by equality comparisons: Normally, the compiler prevents two references of different compile-time types from being compared (such as Int and String ), but an explicit exception is made that allows a nullable type to be compared with a non-nullable type (such as String? and String ).
Other than these specific compiler and runtime features, Null is treated exactly like every other object.
module NullObject {
void run() {
@Inject Console console;
console.print($"Null value={Null}, Null.toString()={Null.toString()}");
// String s = Null; // <-- compiler error: cannot assign Null to a String type
String? s = Null; // "String?" is shorthand for the union "Nullable|String"
String s2 = "test";
console.print($"{s=}, {s2=}, {s==s2=}");
// Int len = s.size; // <-- compiler error: String? does not have a "size" property
Int len = s?.size : 0;
console.print($"{len=}");
if (String test ?= s) {
// "s" is still Null in this test, we never get here
} else {
s = "a non-null value";
}
// if (String test ?= s){} // <-- compiler error: The expression type is not nullable
s2 = s; // at this point, s is known to be a non-null String
console.print($"{s=}, {s2=}, {s==s2=}");
}
}
- Output:
Null value=Null, Null.toString()=Null s=Null, s2=test, s==s2=False len=0 s=a non-null value, s2=a non-null value, s==s2=True
Eiffel
Any reference type variable can be Void. In the following example, STRING is a reference type, while INTEGER is an expanded type. The keyword "detachable" (as opposed to "attached") is used to indicate that the variable "s" may be Void. The default interpretation when neither of these two keywords is used depends on a compiler option. The first if statement will cause a compiler warning because an expanded type variable such as i will never be Void.
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
local
i: INTEGER
s: detachable STRING
do
if i = Void then
print("i = Void")
end
if s = Void then
print("s = Void")
end
end
end
- Output:
s = Void
Elixir
nil
is atom in fact:
iex(1)> nil == :nil
true
iex(2)> is_nil(nil)
true
nil
is thought of as being false
in the conditional expression.
If the condition given to if/2
returns false
or nil
, the body given between do
/end
is not executed and it simply returns nil
.
iex(3)> if nil, do: "not execute"
nil
EMal
^|
| EMal has the Variable type (and its keyword var) that is the nullable universal supertype.
| EMal has the Void type (and its keyword void) that holds only one value: null.
| EMal has not nullable types (logic, int, real, text, blob), but null equality is always allowed.
|^
var a # defaults to null
int b # defaults to 0
void c # only one allowed value: null
writeLine("nullable var equals to not nullable int: " + (a == b)) # allowed, false
^| if the data type of a is void we are sure that a is null |^
writeLine("type of a equals to Void data type: " + (generic!a == void)) # true
writeLine("integer value " + b + " equals to null: " + (b == null)) # allowed, always false
writeLine("a void value equals to null: " + (c == null)) # always true
- Output:
nullable var equals to not nullable int: ⊥ type of a equals to Void data type: ⊤ integer value 0 equals to null: ⊥ a void value equals to null: ⊤
Erlang
Erlang does not have an null object.
As an alternative, many applications tend to pick a convention for returning an empty condition and use that.
Example alternatives:
- Something like
{ok, 3} % normal case
or{err, no_more} % error case
on error. - Don't ever allow an undefined return value, and throw an exception instead.
- Return an atom:
- undefined*
- undef
- null
- nil
- none
undefined is often used by records as an initial value and the stdlib module.
Atoms are erlang's user-defined constants that always evaluates to is itself. It is also equal to no other value else but itself.
F#
As a .Net languages F# inherits the null as a potential value for object variables. Other than in interfacing assemblies written in other .Net languages, null rarely serves a purpose in F# code. Contrived code, to show using null, as per task description:
let sl : string list = [null; "abc"]
let f s =
match s with
| null -> "It is null!"
| _ -> "It's non-null: " + s
for s in sl do printfn "%s" (f s)
Factor
: is-f? ( obj -- ? ) f = ;
Fantom
Test for equality with 'null', which is the null value.
fansh> x := null
fansh> x == null
true
fansh> x = 1
1
fansh> x == null
false
Note, nullable objects have a type ending in a question mark, for example:
Int? y := null
is valid, but
Int y := null
is not.
Forth
Standard ANS Forth does not distinguish a particular invalid memory value like NULL. Instead, ALLOCATE returns an out-of-band success code to indicate a failed allocation. Dictionary words have the option of throwing an exception on a dictionary space overrun. Forth lacks a NULL symbol because it has such a wide variety of target platforms. On some embedded targets, the memory space may be as small as 64 direct-mapped addresses, where eliminating a valid zero address would have a high price.
In practice, all notable hosted implementations follow the C practice of being able to treat a zero address (i.e. FALSE) as a null address for the purpose of list termination.
FreeBASIC
'FB 1.05.0 Win64
' FreeBASIC does not have a NULL keyword but it's possible to create one using a macro
#Define NULL CPtr(Any Ptr, 0) '' Any Ptr is implicitly convertible to pointers of other types
Type Dog
name As String
age As Integer
End Type
Dim d As Dog Ptr = New Dog
d->Name = "Rover"
d->Age = 5
Print d->Name, d->Age
Delete d
d = NULL '' guard against 'd' being used accidentally in future
' in practice many FB developers would simply have written: d = 0 above
Sleep
- Output:
Rover 5
FutureBasic
While objects such as strings can be NULL in FB, arrays, dictionaries and other collections cannot contain NULL objects.
// Object dimensioned, but not assigned
CFStringRef object
if ( object == NULL )
print "object is NULL"
end if
HandleEvents
- Output:
object is NULL
GDScript
Godot has a null value. Here is an example of dealing with null.
extends Node2D
func _ready() -> void:
var empty : Object
var not_empty = Object.new()
# Compare with null.
if empty == null:
print("empty is null")
else:
print("empty is not null")
# C-like comparation.
if not_empty:
print("not_empty is not null")
else:
print("not_empty is null")
return
- Output:
empty is null not_empty is not null
Go
Nil is a predefined identifier, defined for six types in Go. In each case, it represents the zero value for the type, that is, the memory representation of all zero bytes. This is the value of a newly created object. In the cases of these six types, an object must be subsequently initialized in some way before it has much use. Examples of initialization are given in the Go solution of task Undefined values.
package main
import "fmt"
var (
s []int // slice type
p *int // pointer type
f func() // function type
i interface{} // interface type
m map[int]int // map type
c chan int // channel type
)
func main() {
fmt.Println(s == nil)
fmt.Println(p == nil)
fmt.Println(f == nil)
fmt.Println(i == nil)
fmt.Println(m == nil)
fmt.Println(c == nil)
}
Output is "true" in each case.
Haskell
Haskell does not have a universal null value. There is a 'value of every type', the undefined value (sometimes written ⊥, 'bottom'), but it is essentially a sort of exception — any attempt to use it is an error.
undefined -- undefined value provided by the standard library
error "oops" -- another undefined value
head [] -- undefined, you can't take the head of an empty list
When one would use "null" as a marker for "there is no normal value here" (e.g. a field which is either an integer or null), one uses the Maybe type instead. The definition of Maybe is:
data Maybe a = Nothing | Just a
That is, a Maybe Integer is either Nothing or Just <some integer>.
There are many ways to work with Maybe, but here's a basic case expression:
case thing of
Nothing -> "It's Nothing. Or null, whatever."
Just v -> "It's not Nothing; it is " ++ show v ++ "."
It is easy to work with Maybe type using do-notation (since Maybe is a monad):
add_two_maybe_numbers x y do
a <- x
b <- y
return (a+b)
Then
*Main> add_two_maybe_numbers (Just 2) (Just 3)
Just 5
*Main> add_two_maybe_numbers (Just 2) Nothing
Nothing
Icon and Unicon
Icon/Unicon have a null value/datatype. It isn't possible to undefine a variable.
Io
if(object == nil, "object is nil" println)
J
J doesn't have an untyped NULL. Instead, it has a concept of "fill". Numeric fill is 0, character fill is the space character, and boxed fill is the ace (a:) which is an empty box. Fill is what is used to pad an array structure when that is needed. (And some operations support using a user specified value in place of the default fill.)
To indicate "missing data", "normal" data is usually pressed into service (e.g. 0 or _1 in a numeric context, ' ' in a literal context, a: in a boxed context, etc). Frequently, missing data is represented by the empty vector '', or other arrays without any elements.
That said, undefined names in J are not associated with any data of any type. Furthermore, any attempt to use the value of an undefined is treated as an error (this is distinct from the concept of an empty array, which contains no data but which is not an error to use). However, it is possible to check if a name is defined before attempting to use it:
isUndefined=: _1 = nc@boxxopen
Example use:
isUndefined 'foo'
1
foo=:9
isUndefined 'foo'
0
Note, of course, that this "name is not defined" state is not a first class value in J -- you can not create a list of "undefineds".
Finally, note: the concept of an empty array can be natural in J (and APL) for representing data which is not there -- it is the structural equivalent of the number zero. That said, its implications can sometimes be non-obvious for people coming from a languages which requires that arrays have content. As a result, you will sometimes encounter empty array jokes...
- Marie Pennysworth, having spent a productive day shopping, stopped by Robert Cuttingham's butcher shop.
- "How much for your t-bones?" she asked.
- "Eleven dollars per pound," he responded.
- "How about for your sirloin?" she continued.
- "Sirloin is thirteen dollars per pound today," he answered.
- "But Harkin's Grocery down the street is selling sirloin for nine dollars per pound!" she exclaimed.
- "So, why don't you buy it from them?" he asked.
- "Well, they're out," she sighed.
- He smiled, "When I am out, I only charge seven dollars a pound."
That said, note that a typical way to indicate missing or invalid data, in J, is to have a parallel array which is a bit mask (which selects the desired or valid values and, by implication, does not select the invalid values). Or, as a logical equivalent: a list of indices which select the desired and/or valid values. Alternatively, you can have an array without the invalid values and a bit mask which demonstrates how the data would be populated on a larger array -- in other words instead of 3,4,null,5 you could have (3 4 5) and (1 1 0 1). And you can transform between some of these representations:
1 1 0 1#3 4 _ 5 NB. use bitmask to select numbers
3 4 5
I.1 1 0 1 NB. get indices for bitmask
0 1 3
0 1 3 { 3 4 _ 5 NB. use indices to select numbers
3 4 5
1 1 0 1 #inv 3 4 5 NB. use bitmask to restore original positions
3 4 0 5
1 1 0 1 #!._ inv 3 4 5 NB. specify different fill element
3 4 _ 5
3 4 5 (0 1 3}) _ _ _ _ NB. use indices to restore original positions
3 4 _ 5
Java
In Java, "null" is a value of every reference type.
// here "object" is a reference
if (object == null) {
System.out.println("object is null");
}
JavaScript
In Javascript null is the value that isn't anything. null is not an object, but because of a bug typeof null will return "object".
if (object === null) {
alert("object is null");
// The object is nothing
}
typeof null === "object"; // This stands since the beginning of JavaScript
jq
jq has null as a value, but while on the subject of nothing, it may be worth mentioning that jq also has a filter, empty, for producing an empty sequence, a.k.a. nothing.
null is distinct from false. Here are some examples:
null|type # => "null"
null == false # => false
null == null # => true
empty|type # => # i.e. nothing (as in, nada)
empty == empty # => # niente
empty == "black hole" # => # Ничего
Jsish
Like Javascript, Jsish has undefined and null. Unlike Javascript, null is not typed as object, but null.
Jsish, with parameter typed functions, also allows void as a type spec, to indicate the parameter (of whatever type) may be omitted by a caller.
/* null non value */
if (thing == null) { puts("thing tests as null"); }
if (thing === undefined) { puts("thing strictly tests as undefined"); }
puts(typeof thing);
puts(typeof null);
puts(typeof undefined);
- Output:
prompt$ jsish nulling.jsi thing tests as null thing strictly tests as undefined undefined null undefined
Julia
See language reference: https://docs.julialang.org/en/v1/manual/faq/#Nothingness-and-missing-values
K
K has well developed notions of data null :
- The special numeric atoms 0I and 0N refer to integer infinity and “not-a-number” (or “null” in database parlance) concepts, and similarly 0i and 0n for floating-point.
eg : ( 1 2 3 0N 6 7 )
and and missing value nil :
- Empty expressions in both list expressions and function expressions actually represent a special atomic value called nil. ... A list may contain one or more empty items (i.e. the nil value _n), which are typically indicated by omission:
(1;;2) ~ (1 ; _n ; 2) / ~ is ''identical to'' or ''match'' .
1
_n ~' ( 1 ; ; 2 ) / ''match each''
0 1 0
additional properties : _n@i and _n?i are i; _n`v is _n
For more detail on K's concept of typed nulls, see http://code.kx.com/wiki/Reference/Datatypes#Primitive_Types
Klingphix
%t nan !t
$t nan == ?
- Output:
1
Kotlin
Kotlin distinguishes between non-nullable types and nullable types. The latter are distinguished from the former by a '?' suffix. Only nullable types have a 'null' value indicating that they don't currently refer to an object of their non-nullable equivalent.
In addition, Kotlin has a Nothing type which has no instances and is a sub-type of every other type. There is also a nullable Nothing? type whose only value is 'null' and so, technically, this is the type of 'null' itself.
Here are some examples:
// version 1.1.0
fun main(args: Array<String>) {
val i: Int = 3 // non-nullable Int type - can't be assigned null
println(i)
val j: Int? = null // nullable Int type - can be assigned null
println(j)
println(null is Nothing?) // test that null is indeed of type Nothing?
}
- Output:
3 null true
langur
Null can be compared for directly, using equality operators. Operators ending with a ? mark propagate null. A null in an expression test is a non-truthy result.
val .x, .y = true, null
writeln .x == null
writeln .y == null
writeln .x ==? null
writeln .y ==? null
# null not a "truthy" result
writeln if(null: 0; 1)
- Output:
false true null null 1
Lasso
local(x = string, y = null)
#x->isA(::null)
// 0 (false)
#y->isA(::null)
// 1 (true)
#x == null
// false
#y == null
//true
#x->type == 'null'
// false
#y->type == 'null'
//true
Latitude
Nil is an object in Latitude, like any other.
foo := Nil.
if { foo nil?. } then {
putln: "Foo is nil".
} else {
putln: "Foo is not nil".
}.
In particular, Nil satisfies the Collection mixin, so it can be treated as an (immutable) collection.
Nil to (Array). ;; []
Nil is the default value returned if a method body is empty.
func := {}.
func. ;; Nil
Lily
Lily doesn't provide a built-in nothing type, but allows one to be created using enum class:
enum class Option[A] {
Some(A)
None
}
# Only variables of class Option can be assigned to None.
# Type: Option[integer]
var v = Some(10)
# Valid: v is an Option, and any Option can be assigned to None
v = None
# Invalid! v is an Option[integer], not just a plain integer.
v = 10
# Type: integer
var w = 10
# Invalid! Likewise, w is an integer, not an Option.
w = None
Lingo
Null/nil is called "<Void>" in Lingo. Lingo doesn't distinguish undefined variables from <Void> objects, and by using the constant VOID you can even assign <Void> to variables. Functions that don't return anything, return <Void>. Checking for <Void> (e.g. by using built-in function voidP) can be used to implement optional function arguments: if voidP() returns TRUE (1) for some argument, a default value can be assigned in the function body.
put _global.doesNotExist
-- <Void>
put voidP(_global.doesNotExist)
-- 1
x = VOID
put x
-- <Void>
put voidP(x)
-- 1
Logo
to test :thing
if empty? :thing [print [list or word is empty]]
end
print empty? [] ; true
print empty? "|| ; true
Lua
isnil = (object == nil)
print(isnil)
M2000 Interpreter
For Com Objects
There is a Nothing to assign to a COM object to released (but time to actually released depends from system). A com pointer can't get another value (only the first value, and the Nothing at the end).
Module CheckWord {
Declare Alfa "WORD.APPLICATION"
Declare Alfa Nothing
Print Type$(Alfa)="Nothing"
Try ok {
Declare Alfa "WORD.APPLICATION"
\\ we can't declare again Alfa
}
If Not Ok Then Print Error$ ' return Bad Object declaration
}
CheckWord
For Containers
Container's pointers (for arrays, inventories, stack) we have to assign an empty container, there is not a null one.
Module CheckContainers {
\\ Arrays (A() and B() are value types)
Dim A(10)=1, B()
\\ B() get a copy of A(), is not a reference type
B()=A()
\\ we make a pointer to Array
B=A()
\\ now B is a reference type object
Print Len(B)=10 ' ten items
B+=10
Print A(3)=11, A(7)=11
\\ we can change pointer using a pointer to an empty array
B=(,)
\\ we can erase A() and B()
Dim A(0), B(0)
Print Len(A())=0, Len(B())=0
Print Len(B)=0
B=(123,)
\\ B() is a value type so get a copy
B()=B
Print Len(B)=1, B(0)=123
\\ Using Clear we pass a new empty array
Clear B
Print Type$(B)="mArray"
Print Len(B)=1, B(0)=123
\\ Inventrories. Keys must be unique (for normal inventories)
Inventory M=1,2,3,4:=400,5
Print M
Clear M
Inventory M=1,2,3,4,5
Print M
\\ Inventory Queue can have same keys.
Inventory Queue N=1,1,2:="old",2:="ok",3
If Exist(N,2) Then Print Eval$(N)="ok", Eval(N!)=3 ' 4th item
Clear N
Print Len(N)=0, Type$(N)="Inventory"
\\ Stack Object
Z=Stack:=1,2,3
Stack Z {
While not empty {Print Number}
}
Print Len(Z)=0
Z=Stack((Stack:=1,2,3,4),Stack:=20,30,40 )
Print Len(Z)=7
Print Z ' 1 2 3 4 20 30 49
Z=Stack ' This is an empty stacl
Print Len(Z)=0
Print Type$(Z)="mStiva"
}
CheckContainers
For Groups
Groups are value types, but we can make reference to them,or pointer to them
A Named referenced can't get a new reference
A pointer to a named group is actual a reference, and can change type and reference
A pointer to a copy of group (as float group) is actually a pointer to group.
Pointers to groups can be point to an Null Group, assigning a 0& value (a long type)
class something {
}
class alfa as something {
x=10, y=20
}
a->alfa()
Print a is type alfa = true
Print a is type something = true
a->0&
Print a is type null = true
\\ beta is a named object, is static
group beta {
type: something, alfa
x=10, y=20
}
Print beta is type alfa = true
Print beta is type something = true
\\ now a is a pointer as a weak reference to beta
a->beta
print a is type alfa = true
print a is type something = true
a=pointer() ' same as a->0&
Print a is type null = true
\\ now a is a pointer of a copy of beta
a->(beta)
print a is type alfa = true
print a is type something = true
a=pointer() ' same as a->0&
Print a is type null = true
Maple
In Maple, NULL and () represent the null object.
a := NULL;
a :=
is (NULL = ());
true
if a = NULL then
print (NULL);
end if;
A null object is different from an undefined value.
b := Array([1, 2, 3, Integer(undefined), 5]);
b := [ 1 2 3 undefined 5 ]
numelems(b);
5
b := Array([1, 2, 3, Float(undefined), 5]);
b := [ 1 2 3 Float(undefined) 5 ]
numelems(b);
5
b := Array([1, 2, 3, NULL, 5]);
b := [ 1 2 3 5 ]
numelems(b);
4
Mathematica/Wolfram Language
Mathematica can assign a Null value to a symbol, two examples:
x=Null;
x =.
x = (1 + 2;)
FullForm[x]
Both set x to be Null. To specifically test is something is Null one can use the SameQ function (with infix operator: ===):
SameQ[x,Null]
Or equivalent:
x===Null
will give back True if and only if x is assigned to be Null. If x is empty (nothing assigned) this will return False. To test if an object has something assigned (number, list, graphics, null, infinity, symbol, equation, pattern, whatever) one uses ValueQ:
x =.;
ValueQ[x]
x = 3;
ValueQ[x]
gives:
False
True
MATLAB / Octave
The closest think to a NULL element in Matlab/Octave is an empty field or empty string; empty fields in a conditional expression evaluate to false.
a = []; b='';
isempty(a)
isempty(b)
if (a)
1,
else,
0
end;
octave:4> a = []; b=''; octave:5> isempty(a) ans = 1 octave:6> isempty(b) ans = 1 octave:7> if (a) 1, else, 0, end; ans = 0
Maxima
There is no null object in Maxima. Usually, a function that returns nothing (as the builtin "disp") returns in fact the symbol 'done.
MAXScript
if obj == undefined then print "Obj is undefined"
min
null null? puts!
- Output:
true
Modula-3
In Modula-3, NIL
is a value, and NULL
is a type. The NULL
type contains only one value, NIL
. NULL
is a subtype of all reference types, which allows all reference types to have the value NIL
.
This can lead to errors, if for example you write:
VAR foo := NIL
This (most likely incorrectly) gives foo the type NULL
, which can only have the value NIL
, so trying to assign it anything else will not work. To overcome this problem, you must specify the reference type when declaring foo:
VAR foo: REF INTEGER := NIL;
IF foo = NIL THEN
IO.Put("Object is nil.\n");
END;
MUMPS
A variable can be declared implicitly by using it as on the left side in a SET, or by making a new version for the current scope with a NEW statement. A variable can have descendants without having a value set.
The $DATA (or $D) function will return a number:
$DATA returns: | Variable is defined | ||
---|---|---|---|
Variable has children | No | Yes | |
No | 0 | 1 | |
Yes | 10 | 11 |
Or, by examples (in immediate mode):
CACHE>WRITE $DATA(VARI)
0
CACHE>SET VARI="HELLO" WRITE $DATA(VARI)
1
CACHE>NEW VARI WRITE $DATA(VARI) ;Change to a new scope
0
CACHE 1S1>SET VARI(1,2)="DOWN" WRITE $DATA(VARI)
10
CACHE 1S1>WRITE $DATA(VARI(1))
10
CACHE 1S1>WRITE $D(VARI(1,2))
1
CACHE 1S1>SET VARI(1)="UP" WRITE $DATA(VARI(1))
11
<CACHE 1S1>QUIT ;Leave the scope
<CACHE>W $DATA(VARI)," ",VARI
1 HELLO
Nanoquery
$x = $null
if ($x = $null)
println "x is null"
else
println "x is not null"
end if
Neko
/**
<doc>
<p>Neko uses <i>null</i> for undefined variables,
and also as a programmer accessible value.</p>
<p>The <i>null</i> value can be treated as a boolean value with the
builtin $istrue, and tests as false.</p>
</doc>
*/
var n = null
if n == null $print("n is null\n")
if $not($istrue(n)) $print("and tests as boolean false\n")
NetRexx
In NetRexx as in Java, "null" is a value of every reference type.
/* NetRexx */
options replace format comments java crossref symbols binary
robject = Rexx -- create an object for which the value is undefined
say String.valueOf(robject) -- will report the text "null"
if robject = null then say 'Really, it''s "null"!'
Output:
null Really, it's "null"!
NewLISP
#! /usr/local/bin/newlisp
(setq myobject nil)
(println (nil? myobject))
(exit)
true
Nim
There is a nil
value in Nim, which is the same as a 0. It can be explicitly forbidden as a value:
let s: pointer = nil
{.experimental: "notnil".}
let ns: pointer not nil = nil # Compile time error
The value "nil" can be used for pointers, references (i.e. pointers managed by the garbage collector) and procedures. It was also used for strings and sequences, but this is no longer the case (option --nilseqs:on
allows to retrieve the old behavior).
Testing if a pointer “p” is nil
can be done either by using ==
or using the procedure isNil
.
var p: ptr int
if p == nil: echo "it is nil"
if p != nil: echo "it is not nil"
if p.isNil: echo "it is nil"
Oberon-2
MODULE Null;
IMPORT
Out;
TYPE
Object = POINTER TO ObjectDesc;
ObjectDesc = RECORD
END;
VAR
o: Object; (* default initialization to NIL *)
BEGIN
IF o = NIL THEN Out.String("o is NIL"); Out.Ln END
END Null.
- Output:
o is NIL
Objeck
In Objeck, "Nil" is a value of every reference type.
# here "object" is a reference
if(object = Nil) {
"object is null"->PrintLine();
};
Objective-C
The value nil
is used to indicate that an object pointer (variable of type id
) doesn't point to a valid object.
// here "object" is an object pointer
if (object == nil) {
NSLog("object is nil");
}
An interesting thing is that in Objective-C, it is possible to send a message to nil
, and the program will not crash or raise an exception (nothing will be executed and nil
will be returned in place of the usual return value).
[nil fooBar];
Note that nil
is distinct from NULL
, which is only used for regular C pointers.
For class pointers (values of type Class
), they have a separate null pointer value called Nil
.
Confusingly, there is also NSNull
, a singleton class with one value, [NSNull null]
, used as a dummy object to represent the lack of a useful object. This is needed in collections like arrays and dictionaries, etc., because they do not allow nil
elements, so if you want to represent some "empty" slots in the array you would use this.
OCaml
Maybe the closest type of OCaml would be the type option, which is defined like this in the standard library:
type 'a option = None | Some of 'a
match v with
| None -> "unbound value"
| Some _ -> "bounded value"
Oforth
null is an object, the only instance of Null class. When an object is created, all attributes are initiallized to null value. When a method or function is called, all local variables begin with null value.
null isNull
"abcd" isNull
: testNull { | a | a ifNull: [ "Variable value is null" println ] ;
Ol
Ol has no null object in task meaning sense. To indicate the "unassigned" variable state typically used #false because this is only value that triggers the 'unless' and 'if not'.
The builtin null and #null (that a same) means "an empty list". Important note: in contrast with CL the null means #true in 'if' statement!
ooRexx
ooRexx has a special singleton object called .nil that is used to indicate the absence of values in some situations (such as the default values returned from collection objects).
if a[i] == .nil then say "Item" i "is missing"
Uninitialized ooRexx variables do not evaluate to .nil, but rather the character string name of the variable (all uppercase). The var() built-in function allows variable validity to be tested:
a=.array~of('A','B')
i=3
if a[i] == .nil then say "Item" i "of array A is missing"
if \var("INPUT") then say "Variable INPUT is not assigned"
if \var("var") then say "Variable" var "is not assigned"
Output:
Item 3 of array A is missing Variable INPUT is not assigned Variable VAR is not assigned
Oz
There is no explicit null in Oz.
Unbound variables
If an unbound variable is accessed, the current thread will be suspended:
declare
X
in
{Show X+2} %% blocks
If you later assign a value to X in another thread, the original thread will resume and print the result of the addition. This is the basic building block of Oz' declarative concurrency.
Undefined values
Access to undefined values (like using an out-of-range array index or a non-existing record feature) will usually provoke an exception in Oz.
It is also possible to assign a unique "failed" value to a variable. Such a failed value encapsulates an exception. This can be useful in concurrent programming to propagate exceptions across thread boundaries.
declare
X = {Value.failed dontTouchMe}
in
{Wait X} %% throws dontTouchMe
Sometimes algebraic data types like Haskell's Maybe are simulated using records.
declare
X = just("Data")
in
case X of nothing then skip
[] just(Result) then {Show Result}
end
PARI/GP
GP does not have good facilities for this, but this test suffices for most purposes:
foo!='foo
Pascal
See Delphi
Perl
In Perl, undef
is a special scalar value, kind of like null in other languages. A scalar variable that has been declared but has not been assigned a value will be initialized to undef
. (Array and hash variables are initialized to empty arrays or hashes.)
If strict
mode is not on, you may start using a variable without declaring it; it will "spring" into existence, with value undef
. In strict
mode, you must declare a variable before using it. Indexing an array or hash with an index or key that does not exist, will return undef
(however, this is not an indication that the index or key does not exist; rather, it could be that it does exist, and the value is undef
itself). If warnings
is on, most of the time, if you use the undef
value in a calculation, it will produce a warning. undef
is considered false in boolean contexts.
It is possible to use undef
like most other scalar values: you can assign it to a variable (either by doing $var = undef;
or undef($var);
), return it from a function, assign it to an array element, assign it to a hash element, etc. When you do list assignment (i.e. assign a list to a list of variables on the left side), you can use undef
to "skip" over some elements of the list that you don't want to keep.
You can check to see if a value is undef
by using the defined
operator:
print defined($x) ? 'Defined' : 'Undefined', ".\n";
From the above discussion, it should be clear that if defined
returns false, it does not mean that the variable has not been set; rather, it could be that it was explicitly set to undef
.
Starting in Perl 5.10, there is also a defined-or operator in Perl. For example:
say $number // "unknown";
prints $number if it is defined (even if it is false) or the string "unknown" otherwise.
Phix
There is a builtin NULL, however it is equivalent to the integer 0 and will trigger a type check if assigned to a variable declared as string or sequence. In most programs the zero-length string/sequence (""/{}) suffices, but if you want a variable that can be a string/sequence or NULL, but not other arbitrary integer/float values, use something like the following user-defined types:
type nullableString(object o) return string(o) or o=NULL end type nullableString s s = "hello" s = NULL --s = 1 -- error --s = {1,2,3} -- error type nullableSequence(object o) return sequence(o) or o=NULL end type nullableSequence q q = {1,2,3} q = "string" -- fine (strings are a subset of sequences) q = NULL --q = 1 -- error
See also Undefined_values
PHL
if (obj == null) printf("obj is null!\n");
PHP
There is a special value NULL. You can test for it using is_null() or !isset()
$x = NULL;
if (is_null($x))
echo "\$x is null\n";
PicoLisp
New internal symbols are initialized with the value NIL. NIL is also the value for "false", so there is never really an "undefined value". 'not' is the predicate to check for NIL, but many other (typically flow control) functions can be used.
(if (not MyNewVariable)
(handle value-is-NIL) )
or
(unless MyNewVariable
(handle value-is-NIL) )
Pike
In Pike all variables are initialized to , regardless of their type. thus functions as a Null
value for all types except integer.
is also used to indicate the absence of a key or object member.
to tell the difference between a value and absence of a key, zero_type()
is used:
> mapping bar;
> bar;
Result: 0
> bar = ([ "foo":0 ]);
> bar->foo;
Result 0;
> zero_type(bar->foo);
Result: 0
> bar->baz;
Result: 0
> zero_type(bar->baz);
Result: 1
PL/I
declare x fixed decimal (10);
...
if ^valid(x) then signal error;
declare y picture 'A9XAAA9';
...
if ^valid(y) then signal error;
Comment:- In the picture specification, the content of variable y must consist of letters where the letter 'A' is given, digits or space where the digit '9' appears, and the letter X signfies that any character is acceptable.
PowerShell
In PowerShell the automatic variable $null
represents a null value. Comparisons are not left/right symmetrical which means placing $null
on the left side greatly assists when comparing to an array.
if ($null -eq $object) {
...
}
PureBasic
All variables that has not yet been given any other value will be initiated to #Null
If variable = #Null
Debug "Variable has no value"
EndIf
Python
x = None
if x is None:
print "x is None"
else:
print "x is not None"
Output:
x is None
R
R has the special value NULL to represent a null object. You can test for it using the function is.null. Note that R also has a special value NA to represent missing or unknown values.
is.null(NULL) # TRUE
is.null(123) # FALSE
is.null(NA) # FALSE
123==NULL # Empty logical value, with a warning
foo <- function(){} # function that does nothing
foo() # returns NULL
Racket
"null", or its literal form "'()", is used to denote empty lists and sometimes it is used as a generic null value.
-> null
'()
-> (null? null)
#t
-> (null? 3)
#f
But a value that is more used as a generic "nothing" value is "#f", false. Racket also has a void value, mostly the result of side-effect functions. (And an undefined value.)
Raku
(formerly Perl 6)
(as it were...)
In Raku you can name the concept of Nil, but it not considered an object, but rather the absence of an object, more of a "bottom" type. The closest analog in real objects is an empty list, but an empty list is considered defined, while Nil.defined always returns false. Nil is what you get if you try to read off the end of a list, and () is just very easy to read off the end of... :-)
If you try to put Nil into a container, you don't end up with a container that has Nil in it. Instead the container reverts to an uninitialized state that is consistent with the declared type. Hence, Raku has the notion of typed undefined values, that are real objects in the sense of "being there", but are generic in the sense of representing type information without being instantiated as a real object. We call these type objects since they can stand in for real objects when one reasons about the types of objects. So type objects fit into the type hierarchy just as normal objects do. In physics terms, think of them as "type charge carriers" that are there for bookkeeping between the "real" particles.
All type objects derive from Mu, the most-undefined type object, and the object most like "null" in many languages. All other object types derive from Mu, so it is like Object in other languages as well, except Mu also encompasses various objects that are not discrete, such as junctions. So Raku distinguishes Mu from Any, which is the type that functions the most like a discrete, mundane object.
Mostly the user doesn't have to think about it. All object containers behave like "Maybe" types in Haskell terms; they may either hold a valid value or a "nothing" of an appropriate type. Most containers default to an object of type Any so you don't accidentally send quantum superpositions (junctions) around in your program.
my $var;
say $var.WHAT; # Any()
$var = 42;
say $var.WHAT; # Int()
say $var.defined; # True
$var = Nil;
say $var.WHAT; # Any()
say $var.defined # False
You can declare a variable of type Mu if you wish to propagate superpositional types:
my Mu $junction;
say $junction.WHAT; # Mu()
$junction = 1 | 2 | 3;
say $junction.WHAT; # Junction()
Or you can declare a more restricted type than Any
my Str $str;
say $str.WHAT; # Str()
$str = "I am a string.";
say $str.WHAT; # Str()
$str = 42; # (fails)
But in the Raku view of reality, it's completely bogus to ask for a way "to see if an object is equivalent to the null object." The whole point of such a non-object object is that it doesn't exist, and can't participate in computations. If you think you mean the null object in Raku, you really mean some kind of generic object that is uninstantiated, and hence undefined. One of those is your "null object", except there are many of them, so you can't just check for equivalence. Use the defined predicate (or match on a subclass of your type that forces recognition of abstraction or definedness).
Raku also has Failure objects that, in addition to being undefined carriers of type, are also carriers of the reason for the value's undefinedness. We tend view them as lazily thrown exceptions, at least until you try to use them as defined values, in which case they're thrown for real.
Raven
NULL as $v
$v NULL = # TRUE
$v NULL != # FALSE
1 NULL = # FALSE
1.1 NULL = # FALSE
NULL as $v2
$v2 $v = # TRUE
REBOL
x: none
print ["x" either none? x ["is"]["isn't"] "none."]
Output:
x is none.
REBOL also has the concept of unset
values, testable with get/any
unset? get/any 'some-var
unset? get 'some-var
- Output:
true ** Script Error: some-var has no value ** Near: unset? get 'some-var
REXX
REXX can have variables with a null value.
With the symbol built-in function, it can be determined if a variable is defined (or not).
The length built-in function can be used to see what the length of the value of a defined variable.
A variable with a null value has a length of 0 (zero).
The drop statement can be used to "undefine" a REXX variable.
/*REXX program demonstrates null strings, and also undefined values. */
if symbol('ABC')=="VAR" then say 'variable ABC is defined, value='abc"<<<"
else say "variable ABC isn't defined."
xyz=47
if symbol('XYZ')=="VAR" then say 'variable XYZ is defined, value='xyz"<<<"
else say "variable XYZ isn't defined."
drop xyz
if symbol('XYZ')=="VAR" then say 'variable XYZ is defined, value='xyz"<<<"
else say "variable XYZ isn't defined."
cat=''
if symbol('CAT')=="VAR" then say 'variable CAT is defined, value='cat"<<<"
else say "variable CAT isn't defined."
output
variable ABC isn't defined. variable XYZ is defined, value=47<<< variable XYZ isn't defined. variable CAT is defined, value=<<<
Ring
see isnull(5) + nl + # print 0
isnull("hello") + nl + # print 0
isnull([1,3,5]) + nl + # print 0
isnull("") + nl + # print 1
isnull("NULL") # print 1
Ruby
The value when referring to the instance variable which isn't initialized is nil.
puts "@object is nil" if @object.nil? # instance variable
puts "$object is nil" if $object.nil? # global variable, too
# It recognizes as the local variable even if it isn't executed.
object = 1 if false
puts "object is nil" if object.nil?
# nil itself is an object:
puts nil.class # => NilClass
- Output:
@object is nil $object is nil object is nil NilClass
Rust
// If an option may return null - or nothing - in Rust, it's wrapped
// in an Optional which may return either the type of object specified
// in <> or None. We can check this using .is_some() and .is_none() on
// the Option.
fn check_number(num: &Option<u8>) {
if num.is_none() {
println!("Number is: None");
} else {
println!("Number is: {}", num.unwrap());
}
}
fn main() {
let mut possible_number: Option<u8> = None;
check_number(&possible_number);
possible_number = Some(31);
check_number(&possible_number);
}
S-lang
S-Lang uses NULL; it is the only object of type Null_Type:
variable foo = NULL;
print(foo);
if (foo == NULL)
print(typeof(foo));
- Output:
NULL Null_Type
Scala
This blog post has a good explanations of the different types of null-like values.
scala> Nil
res0: scala.collection.immutable.Nil.type = List()
scala> Nil == List()
res1: Boolean = true
scala> Null
<console>:8: error: not found: value Null
Null
^
scala> null
res3: Null = null
scala> None
res4: None.type = None
scala> Unit
res5: Unit.type = object scala.Unit
scala> val a = println()
a: Unit = ()
Scheme
(null? object)
Note: "null?" here tests whether a value is the empty list.
Sidef
The absence of a value is represented by nil
var undefined; # initialized with an implicit nil
say undefined==nil; # true
say defined(nil) # false
However, nil is not an object, so we can't call methods on it. Alternatively, Sidef provides the null object:
var null_obj = null; # initialize with a null value
say null_obj.is_a(null); # true
say defined(null_obj); # true
Slate
Nil isNil = True.
Smalltalk
object isNil ifTrue: [ "true block" ]
ifFalse: [ "false block" ].
nil isNil ifTrue: [ 'true!' displayNl ]. "output: true!"
foo isNil ifTrue: [ 'ouch' displayNl ].
x := (foo == nil).
x := foo isNil
notice that nil is the singleton instance of the UndefinedObject class; i.e. it is a first class object. Thus we can do:
foo := nil.
foo class. "-> UndefinedObject"
foo respondsTo: #'bar'. "asking if a message is implemented"
foo class compile:'fancyOperation ^ 123'.
foo fancyOperation "->123"
the last example being for demonstration only - it is not considered well behaved to add arbitrary code that way, except for framework support, such as encoding, decoding marshalling etc.)
Standard ML
Maybe the closest type of Standard ML would be the type option, which is defined like this in the standard library:
datatype 'a option = NONE | SOME of 'a
case v of NONE => "unbound value"
| SOME _ => "bounded value"
Swift
Swift has Optional<T>
type, where nil
means a lack of value.
T?
is syntactic sugar for Optional<T>
.
let maybeInt: Int? = nil
To just check if variable is nil, you can use ==
operator.
if maybeInt == nil {
print("variable is nil")
} else {
print("variable has some value")
}
Usually you want to access the value after checking if it's nil. To do that you use if let
if let certainlyInt = maybeInt {
print("variable has value \(certainlyInt)")
} else {
print("variable is nil")
}
Tailspin
Tailspin does not have a null value, but a transform is allowed to produce nothing at all, in which case that chain of computation simply stops. A templates transform can explicitly label cases as producing nothing by !VOID but also input values for which there is no matching branch will produce nothing. If you need computation to continue even in the event of nothing being produced, you can wrap the transform in an array/list to get an empty list.
templates mightBeNothing
when <=0> do !VOID
when <=1> do 'something' !
end mightBeNothing
1 -> mightBeNothing -> 'Produced $;. ' -> !OUT::write
0 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write
2 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write
// capture the transform in a list to continue computation when no result is emitted
[1 -> mightBeNothing] -> \(
when <=[]> 'Produced nothing. ' !
otherwise 'Produced $(1);. ' !
\) -> !OUT::write
[0 -> mightBeNothing] -> \(
when <=[]> 'Produced nothing. ' !
otherwise 'Produced $(1);. ' !
\) -> !OUT::write
[2 -> mightBeNothing] -> \(
when <=[]> 'Produced nothing. ' !
otherwise 'Produced $(1);. ' !
\) -> !OUT::write
- Output:
Produced something. Produced something. Produced nothing. Produced nothing.
It is an error to try to assign nothing to a symbol or field.
// throws an error
def nothing: 0 -> mightBeNothing;
// throws an error
{ nothing: 0 -> mightBeNothing }
// OK, simply results in the empty structure without a field called 'nothing'
{ 0 -> mightBeNothing -> (nothing: $) }
Tcl
In Tcl, where every value is a string, there is no out-of band value corresponding to NULL. In many cases, using the empty string is sufficient:
if {$value eq ""} ...
A stricter approximation to NULL can be had with non-existing variables or elements of a dict or array:
if {![info exist nullvar]} ...
if {![info exists arr(nullval)]} ...
if {![dict exists $dic nullval]} ...
Note that lists do not support anything like nulls, since they are strictly sequences of values.
TXR
TXR Lisp has a nil
symbol which serves as the empty list and Boolean false, like Common Lisp and similar dialects. It is a very important symbol which plays a central role.
Variable definitions, global and local, without initial value expressions take on the value nil
. Elements of newly created vectors and structure slots are nil
by default. Optional function parameters that don't receive arguments are given nil
arguments by default. Many functions which search for something use nil
for indicating not found.
Object-oriented programming in TXR Lisp is done with structures, which do not provide a CLOS-like object system. The nil
object isn't a structure, and so it cannot take slot references, or method invocation. Only structures have methods, which means that it's not possible to define a null object method m
such that obj.(m)
can be invoked if obj
is an expression evaluating to nil
.
The Gang-of-Five Null Object Pattern can be employed: defining struct types that behave like null. This null object doesn't have to be related by inheritance to the structs in conjunction with which it is used.
(defstruct null-widget ()
(:method popularity (me) 0))
(defvarl null-widget (new null-widget))
(defstruct real-widget ()
pop
(:method popularity (me) me.pop))
In situations when a null object would be used simply to provide safe treatment of null without the verbosity of checks for its presence, and a default value of nil
is acceptable, TXR Lisp has null-safe slot and method access: obj.?slot
, obj.?(method arg)
.
The expression w.?(popularity)
will evaluate to nil
if w
is nil
, being equivalent to (if w w.(popularity))
, except that w
is evaluated only once.
Like in Common Lisp, nil
an instance of the type null
, which is a unit type having only that instance. And nil
is also the name of the bottom type of the type system: the nil
type is the subtype of every type, including itself.
Like in Common Lisp, the expression (or a b c ...)
evaluates the arguments from left to right, returning the value of the leftmost one which does not evaluate to nil
.
;; Find widget in one of three places in order
(defun find-widget (name)
(or [%widget-hash% name]
(lookup-local-widget name)
(lookup-global-widget name)))
Ursa
# the type at declaration doesn't matter
decl int x
set x null
if (= x null)
out "x is null" endl console
else
out "x is not null" endl console
end if
VBA
Public Sub Main()
Dim c As VBA.Collection
' initial state: Nothing
Debug.Print c Is Nothing
' create an instance
Set c = New VBA.Collection
Debug.Print Not c Is Nothing
' release the instance
Set c = Nothing
Debug.Print c Is Nothing
End Sub
Visual Basic
Null by the definition of this task is called "Nothing" in VB6:
Public Sub Main()
Dim c As VBA.Collection
' initial state: Nothing
Debug.Assert c Is Nothing
' create an instance
Set c = New VBA.Collection
Debug.Assert Not c Is Nothing
' release the instance
Set c = Nothing
Debug.Assert c Is Nothing
End Sub
The Null keyword has a different meaning in VB6: it's one of the states that a Variant type variable can be in. Null means that a Variant doesn't hold valid (i.e.: defined) data.
Public Sub Main()
Dim v As Variant
' initial state: Empty
Debug.Assert IsEmpty(v)
Debug.Assert VarType(v) = vbEmpty
v = 1&
Debug.Assert VarType(v) = vbLong
' assigning the Null state
v = Null
' checking for Null state
Debug.Assert IsNull(v)
Debug.Assert VarType(v) = vbNull
End Sub
V (Vlang)
V (Vlang) does not have nor normally allow null or nil (also called "the billion dollar mistake"):
1) All primitive types/variables have default values.
2) For arrays and structs, default values are automatically assigned.
3) Usage of voidptr or nil, only done in unsafe, and is usually only for the purposes of interoperability with other languages.
// Null or nil not used, default values for various primitive types/variables instead:
a_string :=''
a_bool := false
an_int := 0
[3]string{} // ['', '', '']
[3]bool{} // [false, false, false]
[3]int{} // [0, 0, 0]
Wart
The null value nil
is also the only false value.
(not nil)
Wren
In Wren, it is not technically possible for a variable to have no value at all.
If you define a variable without giving it a value, then it is given the special value null which is the only instance of the Null class and also a keyword.
Similarly, if you define a function but don't give it a return value, then it returns null. In this particular respect, null is similar to void in C.
In boolean expressions, null is considered to be false whereas (apart from false itself) all other values (even 0) are considered to be true. For consistency the Null class therefore overrides the ! operator, which it inherits from the Object class, so that !null returns true.
It is always easy to test for nullness either by querying a variable's type or checking the value of a boolean expression involving a potentially null variable.
// Declare a variable without giving it an explicit value.
var s
// We can now check for nullness in one of these ways.
System.print(s)
System.print(s == null)
System.print(s is Null)
System.print(s.type == Null)
// Similarly, if we define this function without giving it a return value.
var f = Fn.new {
System.print("I'm a function with no explicit return value.")
}
// And now call it.
var g = f.call()
// We find that the return value is null.
System.print(g)
- Output:
null true true true I'm a function with no explicit return value. null
zkl
In zkl, there isn't a C like 0/NULL, a value that, if referenced, causes bad things to happen. There is an Object, Void, that is used as generic NULL like thing but it is just another object.
if(Void == n) ...
return(Void)
Z80 Assembly
Even though this doesn't really apply to assembly, as there is no "null pointer" per se (that is, all data is a number), it would be interesting to demystify what NULL
really is. At the lowest level, the null pointer is just a pointer to a memory location that is of no use to the programmer. The Z80 does not segfault, so any memory address we read is fair game. So without the hardware enforcing NULL
, we need to pick an address we don't mind losing. Typically, using &0000
to equal C's NULL
is acceptable, as address &0000
on any randomly chosen Z80-based hardware is typically a jump to the kernel's entry point (or the main program's entry point, depending on the implementation.)
ld a,(&0000) ;dereference the null pointer as a uint8
ld hl,(&0000) ;dereference the null pointer as a uint16
Typically, you would get 0xC3 when dereferencing as an 8-bit value and 0xC3nn when dereferencing as a 16-bit value, where nn is the low byte of the address of the aforementioned entry point. Neither of these are particularly useful, so having &0000
as the null pointer is perfectly fine. Although there are technically other options, most CPUs can compare with zero more efficiently than most other numbers, and the Z80 is no exception. Of course, the Z80 will not check if a pointer is NULL for you, so you have to do it yourself:
LD HL,myPointers
;there is no LD BC,(HL) so we have to do this:
LD c,(hl)
inc hl
LD b,(hl)
;and compare to null
LD a,b
or c ;compare BC to zero
JR z,isNull
- Programming Tasks
- Basic language learning
- Simple
- 11l
- 6502 Assembly
- 8th
- AArch64 Assembly
- Action!
- ActionScript
- Ada
- ALGOL 68
- ALGOL W
- AmigaE
- APL
- AppleScript
- ARM Assembly
- Arturo
- AutoHotkey
- AutoIt
- AWK
- Axe
- Babel
- BASIC
- Applesoft BASIC
- BBC BASIC
- GWBASIC/QBasic/QB/VBDOS
- Bracmat
- C
- C sharp
- C++
- Chapel
- Clojure
- COBOL
- Common Lisp
- Component Pascal
- Crystal
- D
- Delphi
- DWScript
- Dyalect
- Déjà Vu
- E
- EchoLisp
- Ecstasy
- Eiffel
- Elixir
- EMal
- Erlang
- F Sharp
- Factor
- Fantom
- Forth
- FreeBASIC
- FutureBasic
- GDScript
- Go
- Haskell
- Icon
- Unicon
- Io
- J
- Java
- JavaScript
- Jq
- Jsish
- Julia
- K
- Klingphix
- Kotlin
- Langur
- Lasso
- Latitude
- Lily
- Lingo
- Logo
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Maxima
- MAXScript
- Min
- Modula-3
- MUMPS
- Nanoquery
- Neko
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Objeck
- Objective-C
- OCaml
- Oforth
- Ol
- OoRexx
- Oz
- PARI/GP
- Pascal
- Perl
- Phix
- PHL
- PHP
- PicoLisp
- Pike
- PL/I
- PowerShell
- PureBasic
- Python
- R
- Racket
- Raku
- Raven
- Raven examples needing attention
- Examples needing attention
- REBOL
- REXX
- Ring
- Ruby
- Rust
- S-lang
- Scala
- Scheme
- Sidef
- Slate
- Smalltalk
- Standard ML
- Swift
- Tailspin
- Tcl
- TXR
- Ursa
- VBA
- Visual Basic
- V (Vlang)
- Wart
- Wren
- Zkl
- Z80 Assembly
- GUISS/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- 6502 Assembly/Omit
- 68000 Assembly/Omit
- 8080 Assembly/Omit
- 8086 Assembly/Omit
- MIPS Assembly/Omit
- X86 Assembly/Omit
- Z80 Assembly/Omit
- Pages with too many expensive parser function calls