This document contains preliminary information about U development. It's a live document subject to change.
U syntax is concise and defined by very few but necessary rules to have coherent grammar. Built-in literals can be tailored with ugo.
Source File¶
A U project consists of files in a directory structure managed by ugo, U build system.
Here is U file properties:
- Source code is UTF-8 encoded
- Comments, characters and string literals can contain Unicode characters
- Default character value is as wide as a Unicode character: up to 4 bytes
- Default String value are stored in UTF-8 but may be iterated by char, byte, or Unicode elements.
Main¶
U programs do not need a special function named main
that is invoked to start the program. U uses the very last statement of root file.The root file is either the one passed in the command line or specified in ugo's build file.
'\/'
, the V of U. The symbol consists of the escape apertures '\'
followed by a slash '/'
.
No keywords¶
U syntax is easy to learn and consistent. Unlike other languages, there is, and there will be no direct keywords. All U keywords are guarded with apertures ::
like ::if
. Therefore if
, while
are valid identifiers in U. Readability is key when choosing your identifiers.
As U adoption increase, new needs will arise either for new business models or new hardware platform: new Iphones, AI models, better web architecture, autonomous cars, ...
For example, suppose in five years a new paradigm arise. In that case, it will be easy to add %new-feature
to your code with simply a user defined syntax to implement your logic without breaking legacy code and most critically, without changing U syntax.
Invalid characters¶
U grammar is very permissive. Few character combinations are rejected, mainly when the code is ambiguous. Here are simple examples of invalid source code:
Statements¶
U is line-based, with optional semicolons, like most modern programming languages (Python, Ruby, Swift) because it's visually pleasing. U doesn’t require you to write semicolons. They are only necessary if you want to write multiple statements on a single line.
A semicolon is also required when using delimiters with parameters in a single line:
See Delimiters.
Comments¶
Comments are ignored by the U compiler. They begin with two back-slashes #
. Back-slash character has been chosen because it's not widely used in code bases outside strings. It's a perfect character to improve expressiveness by allowing you to use any character in your source code.
Single line comment¶
Single line comments start with two back-slashes and extend to the end of the line.
Multi-line comment¶
Multi-line comments start with two back-slashes followed by an open parenthesis #(
and end with two back-slashes followed by a close parenthesis #)
:
Nested comment¶
Comments can be nested.
Whitespace¶
Usually, whitespaces – spaces, tabs, weird unicode characters, carriage returns, line breaks, ... – are ignored by parsers as they have no syntactic value. But U is whitespace sensitive for three main reasons:
- Visually coherent: if you have not previously learned that whitespace does not have syntactic meaning in a programming language, then the Principle of Least Astonishment seems natural with U.
- Expressiveness: if
car:run
is different thancar : run
, then more expressions are possible. - Productivity: a linter is not yet necessary in U. You don't need to format your code before sharing it.
If whitespace has meaning to humans, then it should have meaning to machines as well.
It simply means that a combination of space character: ' '
, tab: '\t'
, or comments is treated as a separator. However, the number of spaces is not significant.
Whitespace-sensitivity allows you better expressiveness and more operators (an operator can be prefix, infix, postfix).
:a : [1, 2, 3]
\< a.* 2 # Prints [2, 4, 6] ; multiply EACH element of array 'a' by 2
\< a .* 2 # Prints [[1, 2], [2, 4], [3,9]] ; create pair of 'a' values associated with their double
In the above example, Whitespace sensitivity allows an operator without space .*
and another one with spaces around .*
.
Names, Symbols, and Identifiers¶
Many languages are annoyingly strict about what characters are valid in names. U has very few limits on names.
A name is an interned string i.e. a string associated to a number. The compiler uses names to store and retrieve Values. A name is not accessible from the source code (User dim).
Names rules are:
- Names can contain almost all non-space Unicode characters.
- Names must start with a letter followed by letters, numbers
- Unlike other languages, hyphens
-
and operators might be part of a name when enabled in Ugo: for exampleserver-index?
.
Using hyphens as separators in names increases readiness and productivity:
* you don't have to choose between camelCase
or snake_case
code style.
* names with hyphen are easier to convert to values: login-screen
can easily be converted to a class LoginScreen
, an id login_screen
, or a file name login/screen.png
.
* hyphens are allowed in some languages like css
In U, there are only two named Values:
- Symbol: Symbols start with aperture
':'
followed by a name. - Identifier: Identifiers are simply names in the source code. Identifiers are a reference to a variable.
Here are some examples of names:
:var : 2 # ':var' is a Symbol named 'var'
f var - 3 # 'f', 'var' are Identifiers
# Unicode
:timon : "Timon"
:丁满 : "丁满 in chinese"
:Тимон : "Тимон in russian"
:🐨 : "koala that look like Timon"
:π : 3.14159
# Operator in names
:is_enabled?
:function->>: 1
function->> a, b
:'+++' :> ... # Define an operator '+++'
:result : 1 +++ 4
Delimiters¶
In U, delimiters are Values:
(...)
: define a lexical level grouping like a sequence(a, b)
. Any sequence element is separated by a comma','
.{...}
: define a function, closure, or any construct that needs to execute statements. See Functions.[...]
: define a data model that needs storage at compile time or at run time like sets, array, hash map. See Collections.
{}
, and []
denotes function definition in U. It means that they accept parameters and specialization with operators:
# A function with 2 parameters
{: a, b; a + b }
# An Array that ensure every item pushed is in meter/second
[<< meter-per-second-!; ... ]
See Functions.
See Collections.
Values¶
See Values.
Documentation¶
U has documentation in a predefined format. For example, in markdown:
See Documentation.
Tests¶
U has built-in test and validation constructs:
See Tests.