Since I know JavaScript, some Ruby and a bit of Perl which all have the concept of undefined it was a decision I had to make whether I implement undefined in NGS. This article shows why I decided not to have the undefined value/data type.

Update (thanks /u/EldritchSundae): what you observe in Ruby example below is nil , not undefined . In bash the undefined value is empty string. Ruby does not have undefined but it has the ability to read non-existing hash keys without causing an exception like JavaScript and Perl. In Ruby’s case the result is nil , not undef (Perl) or undefined (JavaScript).



Undefined in other languages

Showing here few common cases, not all possible usages.

JavaScript

> nodejs -e 'const a; console.log(a)' undefined > nodejs -e 'const h={}; console.log(h["xyz"])' undefined > nodejs -e '(function f(a,b) { console.log(a,b) })(1)' 1 undefined

Ruby

> ruby -e 'h={}; puts h["xyz"]' # outputs empty line

Perl

> perl -e '%h=(); print $h{"xyz"}' # outputs nothing

bash

> bash -c 'echo $a' # outputs empty line

Absence of undefined in NGS

Adding yet another data type to NGS needs justification. I can’t find any justification for undefined . I do consider the usages above bugs. Accessing a variable or a place that were not assigned any value is an error.

Conveying absence of a value in NGS is done similar to other languages with the special null value. There are also somewhat experimental Box , FullBox and EmptyBox types, similar to Option, Some and None in Scala.

Undefined as a hash value for non-existing keys

Having undefined returned when looking up non-existing hash key is a trade-off. It’s more convenient and more error-prone. I have chosen Python-like approach: it’s an error.

> ngs -e 'h={}; h["xyz"]' ... Exception of type KeyNotFound ... # and added convenience method "get" > ngs -p 'h={}; h.get("xyz", "NONE")' NONE

Undefined when accessing unset variable

While bash gives you an empty string by default and Perl gives you undef , I do think accessing unset variable is definitely a bug. I guess it was understood at some point by the creators of bash and Perl so bash has -u flag that makes accessing undefined variable an error and Perl has use strict mode which does the same among other things.

> bash -c 'echo $a' # no error > bash -c 'set -u; echo $a' bash: a: unbound variable > bash -c 'a=(); echo ${a[0]}' # no error, just horrible syntax :) > bash -c 'set -u; a=(); echo ${a[0]}' bash: a[0]: unbound variable > perl -e 'print $a' # no error > perl -e 'use strict; print $a;' # no error - I have no idea why, probably some "special" variable # Perl - take number two: > perl -e 'print $abc' # no error > perl -e 'use strict; print $abc;' Global symbol "$abc" requires explicit package name (did you forget to declare "my $abc"?) at -e line 1. Execution of -e aborted due to compilation errors.

Undefined as value for parameters without arguments

Calling an NGS function with less arguments than it expects is an error as in most languages:

> ngs -e '(F (a,b) 10)(1)' ... Exception of type ArgsMismatch ..

By the way, I do cringe every time I see JavaScript code that explicitly uses undefined :

function f(optional_a, optional_b) { } f(undefined, 10)

The programmer took a decision not to pass a value. How in the world is this undefined ? Use null for f*ck sake!

Have a nice day!