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.
par Mansour Ayouni · dans le dépôt depuis le 2025-09-24 · tutoriel · domaine Traitement du langage et linguistique
Cet article est écrit en anglais, comme la bibliothèque.
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:
if word.islower() and word.isascii() and len(word) == 4:
# process word
With Softanza's NNP, the same logic becomes:
? Q("haro").IsAXT([:Lowercase, :Latin, :String]).WhichQ().HasAQ().LengthQ().EqualTo(4)
#--> TRUEillustration
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:
Q("haro") # Creates stzString
Q([1,2,3]) # Creates stzList
Q(123) # Creates stzNumberillustration
Basic Checks and Validations
Simple Property Checks
? Q("haro").IsAString()
#--> TRUE
? Q("haro").IsLowercase()
#--> TRUE
? Q([1,2,3]).IsList()
#--> TRUEillustration
Multiple Property Validation
Check several properties at once:
? Q("haro").IsAXT([:Lowercase, :Latin, :String])
#--> TRUE
? Q("HARO").IsAXT([:Uppercase, :Latin, :String])
#--> TRUEillustration
Chaining with Natural Flow
The Q Suffix Pattern
Add Q to methods to enable chaining:
? Q("haro").IsAQ(:String).InLowercase()
#--> TRUE
? Q("haro").IsAQ(:String).WhichIs().InLowercase()
#--> TRUEillustration
Building Longer Chains
? Q("haro").IsAQ(:String).InLowercaseQ().ContainingQ(TheLetter("i"))
#--> TRUEillustration
Context Memory System
Using LastValue for Comparisons
Set a value to compare against later:
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
? TheWordQ("haro").HasNQ(4).LettersNB()
#--> TRUE
# HasNQ(4) sets LastValue=4, LettersNB() compares letter count to itillustration
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 |
# Different ways to get vowel information:
? Q("AnnIE").Vowels() # Returns ["A", "I", "E"]
? Q("AnnIE").VowelN() # Returns 3 (count)
? Q("AnnIE").Vowel() # Returns random vowelillustration
Working with Collections
Natural Collection Queries
? Q(["Haro", :and = "Ruby"]).AreBothQ(:strings)
#--> TRUE
? Q(["Haro", :and = "Ruby"]).AreBothQ(:strings).HavingQ().TheirQ().FirstCharQ().EqualTo("R")
#--> TRUEillustration
List Validations
? 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:
? BeforeQ("ringo").IsUppercasedFQ().RemoveFFQ("o").AndThenQ().ReturnIt()
#--> HAROillustration
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
? BeforeQ("ringo").IsUppercasedFQ().AndThenQ().SpacifiedFQ().
RemoveFFQ(" o").BoundItWithQ(["<< ", :and = " >>"]).
AndFinallyQ().ReturnIt()
#--> << H A R O O >>illustration
Future Action Management
# Manually manage future actions:
AddFuture(:Uppercase)
AddFuture([:Replace, ["I", "♥"]])
oStr = Q("haro")
ExecuteFutureOn(oStr)
? oStr.Content()
#--> R♥NG
CleanFuture() # Clear the queueillustration
Advanced Natural Expressions
Complex Property Chains
? QM("haro").IsAQ([:Lowercase, :Latin, :String]).WhichQ().HasAQ().LengthQ().EqualTo(4)
#--> TRUE
? TheStringQM("haro").IsAQ([:Lowercase, :Latin, :String]).WithAQ().LengthQ().Of(4)
#--> TRUEillustration
Context-Rich Validations
? TheWordQM("haro").IsAQ([:Lowercase, :Latin, :Word]).WithQ().ALengthQ().
OfQ(4)._Q(:Letters).AndQ().OnlyQM(1).VowelNB()
#--> TRUEillustration
Comparative Expressions
? Q("haro").IsTheQ([:Lowercase, :string]).WhichIsQ().TheQ().ReverseOfB("gnir")
#--> TRUEillustration
Error Tolerance
NNP handles common variations and typos:
? Q("haro").IsAQ(:String).InLowarcase() # Misspelled
#--> TRUE (still works)
? Q("haro").IsAQ(:String).InLowercase() # Correct
#--> TRUEillustration
Practical Examples
Email Validation Style
? Q("user@domain.com").IsAQ(:String).ContainingQ("@").AndQ().ContainingQ(".")
#--> TRUEillustration
Text Processing
? Q("Hello World").ToLowercaseQ().ReplaceQ(" ", "_").Content()
#--> "hello_world"illustration
Data Validation
# 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:
# Instead of complex nested conditions:
SetLastValue(5)
if Q(word).LengthNB() and Q(word).IsLowercase()
# Process word
okillustration
3. Chain Naturally
Write chains as you would speak:
# 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:
# Plan: uppercase first, then remove vowels, then add brackets ? BeforeQ(text).UppercasedFQ().RemoveVowelsFQ().BracketedFFQ().ReturnIt()
illustration
Common Patterns Summary
Validation Pattern:
Q(value).IsAQ(properties).WithQ().AdditionalChecks()
illustration
Transformation Pattern:
Q(value).ActionQ().AnotherActionQ().FinalAction()
illustration
Future Pattern:
BeforeQ(value).ActionFQ().AnotherActionFQ().ExecuteFFQ().ReturnIt()
illustration
Comparison Pattern:
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.
Lectures liées
- The Narrative of Transformations: Tracking Object History in Softanza
- Near-Natural Programming: Bridging Human Thought and Code Execution
- A Guided Path to Problem-Solving: The Softanza Mental Model
- Writability vs. Readability of Computer Code— Softanza Asks: Why NOT Both?
Citer
Mansour Ayouni. « Softanza Near-Natural Programming Tutorial ». Softanza narrations, 2025. https://mayouni.github.io/stzsite/fr/narrations/stz-near-natural-language-tutorial.html
Non exécuté : son code touche aux fichiers, au réseau, à l'horloge ou au hasard. L'article est publié tel qu'il est écrit ; ses blocs sont des illustrations. Le code des articles est du code Haro. Là où un article a été écrit avant que la langue prenne son nom actuel, le nom a été changé et rien d'autre. Genre, domaine et série lus dans le nom du fichier, année tirée du premier commit : dérivés, jusqu'à ce que l'article porte son propre en-tête. Le fichier sur GitHub(s'ouvre dans un nouvel onglet)

