User:Pavel Senatorov/Ya (programming language)

Ya /jˈʌ/ had been started as an attempt to make better [W C++] with the same applicability for any task, just as C++ allows. Yet Ya significantly changes C++ syntax and adds many extra features: Ya and C++ are incompatible. Many additions has been invented, and many gathered from languages: [WL Ceylon], [WL Scala], [WL Rust], [c2 Thelop|ThelopLanguage], [W JetBrains Meta Programming System|JetBrains MPS], [WL XL]. Ya is designed to allow clean, expressive, concise and lightweight (low ceremonial) code to be written.

In Ya, comparing to C++: sources are shorter by 20-40%; better checking and errors for types with args (for ala C++ templates); sigils help understanding of code subconsciously, thus simplier and faster; DSL Domain Specific Languages support allows extending syntax and implementing extra features by libraries; no project files used.

Ya is applicable for any task. This is possible even in cases when some not included extra features are required: they could be added to Ya by implementing DSL Domain Specific Language, as for expert systems; logic programming; GUI through usage of convenient DSL language for description of windows layout and content and feedback actions.

Advantages of Ya
- Sources become shorter by 20%-40% then equavalent С++ for simple code; and could be times shorter when using [W DSL], as it is in case of description of a syntax. This also makes changes simplier to do. -- Type specification is much shorter, no spaces used, no keywords like {.C const signed unsigned} -- Blocks using tabs (similar to Python): removes lines with single {.C \}}; removes {.C \{} and {.C \}} itself; and if {.C \{} occupies whole line then {.C \{} line is also removed. - More full checking of types with using of requirements specifications for (so called template) parameters for types and functions. -- Also error messages become more appropriate and in time because both requirements and their application when such (so called template) type or function is used are checked for compatibility to requirements. - Multiple names for any entity is allowed. Variables, functions, types may be named by a number of names. No need to use {.C #define} instead. Example: {.Ya `Int \Begin \Start \Min =100} - here you can use this var by name {.Ya Begin} or {.Ya Start} or {.Ya Min}. - Usage of sigils {.Ya ` % @ #} makes understanding of source simpler subconsciously, because you understand the nature of item - is it a type, a variable or function, or extra specification like {.Ya %Public} - by instinct and so many times faster. - Statements {.Ya If For Switch Break Continue Use} all are greatly enchanced over their {.C C C++} parents: {.C if for while do...while  switch  break  continue  #include}. Statetment {.Ya Ret} is the same as {.Ya Return} {.C return} but shorter.

- DSL - new sy - double compilation - не нужны аля makefiles из-за компила всегда целой проги в которой все зависимости (типа как #include в С С++) указывают на реализации, а headers нет ваще - опции компила в сорце сорцах

Преимущества Ya: - краткая запись: на 30-50% короче чем на С++ для простых участков; и может быть в разы короче при юзе DSL, как например при описании синта - табблоки - много имён у чего угодно - little ceremonial: мало keywords и их тоже разрешено использовать иначе // не пошло, да и может и неверно - хм, тут бы надо подробней - DSL - new sy - сигилы для подсознательного быстрого понимания - не нужны аля makefiles из-за компила всегда целой проги в которой все зависимости (типа как #include в С С++) указывают на реализации, а headers нет ваще - опции компила в сорце сорцах - requ: контроль за юзом типфй - делат ошибки своевремнными и аккуратными и по сути ошибки - double compilation /* Ya adds to C++: - Double compilation aka metaprogramming: possibility to execute parts of compiled program during it's compilation; - LOP Language Oriented Programming: supports declaring a syntax and parsing it both on runtime and compile-time. Enables extensible syntax, like adding new statements and operators; - Library for SQL-like requests for processing database-like data including real SQL; - And many small improvements over C++.

Ya adds to C++ extensible syntax, extensible lexical tokens, possibility to execute parts of compiled program during it's compilation ([W metaprogramming], we name it [double compilation]), support for [W SQL]-like operations for processing databases and database-like internal data, and [many small improvements over C++|Basics].

Example: Hello World
Hello World example is here in 2 cases: As it is planned for future: {.Ya \@HelloWorld.Ya @Std/StdIo/Print; "Hello, %s!\n"; ProgramArgs/Length > 1 ? ProgramArgs[1] : "World" } And as it is already implemented in current compiler: {.Ya \@HelloWorld.Ya // each module starts by specifying it's name which is file name. Module names are @...s, sigil @ is used for not confusing modules with ids, types... \ specifies a definition of sigil ident that is after \, ie of  module @HelloWorld.Ya here. Use @stdio.h // to use printf // это не сработает тк .h будут парсить как Ya, а надо пронести на выход. хм, это ныне не решаемо. %С++ `Int \main(`Int \argc; `Char* \argv) // %C++ specify calling convention. Type name is sigilled `type_name. Array is a library defined type, not a predefined language type. \ before name specifies that it's definition of name: all definitions are always prefixed by \. `Char* \name = argc > 1 ? argv[1] : "World\0"/Min // so program says Hello to start arg in command line if it exists, else to World. World is appended by 0 to make it 0-terminated, as usual for C C++ yet not for Ya where arrays used instead and no trailing 0es. printf("Hello, %s!"/Min; name) // "string"/Min is used to access data field of a start of this string. Ret 0 } - In Ya each program first initializes static variables and then executes function {.Ya main}, just like as in C C++. ???- Yet {.Ya main} in Ya differs in its args: there are no separate {.C int argv, char**} argc args but {.Ya `char[][] args} : array of strings, which are arrays of chars themselfs. - Function {.Ya Print} is used for outing formatted text. First param specifies a file. It's not specified here, see {.Ya ;} after {.Ya Print(}, so default param value is used, which is {.Ya Std.Out}, that is C's {.C stdout}. Note that use of defaults is possible for any param, including first one, even if some next param is specified. - This program outputs to stdout "Hello, World!" if executed with no params. If with params, then it outputs "Hello, " and first param and "!". Other examples see at [Examples of programs|Examples].

Basics of Ya
- Block structure is primaryly described by tabs at start of lines. Tabs at start of line are counted and used for specifying code blocks {.Ya {...}}, like in [WL Python]. But blocks made in {B single} line with {.Ya \{} and {.Ya \}} are also supported. - [W Sigils|Sigil (computer programming)] {.Ya @ ` # %} are used for prefixing module names with {.Ya @}, like {.Ya @HelloWorld.Ya;}, types with {.Ya `}, like {.Ya `int `char `void}, compile time items with {.Ya #}, like {.Ya #if} and extra specifications with {.Ya %}, like {.Ya %public %C++ %Ya %requirement %inline %outline}. Sigils make understanding of sources faster, no need to remember or see whether it's type or variable or smth else. And allows to use idents of another sigil kind in current kind, for example {.Ya `int int;} specifies variable of type {.Ya `int}, named {.Ya int}. The drawback of sigils is that when entering them there are 2 extra key presses, because it's required to hold [W Shift key] when entering sigil. - Modules, ala #define and no project file. -- Named modules: {.Ya @FileName;} at the start of each compiled file. Module name is sigilled (started) by {.Ya @} and module name is module's file name. Example: {.Ya @C:/S/Ya/YaParser.Ya;} and {.Ya @Ya/YaParser;} - both cases are Ok for this file, directory==folder of file could be ommited or specified partially or fully. -- Header files are not used. Instead the statement {.Ya use @module, @module;} is used so separate header and implementation for a module does not used, because {.Ya use @module;} gets interface of module into work but not implementation details. -- In Ya there are no project files. Each Ya project has{B main} or{B starting} source that is specified for compiler on command line to compile. Main source includes {.Ya use @module, @module;} so that all required modules will be included and compiled. As a result a separate project file is not required. - Double compilation aka [W Metaprogramming] -- While compiler compiles, parts of the compiled program could be executed. -- It's required for extending Ya syntax, lexical tokens and to perform optimizations, defined by source, when optimizer is written in the program being compiled. -- This feature is named [W metaprogramming] in theory of languages. - Extensible syntax -- New statements maybe described. For example it's possible to add statement {.Ya foreach} for newly written type of a container. -- New nonterminals: It will be possible to add to language syntax even a new nonterminal and rules for using it. - Extensible lexical tokens -- Possibility to add new operators to expressions. Examples: --- For sortings it's required comparison result of lesser or equal or bigger and it's possible to add new operator, let's name it {.Ya <=>}, which makes such kind of comparison. --- Let's {.Ya <->} will notify exchange of values of variables (swap). Usage: {.Ya `int i=1,j=2; i <-> j;} -- Possibility to make other new constants. For example a time is typically written like{B 10:53:17} - addition of a new kind of constant is described as regular expression and the code for transforming of text of new constant into required type the programmer writes on Ya. Note that this code will be executed at compile time, not run time. Making new constants not yet ready, because this constants are typically starts like other lexemas and I did not found the way to implement it. Yet. - Support for databases and internal structures like databases - it will be a library. It will be possible to write expression that works with a number of tables, which are sets (f.e. arrays, lists) of fielded type (of class), and perform {.Ya join where sortby} of {B SQL}. In [WL C#] it is named [W LINQ] or {B Language Integrated Query}. - Multiple names for any entity is allowed. Variables, functions, types all may be named by a number of names. No need to use {.Ya #define} instead. Example: {.Ya `int Begin Start Min = 100;} - here you can use this var by name {.Ya Begin} or {.Ya Start} or {.Ya Min}.

Description of types
- Any type name is started by {.Ya `} and type name must go after {.Ya `} without spaces - it's a single token. - Description of type properties, for example 'pointer to type', are {B all} written {B after} the type name, and all properties are specified by signs, and written without spaces. Example: {.Ya `int+-*-} means {.C const unsigned int* const}, here {.Ya +} means {.C unsigned} and {.Ya -} means {.C const}. - All types are considered fielded types (classes), for example it is possible to inherit from {.Ya `int}. - New types are described like here: {.Ya type `constint = `int-; type `PtrToInt = `int*;} - No references {.C &}, only pointers are used. References in C++ is a feature with side-effects and is of value only because no need to write {.C *} to dereference a reference. But the same is with pointers in Ya, even more, see below. - Work with pointers is simple, no need to dereference or getting address, all this is automatically inserted. Example: {.Ya `int** ptrptr; `int i = ptrptr;} - here in {.Ya i = ptrptr;} is automatical double dereferencing a pointer. - Keyword {.Ya class} is not used. Instead you just write {.Ya type `myClass { body of fielded type }} - Specification of requirements for template args are added, like a not included feature of [WL C++ 2011]. This specifications are described as fielded types, for example {.Ya type %requ `= { ``* ``* a = ``* b; }} specifies that types with requirement {.Ya `=} must have assignment operation {.Ya ``* ``* a = ``* b;} - here {.Ya ``} means current specified type. - That makes type description much more short. But it's required to learn the type signs, because words like {.Ya const unsigned signed} all have gone. - If you need to define a number of vars of the same type, for example {.Ya `int**}, then you write {.Ya `int** A, B, C;} instead of {.C int **A, **B, **C;}. Description becomes shorter, yet there is no way to define {.C int A, *B;} in 1 statement, 2 statements are required: {.Ya `int A; `int* B;}.

Other Values
- Specification of new or old operations for some type is made simple, for example {.Ya `T* `T* a = `T* b;} specifies assignment for type {.Ya `T}. Both args and return type are specified as pointers - this is because there are no references and because working with pointers is simple, no need to dereference or getting address, all this is automatically inserted. - {Ya if, for, while, do}. -- Parentheses are not used, like in {.Ya for `int+ i = 10; i; --i \{ total += i; \}} -- The body of {Ya if, for, while, do while} is always a block {.Ya {...}} - typically it means that body of loop is on next lines and 1 tab right shifted. -- {.Ya ... while cond_expr;} could be used for all loops: {Ya for while do}. -- {.Ya do} is made the same as {.Ya for} loop. -- In {Ya for} the incremental expression can be omitted. Example: {.Ya for `int i = 100; --i \{ process(i); \}} - here loop condition is {.Ya --i} and no incremental expression. -- In {Ya for} the conditional expression can also be omitted. Example: {.Ya for `int i = 100 \{ process(i); \} while --i;} -- In {Ya while} it's possible to include incremental expression, like as in {Ya for}. Example: {.Ya while i < 100; ++i \{ process(i); \}} -- {.Ya ... while cond_expr;} example: {.Ya do `int i = 7 \{ `int j = --i; \} while j;} - it's possible to use vars that defined in a loop body. -- Conditionals are changed: they may include variable declaration, like in {.Ya while `char[] s = GetString; \{ ProcessString(s); \}} - {Ya switch} statement. Example: {.Ya switch 10-5 0..3,7		printf("Wow! It's 0,1,2,3 or 7\n"); 5		printf("Simple case!\n"); else printf("default is written as 'default' or 'else'.\n");} -- Each case starts without {.Ya case} and without {.Ya :} after case values. -- Case values can include many values and also ranges value..value, like in {.Ya 0..3,7} - this case works for 0,1,2,3 or 7. -- Also no need to write {.Ya break;} at the end of case - it is automatically included. But if it's required to continue on next case then {.Ya continue;} may be used - it jumps to the body of next case. - {Ya break;} statement - breaking from loops and switches is enchanced, it is possible to break from many loops+switches in 1 step. Example: {.Ya do \{ do \{ switch 7 \{ 0..3,7 \{ break do do switch; \}\}\}\}} - Operator precedence in expressions: in Ya spaces around operators are counted and it's used for defining precedence. Example: {.Ya 1+2 * 3;} - it's {.Ya (1+2) * 3;} because no spaces in {.Ya +2} and 1 space in {.Ya 2 *}. Author's experience shows that it's extremely useful when forgotting operator precedences and also to write less parentheses in simple cases like with {.Ya * / + -}. - {Ya enum} statement is extended:{.Ya enum}s are not only {.Ya `int;} but of any type, the type is specified. Example: {.Ya type `StringEnum enum `char[] Str1 = "lala", Str2 = "bebe" type `ErraType enum `int+:8 // i.e. they are unsigned bytes eFatal, eErr, eWarn, eMess, }