Next we enumerate the fundamental concepts to grasp Bee syntax. After this overview we will go in details. We use long pages you can scroll. Here are the main topics for this page:
We use examples and sometimes a simplified version of BNF notation to explain the syntax rules. If you do not know anything about BNF don't wary, here is a short introduction to this weird notation:
Comments are very important part of Bee code. We have multiple conventions for making good comments for any project. Bee comments are tailored by architectural principle: "if there are no comments in the code the code is wrong."
In next example we are using various comments into a demo program.
#!/bin/bee
+------------------------------------------------------------------
| At the beginning of program you can have several comments, |
| to explain how the program works. This notation is preferred. |
+-----------------------------------------------------------------+
rule main:
continue; -- this statement does nothing
** this is a single line comment
print ("end of line comments", -- first argument
"can be used to explain", -- second argument
"diverse arguments" -- third argument
);
return;
*******************************************************************
** This is the old style boxed comment, used for matrix printers **
** In Bee you can add comments/notes at the end of your code **
*******************************************************************
For single line title comments we use one "#" symbol. This can be used in combination with "!" to create "shebang" comment known in scripting languages on Linux to specify interpreter location. You can use two "##" for subtitles for large code sections.
For single line comments we use two stars like this: "**";
Before new line of code: (EOL) you can use comments starting with: "-- "
Bee has a specific notation for block comments not used in any other language so far. It is a multi-line comment starting with "+-" and end with "-+". The upper right corner is missing. I guess you will notice this defect later. However you can use old-style C comments.
Bee is an expressive language but it's core has about 72 reserved keywords so far:
begin | alias | and | apply | abort |
other | case | continue | done | default |
if | is | do | else | exit |
fail | final | miss | panic | like |
load | next | job | match | over |
pass | void | rule | return | |
fail | retry | none | scrap | type |
read | trial | stop | yield | xor |
write | wait | when | or | with |
hide | new | cycle | let | set |
while | for | resum | put | pop |
raise | not | as | in | start |
try | expect |
Keyword | Purpose |
---|---|
if | conditional executor for one statement block |
is | query element or variable data type |
as | create alias for used modules |
or | alternative for ladder decision |
in | alternative for belong operation |
and | alternative for cascade decision |
xor | alternative for logic operation |
not | alternative for logic operation |
Statements can start with imperative keyword or a declarative keyword:
set | create a constant |
new | create a variable |
let | modify a variable |
type | create a data type |
read | accept input from console into a variable |
write | register in console cash a string |
output to console with end of new line |
Statements can be contained in blocks of code.
Keyword | Block description |
---|---|
start | start local scope for do block |
with | qualifier suppression block |
if | first block in decision statement |
cycle | repetitive or iterative blocks |
match | multi-path value selector block |
trial | exception handler block |
Next statements are used to declare new elements in a module.
Keyword | Purpose |
---|---|
use | Load module or module |
alias | Eliminate scope qualifier |
hide | Hiding public members from a loaded module |
rule | Create a new business rule or prototype |
return | End rule declaration and transfer control to caller |
Next keywords are simple statements. These represents actions called imperative statements.
Keyword | Purpose |
---|---|
apply | Execute a rule and ignore the result if there is one |
begin | Commence execution of a coroutine |
wait | Suspend current thread execution for a number of seconds |
read | Flush the console buffer and accept user input from console |
write | Add something to console buffer but no new line |
Output expression result, variable or constant to console | |
let | Mutate variable value using an expression |
scrap | Remove one element from its collection |
Control statements are used to create local blocks of code that resolve a small task synchronously. After task is finished the control is returned to the main thread.
Keyword | Purpose |
---|---|
start | Create non repetitive local scope |
if | Start a conditional branch |
else | Start an alternative branch |
do | Start a block of code |
cycle | Create repetitive local scope |
for | Create finite iterative block |
while | Create conditional repetitive block |
match | Value multi-path search selector |
when | Create node for match statement |
other | Default branch for match statement |
trial | Start declaration region for a protected block of code |
try | Begin the executable region in a trial statement |
case | Associated with trial to resolve specific errors |
miss | Default trial block, executed when there is no case |
final | Associated with trial to finalize the trial block |
These statements execute a jump or make an interruption of current thread.
Keyword | Purpose |
---|---|
panic | Create unrecoverable error code and stop current program |
over | Silent termination of program. No error is raised in this case. |
exit | Silently stop execution of current rule and return to the caller |
yield | Suspend one coroutine and give control to another routine |
rest | Suspend a routine and wait for all threads created by the routine to finish |
stop | Interrupt execution for current cycle and continue after the cycle, |
redo | Continue current cycle from the beginning making a shortcut, |
next | Continue current iteration from the beginning making a shortcut, |
abort | stop early a trial block |
fail | Create error message and continue with next step |
pass | Skip the rest and continue with next step |
expect | Does nothing if condition is true, otherwise create an $unexpected exception |
raise | Intrerupt a try job or trial and issue an error |
retry | Repeat a trial block from the begioning |
resume | Mark error as handled and continue trial |
done | end a block statement |
repeat | end a repetitive block |
Bee identifiers can start with dolar ($), dot (.), underscore (_), Latin, Greek, Chyrillic. An identifier can contain numbers but can not start with a number.
In mathematics is very popular notation for angles to use Greek letters. We support in Bee a limited number of Greek an Cyrillic letters for identifiers:
Σ Π Δ Ξ Γ Ψ Ω ζ α β ɣ λ π μ φ ε δ η σ ω Б Г Д Ж И Л Ф Ц Ч Ш Э Я
You can use a limited number of letters and numbers available in Unicode as subscript to make identifier names. You can not start an identifier with one of these symbols and you can't add other symbols that are not subscript after a subscript:
x₀ x₁ x₂ x₃ x₄ x₅ x₆ x₇ x₈ x₉ x₁₀ yₐ yₑ yₕ yᵢ yⱼ yₖ yₗ yₘ yₙ yₒ yₚ yᵣ yₛ yₜ yᵤ yᵥ yₓ
Bee has support for exponent using superscript. You can make any integer exponent including negative numbers but you can not use dot or fraction in the exponent.
x⁺ x⁻ x¹ x² x³ x⁴ x⁵ x⁶ x⁷ x⁸ x⁹ x¹⁰
Note: Symbol (^) is exponent operator and is not required when you use superscript exponent. You can use it with expressions, constants or rational numbers to resolve the exceptional cases.
Identifiers that start with a lowercase Latin letter can be used as exponent. The superscript variable can start with a letter and can also use numbers.
yᵃ yᵇ yᶜ yᵈ yᵉ yᶠ yᵍ yʰ yⁱ yʲ yᵏ yᶩ yᵐ yⁿ yᵒ yᵖ yʳ yˢ yᵗ yᵘ yᵛ yʷ yˣ yʸ yᶻ
If you define a constant or variable that start with capital letter there may be some issues. You can't use all Latin letters or any Greek or Cyrilic capital letters in exponent. So your options are limited to create uppercase exponents.
zᴬ zᴮ zᴰ zᴱ zᴲ zᴳ zᵸ zᴵ zᴶ zᴷ zᴸ zᴹ zᴺ zᴻ zᴼ zᴾ zᴿ zᵀ zᵁ zᵂ
In Bee, all variables must be declared using an imperative statement. Variables can be dynamic or static and can have a data type. Data type can be custom or pre-defined.
type | declare custom data type |
new | declare a dynamic variable |
set | declare a static variable |
Expressions are created using identifiers, operators, rules and constant literals. Expressions can be anonymous or can be assigned to identifiers to create lambda expressions.
expressions ...
** expressions
print 10
print 10 + 10 + 15
print "this is a test"
** complex expressions
print (10 > 5) ∨ (2 < 3)
print -b + sqr(b² - 4·a·b)/(2·a)
** enumeration of expressions
print (1,2,3)
print (1,',',2,',',3)
A condition is a logic expression used to control statement execution. For this we use {"if", "else"} keywords at end of statements.
** conditional statement execution
statement if condition;
Note: Previous statement is executed only if the condition is True.
** alternative statement
expect condition else statement;
** alternative expression
expect condition else expression;
Note: Previous statement is executed only if the condition is False.
restrictions:
rule main:
** generate a random number
new a := random(Z);
** conditional execution
new b := a;
let b := -a if a < 0;
** print result
print "|b| = ", a;
return;
Bee has support for fractions. Bee is using regular slash "/" for all fractions. You can use superscript for left and subscript for right: These two are equivalent (1/2 = ¹/₂). Unfortunately we can not support fractional power due to lower readability.
¹/₂ ¹/₃ ¹/₄ ¹/₅ ¹/₆ ¹/₇ ¹/₈ ¹/₉ ¹/₁₀ ¹/₁₀₀ x⁻¹ = 1/x, x⁻² = 1/x², x⁻³ = 1/x³ ...
Power operations have priority but we have support only for (+, -) no other operations are possible in exponent. In next expressions, (n-1) is done first before making the power operation.
-- equivalent notation xⁿ⁻¹ = x^(n-1) xˣ⁺¹ = x^(n+1) -- equivalent notation x^(¹/₂) = √2(x) x^(¹/₃) = √3(x)
Instead of ternary operator we use conditional expressions. Conditional expressions enable many choices unlike ternary operator that enable only 2 choices. Conditional expressions are also known as pattern matching expressions.
rule main:
** define a local variable
new var ∈ type;
** single condition matching
let var := (xp1 if cnd1 else xp);
** multiple matching with default value
let var := (xp1 if cnd1, xp2 if cnd2,..., xp);
** alternative code alignment
let var := ( xp1 if cnd1 else
xp2 if con2 else
xp3 if cnd3 else
xp
);
return;
rule main:
new x := '0'; -- symbol
write "x:"
read x;
new kind := ("digit" if x ∈ ['0'..'9'] else
"letter" if x ∈ ['a'..'z'] else
"unknown");
print ("x is " + kind); -- expect: "x is digit"
return;
Bee operators are ASCII or Unicode symbols. One operator can be created using one or two characters. This is why Bee language is considered experimental, esoteric & disruptive.
Symbol | Description |
---|---|
+-...-+ | Multi-line boxed comments |
#(....) | String interpolation (placeholder) for operator "?" |
(_,_,_) | Expression | List literal |
[_,_,_] | Index | Array literals | Parameterize types |
{_,_,_} | Enumeration type | Set of values | Hash map |
symbol | description |
---|---|
`x` | Back quoted string: regular expression. |
'x' | Single quoted string literal or ASCII code point |
"y" | Double quoted string literal or UTF32 code point |
symbol | description |
---|---|
! | Negation symbol for relations | Excluded from domain |
? | Template modifier. Associated with string templates |
* | String replication | Varargs prefix | Spread operator | Many something |
@ | Domain name | Example @sagecode.pro |
$ | System constant | Environment variables |
& | String concatenation | number concatenation |
# | Title | String interpolation |
∈ | Define variable/constant/result/parameter type |
_ | Anonymous variable | Constant value = one space (_ = ' ') |
+ | Maximum upper limit for a domain | Unicode notation U+ |
- | Minimum lower limit in a domain | Unicode notation U- |
: | Start a block or define something |
: | Pair-up key-value in: objects, rule parameters, rule arguments, hash-map pairs |
; | End of statement | Statement separator |
. | Decimals for real numbers | Path string concatenation |
. | Membership dot notation | Prefix for public member/attribute |
, | Enumeration of elements | expressions |
| | Declarative collection builder: set := { x*2 | x ∈ (0..3)} |
\ | Escape character ( \n := New Line), ( \" = Double Quotes) |
Listed in the order of precedence top down.
symbol | description |
---|---|
- | Change sign, replace "y = -x" with "y = -1*x" |
/ | Rational number division |
^ | Power symbol used with fractions or expressions |
√ | Radical: x√n is equivalent to x^(1/n) |
* | Multiplication alternative |
\ | Rational number division |
/ | Real number division |
× | Array multiplication | Matrix multiplication |
% | Modulo operator 5 % 2 = 2 |
+ | Numeric addition | List append | Matrix addition |
- | Numeric subtraction | Collection difference |
± | Numeric tolerance (use with ≈) |
Double symbols is a group of two ASCII symbols considered as one. Some of these symbols have an Unicode equivalent, some do not. When available, Unicode equivalent is preferred choice.
symbol | description |
---|---|
-- | End of line comments (not in expression) |
## | Single line subtitle comments (no indentation) |
** | Single line comments (allow indentation) |
.. | Define range/domain/slice (n..m) | [n..m] |
.! | Define range/domain with excluded limit (n.!m) | [n.!m] |
!. | Define range/domain with excluded limit (n!.m) | [n.!m] |
!! | Define range/domain with excluded limits: (n!!m) | [n.!m] |
-. | Minus infinite domain: instead of [-∞..0] write: [-..0] |
.+ | Plus infinite domain: instead of [0..+∞] write: [0..+] |
=> | Define: rule expression | rule result |
<- | Define and generate values in a loop from range or set |
<: | Define subset from set | Specify super-type for a new type |
:> | Data cast pipeline operator / Type conversion |
<< | Shift values of collection to right by removing first elements |
>> | Shift values of collection to left by removing first elements |
:: | Deep copy | Clone operator |
++ | Extend an array with one or more elements |
-= | Find and delete one element, from a collection | += | Append an element in a set or a map but not in a list |
+> | Append element to beginning of a list |
<+ | Append element to end of a list | == | Relation operator for identical (the same) | != | Relation operator not identical (not the same) |
~= | Relation operator: regular expression match |
>= | Relation operator: greater then or equal to |
<= | Relation operator: less then or equal to |
Each modifier is created with pattern "x=" where x is a single symbol:
symbol | meaning |
---|---|
:= | Modify | (value | reference) |
+= | Increment value |
-= | Decrement value |
*= | Multiplication modifier |
/= | Real division modifier |
^= | Power modifier |
√= | Radical modifier |
%= | Modulo modifier |
Relation operators are used to compare expressions.
symbol | meaning |
---|---|
∈ | check if element belong to collection |
= | equal { compare values or attributes} |
≠ | different { compare values or attributes} |
≡ | equivalent | { compare values / convert type } |
≈ | approximating equal numbers, used with ± like: (x ≈ 4 ± 0.25) |
> | value is greater than: (2 > 1) |
< | value is less than: (1 < 2) |
≥ | greater than or equal to |
≤ | less than or equal to | ÷ | Exact divisor: 3 &division; 15 ≡ True |
negation:
Operator: "!" can be used in combination with other operators:
x != y; -- equivalent to: ¬(x = y) x !≡ y; -- equivalent to: ¬(x ≡ y) x !∈ y; -- equivalent to: ¬(x ∈ y) x !≈ y; -- equivalent to: ¬(x ≈ y) x !~ y; -- equivalent to: ¬(x ~ y)
symbol | result | meaning |
---|---|---|
∩ | Set | Intersection between two collections |
∪ | Set | Union between two collections |
⊂ | Logic | Set is included in superset: "⊂" |
⊃ | Logic | Set contain subset: "⊃" |
Δ | Set | Set symmetric difference |
+ | String | Concatenation between two strings |
+ | List | Concatenation between two lists |
+ | Array | Concatenation between two arrays |
∀ | Element | All: used in collection qualification |
∃ | Logic | One: used in collection qualification |
Bee is using enumeration symbols: True = 1 and False = 0
symbol | meaning | notes |
---|---|---|
¬ | NOT | unary operator |
∧ | AND | shortcut operator |
∨ | OR | shortcut operator |
⊕ | XOR | exclusive OR |
↓ | NOR | p ↓ q = ¬ (p ∨ q) |
↑ | NAND | p ↑ q = ¬ (p ∧ q) |
p | q | ¬ p | p ⊕ q | p ∧ q | p ∨ q |
---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
0 | 1 | 1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 | 0 | 0 |
Bitwise operators are processing numbers not Boolean values.
symbol | meaning | notes |
---|---|---|
« | bit SHIFTL | shift bits to left |
» | bit SHIFTR | shift bits to right |
~ | bit NOT | negate all bits |
& | bit AND | execute AND between each bits |
| | bit OR | execute OR between each bits |
⊕ | bit XOR | execute XOR between each bits |
a | ~ a | a « 1 | a » 2 |
---|---|---|---|
0000 | 1111 | 0000 | 0000 |
1111 | 0000 | 1110 | 0011 |
0111 | 1000 | 1110 | 0001 |
0110 | 1001 | 1100 | 0001 |
a | b | a & b | a | b | a ⊕ b |
---|---|---|---|---|
00 | 00 | 00 | 00 | 00 |
01 | 00 | 00 | 01 | 01 |
11 | 01 | 01 | 11 | 10 |
10 | 11 | 10 | 11 | 01 |
Symbol | Description |
---|---|
* | string pattern repetition (right operator must be numeric) |
/ | concatenate url or path using / not depending on OS |
+ | concatenate two strings as they are preserving trial spaces. |
- | concatenate two strings and trim spaces to a single space. |
. | concatenate strings with "/" on Linux or "\" on Windows. |
? | string format operator, replace "#" with number. |
Read next: Structure