The Ring is a practical general-purpose multi-paradigm dynamic programming language for developing applications, tools and domain-specific languages. The supported programming paradigms are imperative, procedural, object-oriented, declarative using nested structures, functional, meta programming and natural programming. The language is portable (MS-DOS, Windows, Linux, macOS, Android, WebAssembly, Microcontrollers, etc.) and can be used to create Console, GUI, Web, Games and Mobile applications. The language is designed to be simple, lightweight, flexible and embeddable. Ring is distributed as a Free-Open Source project under the MIT License.
| June 15, 2026 | Game: Prince of Vibe Code |
| June 14, 2026 | Bolt: Web framework for Ring |
| May 28, 2026 | Ring 1.27 Released! |
Ring comes with better support for Natural Language Programming and Declarative Programming. The language support these paradigms with new practical techniques on the top of Object-Oriented Programming and Functional Programming. No need to know anything about (Compilers and Parsing). You get the language constructs ready for use to create domain-specific languages in a fraction of time.
Aim Ring Article Syntax Flexibility The Declarative Approach Natural Language Programming Natural Language Programming Library Programming Without Coding Technology (PWCT)Many of the Ring libraries (StdLib, WebLib, Natural Library, Games Engine, etc.) and the Ring IDE (Ring Notepad, Form Designer, etc.) are written in the Ring language itself. Ring is ready for use in production and increase the developers productivity.
Using Ring you will feel that the language is yours! A lot of modern programming paradigms are ready for use in production and using the Natural Language Programming you can quickly integrate natural interfaces to your programs. Also, you can start your software development with writing natural descriptions, then adding the implementation later.
Many developers reported that using Ring we can develop many GUI applications in a few hours. Ring comes with Rapid Application Development (RAD) tools that we can use to quickly develop GUI applications using the MVC design pattern. Also, using the same source code we can distribute our applications for Desktop, Web and Mobile platforms.
We believe in Games as a nice way to encourage people to learn programming. Ring comes with many game programming libraries in the standard library. Ring provides native support for Allegro, LibSDL, RayLib, OpenGL and Qt3D libraries. Also, Ring comes with simple game engine for 2D games development using Declarative Programming.
Using Ring we can quickly develop web applications using WebAssembly (Binary format that allows sand-boxed executable code in web pages. This format is nearly as fast as native machine code, and is now supported by all major web browsers)
Using Ring we can quickly develop web applications using the MVC design pattern. We can easily use HTML templates with embedded Ring code. Also, we can generate HTML code from Ring programs using Declarative Programming.
Using Ring we can distribute our applications for Mobile platforms (Android, iOS, etc.)
Using Ring we can whip up a CLI tool quickly and distribute it with ease. The Ring Package Manager is an example about a powerful tool that we developed using Ring in a few hours. We recorded the development time (21 hours of development includes explaining each step)
The language is simple, trying to be natural, encourage organization and comes with transparent and visual implementation. It comes with compact syntax and a group of features that enable the programmer to create natural interfaces and declarative domain-specific languages in a fraction of time. It is very small, flexible and comes with smart memory management system that puts the memory under the programmer control. It supports many programming paradigms, comes with useful and practical libraries. The language is designed for productivity and developing high quality solutions that can scale.
see "Hello, World!"The Main function is optional and will be executed after the statements, and is useful for using the local scope.
func main see "Hello, World!"Uses Dynamic Typing and Lexical scoping.
nCount = 10 # Global variable func main nID = 1 # Local variable see "Count = " + nCount + nl + " ID = " + nID
see "Enter your name ? " give name see "Hello " + Name # Name is the same as nameThe list index starts from 1
aList = ["one","two","three"] see aList[1] # print oneCall functions before definition
one() two() three() func one see "One" func two see "two" func three see "three"The assignment operator uses Deep copy (no references in this operation)
aList = ["one","two","three"] aList2 = aList aList[1] = 1 see alist[1] # print 1 see aList2[1] # print onePass numbers and strings by value, but pass lists and objects by reference.
func main aList = [1,2,3] update(aList) see aList # print one two three func update aList for x in aList switch x on 1 x = "one" on 2 x = "two" on 3 x = "three" off nextUsing Lists during definition
aList = [ [1,2,3,4,5] , aList[1] , aList[1] ] see aList # print 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5Exit from more than one loop
for x = 1 to 10
for y = 1 to 10
see "x=" + x + " y=" + y + nl
if x = 3 and y = 5
exit 2 # exit from 2 loops
ok
next
next
/* Program Name : My first program using Ring Author : Ring Team */ see "What is your name? " # print message on screen give cName # get input from the user see "Hello " + cName # say hello! // See "End of Program!"
Ring contains only four (4) types that represent the program data. These types are (String, Number, List & Object). The idea is to have many use cases for each type which increase the flexibility and the ability to write functions that are more usable in different situations.
The String type is used to represent:cStr1 = "a" # One character cStr2 = "Hello, World!" # A string of many characters cStr3 = "Hello Welcome to the Ring language! " # Multi-line string cStr4 = read(EXEFileName()) # Read executable file (Binary Data)The Number type is used to represent
nNum1 = True # Boolean Value (1) nNum2 = False # Boolean Value (0) nNum3 = 10 # Integer nNum4 = -10 # Signed Integer nNum5 = 1250.11 # Float/DoubleThe List type is used instead of
aList1 = ["one","two","three"] # Strings aList2 = [1,2,3,4,5,6,7,8,9,10] # Numbers aList3 = ["Ring",1234] # Multiple types aList4 = [["Fayed","Egypt"],["Mansour","Tunisia"]] # Nested Lists aList5 = [ :name = "Fayed", :country = "Egypt"] # Hash TablesThe Object type is used to represent objects created from classes
The language is not line sensitive, you don't need to write ; after statements, also you don't need to press ENTER or TAB, so we can write the next code
see "The First Message" see " Another message in the same line! " + nl see "Enter your name?" give Name see "Hello " + Name
The next code create a class called Point contains three attributes X,Y and Z. No keywords is used to end the package/class/function definition. Also, we can write the attributes names directly below the class name.
class Point X Y Z
We can use classes and functions before their definition, In this example we will create new object, set the object attributes then print the object values.
o1 = new point o1.x=10 o1.y=20 o1.z=30 see O1 class Point X Y Z
Instead of using the dot '.' operator to access the object attributes and methods we can use braces { } to access the object, then we can use the object attributes and methods.
o1 = new point { x=10 y=20 z=30 } see O1 class Point X Y Z
Now we will call a method after accessing the object using { }
oPerson = new Person
{
Name = "Somebody"
Address = "Somewhere"
Phone = "0000000"
Print() # here we call the Print() method
}
class Person Name Address Phone
func Print
see "Name :" + name + nl +
"Address :" + Address + nl +
"Phone : " + phone + nl
When we use { } to access the object then write any attribute name, the language will check the class for any setter/getter methods that will be called automatically.
new Number {
see one # Execute GetOne()
see two # Execute GetTwo()
see three # Execute GetThree()
}
class Number one two three
func GetOne
see "Number : One" + nl
return 1
func GetTwo
see "Number : Two" + nl
return 2
func GetThree
see "Number : Three" + nl
return 3
Ring comes with many styles for writing your source code. Also, You can change the language keywords and operators and create your custom style!
? "Welcome to Ring! "
new test { start() }
class Test
x=10 y=20
func start
? "x+y=" + (x+y)
for t=1 to 10
? "t = " + t
if t=3
? "Three"
ok
next
def main
put "Welcome to Ring! " + nl
new test { start() }
end
class Test
x = 10
y = 20
def start
put "x+y=" + (x+y) + nl
for t=1 to 10
put "t = " + t + nl
if t=3
put "Three" + nl
end
end
end
end
load "stdlib.ring"
func main() {
print("Welcome to Ring! \n")
new test { start() }
}
class Test {
x = 10
y = 20
func start {
print("x+y=" + (x+y) + "\n")
for t=1 to 10 {
print("t = " + t + " \n")
if t=3 {
print("Three \n")
}
}
}
}
ChangeRingKeyword See Print Print "Hello, World!" ChangeRingKeyword Print See See "Hello, World!" ChangeRingKeyword See Show Show "Hello, World!"
After the object access using { } if the class contains a method called BraceEnd() it will be executed!
TimeForFun = new journey
# The first surprise!
TimeForFun {
Hello it is me # What a beautiful programming world!
}
# Our Class
class journey
hello it is me
func GetHello
? "Hello"
func braceEnd
? "Goodbye!"
We can execute code written in strings using the Eval() function
cCode = "See 'Code that will be executed later!' " Eval(cCode) # execute the code to print the message
We can create a list then execute code generated from that list
aWords = ["hello","it","is","me"] for word in aWords cCode=word+"=0" eval(cCode) next
We can read text files using the Read(cFileName) function and we can write files using the Write(cFileName,cString) function.
see "Enter File Name:" give cFileName see read(cFileName) # Print the file content
The next example presents how to create a class that defines two instructions
The first instruction is : I want window
The second instruction is : Window title = Expression
Also keywords that can be ignored like the **the** keyword
new App
{
I want window
The window title = "hello world"
}
class App
# Attributes for the instruction I want window
i want window
nIwantwindow = 0
# Attributes for the instruction Window title
# Here we don't define the window attribute again
title
nWindowTitle = 0
# Keywords to ignore
the
func geti
if nIwantwindow = 0
nIwantwindow++
ok
func getwant
if nIwantwindow = 1
nIwantwindow++
ok
func getwindow
if nIwantwindow = 2
nIwantwindow= 0
? "Instruction : I want window"
ok
if nWindowTitle = 0
nWindowTitle++
ok
func settitle cValue
if nWindowTitle = 1
nWindowTitle=0
? "Instruction : Window Title = " + cValue
ok
To complete the previous example, use read() to get the content of a file that contains
I want window
The window title = "hello world"
Then use eval() to execute the content of that file!.We learned how to use Natural statements to execute our code and using the same features we can use nested structures to execute our code.
The next example from the Web library, generate HTML document using the Bootstrap library.
No HTML code is written directly in this example, we created a similar language (just as example)
Then using this declarative language that uses nested structures, we generated the HTML Document..
The idea in this example is that the GetDiv() and GetH1() methods return an object that we can
access using {} and after each object access the method BraceEnd() will be executed to send the
generated HTML to the parent object until we reach to the root where BraceEnd() will print the output.
load "weblib.ring"
import System.Web
func Main
BootStrapWebPage()
{
div
{
classname = :container
div
{
classname = :jumbotron
H1 { text("Bootstrap Page") }
}
div
{
classname = :row
for x = 1 to 3
div
{
classname = "col-sm-4"
H3 { html("Welcome to the Ring programming language") }
P { html("Using a scripting language is very fun!") }
}
next
}
}
}
The classes that power the declarative interface looks like this
class Link from ObjsBase title link func braceend cOutput = nl+GetTabs() + " "+ Title + " " + nl class Div from ObjsBase func braceend cOutput += nl+' " + nl cOutput = TabMLString(cOutput)
see "Hello, World!"Output
==================================================================
Tokens - Generated by the Scanner
==================================================================
Keyword : SEE
Literal : Hello, World!
EndLine
==================================================================
==================================================================
Grammar Rules Used by The Parser
==================================================================
Rule : Program --> {Statement}
Line 1
Rule : Factor --> Literal
Rule : Range --> Factor
Rule : Term --> Range
Rule : Arithmetic --> Term
Rule : BitShift --> Arithmetic
Rule : BitAnd --> BitShift
Rule : BitOrXOR --> BitAnd
Rule : Compare --> BitOrXOR
Rule : EqualOrNot --> Compare
Rule : LogicNot -> EqualOrNot
Rule : Expr --> LogicNot
Rule : Statement --> 'See' Expr
==================================================================
==================================================================
Byte Code - Before Execution by the VM
==================================================================
PC OPCode Data
1 FuncExE
2 PushC Hello, World!
3 Print
4 ReturnNull
==================================================================
aList = [1,2,3,4,5] aList = "nice"After the second line directly, The list [1,2,3,4,5] will be deleted from the memory and we will have a string "nice"
When we use threads in Ring applications, We don't have global interpreter (VM) lock (No GIL)
So threads can work in parallel and execute Ring instructions at the same time
This is better for threads and concurrency (More Faster!)
Ring is designed to be a simple, lightweight, flexible and embeddable language in the first place, but also it is fast enough for many applications.
Ring can do each of the next tasks in around one second.
Tested using Victus Laptop [13th Gen Intel(R) Core(TM) i7-13700H, Windows 11, Ring 1.27]
(1) Compiling 200,000 lines of code
(2) Executing an empty loop that count from 1 to 100,000,000
(3) Creating list contains 7,000,000 items then summing all of the list items
(4) Printing numbers from 1 to 40,000 using command prompt
(5) Printing numbers from 1 to 500,000 using output redirection and Ring Notepad
(6) Adding 180,000 nodes to the TreeWidget in GUI applications
(7) Executing 3000 search operations using linear search in a list contains 100,000 items, trying to find the last item (The worst case)
Also when we need more speed we can use C/C++ extensions!