Softanza
StartFrançais
Softanza
Research · narration

Softanza Near-Natural Programming Tutorial

Near-Natural Programming (NNP) bridges the gap between human thought and code execution. Instead of forcing your ideas into rigid programming syntax, NNP lets you express logic in flowing, readable chains that mirror natural language.

by Mansour Ayouni · in the repository since 2025-09-24 · tutorial · area NLP & linguistics

Learn to write code that reads like English (or any other human language) using Softanza's NNP features.

What is Near-Natural Programming?

Traditional code often looks like this:

Python, shown for comparison, not run
if word.islower() and word.isascii() and len(word) == 4:
    # process word

With Softanza's NNP, the same logic becomes:

Haro
? Q("haro").IsAXT([:Lowercase, :Latin, :String]).WhichQ().HasAQ().LengthQ().EqualTo(4)
#--> TRUE

illustration

NNP isn't AI or natural language processing—it's carefully designed method chaining that makes code thinkable. You write executable expressions that read like sentences while maintaining full programming precision.

For an in-depth exploration of NNP's philosophy and elegant design principles, see the companion article "Near-Natural Programming: Bridging Human Thought and Code Execution."

Getting Started: The Q() Function

Every NNP expression starts with Q() to create a Softanza object:

Haro
Q("haro")      # Creates stzString
Q([1,2,3])     # Creates stzList  
Q(123)         # Creates stzNumber

illustration

Basic Checks and Validations

Simple Property Checks

Haro
? Q("haro").IsAString()
#--> TRUE

? Q("haro").IsLowercase()
#--> TRUE

? Q([1,2,3]).IsList()
#--> TRUE

illustration

Multiple Property Validation

Check several properties at once:

Haro
? Q("haro").IsAXT([:Lowercase, :Latin, :String])
#--> TRUE

? Q("HARO").IsAXT([:Uppercase, :Latin, :String])
#--> TRUE

illustration

Chaining with Natural Flow

The Q Suffix Pattern

Add Q to methods to enable chaining:

Haro
? Q("haro").IsAQ(:String).InLowercase()
#--> TRUE

? Q("haro").IsAQ(:String).WhichIs().InLowercase()
#--> TRUE

illustration

Building Longer Chains

Haro
? Q("haro").IsAQ(:String).InLowercaseQ().ContainingQ(TheLetter("i"))
#--> TRUE

illustration

Context Memory System

Using LastValue for Comparisons

Set a value to compare against later:

Haro
SetLastValue(4)
? Q("haro").LengthNB()  # N=Number, B=Binary comparison
#--> TRUE (length 4 matches LastValue)

SetLastValue(3)
? Q("AnnIE").VowelNB()  # Compares vowel count to LastValue
#--> TRUE (3 vowels matches LastValue)

illustration

Context in Action

Haro
? TheWordQ("haro").HasNQ(4).LettersNB()
#--> TRUE
# HasNQ(4) sets LastValue=4, LettersNB() compares letter count to it

illustration

Suffix Patterns Guide

Suffix Purpose Example
(none) Action only Remove("x")
Q Action + return object RemoveQ("x")
N Return number VowelN() returns count
B Return boolean LettersNB() compares to LastValue
NB Number comparison Counts and compares to LastValue
Haro
# Different ways to get vowel information:
? Q("AnnIE").Vowels()     # Returns ["A", "I", "E"]
? Q("AnnIE").VowelN()     # Returns 3 (count)
? Q("AnnIE").Vowel()      # Returns random vowel

illustration

Working with Collections

Natural Collection Queries

Haro
? Q(["Haro", :and = "Ruby"]).AreBothQ(:strings)
#--> TRUE

? Q(["Haro", :and = "Ruby"]).AreBothQ(:strings).HavingQ().TheirQ().FirstCharQ().EqualTo("R")
#--> TRUE

illustration

List Validations

Haro
? Q([-1200, -10200, -820, -10]).AreQ(:numbers).ThatQ().AreNegativeQ().AndQ().DividableBy(10)
#--> TRUE

illustration

Future Programming: Planning Ahead

Basic Future Actions

Queue actions to execute later:

Haro
? BeforeQ("ringo").IsUppercasedFQ().RemoveFFQ("o").AndThenQ().ReturnIt()
#--> HARO

illustration

How it works: 1. IsUppercasedFQ() queues "make uppercase" 2. RemoveFFQ("o") executes all queued actions, then removes "o" 3. ReturnIt() returns the result

Complex Future Chains

Haro
? BeforeQ("ringo").IsUppercasedFQ().AndThenQ().SpacifiedFQ().
  RemoveFFQ(" o").BoundItWithQ(["<< ", :and = " >>"]).
  AndFinallyQ().ReturnIt()
#--> << H A R O O >>

illustration

Future Action Management

Haro
# Manually manage future actions:
AddFuture(:Uppercase)
AddFuture([:Replace, ["I", "♥"]])

oStr = Q("haro")
ExecuteFutureOn(oStr)
? oStr.Content()
#--> R♥NG

CleanFuture()  # Clear the queue

illustration

Advanced Natural Expressions

Complex Property Chains

Haro
? QM("haro").IsAQ([:Lowercase, :Latin, :String]).WhichQ().HasAQ().LengthQ().EqualTo(4)
#--> TRUE

? TheStringQM("haro").IsAQ([:Lowercase, :Latin, :String]).WithAQ().LengthQ().Of(4)
#--> TRUE

illustration

Context-Rich Validations

Haro
? TheWordQM("haro").IsAQ([:Lowercase, :Latin, :Word]).WithQ().ALengthQ().
  OfQ(4)._Q(:Letters).AndQ().OnlyQM(1).VowelNB()
#--> TRUE

illustration

Comparative Expressions

Haro
? Q("haro").IsTheQ([:Lowercase, :string]).WhichIsQ().TheQ().ReverseOfB("gnir")
#--> TRUE

illustration

Error Tolerance

NNP handles common variations and typos:

Haro
? Q("haro").IsAQ(:String).InLowarcase()  # Misspelled
#--> TRUE (still works)

? Q("haro").IsAQ(:String).InLowercase()  # Correct  
#--> TRUE

illustration

Practical Examples

Email Validation Style

Haro
? Q("user@domain.com").IsAQ(:String).ContainingQ("@").AndQ().ContainingQ(".")
#--> TRUE

illustration

Text Processing

Haro
? Q("Hello World").ToLowercaseQ().ReplaceQ(" ", "_").Content()
#--> "hello_world"

illustration

Data Validation

Haro
# Check if all items in list are positive numbers
? Q([10, 20, 30]).AreQ(:numbers).ThatQ().ArePositive()
#--> TRUE

illustration

Best Practices

1. Start Simple

Begin with basic Q() and IsA() patterns before adding complexity.

2. Use Context Wisely

SetLastValue() and HasNQ() create powerful comparisons:

Haro
# Instead of complex nested conditions:
SetLastValue(5)
if Q(word).LengthNB() and Q(word).IsLowercase()
    # Process word
ok

illustration

3. Chain Naturally

Write chains as you would speak:

Haro
# Natural: "Is this string lowercase and containing 'i'?"
? Q("haro").IsLowercaseQ().AndQ().Contains("i")

illustration

4. Plan with Future Actions

Use future programming for multi-step operations:

Haro
# Plan: uppercase first, then remove vowels, then add brackets
? BeforeQ(text).UppercasedFQ().RemoveVowelsFQ().BracketedFFQ().ReturnIt()

illustration

Common Patterns Summary

Validation Pattern:

Haro
Q(value).IsAQ(properties).WithQ().AdditionalChecks()

illustration

Transformation Pattern:

Haro
Q(value).ActionQ().AnotherActionQ().FinalAction()

illustration

Future Pattern:

Haro
BeforeQ(value).ActionFQ().AnotherActionFQ().ExecuteFFQ().ReturnIt()

illustration

Comparison Pattern:

Haro
SetLastValue(expected)
Q(value).SomePropertyNB()  # Compares to LastValue

illustration

Start with these patterns and gradually build more complex natural expressions as you become comfortable with the system.

Related reading

Cite

Mansour Ayouni. "Softanza Near-Natural Programming Tutorial". Softanza narrations, 2025. https://mayouni.github.io/stzsite/en/narrations/stz-near-natural-language-tutorial.html

Not run: its code touches files, the network, the clock or chance. The article is published as written; its blocks are illustrations. The code of the articles is Haro code. Where an article was written before the language took its present name, the name was changed and nothing else. Genre, area and series read from the file's name, the year from its first commit: derived, until the article carries its own header. The file on GitHub(opens in a new tab)