Говорим и писмен език, който може да бъде разбран както от човек, така и от компютър. Нека бъде известно разговорно като Обратно.

За цялата тази статия кодът на езика ще бъде изразен в кодови блокове, където ## обозначава коментар от един ред (текст, който не е специфичен за езика).

Започваме с елементите на езика.

Граматика

Граматиката (или синтаксисът) е начинът, по който е написан езикът и правилата, които трябва да следва. Всички изречения на езика (или изрази) трябва да завършват със символ за точка (.). Изреченията включват множество думи, разделени с един или повече интервали. Думите в езика могат да бъдат нещо или оператор. Да започнем с операторите.

Оператори

Операторите са думи, които действат върху нещата около тях. Този акт на работа е известен като операция. Една операция винаги ще се оценява като нещо.

Граматиката за операция е следната:

thing operator thing.

Операторът стои в средата на две неща и оценява само едно нещо. Също така е граматически правилно операторът да оперира с едно нещо:

operator thing.

Това е, което бихте могли да наречете унарна операция (за разлика от двоична операция).

Всички оператори в Обратно са както следва:

is
of
to
in
as
and

Тези операции ще бъдат проучени в дълбочина, докато вървим.

Ред на операциите

Редът на операциите обикновено следва приоритет отляво надясно:

((thing operator thing) operator thing).

Има две уникални изключения от това правило (които ще бъдат обсъдени по-късно). Този ред обаче означава, че първата операция трябва да се изчисли на нещо, преди вторият оператор да може да оперира с това нещо с друго нещо.

неща

Едно нещо е основен елемент в езика. Едно нещо може да бъде описано най-добре по следния начин:

  • Едно нещо може да представлява стойност на езика (като число, низ, функция или друга форма на данни).
  • Типът на предмета се определя от това какъв вид стойност представлява предметът.
  • Едно нещо може да съдържа други неща в себе си.

Нещо може да бъде изразено с буквални представяния на стойност:

123456. ## A number
"String of characters". ## A string

В горния случай или число, или низ.

Нещо може също да бъде дефинирано с помощта на тези литерали и оператора is:

mything is 123.

След което нещо mything сега е представяне на нещо 123.

Нещата могат да съдържат и други неща чрез използване на оператора in за достъп до потенциални неща в друго нещо (ако споменатото нещо съществува или трябва да бъде дефинирано):

myotherthing in mything is 456. ## Sets an inner thing
myotherthing in mything. ## Gets the inner thing; evaluates to 456

Вътрешните неща могат да бъдат идентифицирани или чрез идентификатора на нещото (поредица от знаци, което е името на нещото), или чрез индекс:

0 in mything. ## Gets the first inner thing
1 in mything. ## Gets the second inner thing
## ...

Индексът е число, което представлява реда на вътрешно нещо.

Тези индекси могат да бъдат създадени с помощта на оператора and:

'one' and 'two'.

В този случай изразът ще се изчисли на нещо, което има две вътрешни неща ‘one’ и ‘two’ съответно с индекси 0 и 1. Ние наричаме този тип неща набор от неща.

Операцията and също ще оцени едно измерение на набор от неща:

'one' and 'two' and 'three'.
## A set of things ['one', 'two', 'three'] is the result
## Not [['one','two'], 'three']

Продължаваме...Един от най-интересните типове неща е функцията.

Функции

Функциите са видове неща, които могат да определят връзка между вход и изход.

Функциите могат да бъдат извикани с помощта на оператора to:

to f. ## Invokes the function called "f"

Функциите могат да бъдат извикани с нещо като вход:

x to f. ## Invokes the function "f" with input "x"

Множество входове могат да бъдат предадени на извикването на функция с помощта на набор:

x and y and z to f. ## Passes the set of things [x, y, z] to f

Функциите могат да бъдат изразени с помощта на оператора of:

23 of x. 
## Evaluates to a function with one input, `x` and an output of `23`

Нещата могат да бъдат дефинирани като функции с помощта на добрия оператор is:

f is 23 of x.

Сега би бил добър момент да се върнем към реда на операциите и изключението, което споменахме по-рано. Причината: is и of продължават по реда на операциите.

Специалната поръчка на е и на...

Отсега нататък ще редувам обратен код и JavaScript, за да помогна в разбирането.

Първо, най-десният is оператор се оценява преди всеки друг оператор. Десният израз на този оператор се оценява преди завършване на операцията. Операторът is е алчен, тъй като ще вземе цялата си дясна страна като израз, който трябва да бъде оценен, преди да приключи със собствената си операция. Например:

x is y is z.
## Is not
((x is y) is z)
## Rather it is
(x is (y is z))
## Similarly
w is x is y is z
## Is not
(((w is x) is y) is z)
## But rather it is
(w is (x is (y is z)))
## Also note
x is y to f
## Is not
(x is y) to f)
## But rather
(x is (y to f))

Последният пример показва, че това помага да се определи лявото нещо като оценка на дясното нещо до края на изречението (точката).

Нека ви покажа примери, използвайки JavaScript като справка:

x is y.
var x = y;

x is y is z.
var x = (y = z);

x is y to f.
var x = f(y);

Важно е да се отбележи, че is нарушава реда на операциите по този начин, защото помага да се правят неща, които иначе не биха били възможни, като къри.

Пример за къри в JavaScript:

curry(x)(y);

Curry in Reverse се постига само чрез съхраняване на резултата от първото извикване на функция в друго нещо, преди да се извика това нещо. Ето един пример, все още в JS:

var what = curry(x);
what(y);

Ето как същият код се прави в обратна посока:

what is x to curry.
y to what.

Така че можете да видите, че първо дефинираме what като нещо, което е резултат от x to curry и след това извикваме what с входа y. Всичко това може да се направи с едно изречение поради реда на оператора is:

y to what is x to curry.
## Order:
(y to (what is (x to curry))).

Сега можете да видите как is помага при „обръщането“ (предназначено за игра на думи) на реда на операциите. Ако не е променен редът на операциите, тогава:

y to what is x to curry.
## Would become:
(((y to what) is x) to curry).

И това би причинило грешка, защото what не е дефинирано. И дори ако what беше дефинирано, тогава как определяте оценката на y to what с оператора is да бъде x? Просто няма да има смисъл по този начин, поради което is обръща реда на операциите.

Какво ще кажете за?

Сега of също е алчен. Той ще оцени целия ляв израз до началото на израза, докато не оцени себе си. Това е като реципрочната стойност на is.

f is x is 23 of x.
## Becomes
(f is ((x is 23) of x))
## Not
(f is (x is (23 of x)))

Забележете, че of ще принуди второто is в x is 23 да бъде оценено, преди да принуди of да оцени неговия ляв израз. Това е така, защото редът на операциите за is и of се сменя напред и назад между двата оператора: първият is ще вземе всичко от дясната страна, след това последният of ще вземе всичко от лявата страна на своята операция, тогава вторият is ще вземе всичко от дясната страна на себе си, след това предпоследният of ще вземе всичко от лявата си страна… и така нататък:

f is x is y is 23 of y of x.
## the first `is` evaluate left-hand
f is (x is y is 23 of y of x).
## the last `of` evaluates right-hand
f is ((x is y is 23 of y) of x).
## second `is` evaluates
f is ((x is (y is 23 of y)) of x).
## second to last `of` evaluates
f is ((x is ((y is 23) of y)) of x).

Това напред и назад между тези два оператора създава отделна връзка между тях и позволява създаването на вътрешни функции в рамките на други функции.

Как би изглеждало горното в JavaScript?

f is ((x is ((y is 23) of y)) of x).
## becomes
var f = (x) => (x = (y) => (y = 23))
## Or if you fancy ES5
var f = function(x){
  return x = function(y){
    return y = 23;
  }
}

Кратка бележка: Можете да пропуснете десния израз в оператора of:

f is 23 of.
## Is the same as:
var f = function(){ return 23; };
## And
f is f is 23 of of.
## Becomes
(f is (f is (23 of) of)).
## or in JS
var f = function(){ return var f = function(){ return 23}; };

По този начин можем да имаме функции без входове.

Но какво ще стане, ако искаме да изпълняваме анонимни функции; функции без имена? Кажете, че искате да направите:

(function(){
  return 23;
})()

Не можете да направите:

to 23 of.
## Because that means
(to 23) of.
## Which in JS would be
function(){
  return 23();
}

Което не би имало смисъл и би довело до грешка. Е, за да разрешим това, ще ни трябва начин да съхраним стойността на функцията, преди да можем да я извикаме. Това звучи като нашия проблем с кърито! Спомняте ли си как го решихме?

var what = function(){ return 23; };
what();

В обратен ред ще изглежда така:

what is 23 of.
to what.
## Or in one expression:
to what is 23 of.

Но това не е анонимна функция, казвате вие. Вярно. Дълга история накратко. Няма анонимни функции (има само фиктивни имена, които се използват временно).

Това е горе-долу всичко, което може да се каже за реда на is и of.

Обхват!

Какво ще кажете за обхвата? Какъв е обхватът?!

Обхватът е подобен на обхвата на JavaScript: Функционален обхват.

x is 23. ## let x be 23
f is x of. ## function has access to x outside of it
to f. ## returns 23
x is 11.
to f. ## return 11
f is x of x.
23 to f. ## returns 23, even though the outside x is 11

Как дефинирате нещата в тялото на функция? Как да направя това:

var f = function(){
  var secret = 11;
  return function(){ 
    return secret;
  }
}

Вие не бихте. Това е тъпо. Просто го направи:

f is 11 of of.

Което е функция, която връща функция, която връща 11.

Но какво ще стане, ако искате да промените състоянието на секретност въз основа на външната функция?

var f = function(parameter){ 
  var secret = parameter;
  return function(){
    return secret;
  }
}

Е… Това също е тъпо, защото можеше просто да направиш:

f is parameter of of parameter.

Но какво да кажем за затварянето?? Това е, което наистина получаваме тук. Прост отговор на затварянията. Няма други затваряния освен входове. Функциите са по-чисти по този начин.

f is parameter and 2 to multiply of of parameter.
## In JS it would look like
var f = function(parameter){
  return function(){ 
    parameter * 2; 
  };
}

Функциите са чисто отношение между вход и изход. Няма допълнително изпълнение на код, освен действие върху входа и връщане на изход.

Какво ще кажете за функциите от по-висок ред?

var f = function(x, y){
  x(); // Do one thing
  y(); // Do another
}
## Easy
f is 
  to x and to y
of x and y

Забравих ли да спомена, че можете да направите деструктуриране в дясната страна на оператора of? Моя грешка. Ами можете! И това е доста удобно.

Също така забележете, че f ще върне набор от резултатите от извикването на x и резултатите от извикването на y. Което е хубаво, ако искате да предадете този набор на друга функция, която може да направи нещо с него.

Заключение.

Има още какво да говорим. Но това беше моят опит да изложа всичките си мисли относно тази идея, която имам за език. Исках да напиша тази статия както като справка за себе си за по-късно, така и за да я пусна на другите, за да ми дадат обратна връзка. Моля, оставете ми коментар или отговор!

Само забравих да спомена оператора as. Което е просто начин за дефиниране на идентификатор в набор:

1 as foo and 2 as bar.
## Is like this in JS:
{foo: 1, bar: 2}

Единствената разлика между набор и обект в JS е, че елементите са индексирани в JS. Все още обаче не съм решил това...

Така че as го прави хубаво да има етикетирани входове за функции:

f is 
  dividend and divisor to divide to square
of dividend and divisor.
1 as dividend and 2 as divisor to f.

Просто малко забавен начин да направите реда на аргументите без значение.

Както и да е, ако сте стигнали дотук... Тогава може да искате да направите нещо друго. Благодаря все пак за четенето!