28 KiB
Claro v1.18.26
Claro is a small, readable scripting language designed to help beginners — especially learners with learning disabilities — learn programming without being overwhelmed by punctuation-heavy syntax.
Claro stays plain-text first: simple enough to start with SET name "Jon", but able to grow into stronger typed scripts, objects, packages, networking, and tooling over the v1 line. Graphics/SDL work is experimental and not enabled in the stable executable.
Status
Current release: Claro v1.18.26
For the current feature map and beginner-safe limits, start with docs/CURRENT_STATUS.md. The sequenced development priorities are in docs/ROADMAP.md; older release-candidate notes are historical.
Validated in this package:
./claro --version
# Claro v1.18.26
./claro test
# PASS: 0 failure(s)
./claro validate
# Validation passed. Claro v1.18.26 networking reliability is ready for use.
python3 tools/validate_typecheck_diagnostics.py
python3 tools/validate_ide_metadata.py
python3 tools/validate_version_convention.py
python3 tools/validate_package_security.py
python3 tools/validate_compiler_warnings.py
python3 tools/validate_ci_workflow.py
The CI workflow validator also requires its own command to remain in an executable run step, so the release-gate check cannot silently disappear from CI. make builds both claro and claro.exe, allowing the version validator to exercise the same source build on every platform.
Beginner-first syntax
Claro accepts both the sentence-like style and the shorter simple style:
SET name TO "Jon"
SET name "Jon"
SET city to "Edmonton"
ASK "What is your name?" name
SAY "Hello " + name
IF name = "Jon"
SAY "Nice name!"
END
Older forms such as ASK "Name?" AS name, ENDIF, DONE, and LEARNED still work so older Claro examples do not break.
Simple functions
TEACH greet name
SAY "Hello " + name
END
DO greet "Jon"
Older function syntax still works:
TEACH greet TAKES name
SAY "Hello " + name
LEARNED
CALL greet WITH "Jon"
Objects and classes
Classes can have typed fields and simple methods.
CLASS Player
HAS name TEXT
HAS score NUMBER
TEACH show
SAY name
SAY score
END
TEACH add points
SET score score + points
END
END
NEW Player player
SET player.name "Jon"
SET player.score 10
SET player.score player.score + 1
DO player.show
DO player.add 5
SAY player.score
Object helper commands:
OBJECT CLASS player AS kind
OBJECT FIELDS player AS fields
When a script already declares classes, claro typecheck also catches a typo in a NEW class name and explains how to repair it:
Class Plaeyr is not known yet. Check the class name or declare CLASS Plaeyr before creating player.
Inside a method, an inline field type must agree with the class declaration. For example, HAS score NUMBER must not be assigned with SET score TEXT 10; claro typecheck explains the conflict and suggests NUMBER. The same check applies to older TEACH ... TAKES ... / LEARNED methods, so compatibility lessons get the same feedback.
If an inline method-field annotation is not a Claro type, claro typecheck names the field and method and suggests the class declaration. For example, SET score AS BANANA TO 10 reports that BANANA is unknown and recommends NUMBER.
The same diagnostic is covered for older TEACH ... TAKES ... / LEARNED methods, so compatibility lessons do not silently accept misspelled field types.
Static type safety
Beginners can still write the simplest form:
SET name "Jon"
When learners are ready, Claro can protect variables with plain-text types:
SET score NUMBER 10
SET name TEXT "Jon"
SET ready YESNO YES
TYPE OF score AS kind
SAY kind
CHECK TYPE score IS NUMBER
CHECK TYPE gives a direct repair hint when IS is missing:
CHECK TYPE needs IS. Try: CHECK TYPE score IS NUMBER.
If extra words follow the result name, claro typecheck explains that TYPE OF accepts one expression, AS, and one result name:
TYPE OF score AS kind extra
TYPE OF score has extra text after result name kind. Keep only the expression, AS, and one result name.
If the learner leaves out the expression as well, the checker explains all three required parts:
CHECK TYPE needs an expression, IS, and a type. Try: CHECK TYPE score IS NUMBER.
If IS is present but the expression is missing, Claro points out that the expression belongs before IS:
CHECK TYPE needs an expression before IS. Try: CHECK TYPE score IS NUMBER.
TYPE OF also explains when the result variable is missing its AS keyword:
TYPE OF needs AS. Try: TYPE OF score AS kind.
If the learner writes IS but leaves out the expected type, Claro names the missing piece and shows a complete example:
CHECK TYPE score needs a type after IS. Try: CHECK TYPE score IS NUMBER.
If extra words follow the expected type, claro typecheck explains that only one type belongs there:
CHECK TYPE score IS NUMBER TEXT
CHECK TYPE score has extra text after type NUMBER. Keep only the expression, IS, and one type.
If RETURNS is present without a type, claro typecheck explains what is missing and shows a beginner-friendly repair:
Function greet needs a return type after RETURNS. Add a type such as NUMBER.
The same missing-type check covers the older TEACH ... TAKES ... RETURNS / LEARNED spelling, so compatibility lessons receive the same repair instead of silently accepting an incomplete return declaration.
The same repair applies to object methods and older compatibility methods, and names the class so the learner can find the declaration:
Method Player.score needs a return type after RETURNS. Add a type such as NUMBER.
CHECK TYPE names a real Claro type. If a type name is misspelled, the checker explains the allowed beginner types instead of reporting a confusing value mismatch:
CHECK TYPE score IS BANANA
CHECK TYPE needs a known type such as NUMBER, TEXT, YESNO, LIST, or MAP, but BANANA is not a Claro type.
Advanced container checks are available through claro typecheck:
SET names AS LIST OF TEXT TO LIST
ADD "Ada" TO names
SET scores AS MAP OF NUMBER TO MAP
PUT scores KEY "math" VALUE 98
claro typecheck also has an early function-argument diagnostic foundation. A function can state a parameter expectation with CHECK TYPE, and calls with the wrong value type or a missing checked argument get a friendly error:
TEACH square amount
CHECK TYPE amount IS NUMBER
SAY amount
END
DO square "oops"
Type mismatch for function square: parameter amount needs NUMBER, but this argument looks like TEXT.
Function square needs argument amount as NUMBER, but this call does not provide it.
Function greet needs 1 argument, but this call gives 0. Add the missing argument.
Function square only accepts 1 argument, but this call gives 2. Remove the extra argument.
Function squre is not known yet. Check the function name or add TEACH squre before calling it.
If a function repeats a parameter name, claro typecheck reports the declaration mistake before the function is called. This applies to both modern END functions and compatibility TAKES / LEARNED functions:
Function greet declares parameter name more than once. Give each parameter a different name.
Top-level functions must also have unique names. If a script declares TEACH greet twice, claro typecheck reports Function greet is declared more than once. Give each function a different name. Rename one function before calling it. A function declaration must include a name; writing only TEACH reports TEACH needs a function name. Add a name after TEACH, such as TEACH greet. Inside CLASS Player, the same mistake reports Method Player needs a method name. Add a name after TEACH, such as TEACH show.
The same declaration check applies to object methods in both syntax styles. For example, TEACH greet name, name inside CLASS Player reports Method Player.greet declares parameter name more than once. Give each parameter a different name. Duplicate method names are also rejected in both modern END methods and compatibility TAKES / LEARNED methods, with a rename hint before a call can become ambiguous.
Object methods must also have unique names within their class. If CLASS Player declares TEACH show twice, claro typecheck reports Method Player.show is declared more than once. Give each method a different name. Rename one method before calling it.
Class fields must also have unique names and known types. If CLASS Player declares HAS score NUMBER twice, or declares the same field with another type, claro typecheck reports Class Player declares field score more than once. Give each field a different name. A bare HAS reports Class Player needs a field name. Add a name and type after HAS, such as HAS score NUMBER. If a field omits its type, it reports Class Player field score is missing a type. Add a type such as NUMBER, TEXT, YESNO, LIST, or MAP after the field name. If a field uses an unknown type such as BANANA, it reports Class Player field score uses an unknown type BANANA. Use a Claro type such as NUMBER, TEXT, YESNO, LIST, or MAP. If extra text follows a valid type, it reports Class Player field score has extra text after type NUMBER. Keep only the field name and one type. Keep one HAS line for each field and use one supported type.
Class declarations must include a name. A bare CLASS reports CLASS needs a class name. Add a name after CLASS, such as CLASS Player. Class names must also be unique and use one name only. If a file declares CLASS Player twice, claro typecheck reports Class Player is declared more than once. Give each class a different name. If extra words follow the name, it reports Class Player has extra text after its name. Keep only the class name after CLASS. Rename or simplify the declaration before creating its objects. Object names must also be unique within a script: creating NEW Player player twice reports Object player is created more than once. Give each object a different name. Use a different object name for the second instance. A NEW declaration must include both a class name and an object name; bare NEW reports NEW needs a class name. Add a class and object name, such as NEW Player player., while NEW Player reports NEW Player needs an object name. Add a name after the class, such as NEW Player player.
Extra words after an object name are also rejected, for example NEW Player player extra reports NEW Player has extra text after object name player. Keep only the class and object names. Keep each NEW declaration to one class name and one object name.
Simple functions and object methods can also declare a return type. claro typecheck checks each RETURN expression against it and reports a missing return when a declaration never returns a value:
TEACH square amount RETURNS NUMBER
CHECK TYPE amount IS NUMBER
RETURN amount
END
The same focused check applies to methods such as Player.score RETURNS NUMBER; a wrong return reports the full method name, for example: Type mismatch for return from Player.score: expected NUMBER, but this value looks like TEXT.
The older compatibility spelling keeps the same return check for functions and methods. For example, TEACH square TAKES amount RETURNS NUMBER with LEARNED and CALL square WITH 4 is checked before it runs, so older lessons get the same type-safety feedback. A compatibility method such as TEACH score TAKES amount RETURNS NUMBER inside a class is checked the same way; a correct CALL player.score WITH 4 path is covered by release validation too.
If a function or method declares RETURNS TYPE but uses RETURN without a value, the checker points out the missing expression:
Function square needs a NUMBER value after RETURN. Add a NUMBER expression.
The same repair applies to compatibility methods written with TAKES / LEARNED, so older lessons also receive a method-specific hint instead of a generic type error.
If a return value has extra space-separated text, claro typecheck identifies the first value and explains that RETURN accepts one expression:
TEACH square amount RETURNS NUMBER
RETURN amount extra
END
Function square has extra text after return value amount. Keep only one expression after RETURN.
If a function or method declares RETURNS TYPE but contains no RETURN, the checker points out the missing statement:
Function square declares RETURNS NUMBER but has no RETURN statement. Add RETURN with a NUMBER value.
Return declarations must use a known Claro type. If the type name is misspelled, the checker explains the supported beginner types:
Function square declares an unknown return type BANANA. Use a Claro type such as NUMBER, TEXT, YESNO, LIST, or MAP.
The same check applies to methods, so Player.score RETURNS BANANA reports Method Player.score declares an unknown return type BANANA... instead of allowing a misspelled type into a class definition. If a return expression cannot be understood yet, the diagnostic names the function or method and the type it needs; this is covered for both modern and older compatibility method syntax. When a NUMBER return contains a known TEXT operand in arithmetic, the checker names the operation and operand, for example: Type mismatch for return from total: addition needs NUMBER values, but "oops" looks like TEXT. Complete IF/ELSE return branches are also accepted inside typed functions and methods, including a nested conditional whose own branches all return; an incomplete path still gets a missing-return diagnostic.
The same return diagnostic names the arithmetic operation when a NUMBER return mixes in a known TEXT operand, so the learner sees both the operation rule and the offending value instead of only a generic return mismatch. This is covered for addition, subtraction, multiplication, and division in functions and object methods. For example, Player.total reports subtraction needs NUMBER values when its return expression mixes a checked NUMBER parameter with a TEXT value.
Claro keywords are case-insensitive here, so returns NUMBER is accepted as the same return declaration as RETURNS NUMBER. The type checker keeps the return-value diagnostic when a lowercase declaration is used, which helps learners who are still learning Claro's capitalization style.
The unknown-function diagnostic is validated for both modern DO squre 4 and compatibility CALL squre WITH 4 calls. Compatibility calls that leave WITH empty, such as CALL greet WITH, now count as zero arguments, so learners get the same missing-argument guidance as DO greet instead of the checker treating the blank as an argument.
For functions with more than one checked parameter, Claro reports each mismatched argument with the parameter name:
TEACH label TAKES name, age
CHECK TYPE name IS TEXT
CHECK TYPE age IS NUMBER
END
CALL label WITH 7, "old"
The same narrow diagnostic foundation now covers simple object method calls when the object was created with NEW and the method body uses CHECK TYPE for a parameter. Correct calls such as DO player.add 5 and compatibility calls such as CALL player.add WITH 5 are covered by validation, and wrong-type calls get a focused learner-facing error. This also works when the checked method appears after another method in the same class, so normal multi-method class examples still get the same wrong-type and extra-argument guidance:
CLASS Player
HAS score NUMBER
TEACH add points
CHECK TYPE points IS NUMBER
SET score score + points
END
END
NEW Player player
DO player.add "five"
CALL player.add WITH "five"
Type mismatch for method Player.add: parameter points needs NUMBER, but this argument looks like TEXT.
Method Player.add needs argument points as NUMBER, but this call does not provide it.
Method Player.rename needs 1 argument, but this call gives 0. Add the missing argument.
Method Player.add only accepts 1 argument, but this call gives 2. Remove the extra argument.
If a learner calls a simple object method before creating the object with NEW, claro typecheck now points to the missing setup instead of letting the dotted call look like an ordinary unknown function. This covers both the modern DO player.add 5 form and the older compatibility CALL player.add WITH 5 form, including CALL mistakes where the method name itself is wrong:
Object player is not known yet. Create it with NEW ClassName player before calling player.add.
Object player is not known yet. Create it with NEW ClassName player before calling player.fly.
If the object exists but the class does not declare that method, Claro now names the class and suggests where to add the missing TEACH block. This is validated for both modern DO player.fly 5 and compatibility CALL player.fly WITH 5 calls:
Object Player has no method fly. Check the method name or add TEACH fly inside CLASS Player.
For simple object fields created with NEW Class name, claro typecheck also catches direct wrong-type field assignments such as SET player.score "ten" when the class says HAS score NUMBER. This remains true if the HAS field appears after a simple method in the class, so learners get the field-type error instead of a misleading unknown-field hint:
Type mismatch for field player.score: expected NUMBER, but this value looks like TEXT.
It also catches direct assignments to undeclared fields and suggests the matching HAS line:
Object Player has no field level. Check the field name or add HAS level NUMBER to the class.
The same field check follows a simple object alias. After SET alias player, assignments through alias.score still use the field type declared by Player:
NEW Player player
SET alias player
SET alias.score "ten"
Type mismatch for field alias.score: expected NUMBER, but this value looks like TEXT.
The same check follows simple arithmetic and text-concatenation expressions. For example, SET player.score player.name + 1 now names the text operand and explains that addition into a NUMBER field needs numeric values, rather than silently accepting an expression whose result cannot fit the field.
The checker identifies text operands in arithmetic expressions and explains the operator rule instead of treating an invalid numeric field assignment as an unknown expression:
Type mismatch for field player.score: subtraction needs NUMBER values, but player.name looks like TEXT.
Type mismatch for field player.score: addition needs NUMBER values, but player.name looks like TEXT.
Type mismatch for field player.score: multiplication needs NUMBER values, but player.name looks like TEXT.
Type mismatch for field player.score: division needs NUMBER values, but player.name looks like TEXT.
Valid numeric subtraction is covered too:
SET player.score 10
SET player.score player.score - 2
The focused typecheck validation keeps this valid subtraction example beside the existing valid multiplication and division examples, so a useful expression is not confused with a nearby text-operand mistake.
TEXT-valued and YESNO-valued field-name mistakes are validated too:
Object Player has no field nickname. Check the field name or add HAS nickname TEXT to the class.
Object Player has no field ready. Check the field name or add HAS ready YESNO to the class.
If Claro cannot infer the value type for an undeclared field yet, it avoids exposing the internal ANY placeholder and keeps the hint beginner-facing:
Object Player has no field level. Check the field name or add the field to the class with the right type.
Direct object-field CHECK TYPE metadata mismatches are validated for NUMBER, TEXT, and YESNO fields too. For example, after HAS ready YESNO and SET player.ready YES, CHECK TYPE player.ready IS TEXT reports:
Type check failed: expected TEXT, but player.ready looks like YESNO.
If CHECK TYPE names an undeclared field, Claro now gives the same class-and-field hint as direct field assignment. For example, CHECK TYPE player.level IS NUMBER after NEW Player player reports:
Object Player has no field level. Check the field name or add HAS level NUMBER to the class.
TEXT expectations are validated with the same pattern, for example CHECK TYPE player.nickname IS TEXT reports:
Object Player has no field nickname. Check the field name or add HAS nickname TEXT to the class.
YESNO expectations are validated too; CHECK TYPE player.enabled IS YESNO reports:
Object Player has no field enabled. Check the field name or add HAS enabled YESNO to the class.
If a learner checks a field before creating the object with NEW, claro typecheck points to the missing object setup:
Object player is not known yet. Create it with NEW ClassName player before checking player.score.
The same missing-object guidance is now validated for direct field assignment before NEW:
Object player is not known yet. Create it with NEW ClassName player before setting player.score.
The checker also names typed method-body field checks and assignments. Inside Player.rename, CHECK TYPE name IS NUMBER reports Type check failed in Player.rename: expected NUMBER, but name looks like TEXT. Inside Player.add RETURNS NUMBER, SET score score + name reports Type mismatch for field score in Player.add: addition needs NUMBER values, but name looks like TEXT. The same metadata check is covered for compatibility TAKES / LEARNED methods with YESNO fields, so CHECK TYPE ready IS TEXT reports Type check failed in Player.toggle: expected TEXT, but ready looks like YESNO. The learner sees that the field belongs to the current class method, not an unrelated variable.
The release validator also runs the modern and compatibility method-body field diagnostic fixtures, including CHECK TYPE checks in older TAKES / LEARNED methods, so these learner-facing errors remain part of claro validate, not only the standalone typecheck diagnostic script.
Project and package workflow
v1.18.26 hardens Claro's project/package workflow.
Create a starter project:
claro new MyProject
cd MyProject
claro run
Manage packages:
claro package init
claro package add text
claro package list
claro package remove text
claro package doctor
claro package lock
Claro now creates and maintains:
claro.project
claro.lock
packages/
claro package doctor also checks that every listed package has a manifest whose
name: matches the package name in claro.project; a mismatch is reported as
BAD package manifest name instead of being treated as a healthy package.
It also compares the complete checksum: field, so extra or trailing checksum
text, or a duplicate checksum field, is rejected as BAD package checksum.
Package manifests must contain exactly one version: 1 field; duplicate or
prefix-matching values such as version: 10 are rejected as BAD package version.
The project manifest must contain exactly one manifest-version: 1 field; duplicate
or prefix-matching values such as manifest-version: 10 are rejected as
BAD project manifest version: expected 1. It must also contain exactly one non-empty name: field;
otherwise doctor reports BAD project manifest name: expected a non-empty name.
Starter projects created with claro new MyProject use the same manifest-version: 1 and lock-version: 1 headers as claro package init, so the first project files match the package maintenance tools.
Project names and package names are checked so unsafe names such as ../bad are rejected before Claro creates folders. Names must also be 64 characters or fewer, which keeps generated project and package paths predictable. If an unsafe package name is already present in claro.project, claro package doctor, claro package lock, claro package list, claro package init, claro package add, and lockfile refreshes during claro package remove flag it instead of treating it as safe lockfile data. claro package remove can also remove the exact unsafe entry, so a learner can repair a bad project file without Claro using that unsafe name as a folder path. claro package doctor also verifies listed package lockfile checksums, reports stale lock entries, and rejects lockfile package entries that are not listed in claro.project.
Standard-library path and collection helpers
Claro includes tested, namespaced helpers for everyday programs:
IMPORT "lib/path.claro" AS path
IMPORT "lib/collections.claro" AS collections
CALL path.join WITH "notes", "today.txt"
SAY RESULT
SET names AS LIST OF TEXT TO LIST
ADD "Ada" TO names
ADD "Grace" TO names
CALL collections.join WITH names, " and "
SAY RESULT
The path module includes join, basename, dirname, ext, stem, and absolute. The collections module includes list length/search/join/reverse helpers and map key/value/default-access helpers. See docs/STDLIB.md for the complete, current API.
Networking
v1.18.26 adds safer beginner networking commands with offline claro:// test URLs.
HTTP CHECK "claro://hello" AS safe
SAY safe
HTTP GET "claro://hello" AS page STATUS status
SAY page
SAY status
HTTP SAVE "claro://json" TO "network_demo.json" AS saveStatus
SAY saveStatus
The latest HTTP status is also stored in LASTHTTP. Real http:// and https:// requests use curl when available, while claro:// works offline for lessons and tests.
Useful commands
claro help
claro --version
claro test
claro validate
claro doctor
claro examples
claro check examples/quiz.claro
claro typecheck examples/type_hardening.claro
claro fmt examples/quiz.claro
claro repl
claro new MyProject
claro run
claro package init
claro package add text
claro package list
claro package doctor
claro ide
Good first scripts
./claro lessons/01_hello.claro
./claro examples/quiz.claro
./claro examples/simple_functions.claro
./claro examples/objects_classes.claro
./claro examples/text_polish.claro
./claro examples/networking.claro
Documentation map
If you are new to Claro, start here:
docs/QUICK_START.mddocs/FIRST_HOUR.mdlessons/README.mddocs/CLI.mddocs/CURRENT_STATUS.md
Feature references by current status:
- Ready for beginner lessons: language reference (
docs/SPEC.md), friendly errors/checking (docs/ERRORS.md,docs/LINTER.md,docs/TESTING.md), formatter (docs/FORMATTER.md), and simple functions (docs/SIMPLE_FUNCTIONS.md). - Foundation present, still being polished: static typing (
docs/ADVANCED_STATIC_TYPING.md), objects/classes (docs/V1_15_OBJECTS_CLASSES.md), local projects/packages (docs/V1_16_PACKAGES_PROJECTS.md), HTTP client networking (docs/V1_17_NETWORKING.md), cooperative tasks (docs/CONCURRENCY.md), and IDE metadata/helper support (docs/IDE.md). - Planned or experimental, not stable beginner features yet: remote package registry (
docs/PACKAGE_REGISTRY.md), web server API (docs/WEB_SERVER_PLAN.md), full editor extension/LSP (docs/EDITOR_EXTENSION_PLAN.md), and real SDL graphics (docs/GRAPHICS.md,docs/SDL12.md). - Roadmaps:
docs/ROADMAP.mdfor the current v1 direction anddocs/COMPLETE_PLATFORM_ROADMAP.mdfor the larger platform goal.
Historical release notes and validation logs are kept in files such as docs/RC*_NOTES.md, docs/RC*_VALIDATION.md, and older docs/V1_*_VALIDATION.md. They are useful for project history, but they are not the beginner starting path.
Release direction
Claro should remain in the v1.xx.yy line for normal development. A future Claro v2 should mean a full rewrite years later, not an ordinary feature update.