> commit 1edd2abb changed awk(1) so that srand() called without a seed
> triggers the use of arc4random(3) for subsequent rand() calls
> (unfortunately, this feature is not documented).
> 
> however, awk has historically assumed $0 for builtin functions called
> without an explicit argument:
The manpage documents srand() to assume the time of day when no argument
is provided (like posix specifies), not $0 - which is also not what
really happens.

I think srand() has two main uses cases:

1) Set a *specific* seed to generate reproducible results.

2) Initialize the random number generator so, that reasonable random
numbers are generated. I guess at some point in time using the time of
day as a seed was state of the art - but not today. arc4random() makes
much more sense. Posix doesn't specify which RNG is used, so using
arc4random should be ok. IMHO, the only thing which should be changed
is the documentation:

diff --git a/usr.bin/awk/awk.1 b/usr.bin/awk/awk.1
index 514f989..e1c8ccc 100644
--- a/usr.bin/awk/awk.1
+++ b/usr.bin/awk/awk.1
@@ -487,7 +487,7 @@ to
 and returns the previous seed.
 If
 .Fa expr
-is omitted, the time of day is used instead.
+is omitted, the random number generator is seeded in a system dependant manner.
 .El
 .Ss String Functions
 .Bl -tag -width "split(s, a, fs)"

> do we want to keep this behaviour, or should we revert 1edd2abb? while i
> like the idea of allowing the use of arc4random(), i treasure semantic
> congruence in a programming language, so i'm inclined towards the latter
> option. thoughts?
Meh. The current solution seems to have been good enough to survive for
a whole decade - also, I think using arc4random() is a good thing (TM).
The use case where the values produced are predictable (when srand() is
called with an argument) continues to be.

> there's also the fact that srand() is supposed to return the last seed
> used. srand() (w/o arguments) currently returns garbage (that is
> undoubtedly a bug):
> 
> # echo 1 | awk '{ print srand }'
> 4.22615e-317
> # echo 1 | awk '{ srand(1); print srand; srand(1); print srand(2) }'
> 2.122e-314
> 1
srand() without argument errornously doesn't set the return value.
Following patch lets srand() without argument return the current seed.

diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c
index 9bb85fd..b798da5 100644
--- a/usr.bin/awk/run.c
+++ b/usr.bin/awk/run.c
@@ -1588,9 +1588,10 @@ Cell *bltin(Node **a, int n)     /* builtin functions. 
a[0] is type, a[1] is arg lis
                        u = (Awkfloat)arc4random() / 0xffffffff;
                break;
        case FSRAND:
-               if (isrec(x))   /* no argument provided, want arc4random() */
+               if (isrec(x)) { /* no argument provided, want arc4random() */
                        use_srandom = 0;
-               else {
+                       u = srand_seed;
+               } else {
                        use_srandom = 1;
                        u = getfval(x);
                        tmp = u;


cheers,
natano

Reply via email to