Profiles / Programming
TM

The MQL language in depth

Data types and null, booleans, comments, variables and scope, eval and mql blocks, coded errors and try.

10 recipes on this page · open in the interactive view

Recipes
  1. MQL syntax, nesting and numeric traps
  2. Null, empty and blank fields of an API payload
  3. Booleans and feature flags typed by hand
  4. Comments, line ends and quoting: a CSV export for Excel
  5. Variables: dynamic names, counters and their traps
  6. Variable scope: execute, call and include compared
  7. Discount rules engine with mql and eval
  8. Coded errors, nested try and a finally step: a payment pipeline
  9. Loops: continue, break, retry with backoff and parallel
  10. Atom lists: negotiate the language of a response
executed on MentDB

MQL syntax, nesting and numeric traps

The rule of every MQL statement (category, action, parameters), operator order decided only by nesting, n-ary operators, and the numeric traps: double rounding, division by zero, a non-number giving null, bare words and the difference between equal and ==.

Pipeline
Script
admin
#1. Syntax: category, action, then the parameters, separated by spaces;
-> "[len]" (string length "MentDB");
#2. No operator precedence: the nesting decides. Price 12 + 8 x 3 then the reverse;
-> "[a]" (+ 12 (* 8 3));
-> "[b]" (* (+ 12 8) 3);
#3. Arithmetic operators take any number of operands;
-> "[sum]" (+ 10 20 30 40);
#4. Numbers are strings that look like numbers: double precision traps;
-> "[float]" (+ 0.1 0.2);
-> "[exact]" (bd+ 0.1 0.2);
-> "[div0]" (/ 1 0);
-> "[sci]" (* 1e3 2);
-> "[nan]" (+ 1 "abc");
#5. A word without quotes is a string too, quotes are needed for spaces;
-> "[word]" (concat Hello "-" World);
#6. Compare texts with equal, numbers with ==;
concat "string length: " [len] ", 12 + 8x3 = " [a] ", 12+8 x3 = " [b] ", sum of four: " [sum] [_n_] "+ 0.1 0.2 = " [float] ", bd+ 0.1 0.2 = " [exact] [_n_] "1/0 = " [div0] ", 1e3 x 2 = " [sci] ", 1 + abc = " [nan] ", is null: " (is null [nan]) [_n_] "bare words: " [word] [_n_] "equal 1.0 1 = " (equal "1.0" "1") ", == 1.0 1 = " (== "1.0" "1") ", type is_number 1e3 = " (type is_number "1e3") ", type is_integer 2.0 = " (type is_integer "2.0" 5);
Result
mentdb
string length: 6, 12 + 8x3 = 36, 12+8 x3 = 60, sum of four: 100
+ 0.1 0.2 = 0.30000000000000004, bd+ 0.1 0.2 = 0.3
1/0 = Infinity, 1e3 x 2 = 2000, 1 + abc = , is null: 1
bare words: Hello-World
equal 1.0 1 = 0, == 1.0 1 = 1, type is_number 1e3 = 1, type is_integer 2.0 = 0
Go further
  • Use bd+ bd- bd* bd/ for money, bi* for big integers.
  • + 1 "abc" returns null without error: validate inputs with type is_number first.
executed on MentDB

Null, empty and blank fields of an API payload

Classify the fields of a partner payload (missing value, JSON null, empty, spaces, the text null) with is null, is empty, is null or empty and string is_blank, and see how a null variable behaves.

Pipeline
Script
admin
#1. A customer payload from a partner API: missing, null, empty and blank fields;
json load "tuto_lang_cust" "{\"name\": \"Ana Lopez\", \"phone\": null, \"company\": \"\", \"vat\": \"   \", \"note\": \"null\"}";
-> "[report]" "";
-> "[fields]" "name,phone,company,vat,note";
for (-> "[i]" 1) (<= [i] (atom size [fields] ",")) (++ "[i]") {
	-> "[f]" (atom get [fields] [i] ",");
	-> "[v]" (json select "tuto_lang_cust" (concat "/" [f]));
	#2. Four different tests, four different answers;
	-> "[report]" (concat [report] (string rpad [f] "." 9) " is null " (is null [v]) ", is empty " (is empty [v]) ", is null or empty " (is null or empty [v]) ", string is_blank " (string is_blank [v]) [_n_]);
};
json unload "tuto_lang_cust";
#3. A null variable exists, prints as nothing in concat, and is not the text null;
-> "[fax]" null;
concat [report] "fax exists: " (env exist var "[fax]") ", printed: [" [fax] "], is null: " (is null [fax]) ", text null is null: " (is null "null");
Result
mentdb
name..... is null 0, is empty 0, is null or empty 0, string is_blank 0
phone.... is null 1, is empty 0, is null or empty 1, string is_blank 1
company.. is null 0, is empty 1, is null or empty 1, string is_blank 1
vat...... is null 0, is empty 0, is null or empty 0, string is_blank 1
note..... is null 0, is empty 0, is null or empty 0, string is_blank 0
fax exists: 1, printed: [], is null: 1, text null is null: 0
Go further
  • is empty null is 0 and is null or empty " " is 0: use string is_blank for required text fields.
  • The text "null" is not null: compare it with equal if a partner sends it.
executed on MentDB

Booleans and feature flags typed by hand

Read feature flags from a config line: if is true only for 1 or true, so yes, TRUE, 2 or a variable holding the text true are false; normalize with type is_enum and see how and, or, xor and not treat non-boolean texts.

Pipeline
Script
admin
#1. Feature flags typed by hand in a config file;
-> "[flags]" "dark_mode=1,beta=true,export=yes,chat=TRUE,audit=2,legacy=0";
-> "[out]" "";
for (-> "[i]" 1) (<= [i] (atom size [flags] ",")) (++ "[i]") {
	-> "[name]" (atom get (atom get [flags] [i] ",") 1 "=");
	-> "[raw]" (atom get (atom get [flags] [i] ",") 2 "=");
	#2. if sees true only for 1 and true, any other text is false;
	-> "[as_if]" (if ([raw]) {"ON"} {"off"});
	#3. Normalize: accept a closed list of words, refuse the others;
	-> "[norm]" (case
		(type is_enum (string lower [raw]) "1,true,yes,on") {true}
		(type is_enum (string lower [raw]) "0,false,no,off") {false}
		{"invalid"}
	);
	-> "[out]" (concat [out] [name] "=" [raw] ": raw if " [as_if] ", normalized " [norm] [_n_]);
};
#4. Trap: the literal true is 1, but a variable holding the text true stays a text;
-> "[txt]" "true";
#5. true and false are 1 and 0, and the boolean operators follow the same rule;
concat [out] "true is " true ", false is " false ", not yes = " (not "yes") ", and 1 yes = " (and 1 "yes") ", or 0 true = " (or 0 "true") ", xor 1 0 = " (xor 1 0) [_n_] "if literal true: " (if (true) {"ON"} {"off"}) ", if variable holding true: " (if ([txt]) {"ON"} {"off"}) [_n_] "type is_bool Y Y N = " (type is_bool "Y" "Y" "N");
Result
mentdb
dark_mode=1: raw if ON, normalized 1
beta=true: raw if off, normalized 1
export=yes: raw if off, normalized 1
chat=TRUE: raw if off, normalized 1
audit=2: raw if off, normalized invalid
legacy=0: raw if off, normalized 0
true is 1, false is 0, not yes = 0, and 1 yes = 0, or 0 true = 1, xor 1 0 = 1
if literal true: ON, if variable holding true: off
type is_bool Y Y N = 1
Go further
  • Store flags as 1/0 so if ([flag]) works without conversion.
  • Trap: the literal true is 1, but -> "[b]" "true" stores the text true, which is false in if.
executed on MentDB

Comments, line ends and quoting: a CSV export for Excel

Build a CSV with CRLF line ends ([_r_][_n_]) and quotes doubled inside fields, make the invisible characters visible, and run the two comment traps: a lone string starting with # is a comment, and a comment stops at the first semicolon.

Pipeline
Script
admin
#1. Suppliers to export for Excel: CSV with CRLF line ends;
-> "[rows]" "Le \"Bistrot\" SARL|Paris|1250.5,Acme Ltd|London|980";
-> "[csv]" (concat "name;city;amount" [_r_] [_n_]);
for (-> "[i]" 1) (<= [i] (atom size [rows] ",")) (++ "[i]") {
	-> "[r]" (atom get [rows] [i] ",");
	#2. In a string only \" is an escape: CSV doubles the quotes of a field;
	-> "[name]" (string replace (atom get [r] 1 "|") "\"" "\"\"");
	-> "[csv]" (concat [csv] "\"" [name] "\";" (atom get [r] 2 "|") ";" (atom get [r] 3 "|") [_r_] [_n_]);
};
#3. Make the invisible characters visible to check the file;
-> "[shown]" (string replace (string replace [csv] [_r_] "<CR>") [_n_] (concat "<LF>" [_n_]));
#4. Two comment traps, run with eval to show them;
-> "[trap1]" (eval "\"# total\";");
-> "[trap2]" (try {eval "#see the doc; part two;";} {"error: the comment stopped at the first semicolon"} "[e]");
#5. A backslash alone is a normal character;
concat [shown] "bytes: " (string length [csv]) ", lines: " (string regexp_count [csv] [_n_]) [_n_] "a lone string starting with # gives: " [trap1] [_n_] [trap2] [_n_] "the text \n has " (string length "\n") " characters";
Result
mentdb
name;city;amount<CR><LF>
"Le ""Bistrot"" SARL";Paris;1250.5<CR><LF>
"Acme Ltd";London;980<CR><LF>
bytes: 77, lines: 3
a lone string starting with # gives: This is a comment ...
error: the comment stopped at the first semicolon
the text \n has 2 characters
Go further
  • Only \" is an escape in a string: \n is two characters, use [_n_] for a line feed.
  • To return a text that starts with #, build it: concat "#" "total".
executed on MentDB

Variables: dynamic names, counters and their traps

Total the orders per country with variable names built at run time (env set var / env get var / env exist var), then the traps: concat_var appends to the variable, a quoted name is only a text, ++ on an unknown variable is an error, env del var removes one.

Pipeline
Script
admin
#1. Orders of the day: country and amount;
-> "[orders]" "FR:120,DE:80,FR:45.5,IT:60,DE:20,FR:10";
-> "[codes]" "";
for (-> "[i]" 1) (<= [i] (atom size [orders] ",")) (++ "[i]") {
	-> "[c]" (atom get (atom get [orders] [i] ",") 1 ":");
	-> "[amt]" (atom get (atom get [orders] [i] ",") 2 ":");
	-> "[codes]" (concat [codes] (if (is empty [codes]) {""} {","}) [c]);
	#2. A variable name is a string, so it can be built: one total per country;
	-> "[var]" (concat "[total_" [c] "]");
	if (not (env exist var [var])) {env set var [var] 0;};
	env set var [var] (+ (env get var [var]) [amt]);
};
#3. Read them back by name;
-> "[countries]" (atom distinct [codes] ",");
-> "[report]" "";
for (-> "[i]" 1) (<= [i] (atom size [countries] ",")) (++ "[i]") {
	-> "[c]" (atom get [countries] [i] ",");
	-> "[report]" (concat [report] [c] "=" (env get var (concat "[total_" [c] "]")) " ");
};
#4. Traps: concat_var appends to the variable, a name in quotes is only a text;
-> "[path]" "/api";
concat_var "[path]" "/v2" "/orders";
-> "[alias]" "[path]";
#5. ++ works on decimals, an unknown variable is an error, env del var removes one;
-> "[rate]" 1.5;
++ "[rate]";
-> "[unknown]" (try {++ "[visits]";} {"error: [visits] does not exist"} "[e]");
env del var "[total_IT]";
concat "totals: " (string trim [report]) [_n_] "concat_var: " [path] ", alias: " [alias] [_n_] "++ 1.5 = " [rate] ", " [unknown] [_n_] "after env del var, total_IT exists: " (env exist var "[total_IT]");
Result
mentdb
totals: FR=175.5 DE=100 IT=60
concat_var: /api/v2/orders, alias: [path]
++ 1.5 = 2.5, error: [visits] does not exist
after env del var, total_IT exists: 0
Go further
  • env show lists every variable of the session: handy to debug a script.
  • A JSON document (json load) is often clearer than many dynamic variables.
executed on MentDB

Variable scope: execute, call and include compared

Create a VAT helper script and run it three ways: execute starts a new environment (the caller country is not seen, nothing leaks), call shares the caller environment (country seen, local variables left behind) and checks the typed parameters, include shares it too but skips the parameter checks.

Pipeline
Script
admin
#1. A shared helper: price with VAT, the country is read from the caller if it exists;
script create exe "tuto.lang.vat" false 1
	(param
		(var "[amount]" {type is_number [amount]} "Amount without VAT" is_null:false is_empty:false "100")
	)
	"Add the VAT of the current country"
{
	-> "[rate]" (if (env exist var "[country]") {switch ([country]) ("DE") {19} ("FR") {20} {0}} {20});
	-> "[vat]" (math round (/ (* [amount] [rate]) 100) 2);
	+ [amount] [vat];
} "The amount with VAT";
-> "[country]" "DE";
#2. execute: new environment, the caller country is not seen, nothing comes back but the result;
-> "[r1]" (execute "tuto.lang.vat.exe" "[amount]" 100);
-> "[leak1]" (env exist var "[vat]");
#3. call: same environment, the script sees the country and leaves its variables;
-> "[r2]" (call "tuto.lang.vat.exe" "[amount]" 100);
-> "[leak2]" (concat (env exist var "[vat]") ", vat=" [vat] ", rate=" [rate]);
env del var "[vat]";
#4. Parameters are checked by execute and call, include does not check them;
-> "[r3]" (try {call "tuto.lang.vat.exe" "[amount]" "abc";} {string regexp_extract [e] "\[\[\[ (.*) \]\]\]" 1} "[e]");
-> "[r4]" (try {include "tuto.lang.vat.exe" "[amount]" "abc";} {string regexp_extract [e] "\[\[\[ (.*) \]\]\]" 1} "[e]");
script delete "tuto.lang.vat.exe";
concat "execute: " [r1] " (default 20%), vat left in caller: " [leak1] [_n_] "call: " [r2] " (DE 19%), left in caller: " [leak2] [_n_] "call with abc: " [r3] [_n_] "include with abc, the script runs and fails inside: " [r4] [_n_] "script still exists: " (script exist "tuto.lang.vat.exe");
Result
mentdb
execute: 120 (default 20%), vat left in caller: 0
call: 119 (DE 19%), left in caller: 1, vat=19, rate=19
call with abc: Sorry, the variable '[amount]' in the script 'tuto.lang.vat.exe' is not valid (type is_number [amount];).
include with abc, the script runs and fails inside: Sorry, the number to round cannot be null.
script still exists: 0
Go further
  • Use execute for services, call for helpers that must read the context, include only for trusted snippets.
  • Clean the variables a called script leaves with env del var.
executed on MentDB

Discount rules engine with mql and eval

Keep business rules as MQL text with mql {...} (not run, variables not replaced), run them per order with eval so they read the values of that moment, inject a user value safely with mql encode, and compare parentheses, blocks and the lazy branches of if.

Pipeline
Script
admin
#1. Discount rules written by the sales team, kept as MQL code;
-> "[rule_qty]" (mql {if (>= [qty] 10) {* [total] 0.10} {0};});
-> "[rule_vip]" (mql {if (equal [tier] "gold") {* [total] 0.05} {0};});
#2. mql keeps the text as it is: nothing is run and the variables are not replaced;
-> "[stored]" [rule_qty];
#3. eval runs the text later, with the values of that moment;
-> "[orders]" "12:250:gold,3:90:silver,20:400:silver";
-> "[out]" "";
for (-> "[i]" 1) (<= [i] (atom size [orders] ",")) (++ "[i]") {
	-> "[o]" (atom get [orders] [i] ",");
	-> "[qty]" (atom get [o] 1 ":");
	-> "[total]" (atom get [o] 2 ":");
	-> "[tier]" (atom get [o] 3 ":");
	-> "[disc]" (+ (eval [rule_qty]) (eval [rule_vip]));
	-> "[out]" (concat [out] "order " [i] ": " [total] " - " [disc] " = " (- [total] [disc]) [_n_]);
};
#4. A value typed by a user goes into generated code through mql encode;
-> "[shop]" "Le \"Bistrot\"";
-> "[code]" (concat "string upper \"" (mql encode [shop]) "\";");
#5. Parentheses are evaluated before the call, a block in if runs only when chosen;
-> "[runs]" 0;
if (false) {++ "[runs]";} {"skipped"};
concat "stored rule: " [stored] [_n_] [out] "generated code: " [code] " gives " (eval [code]) [_n_] "the true block of if false ran " [runs] " time, concat a {+ 1 1} = " (concat "a" {+ 1 1});
Result
mentdb
stored rule: if (>= [qty] 10) {* [total] 0.10} {0};
order 1: 250 - 37.5 = 212.5
order 2: 90 - 0 = 90
order 3: 400 - 40 = 360
generated code: string upper "Le \"Bistrot\""; gives LE "BISTROT"
the true block of if false ran 0 time, concat a {+ 1 1} = a2
Go further
  • Store the rules in a tuto_ parameter or a node so the sales team changes them without a deploy.
  • Wrap eval of user code in try, and refuse some words first (see the safe formula evaluator recipe).
executed on MentDB

Coded errors, nested try and a finally step: a payment pipeline

A charge script raises business codes (CARD_DECLINED, LIMIT); the caller wraps the error with context in an inner try, maps the original code to an HTTP status in the outer try, frees its JSON work key on both paths like a finally block, and checks that the error variable does not exist after a clean try.

Pipeline
Script
admin
#1. A payment service that raises coded business errors;
script create exe "tuto.lang.charge" false 1
	(param
		(var "[card]" {type is_varchar [card] 19} "Card number" is_null:false is_empty:false "4111111111111111")
		(var "[amount]" {type is_number [amount]} "Amount" is_null:false is_empty:false "25")
	)
	"Charge a card"
{
	if (string ends_with [card] "0000") {exception ("CARD_DECLINED") ("the bank declined the card");};
	if (> [amount] 1000) {exception ("LIMIT") (concat "amount " [amount] " over the limit of 1000");};
	concat "charged " [amount];
} "A confirmation";
#2. Each payment: a JSON work key that must be freed whatever happens;
-> "[payments]" "4111111111111111:25,4000000000000000:40,4111111111111111:1500";
-> "[out]" "";
for (-> "[i]" 1) (<= [i] (atom size [payments] ",")) (++ "[i]") {
	-> "[p]" (atom get [payments] [i] ",");
	json load "tuto_lang_tx" "{}";
	try {
		#3. Inner try: add context then raise again with a new code;
		try {
			-> "[msg]" (execute "tuto.lang.charge.exe" "[card]" (atom get [p] 1 ":") "[amount]" (atom get [p] 2 ":"));
		} {
			exception ("PAYMENT_FAILED") (concat "payment " [i] " / " (string regexp_extract [inner] "([A-Z_]+: [^\n]*)$" 1));
		} "[inner]";
		-> "[status]" (concat "200 " [msg]);
	} {
		#4. Map the business code of the original error to an HTTP status;
		-> "[code]" (string regexp_extract [err] "([A-Z_]+): [^:\n]*$" 1);
		-> "[status]" (concat (switch ([code]) ("CARD_DECLINED") {"402"} ("LIMIT") {"422"} {"500"}) " " (string regexp_extract [err] "PAYMENT_FAILED: ([^\n]*)" 1));
	} "[err]";
	#5. Finally-like step: runs after both paths;
	json unload "tuto_lang_tx";
	-> "[out]" (concat [out] [status] [_n_]);
};
script delete "tuto.lang.charge.exe";
#6. Trap: after a try without error, its error variable does not exist;
try {+ 1 1;} {"never"} "[err2]";
concat [out] "work key still loaded: " (json exist "tuto_lang_tx") ", error variable after a clean try: " (env exist var "[err2]");
Result
mentdb
200 charged 25
402 payment 2 / CARD_DECLINED: the bank declined the card
422 payment 3 / LIMIT: amount 1500 over the limit of 1000
work key still loaded: 0, error variable after a clean try: 0
Go further
  • The error text stacks one line per level: the last line ends with code: message.
  • Write the failed payments with log write for the support team.
executed on MentDB

Loops: continue, break, retry with backoff and parallel

An import reads a feed line by line, skips comments and blank lines with continue, stops at the END marker with break, then pushes the total to a flaky partner with a repeat loop and an exponential backoff. Three independent checks run at the same time with parallel.

Pipeline
Script
admin
#1. A feed file to import: skip comments and blank lines, stop at the END marker;
-> "[feed]" "# export 2026-11-01|A1;12||B7;oops|# warehouse 2|C2;5|END|Z9;99";
-> "[ok]" 0;
-> "[bad]" "";
-> "[qty]" 0;
for (-> "[i]" 1) (<= [i] (atom size [feed] "|")) (++ "[i]") {
	-> "[line]" (string trim (atom get [feed] [i] "|"));
	if (or (equal [line] "") (string starts_with [line] "#")) {continue;};
	if (equal [line] "END") {break;};
	-> "[q]" (atom get [line] 2 ";");
	if (not (type is_integer [q] 6)) {-> "[bad]" (concat [bad] "line " [i] " ");} {++ "[ok]"; -> "[qty]" (+ [qty] [q]);};
};
#2. Push the total to a flaky partner: retry with an exponential backoff;
-> "[try]" 0;
-> "[delay]" 100;
-> "[sent]" 0;
-> "[trace]" "";
repeat (< [try] 5) {
	++ "[try]";
	#The partner answers 503 twice, then 200;
	-> "[http]" (if (< [try] 3) {503} {200});
	-> "[trace]" (concat [trace] "try " [try] ": " [http] (if (equal [http] 200) {""} {concat ", wait " [delay] " ms"}) [_n_]);
	if (equal [http] 200) {-> "[sent]" 1; break;};
	wait [delay];
	-> "[delay]" (* [delay] 2);
};
#3. Three independent checks at the same time;
-> "[par]" (parallel {date is_weekend "2026-11-01"} {type is_email "ops@example.com"} {math round (/ [qty] 3) 2});
-> "[i]" 0;
-> "[checks]" "";
while (< [i] 3) {
	-> "[checks]" (concat [checks] (json load select "rx_p4m_par" [par] (concat "/[" [i] "]/result")) " ");
	++ "[i]";
};
json unload "rx_p4m_par";
concat "imported " [ok] " lines, qty " [qty] ", rejected: " [bad] [_n_] [trace] "sent: " [sent] [_n_] "parallel results: " [checks]
Result
mentdb
imported 2 lines, qty 17, rejected: line 4
try 1: 503, wait 100 ms
try 2: 503, wait 200 ms
try 3: 200
sent: 1
parallel results: 1 1 5.67
Go further
  • parallel returns a JSON array of {status, result}: read it with json load select.
  • Put a maximum on every retry loop, here 5 tries: an endless repeat blocks a stack thread.
executed on MentDB

Atom lists: negotiate the language of a response

A web service reads the Accept-Language header, cleans it into atoms, extracts the language tags and their weights, and picks the best language supported by the site. Other atom functions show how to count, find and cut the list.

Pipeline
Script
admin
#1. The Accept-Language header of a request and the languages of the site;
-> "[header]" " fr-RE , en;q=0.8, fr;q=0.9 ,de;q=0.3, en ;q=0.5, *;q=0.1 ";
-> "[site]" "en,fr,es";
#2. Clean atoms, one per language, best weight first;
-> "[langs]" (atom lrtrim [header] ",");
-> "[best]" "";
-> "[bestq]" -1;
for (-> "[i]" 1) (<= [i] (atom size [langs] ",")) (++ "[i]") {
	-> "[part]" (atom get [langs] [i] ",");
	-> "[tag]" (string lower (atom get_first_lrtrim [part] ";"));
	-> "[q]" (if (string contains [part] "q=") {atom get_last [part] "="} {1});
	#fr-RE is served by fr;
	-> "[base]" (atom get_first [tag] "-");
	if (and (> (atom find [site] [base] ",") 0) (> [q] [bestq])) {-> "[best]" [base]; -> "[bestq]" [q];};
};
#3. More atom tools on the same list;
-> "[tags]" "";
for (-> "[i]" 1) (<= [i] (atom size [langs] ",")) (++ "[i]") {-> "[tags]" (concat [tags] (if (equal [i] 1) {""} {","}) (atom get_first_lrtrim (atom get [langs] [i] ",") ";"));};
-> "[uniq]" (atom distinct_lrtrim_1sbefore [tags] ",");
-> "[upto]" (atom before_includ [tags] (atom position [tags] "fr" ",") ",");
-> "[before]" (atom before_exclud [tags] (atom position [tags] "fr" ",") ",");
concat "atoms: " [langs] [_n_] "language tags: " [tags] ", distinct: " [uniq] [_n_] "en appears " (atom count [tags] "en" ",") " times, fr at position " (atom position [tags] "fr" ",") [_n_] "up to fr: " [upto] " | before fr: " [before] [_n_] "Content-Language: " [best] " (q=" [bestq] ")"
Result
mentdb
atoms: fr-RE,en;q=0.8,fr;q=0.9,de;q=0.3,en ;q=0.5,*;q=0.1
language tags: fr-RE,en,fr,de,en,*, distinct: fr-RE, en, fr, de, *
en appears 2 times, fr at position 3
up to fr: fr-RE,en,fr | before fr: fr-RE,en
Content-Language: fr (q=1)
Go further

Also in Programming

MB
MQL beginner
Variables, operators, if, loops and your first try/exception: learn MQL step by step.
10 recipes
MD
MQL developer
Atom lists, data types, constants, translations, session variables and error patterns.
10 recipes
BW
Backend & web service developer
Typed scripts, execute / call / include, generated calls and URLs, parameters and logs.
10 recipes
DT
Date & time developer
Calendars, business days, time zones, ISO and epoch, durations, quarters and week numbers.
10 recipes
SE
String & encoding developer
Cleaning, case styles, regex, URL/HTML/Base64 encodings, number bases and encryption.
10 recipes
DV
Data validation developer
IBAN, BIC, SIRET, Luhn, email, IP, UUID, JSON and date checks gathered in a validation report.
10 recipes
JD
JSON & document store developer
In-memory JSON documents, persistent nodes and sequences: build, walk, sort, clean up.
10 recipes
SD
Script developer
Full script lifecycle in the MQL editor: typed parameters, read back, generate, patch, deploy, copy, grant, delete.
10 recipes
EM
Execution modes
execute, call, include, sub_include, parallel, stack: which environment, which checks, which logs.
11 recipes
WS
Web service developer
A small REST resource with get, post, put and delete scripts: validation, JSON answers, codes, grants, URLs and API docs.
10 recipes
AD
Async developer
Asynchronous processing with the stack: push runs now or later, priorities and parallel limits, errors and replays, flows and cleanup.
10 recipes
SD
Scheduler developer
Cron jobs and delayed runs: add, resume, pause, update and remove jobs, prove they ran, and postpone stack runs with a delay condition.
10 recipes
ED
Event developer
Event-driven scripts: file watchers that push each file event to the stack, validation, archiving, errors and safe restarts.
10 recipes
CC
Configuration & connections
Parameters (private, described, locked, deployed), environment variables, sessions and connections used by your scripts.
12 recipes
VD
Versioning & deployment
Group your scripts, commit, compare, roll back, export, import and package a release.
10 recipes
DE
Debugging & error handling
Coded errors with try/exception, logs with correlation ids, timing, metrics and defensive checks.
10 recipes
SD
SQL developer in MQL
Connections, DDL and DML with sql encode, transactions, cursors, parse, and exports to JSON, CSV, Excel and PDF on a real local database. Run the recipes in order: the first one creates the tuto_db_h2 database.
10 recipes
CD
CRUD & data API developer
Generate SCRUD scripts from a table, patch and install them, write typed read and write APIs, check data quality and manage connections per environment. Uses the tuto_db_h2 database of the SQL developer recipes; the last recipe removes it.
10 recipes
WA
Web application developer
Create a web app, its host name, pages, ajax forms, menu and grants, then remove it all.
10 recipes
AI
Algorithms in MQL
Sorting, searching, recursion, data structures and number algorithms: MQL is a real programming language.
10 recipes
CF
Control flow
if, if force, case, switch, mode, for, while, repeat, break, continue, parallel and synchronized on real cases.
10 recipes
SU
Screen & UI developer (sajax)
Build the screens of MentDB web apps in MQL: Bootstrap grids, forms and every control, ajax buttons, alerts, refreshes and charts.
10 recipes