Show HN: I created a language called AntiLang – breaking all the conventions (siruscodes.github.io)
The idea for this project came when I was having a long midnight conversation with my friend and thought of writing such a weird language. The initial draft was far worse than the current implementation; we thought of reversing the brackets and the language would be read from bottom to top. I'm happy that I dropped that idea
Technical details: As the interpreter is written in Golang, I compiled it to WASM, and the whole interpreter is running in the browser. For the editor, I'm using Monaco, the same library that powers the text editor in VSCode. I learnt how to build it while reading "Write an Interpreter in Go" by Thorsten Ball.
The project is opensourced - https://github.com/SirusCodes/AntiLang - do give it a star if you like the project.
131 comments
[ 2.6 ms ] story [ 196 ms ] thread```
[condition] whileTrue: [code]
(condition) ifTrue: [code] ifFalse: [code]
```
The lack of ambiguity also means it takes fewer commands to describe a single operation. For example, in an calculator with infix notation, which is what most people learn, calculating the multiple of four pairs of sums would require the following keypresses:
With an RPN calculator, which has a postfix notation, it would only require these keypresses: That's 24 in the first example and 19 in the latter, a reduction of over 20%.My grandma never really learned how to use a computer and was generally not very good at complex instructions. When she learned to use a calculator, RPN was just as common as postfix notation, and she was able to figure out how to use RPN, but had trouble figuring out postfix notation. Nowadays, schools usually only teach postfix notation, so most students aren't exposed to the easier method, and will have to do extra work, in the short term, to lean it, but it means calculations will require less work, once learned.
tl;dr: Postfix notation is the Dvorak keyboard to infix notation's Qwerty keyboard. The former is easier and faster, but everyone learns the latter. Putting in the extra work to learn the former will save you more time in the long run.
It might be fewer keystrokes, but I feel for most people, the difference in keystrokes doesn't justify the cognitive load it adds.
https://en.wikipedia.org/wiki/RPL_(programming_language)
I wouldnt discount your work. Someone who thinks a bit different might find it a workable onramp into coding where others have failed.
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/cs...
Raised an issue on GitHub - https://github.com/SirusCodes/AntiLang/issues/7
I think a true AntiLang would also break conventions of how programming itself works too. This just seems like a normal language with weird syntax.
Plus, reverse function application/composition works better with our tendency to write the domain of the function before its range. Given f : A -> B and g : B -> C, the composite function is written as g o f which is mildly annoying.
Consider the following permutation:
This is typically written in cycle-notation like this: If we look at the cycle notation, f maps each symbol to the one on the right. For example, it maps 1 to 1, 2 to 4, 4 to 3, and 3 to 2.Now if we want to find out what happens to the sequence (4 3 2 1) when we apply f to it, we normally write it as
The argument comes first. The function name comes next. It makes it quite convenient to work with permutations, composition of permutations, etc. For example, the result for the above application is:Herstein does it.
This is an interesting question but it's further complicated by how frequently Euler was writing in Latin, which usually prefers (but doesn't require) SOV order.
I just looked up a random text by Euler (https://scholarlycommons.pacific.edu/euler-works/298/) and I see
> Genus autem secundum eiusmodi problemata complectetur, ad quae soluenda coordinatae ad duo curuae puncta pertinentes simul considerari debent; cuiusmodi erat problema de traiectoriis reciprocis, illudque problema catoptricum, quod ante aliquot annos tractavi. Cum enim in his continuo bina curuae puncta inter se conferantur, et coordinatae ad ea pertinentes in computum ingrediantur; per principium continuitatis effici debet, ut bina haec puncta ad eandem lineam curuam referantur, sicque aequatio inter coordinatas unicum punctum spectantes eliciatur.
I put all of the clauses' main verbs in italics. All of them except for "erat" ('was') are at the ends of their respective clauses! So, Euler had quite a lot of experience writing SOV sentences in technical contexts.
Programmers are pretty accustomed to thinking of functions as verbs. In some programming styles, we're even explicitly encouraged to name our functions after verbs describing what they do.
Sometimes mathematicians think of functions more as expressing a complete (and sort of timeless) relationship between a domain and a range. That relationship, considered in its totality, can be thought of as a noun rather than a verb.
Earlier mathematicians might also have tended to think of functional notation as referring to individual specific instances of the result of the calculation that the function refers to, like "the sine of 1/2" being a specific number (the result of computing the sine of one half, or, alternatively, the output of the function given a specific input). So when writing something like sin(1/2) they might not be thinking "please [person or machine] perform this computation on the number 1/2 right now" so much as "[I am here indicating] the specific [timeless and inherent] number that is the sine of 1/2". That's a different way that a function could be seen as a noun, essentially seeing the function as merely a way of referring to its output.
Calculus and real analysis start to give stronger reasons for thinking of functions as abstract objects in their own right (e.g. because we can say something like "d/dx sin(x) = cos(x)" or even "the derivative of sin is cos" without thinking about specific values. Or questions like "can a function exist that is continuous but not differentiable?". Maybe computer science then starts to give reasons for thinking of functions as descriptions of how to perform them (like source code or even machine code punched on punch cards) as opposed to references to their specific results (like a printed book of function tables, which someone else calculated ahead of time so you wouldn't have to).
This is all to say basically that maybe it's more natural for us as programmers to think of functions as verbs, but maybe Euler didn't conceive of them that way at all!
Herstein's Topics in algebra uses that notation for function application. It's surely not a coincidence that he was Polish, and that that reminds one of RPN.
>> A lot of people said this, why building this I had no idea of how these languages looked. Now that I know about them my project looks like a cheap imitation of them :(
> Don't be disappointed. That's cool! You've independently discovered something.
I completely agree with mkingston's comment. Whether or not this project resembles other programming languages is beside the point. What truly matters is the joy you had building it. As Alan Perlis wisely said, "I think that it's extraordinarily important that we in computer science keep fun in computing."
This is a fascinating project, and in that same spirit of playful exploration, I'd like to share a minimalist, esoteric postfix language for drawing on a canvas that I built some time back: <https://susam.net/fxyt.html>.
You can also look at this polyglot thread with 65 languages https://codegolf.stackexchange.com/questions/102370/add-a-la...
All these should be equivalent:
More insidiously, these should be equivalent:Like, rather than
if you have (Though 'otherwise [condition] then' breaks your pure postfix style).Similarly "while" could be "yields".
And "let" could be "over" (CB radio-style):
We can go ahead and make + behave as - and similarly for other operators.
(the number of times I've noticed code that does `unless !some_condition`... which is of course just the same thing as `if some_condition`)
Get real torturous with it and make the amount of whitespace the line number, ala BASIC. 3 trailing spaces is line 3 for instance. Tab character counts as powers of ten separator? Space space space tab space space is line 32?
For the whitespace, you'd have to know how deeply to indent the outermost part of your code.
So if you add an if block to a for loop, every line of the code has to be indented and only the contents of the new if would be at indent of 0.
I am not going to write this pseudocode in AntiLang because I am not that much of a masochist.
becomes If you antilanged this the rest of the way, you could have a common `start` to indicate the start of a block and then replace the `end with the actual conditional. This gets horrible pretty quick. So as terrible as trailing line space is, leading line space is quite possibly worse.Which leads me to the ultimate conlusion -
Raised issue for it - https://github.com/SirusCodes/AntiLang/issues/9
Q1: How close could one get to a grammar that would basically recognize C with each line reversed character-by-character?
Q2: What would a language look like where instead of being oriented into right- or leftward-marching lines, it was oriented into downward-marching columns?
Better - check the computer's region setting and use the local language convention, so decimal point is "." is English speaking regions, and "," is Euro regions, and who knows what else in other regions. That way code might work in one location but fail in another ;)
A few years ago Excel and some other softwares started to be locale dependent and I never wanted to burn my computer this much
Another good example is how "İ" is popping up everywhere, even in English, because of misconfigured locale settings and how changing case is affected by it. We (Turks) are responsible for that, sorry (We have ı,i,I,İ =D ).
Dot is often used as thousands separator too.
I remember the first time I saw 10,000 as a price and thought: 10 bucks? So cheap. But also: who needs 3 decimal points for a price?
Looks like its more or less 50% of the world [0].
[0]: https://en.wikipedia.org/wiki/Decimal_separator#Conventions_...
10 million = 1,00,00,000
https://en.wikipedia.org/wiki/Lakh
Petrol stations... I have no idea how widespread this practice is, but at least in Germany fuel prices have 3 decimal points to better confuse motorists. The third number is usually displayed smaller and is of course always a nine. So, if you see the price for a litre of diesel at e.g. 1.62⁹ €, you might forget to round it up mentally.
That’s why in region settings on your computer you will find not only date/tome formatting, but also the number format.
See https://en.wikipedia.org/wiki/Decimal_separator#Hindu%E2%80%...
I will implement this thing.
AFAIR, Windows always reports US_EN for the locale, so you can write locale unaware code everywhere, but when running on Linux, you get the correct locale of the system (of course), and things break spectacularly.
I remember debugging an integer overflow, and I literally facepalmed following a "you didn't do THAT, did you!?".
The thing they did was parsing the date from the date string (formatted for system locale, without giving a specific locale) Java returned to them instead of fixing the locale and getting the date or getting the parts with relevant functions.
I have a relatively short fuse for people who doesn't read (or at least skim) the manual of the library they're using.
Raised issue - https://github.com/SirusCodes/AntiLang/issues/7
If you don't know about it, you're in for a treat.
https://en.wikipedia.org/wiki/INTERCAL
The joke runs longer: https://en.wikipedia.org/wiki/COMEFROM
If multiple comefroms to the same line are specified, the comefrom to jump to is selected randomly.
So instead of
You have Really, that's just syntax. Declare your labels with "comefrom", and ":" means "jump". But it looks a lot more confusing this way.