- the pyx scripting langauge and REPL shell.
The programming language is named after Winnie-the-Pooh, in the Russian translation of Boris Zahoder
- an interpreted language that is easy to learn / educational programming language
- save some complexity, by throwing out some of the features of a regular scripting language (only one number type, no classes here, fewer variants of 'import' - fewer than in python. No equivalent concept of a python package - but you can have modules by importing a single file)
- must provide a Read–eval–print loop/Shell as a development environment.
- should provide for concise expression (map/reduce/short functions/possibly one line scripts)
- it should be easy to handle structured data, such as json.
- integration with shell (the REPL/shell has tab completion for commands - upon writing a special backtick operator)
- the most important thing: readable and detailed error messages. Look at what I mean as error messages for accessing lists and strings
accessing a list [1,2,3]
Error: Can't lookup List entry - the index value must be a number. Instead got a String
#(errorTest/11-array-access.p:7) println(a['aa'])
|...............^
#(errorTest/11-array-access.p:7) println(a['aa'])
|.............^
#(errorTest/11-array-access.p:7) println(a['aa'])
|.....^
Error: Can't lookup List entry - the index value is out of range. Got 4 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:14) println(a[4])
|...............^
#(errorTest/11-array-access.p:14) println(a[4])
|.............^
#(errorTest/11-array-access.p:14) println(a[4])
|.....^
Error: Can't lookup List entry - the index value is out of range. Got -1 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:20) println(a[-1])
|................^
#(errorTest/11-array-access.p:20) println(a[-1])
|.............^
#(errorTest/11-array-access.p:20) println(a[-1])
|.....^
Error: Can't assign this List index. Index value is out of range. Got 4 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:26) a[4] = 1
|.......^
Error: Can't assign this List index . Index value of must be an number, instead got b
#(errorTest/11-array-access.p:32) a['b'] = 1
|.......^
accessing a string abc
Error: Can't lookup String entry - the index value must be a number. Instead got a String
#(errorTest/11-array-access.p:42) println(a['aa'])
|...............^
#(errorTest/11-array-access.p:42) println(a['aa'])
|.............^
#(errorTest/11-array-access.p:42) println(a['aa'])
|.....^
Error: Can't lookup String entry - the index value is out of range. Got 4 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:49) println(a[4])
|...............^
#(errorTest/11-array-access.p:49) println(a[4])
|.............^
#(errorTest/11-array-access.p:49) println(a[4])
|.....^
Error: Can't lookup String entry - the index value is out of range. Got -1 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:55) println(a[-1])
|................^
#(errorTest/11-array-access.p:55) println(a[-1])
|.............^
#(errorTest/11-array-access.p:55) println(a[-1])
|.....^
Error: Can't assign this String index. Index value is out of range. Got 4 - must be smaller than 3 and greater or equal to zero
#(errorTest/11-array-access.p:61) a[4] = 'z'
|.......^
Error: Can't assign this String index . Index value of must be an number, instead got b
#(errorTest/11-array-access.p:67) a['b'] = 1
|.......^
Error: Can't assign string index to List right handd side value must be a string
#(errorTest/11-array-access.p:73) a[0]=[1,2,3]
|.......^
Now the interesting part is that all these features are also required for a good shell. I think we need a shell that is better at handling complex nested data, you have that a lot when dealing with JSON and YAML. I think the bash language is reaching it's limits, when dealing with this class of problem: it is possible to deal do that with jq, but it's not a very easy and pleasant thing to do.
However the objective of a general purpose shell may be out of scope, due to the following reasons:
- The current project is written in nodejs/javascript; now a shell is more resource constrained environment. This means that the current approach is not quite optimal for an OS shell. However it may be possible to rewrite this solution in Rust, if needed.
- need to add lots of features, again (like regular expressions etc. etc). This might contradict the primary goal.
-
the language is not typed, simple language
-
the runtime is interpreter that works on the AST (abstract syntax tree)
Strictness of semantics: should be similar to python:
- reading undefined variables is an error,
- do not allow too much type conversion. (don't allow to add string to number - unlike javascript)
- multi assignment: it is an error if the number of elements in the right hand side does not match the number of left hand side
-
syntax: go - like syntax (in the sense of: less frequent braces, but without strong typing)
-
leave out confusing features
- no += -= operators (can do a = a + 1 - bit more verbose) for logical operators - require and or (instead of && ||)
- don't have 2 ** 3 for power, have a function instead don't have bitwise operators & | ^ ~ - have functions instead
- object system: you can have objects as maps with elements that are closures, but don't have equivalent of javascript prototypes or python classes/metaclasses (i think these concepts are a bit too difficult to teach, also you can do without it in a shell)
-
features: (in a flux right now)
types
strings, floating point numbers - yes
lists - yes
maps - yes
objects - as syntax sugar for maps - yes (but no prototypes or classes)
type hints - no
f-strings - yes
regular expressions - yes
functions
closures - YES
named parameters - no
parameters with default values - yes
multiple return values, multiple assignment - as list (similar to python) - yes
f-strings - yes
yield / generators - yes
iterators - no (generators are good enough, less features)
include of source code in another file - yes
modules/packages - no (can skip that, as an educational language)
try/catch - yes
with statement - later(?)
Currently the language is defined by the PEG parser
Also see these tests scripts here - see files with extension .p (.out - expected output of the script)