Randomness in Ring and SoftanzaLib

49 views
Skip to first unread message

Mansour Ayouni

unread,
Feb 7, 2024, 9:33:27 AMFeb 7
to The Ring Programming Language
Hello All,

In this narration; I will show how Sofanza compliments Ring in some corner areas, by taking as an example the generation of random numbers. I Hope you will find it interesting...

If you write this to ask Ring to generate a random number (version 1.19)

? random(9_999_999_999)
#--> NULL

The result will be a NULL string.

In Softanza, using the alternative StzRandom() function, an error message is raised:

? StzRandom(9_999_999_999)
#--> ERROR: Can't proceed. The maximum value you can provide is 999_999_999.

It turns out that Softanza is aware of the fact that the Ring random() function has a limit. And you get the info about it by calling the function :

? RingMaxRandom()
#--> 999_999_999

In the same way, Softanza manages another limit of the standard srandom() function. srandom(n) seeds the randomness engine with the number n, so the sequence of generated numbers follows a different path every time the random() function is called.

Hence, if you say:

? srandom(2_999_999_999)
#--> RING ERROR: Bad parameters value, error in range!

Then, as you see, you will get an error.

Softanza knows what is the maximum number you can seed the engine with:

? RingMaxSeed()
#--> 1_999_999_999

So, you have the possibility to specify it in a more controlled (yet informative) way using the Softanza alternative function StzSRandom(), like this:

? StzSRandom(2_999_999_999)
#--> ERR : Can't proceeed. n must be less than 1_999_999_999.

In practice, when you ask Softanza for a random number, you can get it by using this function :

? ARandomNumber()
#--> 133_322_384


And when you want to specify the seed, you can do it directly, as a second parameter of the eXtended form of the function:

? ARandomNumberXT(77)
#--> 32_438_4546

There is a lot to show, regarding the features that are available to you to play with randomness in Softanza, like ARandomNumberIn(panListOfNumbers), SomeRandomNumbers(), and NRandomNumbersBetween(nMin, nMax), but I'll leave this to another time.

Before leaving, as usual, a snapshot:
image.png

All the best,
Mansour.

Ilir Liburn

unread,
Feb 7, 2024, 10:07:58 AMFeb 7
to The Ring Programming Language
Hello Mansour,

9_999_999_999 issue (it is not valid number in Ring) can be solved by adding multiple parameters in function like random, but then also number function converting string to number and others like that needs to be adjusted as well.

Still, nice idea for the Ring2C capabilities demo. Thanks.

Greetings,
Ilir

Mansour Ayouni

unread,
Feb 7, 2024, 2:30:06 PMFeb 7
to Ilir Liburn, The Ring Programming Language
Hello Ilir,

Thank you for your feedback.

For the end user,  9_999_999_999   is a valid number, since we can use it to make calculations like:
image.png
All the best,
Mansour

--

---
You received this message because you are subscribed to the Google Groups "The Ring Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-lang+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ring-lang/e8f41fcb-aec7-4d2c-aa72-54686ac03226n%40googlegroups.com.

Bert Mariani

unread,
Feb 7, 2024, 6:15:47 PMFeb 7
to The Ring Programming Language
Hello Mansour et ALL

Unfortunately the random() does not generate truly unique random numbers.
There are lots of repeated numbers and missing numbers.

The following was provided by Mahmoud in a previous conversation
    --- Random() Function - Not generating even distribution
"Try this simple algorithm, It will provides 100 numbers (Random numbers) without repeating any number"

//========================================== 
aList = 1:100                                 // Generate list 1 to 100
aOut = []

while len(aOut) != 100
    nSize = len(aList)
    if nSize > 1
        nIndex = random(nSize)      // Random pointer into list
        if nIndex = 0  nIndex=1 ok   // Ignore 0, Ring Index at 1
        aOut + aList[nIndex]             // Extract list entry contents
        del(aList,nIndex)                   // Shorten list, remove value entry picked
    else
        aOut + aList[1]
        aList = []
    ok
end

? aOut
//==========================================


Ilir Liburn

unread,
Feb 7, 2024, 6:37:08 PMFeb 7
to The Ring Programming Language
Hello Bert,

you need to generate seed (srandom) before calling random. However, random is calling C rand which is giving only 16 bit output (0-65535), Even documentations is saying that numbers can repeat (end possibly not evenly distributed).

Because of that, random now combines s_rand and rand to produce 32 bit numbers in random function. Additionally, randomize function which doesn't require seed can be used (returns 53 bit integer). Still, no guaranties about distribution (it is all coming from C). 

Greetings,
Ilir

Mansour Ayouni

unread,
Feb 7, 2024, 9:24:06 PMFeb 7
to Ilir Liburn, The Ring Programming Language
Hellor Bert and Ilir,

Softanza can generate random numbers repeated and non repeated. The non repeated numbers are guaranteed to be unique by the use of the U() extension with the available functions (U for Unique).

The next example shows how we can generate 3 random numbers between 1 and 10 using NRandomNumbersIn(), and then how to use NRandomNumbersInU() for the generated numbers to be unique:

image.png
All the best,
Mansour

Ilir Liburn

unread,
Feb 8, 2024, 5:15:32 AMFeb 8
to The Ring Programming Language
Hello Mansour,

Ring provides two kinds of the random number generators

1. srandom/random which are saving internal states, therefore functions are not thread safe
2. randomize which doesn't save state, doesn't need seed, therefore it is thread safe

Does Softanza lib cares about thread safety and/or provides locking mechanism?

Greetings,
Ilir

Mansour Ayouni

unread,
Feb 8, 2024, 3:54:42 PMFeb 8
to Ilir Liburn, The Ring Programming Language
Hello Ilir,

I'm not aware of the existence of a randomize() function in Ring. I don't find it in the documentation...

That's why I included a function called Randomise() to stzList and stzString that means other things (changing randomly the positions of items or chars).

Softanza has not particularly been designed with threads and thread safety in mind, since this is not a subject I'm skilled in, or use often in my real projects. But I have a plan to get prepared for that in the future...

This being said, Softanza data structures can be used in an immutable way, using the Copy() function. So, for example, if we have a stzString like that:

o1 = new stzString("ilir")

And we want to uppercase it without altering its value, we can say:

o1.Copy().Uppercase()

Now we get "ILIR", but if we inspect the value of o1:

? o1.Content()

We find it unchanged ("ilir").

This technique is further streamlined in what Softanza calls @FunctionFluidForm. So you can chain as many actions as you want, on as many objects as you need, without altering the initial object, and by returning each time a new copy under the scene. This is made possible by the use of the Q() extension to any Softanza method.

Look at this example:

o1 = new stzString("ilir")
? o1.Copy().UppercaseQ().SpacifyQ().ReplaceQ(" ", "*").Content()
#--> "I*L*R"
? o1.Content()
#--> "ilir"

Here you get the final result of a chain of actions:
  • First, a copy() of o1 is made
  • Second, an Uppercase() is applied to that copy of o1. Hence, the copy is uppercased ("ILIR") but o1 stays unchanged ("ilir")
  • Then Spacify is applied on the copy. The copy becomes "I L I R", and the initial object (o1) stays unchanged.
  • Finally, Replace() function is applied on the copy. Its value becomes "I*L*R", and the initial o1 object stays unchanged.
Of course, the intermediate copy remains live in the chain until its final action, but the programmer won't deal with it since it has no variable name. Definitely, the garbage collector will know how to free it from memory.

I don't know if this helps in enabling thread safety, but what I know is that by embracing this simple technique, we can develop immutable functions and mimic the way how Functional Programming is used to make scalable and stateless programs and systems.

A snapshot, if you want :

image.png

All the best,
Mansour

Ilir Liburn

unread,
Feb 8, 2024, 5:09:27 PMFeb 8
to The Ring Programming Language
Hello Mansour,

>> I'm not aware of the existence of a randomize() function in Ring. I don't find it in the documentation...

While fixing random function to support 31 bit random number and have better numbers distribution by adding s_rand/rand_r function(s); I also added randomize function since version 1.16 if I remember correctly. It was never documented like some other things I found, but I mentioned it several times in a past.

>> I don't know if this helps in enabling thread safety,

Thread safety is about the global scope because each thread uses isolated VM, while global scope is shared. Since you are using Ring way of creating objects,   standard rules apply here. Yes, copy is a good way to have tread safety, as long entire list (object) is copied. Access to list item is not thread safe because index access stores list state internally. Can be avoided by using jagged arrays and swap.

Greetings,
Ilir
 

Mansour Ayouni

unread,
Feb 8, 2024, 5:19:16 PMFeb 8
to Ilir Liburn, The Ring Programming Language
Hello Ilir,

Thank you for this information. I'll do my homework on threat safety after the first release of the library.

All the best,
Mansour


Ilir Liburn

unread,
Feb 8, 2024, 5:25:19 PMFeb 8
to The Ring Programming Language
Hello Mansour,

You're Welcome.

Greetings,
Ilir

Reply all
Reply to author
Forward
0 new messages