free software resistance
the cost of computing freedom is eternal vigilance
### design.txt
*original date:* feb 2021
*originally posted:* oct 2024
design.txt:
```
design notes across toy languages
if you want to learn more about coding, i strongly recommend you create your programming language.
this could seem like a crazy way to learn when youre a beginner, but its not as difficult as it sounds.
there are all kinds of things you want to do if youre writing a serious programming languiage. and people are very quick to tell you what they are, when you dont do them.
i could step you through how to get started, or i could just describe it to you. *the first thing you want to be able to do is open and read from a file*.
if you can do that, youre halfway to making the simplest programming language you can think of.
rather than set out to do everything right, like you would eventually do if you got really serious about creating a language, i recommend you simply get started and have fun. i made a few first attempts years before i ever made a language i could use for getting real work done. and it started out as a way to do ascii demos.
at brown university (i never went there) they teach you *not* to worry about the parser first. first think about features. you can write more than one parser, and you can output more than one language. some people may not even write a parser, they will use someone elses instead.
but if youre writing the simplest language possible, youre only going to have one feature. you know when you first learn to code, a popular program is "hello world" and its very useless, it barely does anything and it barely teaches you anything. but it demonstrates the idea that you write code, you run code, and at least it does something. thats what "hello world" is for.
if you want to make a hello world program more useless, you can complicate it until its a hello world language. then instead of a useless program, you have a useless programming language-- this is a major upgrade.
so how do you make a hello world programming language? first you open a file, then you read it, then you look for the command that tells the computer to say "hello world", then you say "hello world" when its told that command. *voila*, programming language.
by the time youve written that very silly thing, you have either taught yourself and demonstrated the concept of compiling or interpreting. if your program just looks for the command and does what its told, thats an interpreter. for a language with very few features, (like 10 or fewer) an interpreter should be easy. if you want it to do things like loop or have conditionals or functions, its easier to write a compiler.
you can try both. to make a compiler for a hello world language, instead of saying "hello world" it writes a file in your target language that says hello world. so for example, if this is the "source code" in your language:
hw
if your target language is shell scripts, then when your compiler is run it translates *hw* into:
echo "hello world"
now you can think about things like-- what if the coder writes more than one command? will this work:
hw
hw
hw
what abuot this?
hw hw hw
do i want to require commands to be separated with something, which is typical?
hw ; hw ; hw
do i want to make it required for all lines to end with a semicolon?
hw ; hw ; hw ;
maybe you want to be able to specify a name to use instead of "world", maybe you want a default of "world" if that isnt specified. the important thing is that doing things this way will let a lot more people experiment with the idea of creating a language who might otherwise think its impossible.
for a long time, the best reason i had to write a language was that i was creating animated ascii art, and wanted a simple scripting language for just that task. i wanted to be able to "draw" a sprite with text, sort of like this:
sprite diamond
/\
/ \
\ /
\/
next
then be able to say something like
put diamond 10 5 10 1
where "10 5" was column 10, row 5 and "10 1" was lime on dark blue. with your own language you can do this stuff. i wanted to be able to create an animation from just text, with delays that i could set myself.
you can totally make a language like this.
later on i was getting closer to a general purpose language. id written most of this stuff in basic, until i learned python in 2009. so i made useless, silly toy languages in python. but while doing so i got better at it.
i didnt originally set out to write fig as a useful language. it was originally a playful toy language designed to have no punctuation in its syntax-- to be spoken instead of typed.
i got bored with that, though had some fun with it, but i started playing with the idea of something related (based on the same code, which compiles to python)-- a language a little closer to the sort i actually use. i called this version "fig basic".
the idea of fig basic was to use basic-like names and try to make the language even simpler (to learn, to explain) than basic.
basic is really easy, so going easier is tricky if even possible. for years id wanted to try a language like logo, but with basic-like features.
skipping through a few decisions i made, i came up with a language i use all the time, including these features:
[lit]*[lit] not case-sensitive
[lit]*[lit] fewer than 100 commands
[lit]*[lit] very minimal punctuation
[lit]*[lit] parses left to right
[lit]*[lit] fixed, minimal parameter count per line
[lit]*[lit] optional command separators
[lit]*[lit] automatically switches to gfx mode if gfx commands used
[lit]*[lit] emulates gfx with text if graphics library unavailable
ultimately i called this language fig instead of fig basic, and by version 5.0 id dropped support for pygame in protest of it being on microsoft github (since then, sdl itself has recently moved to github).
github wasnt owned by microsoft when i first created fig and fig os. but fig was created in 2015, and it was harder to get ansi escapes working in windows at the time. i designed fig to run on free software, but it also works in macos and windows. 5.0 drops all 3rd party libraries, including pygame and colorama. it is a single python script between 1000 and 2000 lines long.
before that i was modifying qb64 (now THATS a long program) to output python instead of c++. i got it to work with print and for loops, but for some reason nesting for loops created probelms. part of the reason i bring this up, is if you think that 1000-2000 lines is a long or complex programming language, try modifying qb64.
most lines in fig start with a variable like this:
v
when you start a line with a variable, it is automatically set to 0-- unless it is an array.
the variable is always first, which makes variables easier to find and track
to make an array, just use the arr command:
v arr
if you want to add to an array, no problem:
v plus "hello"
v plus "there" plus "world"
you can also create an array this way:
v "hello there world" split v " "
split always has two parameters: the variable to split and the string (or variable) to split it by.
but a few commands (mostly the ones with more than one line) instead of sharing the line with a variable or other commands, get their own line:
for c 1 5 1
now = c print
next
see the equals sign? its optional. you can even use *:=* if you prefer.
these symbols are allowed, but do nothing:
( ) | = ; : ,
originally i didnt allow these, and someone said that code separated only with spaces like logo would be too difficult to read.
so i allowed *:*
for c 1 5 1
now c : print
next
but ultimately i thought you could do a lot of cool stuff with optional syntax when dressing up fig for helping people transition to other languages:
for c = (1, 5, 1)
now = c ; print()
next
someone learning fig can ignore most punctuation, simply going left to right.
fig has arrays (python lists) but no dicts. i kind of like dicts, i thought about adding them to fig.
i created a version of fig with extra features, called figplus. i dont use it often, but it has dicts.
i created a slightly different language called rose, which is more implicit than fig-- you dont have to name variables as often. i dont use it.
rose has a really cool feature called "codices" that im proud of. theyre a "virtual" data type created through the way the data is handled by native functions-- basically theyre a python dict that you can create and access like a list if you prefer. if used as a dict you get the speed of a dict, if used as a list you get the order and simplicity of a list, but you might pay with the time needed to convert. for simple programs its really cool.
when i created figplus i threw in codex support from rose. i still dont use it much, though i am proud of it.
figplus has another cool feature, which i call a "compterpreter" because it compiles and runs from inside the same instance. basically it compiles the entire program-- then it runs the program using exec().
you might not like that, and fig went out of its way to avoid it. but unless you use figplus with a switch for it, figplus just compiles to a python script like fig does. more options means more complexity, and figplus answers the question "what could i have added if i made fig more complex?"
but i designed fig to do most of what i want, and it does. so im happy with that. when i use fig, i dont worry much about which features im going to use. it doesnt have too many to choose from, so i focus on doing the task. of course with a language like python, you can do a better job-- but sometimes i spent too much time deciding how to write something, instead of writing it.
fig is just a simpler language. but i did make it so that it can be extended with inline python code.
for quasi, which was my foray into a fig-like language compiled and run with javascript, i made the parsing a little more standard-- it was easier to parse, slightly, and more consistent than fig.
so for a for loop, instead of:
for v 1 5 1
every line starts with a variable:
v for 1 5 1
we learn something about consistency here. fig was designed to be reasonably consistent-- to have as few rules as possible. but sometimes it just does something thats different because its better.
i dont like quasis variable-first for loop, and i only know i dont like it because i made it-- ive used it.
sure, *v for* vs. *for v* is a small thing, but all decisions are tradeoffs.
i like that most lines in fig start with a variable. i get something from that. and with quasi, you get the harder rule of consistency, but the tradeoff isnt worth it.
its easier to learn from making that sort of thing than it is to guess.
sometimes when i want to do something in javascript, which i tend to avoid-- ill code it in quasi and then look at the output it compiles. i dont like javascript that much, except it is so ridiculously easy to make a gui.
quasi development stopped when it came time to add gui stuff. id have to refactor it so it compiles certain functions in a certain order, otherwise the gui elements it creates arent in the dom or something-- it compiles the code to address the elements its compiled, but it thinks they arent there.
but its the most complicated javascript program ive written, and it can be used for teaching beginner-level coding.
if you create a "hello world programming language"-- it will get you started on the basics of the basics of how interpreters and possibly compilers work. if you keep going and add other features, youll learn more.
you can create a programming language with 5 or more commands in a week. by then perhaps youll get bored and give it up, but youve learned something. if you really love it, maybe youll make a language in the future that actually does something useful for you.
fig actually helps me do real work, because the complexity of python isnt always needed. i learned python as a basic replacement, not because i loved python itself. eventually i did like python a lot, but there are many things i dont like-- particularly in python 3.
when they announced the end of python 2, i tried fig with pypy instead of python 2. it works well. fig 5.0 is based on pypy, not python 2-- but you can really use either one.
quasi was my first serious effort to do fig in another language. im not thrilled with it, but it was fun and interesting. if lua wasnt on github i might try that instead. but fig makes heavy use of python lists, as well as python 2 strings, and im not very interested in python 3 or languages that arent as flexible with arrays as python is.
still, working on your own language lets you set things the way you think they should be. for example, both split and join in fig put the variable to work on BEFORE the string to apply to it. python reverses the two. ive always found that very annoying. i think javascript (one of its good points) is consistent about that too.
lets ask quasi:
p "hello" split p "e"
p join p "e"
the *split p "e"* part compiles to *q_split(vars.p, vars.p, "e")* and the *join p "e"* part compiles to *q_join(vars.p, vars.p, "e")* but those are defined functions.
if we right-click and view source we can find the native functions they use:
function q_split(p, s, o) {
return s.split(o)
}
function q_join(p, s, o) {
return s.join(o)
}
so fig and javascript order the parameters for split and join the same way, while python is funny that way. ive really never liked that.
its not always simple to transform the functionality of an existing language to the functionality you prefer. but its nice when you really want to, and you find a way.
my feeling is that if more people did this, people would understand coding better-- and language developers would understand users better. alright... maybe.
```
license: 0-clause bsd
```
# 2021 mn
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```
=> https://freesoftwareresistance.neocities.org