GeezerVison is showing cuffscript.pages.dev — CuffScript — A Human-Friendly Programming Language
CuffScript
“As easy as a game, as light as a feather, and as fast as a flash.”
CuffScript is a language built less to perfect any one piece of syntax than to make programming itself feel less intimidating. There is nothing to install or configure: open the IDE and you can run your first line in your browser within a few seconds.
Highlights
What sets CuffScript apart, in six short programs. Every snippet here is run by the real engine when the site is built, so the output shown is the output you get.
Reads like plain English
Keywords are words you already know: if, loop, and, or, is, do: and end. A variable is declared with its type, as in number age = 25, and changed with a plain =. A block opens with do: and closes with end, so you can always see where it starts and stops.
number age = 25
age = age + 1
if age >= 18 do:
print("adult")
end
adult
Counting starts at 1
The first item of a list or a text is number 1, a slice includes both of its ends, and -1 is the last item. It is the way people count.
list colors = ["red", "green", "blue"]
print(colors[1], colors[-1], colors[2~3])
red blue ["green", "blue"]
Patterns you can read
Describe text with words like [num] and [let] instead of cryptic symbols, then use the pattern to check, find, replace or split text.
str phone = "010-1234-5678"
print(phone matches p"[num]3-[num]4-[num]4")
print(replace(phone, p"[num]4-[num]4", "****-****"))
true
010-****-****
Errors you can handle
A statement that fails can be recovered on the spot with or_else, and your own program can raise errors with fail. When an error does stop a program, the report shows the line, points at the problem and often says how to fix it.
number n = to_number("abc") or_else do:
print("not a number, using 0")
n = 0
end
print(n)
not a number, using 0
0
Classes without ceremony
Fields, methods, inheritance and private members, with self to mean the object and no boilerplate around it.
class Dog do:
str name = "Rex"
func speak() do:
return f"{self.name} says woof"
end
end
print(Dog().speak())
Rex says woof
Runs anywhere
The same engine runs in your browser as WebAssembly (the IDE on this site), as the command-line tool cuffc, and inside your own JavaScript or TypeScript project.
npm install cuffscript-wasm
Why CuffScript
The first wall most people hit when they start learning to program is not logic but unfamiliar symbols and strict rules. After a missing semicolon produces a cryptic error message, it is easy to conclude "I can't think logically", when the real problem is only that you haven't memorized the language's rules yet.
CuffScript started from the idea of lowering that first wall. It uses keywords close to the words people actually use (if, loop, is, and, do:, end), and when something is wrong it tells you where and why. Each of these choices adds up to an experience where you can understand what you are doing. That doesn't cost expressiveness: functions, classes, asynchronous execution and regex-style pattern matching are all there, and it is a real, working language for small automation scripts or game logic.
The "Cuff" in the name means a sleeve cuff. Like a tool that sits lightly on your wrist and is always within reach, the hope is that you can put the language on without effort and start making something right away. It suits people who have always been afraid of regular expressions, and people who want to run an idea immediately without setting up a project.
Core syntax at a glance
The guide covers the full syntax step by step; here is just a quick look at what it looks like.
| Concept | Code | Notes |
|---|
| Variable | number x = 10 | Declared with a type, reassigned with =; any holds every type | | Constant | constant list PRIMES = [2, 3, 5] | Names are ALL-CAPS; lists can be frozen like tuples | | Conditions and loops | if x > 0 do: ... end | Every block is wrapped in do: ... end; loop each visits a collection | | Functions | async pure func f() do: ... end | async and pure are optional and can be combined | | Classes | class Hero extends Player do: ... end | Fields, methods, inheritance and private members | | Pattern matching | text matches p"[num]+" | Readable names like [num] instead of \d | | Error recovery | risky() or_else as Error err do: ... end | Recovers only from calls that raise an error, like a game's restart button; err is an object | | Built-in libraries | use DLC:map | 11 libraries: math, string, time, datetime, random, list, map, convert, json, network, filesystem |
Browse the documentation
The language guide is organized into the 8 topics below.
Basics
Values and types, variables and constants, text, operators, indexing, comments
Control flow
Conditionals, loops, printing and input, working with lists and maps
Functions
Declaring and calling functions, parameters, scope and global, pure and async functions
Classes and objects
Classes, objects, private members, inheritance, the with block
Error handling
Reading error reports, or_else, error objects, fail, the error codes
Pattern matching
Pattern literals, tokens, quantifiers, captures, and the text functions
Modules and libraries
Splitting a program into files, and the 11 built-in libraries (DLC)
Reference
Common mistakes, known limitations, related links
Example code
A recursive Fibonacci example.
func fib(number n) do:
if n <= 1 do: return n end
return fib(n - 1) + fib(n - 2)
end
print(f"fib(10) = {fib(10)}")
The IDE comes with 18 ready-made examples that take you from basic syntax to modules, in order.
Get started
Try it right away without installing anything, or bring the engine into your own project.
1. In the browser, with nothing to install
The IDE on this site runs the CuffScript engine itself, compiled to WebAssembly, so you can run code immediately without installing anything.
2. Embed in a JS/TS project
With the cuffscript-wasm package you can run CuffScript anywhere, in Node or in the browser.
npm install cuffscript-wasm
3. Build the native CLI yourself
With just a C++17 compiler you can build cuffc straight from source. (Prebuilt binaries aren't provided yet.) File reading and writing (DLC:filesystem) is available only in this native CLI; it is blocked in the browser IDE.
git clone https://github.com/cuffscript/cuffscript.git
cd cuffscript
make
./cuffc your_script.cuff
For more on the syntax, see the language guide; for the history of changes, see the CHANGELOG.
Frequently asked questions
Short answers to the questions people ask first. Click a question to open it.
Is CuffScript only for beginners?
It is designed to be easy to start with, but it is a complete language and not a toy. It has functions (with typed parameters and default values), classes with inheritance and private members, async calls, pattern matching, error handling with or_else and fail, modules, and built-in libraries for math, text, lists, maps, JSON, dates, time and random numbers. What it leaves out on purpose, such as closures, multiple inheritance and ==, keeps the language small enough to learn completely.
Do I need to install anything to try it?
No. The IDE on this site runs the engine inside your browser, and its Share link button turns your whole program into a URL, so passing code to someone else takes one click. To run files on your own computer, build the cuffc command-line tool from source with a C++17 compiler, or install the cuffscript-wasm package to use CuffScript from JavaScript or TypeScript.
Why does counting start at 1?
Because that is how people count: the first item is item 1, and the last of five is item 5. The same rule applies to lists, texts, slices and the groups captured by a pattern. A slice includes both of its ends, and a negative number counts from the end.
list items = ["a", "b", "c", "d", "e"]
print(items[1], items[-1], items[2~4])
a e ["b", "c", "d"]
Why does = store a value while is compares?
So that each symbol means one thing. = always stores: number age = 25 declares a variable and age = 26 gives it a new value. Comparing is a different job, so it has its own word, and age is 26 reads as a question. Because = never means "equals", putting it where a comparison belongs, as in if x = 1 do:, is a syntax error, and its hint tells you to write is.
number age = 25
age = 26
print(age is 26)
true
How is it different from Python or JavaScript?
Like Python, CuffScript reads close to plain English and indents its blocks. The differences you will notice first are these: counting starts at 1; every block is closed with end; a variable is declared together with its type (number x = 5); patterns are written with readable tokens such as [num] instead of regular-expression symbols; recovering from a failed statement uses or_else instead of try and except; and functions are not values, so there are no closures.
What can I build with it?
CuffScript suits small programs: text processing and validation, working with lists, maps and JSON, calculations, game logic, teaching examples, and scripts that live inside another application. In a browser tab a program has no file access and cannot open network connections. The native cuffc adds reading and writing files and folders (DLC:filesystem) and plain HTTP requests (DLC:network).
What are DLCs?
DLC is the name for the built-in libraries: math, string, time, datetime, random, list, map, convert, json, network, filesystem. You switch one on with a line such as use DLC:math, and from then on its functions, which are named like math_sqrt, can be called directly. There are 11 libraries in this version, and the guide lists every function in each of them.
Can I use it inside my own application?
Yes. The engine is a library: use the cuffscript-wasm package from JavaScript or TypeScript, or the CuffEngine class from C++. The host decides what a program may touch. For example cuffc can switch the network and file libraries off (--no-network, --no-filesystem) and give a program a step or time budget (--max-steps, --timeout).
Is it safe to run a program I did not write?
CuffScript is built so that a program can do only what its host allows. File access is confined to one folder and cannot escape it with .. or links, network requests to local and private addresses are blocked, and an execution budget stops runaway loops. In the browser IDE the file library is blocked and the browser stops raw network access. Treat these as protections and not as a guarantee, and read the project's security policy before you rely on them for untrusted code.
Is it free to use?
Yes. CuffScript is open source under the Apache-2.0 license, so you can use it, change it and ship it in your own projects under that license's terms.
Where should I start?
Open the IDE, pick a program from the Load an example menu and run it. Then read the guide from its first page: each page teaches one area and explains the rules before it shows examples.
Community & contributing
CuffScript is an open-source project released under the Apache-2.0 license. If you find a bug or want to suggest a feature, please open an issue first. Large features sent as pull requests without prior discussion may be turned down.
|