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!