What is new in Ring 1.23

In this chapter we will learn about the changes and new features in Ring 1.23 release.

List of changes and new features

Ring 1.23 comes with the next features!

  • Research Article

  • PWCT 2.0 (Source Code)

  • Snakes and Ladders 2

  • Adhkar App (Arabic/WASM)

  • More RingPM Packages

  • Better Applications and Samples

  • Better StdLib

  • Better RingFastPro

  • Faster String Operations

  • Better Find() function

  • Better OptionalFunc() function

  • More Improvements

Research Article

URL: https://doi.org/10.3390/app15031521

Research Article

PWCT 2.0 (Source Code)

Programming Without Coding Technology 2.0 source code is released on GitHub.

PWCT2 comes with Arabic/English translations.

URL: https://github.com/PWCT/pwct2

PWCT2Arabic

Snakes and Ladders 2

Two players version of the game (applications/snakesandladders2).

SnakesAndLadders2

Adhkar App (Arabic/WASM)

This applications is developed using Ring and RingQt.

We can get the application using the Ring Package Manager (RingPM).

ringpm install Adhkar_Ring_App
ringpm run Adhkar_Ring_App

The previous commands will launch the desktop version of the application.

The next screenshot shows the online version (using WebAssembly).

AdhkarApp

More RingPM Packages

The following packages have been added to the RingPM registry.

  • RingRegex: Regular expression library built on top of the PCRE2

  • RingThreadPro: Threads management library

  • RingSubProcess: Creating and managing system processes

  • Markdown: A Markdown parser and HTML converter

  • TOML: A comprehensive TOML parser

Example:

ringpm install Markdown

Better Applications and Samples

The next applications and samples are revised:

  • applications/othellogame

  • applications/fifteenpuzzle

  • applications/getquoteshistory

  • applications/weighthistory

  • applications/employee

  • samples/UsingQt/XML

  • samples/General/TimeServer

  • samples/General/NumberToWords/

The next applications and samples are added:

  • applications/trianglecalculator

  • samples/UsingLibCurl/t5.ring

  • samples/UsingLibCurl/t6.ring

  • samples/UsingLibCurl/t7.ring

  • samples/UsingLibCurl/t8.ring

  • samples/UsingLibCurl/t9.ring

  • samples/UsingLibCurl/t10.ring

  • samples/UsingLibCurl/t11.ring

  • samples/UsingCSVLib/usinglist2csv.ring

  • samples/UsingQt/ObjectPointer/test.ring

  • samples/Language/AnonFunctions/me.ring

  • samples/Language/SwitchCheck/switchcheck.ring

  • samples/General/EpochToDateTime/EpochToDateTime.ring

  • samples/Drawing/Keplers3Laws/Keplers3Laws.ring

  • samples/Drawing/RotationIllusion/Rotation-Illusion.ring

  • samples/Drawing/OrbitPlanetRetrograde/Orbit-Planet-Retrograde.ring

  • samples/ProblemSolving/RandomLatinSquares/LatinSquaresUsingGUILib.ring

  • samples/General/SmallExamples/Delivery/delivery.ring

Better StdLib

The next functions are added to StdLib:

  • StringToBase64(cString) —> cBase64

  • Base64ToString(cBase64) —> cString

Example:

load "stdlibcore.ring"

cStr = "Hello World"
? StringToBase64(cStr)

cBase64 = "SGVsbG8gV29ybGQ="
? Base64ToString(cBase64)

Output:

SGVsbG8gV29ybGQ=
Hello World

Better RingFastPro

The updateList() function is improved to support many new operations and features.

aListC = updateList(<aList>,:add,:matrix,<aListB>)
aListC = updateList(<aList>,:sub,:matrix,<aListB>)
aListC = updateList(<aList>,:mul,:matrix,<aListB>)
aListC = updateList(<aList>,:transpose,:matrix)
aListC = updateList(<aList>,:scalar,:matrix,<nValue>)
valueA/aListC = updateList(<aList>,:dotproduct,:matrix,<aListB>)
aListC = updateList(<aList>,:fill,:matrix,<nValue>)
valueA = updateList(<aList>,:maximum,:matrix,<nValue>)
aList  = updateList(<aList>,:identity,:matrix)
aList  = updateList(<aList>,:random,:matrix)
valueA = updateList(<aList>,:mean,:matrix)
aListC = updateList(<aList>,:sqrt,:matrix)
aListC = updateList(<aList>,:square,:matrix)
aListC = updateList(<aList>,:sigmoid,:matrix)
aListC = updateList(<aList>,:sigmoidprime,:matrix)
aListC = updateList(<aList>,:tanh,:matrix)
aListC = updateList(<aList>,:leakyrelu,:matrix)
aListC = updateList(<aList>,:leakyreluprime,:matrix)
aListC = updateList(<aList>,:relu,:matrix)
aListC = updateList(<aList>,:reluprime,:matrix)
aListC = updateList(<aList>,:exp,:matrix)
aListC = updateList(<aList>,:sum,:matrix)
aListC = updateList(<aList>,:softmax,:matrix)
aListC = updateList(<aList>,:scalardiv,:matrix,<nValue>)
aListC = updateList(<aList>,:horstack,:matrix,<aListB>)
aListC = updateList(<aList>,:verstack,:matrix,<aListB>)
aListC = updateList(<aList>,:ravel,:matrix)
aListC = updateList(<aList>,:zerolike,:matrix)
aListC = updateList(<aList>,:atleast2d,:matrix)
valueA = updateList(<aList>,:argmax,:matrix)
aListC = updateList(<aList>,:derepeat,:matrix)
aListC = updateList(<aList>,:append,:matrix,<aListB>,<nValue>)
valueA = updateList(<aList>,:allsum,:matrix)
aListC = updateList(<aList>,:mandelbrot,:matrix,<aFlatB>)

The next samples are added to introduce these features:

  • samples/UsingFastPro/MergeMultiply.ring

  • samples/UsingFastPro/RegAddSubMulDivColRowDest.ring

  • samples/UsingFastPro/MergeAddSubMulDivColRowDest.ring

  • samples/UsingFastPro/SetManyCopySerialPowRemItemsColRow.ring

  • samples/UsingFastPro/ManyAddSubMulDivSerialPowRem.ring

  • samples/UsingFastPro/MatrixAddSubMul.ring

  • samples/UsingFastPro/SpeedMatrixMul.ring

  • samples/UsingFastPro/MatrixScalar.ring

  • samples/UsingFastPro/MatrixTranspose.ring

  • samples/UsingFastPro/MatrixDotProduct.ring

  • samples/UsingFastPro/Matrix2DDotProduct.ring

  • samples/UsingFastPro/FillMatrix.ring

  • samples/UsingFastPro/MatrixMaximunAllDiag.ring

  • samples/UsingFastPro/MatrixIdentity.ring

  • samples/UsingFastPro/MatrixRandom.ring

  • samples/UsingFastPro/MatrixMean.ring

  • samples/UsingFastPro/MatrixSqrt.ring

  • samples/UsingFastPro/MatrixSquare.ring

  • samples/UsingFastPro/MatrixSigmoid.ring

  • samples/UsingFastPro/MatrixSigmoidPrime.ring

  • samples/UsingFastPro/MatrixTanh.ring

  • samples/UsingFastPro/MatrixLeakyReLu.ring

  • samples/UsingFastPro/MatrixLeakyReLuPrime.ring

  • samples/UsingFastPro/MatrixReLu.ring

  • samples/UsingFastPro/MatrixReLuPrime.ring

  • samples/UsingFastPro/MatrixExp.ring

  • samples/UsingFastPro/MatrixSumAxis.ring

  • samples/UsingFastPro/MatrixSoftMax.ring

  • samples/UsingFastPro/MatrixHorStack.ring

  • samples/UsingFastPro/MatrixScalarDiv.ring

  • samples/UsingFastPro/MatrixVertStack.ring

  • samples/UsingFastPro/MatrixRavel.ring

  • samples/UsingFastPro/MatrixZeroLike.ring

  • samples/UsingFastPro/MatrixAtLeast2D.ring

  • samples/UsingFastPro/MatrixArgMax.ring

  • samples/UsingFastPro/MatrixDeRepeat.ring

  • samples/UsingFastPro/MatrixAppend.ring

  • samples/UsingFastPro/MatrixAllSum.ring

  • samples/UsingFastPro/Mandelbrot.ring

  • samples/UsingFastPro/MugRotation/Mug-Rotation-FastPro.ring

  • samples/UsingFastPro/MandelbrotAnimate/MandelbrotAnimate.ring

Mug Rotation

Faster String Operations

This release brings optimized string operations for improved performance.

Example:

Decimals(3)
t1 = clock()
cStr = "Welcome"

for t=1 to 200_000
        cStr += "Welcome"
next

? (clock()-t1)/clocksPerSecond()

Output:

0.014           # Ring 1.23
0.038           # Ring 1.22

Example:

Decimals(3)
t1 = clock()
cStr = "Welcome to the Ring programming language"

for t=1 to 200_000
        cStr2 = subStr(cStr,"Ring","***Ring***",True)
next

? (clock()-t1)/clocksPerSecond()

Output:

0.077           # Ring 1.23
0.114           # Ring 1.22

Better Find() function

The find() function is revised and improved:

  • Support searching in lists/Attributes using C Pointers

  • Support searching in lists/Attributes using list/object reference

Example:

fp1 = fopen(filename(),"r")
fp2 = fopen(filename(),"r")
fp3 = fopen(filename(),"r")

aList = [fp3, fp2, fp1]

? find(aList,fp1)
? find(aList,fp2)
? find(aList,fp3)

Output:

3
2
1

Note

The fopen() function returns a Ring list that wraps a C Pointer.

Tip

It is not necessary to call the fclose() function, as Ring automatically manages this.

Example:

func main

        subject   = new Subject
        observer1 = new ObserverA
        observer2 = new ObserverB

        subject.addObserver(observer1)
        subject.addObserver(observer2)

        subject.setValue(42)
        subject.setValue(99)

        subject.removeObserver(observer1)

        subject.setValue(101)

class Subject

        aObservers = []
        value      = 0

        func addObserver(observer)
                add(aObservers, ref(observer))

        func removeObserver(observer)
                nPos = find(aObservers,observer)
                if nPos
                        del(aObservers,nPos)
                ok

        func notify()
                for oObj in aObservers
                        oObj.update(value)
                next

        func setValue(newValue)
                value = newValue
                notify()

class Observer

        func update(value)

                ? "Observer updated with value: " + value

class ObserverA from Observer

        func update(value)

                ? "ObserverA received value: " + value

class ObserverB from Observer

        func update(value)

                ? "ObserverB received value: " + value

Output:

ObserverA received value: 42
ObserverB received value: 42
ObserverA received value: 99
ObserverB received value: 99
ObserverB received value: 101

Better OptionalFunc() function

The OptionalFunc() function implementation is revised.

The new optional function name will be added to the RingOptionalFunctions list.

Example:

? "Declare optional functions"
optionalFunc(:one)
optionalFunc(:two)
optionalFunc(:three)

? "Call optional functions"
one() two() three()

? "Print list of optional functions"
? RingOptionalFunctions

? "Define optional functions"
eval(`
func one   ? "Message from one() function"
func two   ? "Message from two() function"
func three ? "Message from three() function"
`)

? "Call optional functions"
one() two() three()

Output:

Declare optional functions
Call optional functions
Print list of optional functions
one
two
three

Define optional functions
Call optional functions
Message from one() function
Message from two() function
Message from three() function

Example:

Add(RingOptionalFunctions, [
        :one,
        :two,
        :three,
        :four,
        :five
], True)

one() two() three() four() five()       # No Error

eval(`
func one   ? 1
func two   ? 2
func three ? 3
func four  ? 4
func five  ? 5
`)

? RingOptionalFunctions                 # Print Names

one() two() three() four() five()       # Print Numbers

Output:

one
two
three
four
five

1
2
3
4
5

More Improvements

  • Better Documentation

  • Qt version is updated to Qt 5.15.19

  • Form Designer - Better support for translation

  • Form Designer - Objects Order - Using closeAction() method

  • Form Designer - Display forms at the centre of the screen

  • AddMethod()/MergeMethods() functions - Better implementation

  • RingQt - OpenGLWidget/QAllEvents classes - Use: RINGQT_EVENT_SIZE

  • RingQt - CodeEditor control - Same font size for code/line number

  • VSCode Extension - Added support for the EndIf keyword

  • VSCode Extension - Support for using underscore inside numbers

  • Added FreeBSD support in ring.h and general.c for executable path retrieval

  • RingPM - Support FreeBSD files in install and remove commands

  • RingLibCurl - The extension is updated with more helper functions

  • RingLibuv - The implementation of the internal uv_new_mutex() function has been revised

  • RingLibuv - Support compilation on Linux with GCC 14/Clang 19+

  • RingLibSDL - Support compilation on Linux with GCC 14/Clang 19+

  • RingThreads - Support Windows (32bit/64bit), Linux & macOS

  • CMakeLists.txt - Require version 3.16 and improve OS detection messages

  • language/README_CMake.md - Better documentation for build instructions

  • Ring Compiler - Scanner - Support repeating stars in multi-line comments

  • Ring Compiler - Using & to return item reference is supported only after Return

  • Ring VM - Save/Restore pParser->lFuncCallOnly when using anonymous function

  • Ring VM - The ~ operator precedence is revised to follow the documentation

  • Ring VM - Check for a scope ID overflow and reset any associated instructions

  • Ring VM - Uninitialized variable - Correct error message when name contains underscores

  • Ring VM - ring_vm_retitemref() - Better implementation (used by Return &)

  • Ring VM - ring_hashtable_rebuild_gc() - Faster implementation

  • Ring VM - ring_state_realloc() - Using RING_MEMCPY

  • Ring Compiler/VM - Use GC functions for internal HashTable operations