A compile to JS language where less is more, worse is better, and reliability is king.
A compile to JS language where less is more, worse is better, and reliability is king.
class
and no prototype
)PROJECT STATUS: Abandoned… at least for now. read more
; only line comments are supported
; comments start with `;`
; types always start with an uppercase first character
; values always start with a lowercase variable
ann str = String ; annotate a variable's type
def str = "hello" ; define a variable
def n = 1 ; type of n is inferred
; Map/Hash/Dict/Struct
ann foo = {a: Number}
def foo = {a: 1}
; function bodies are expressions
ann add = Fn(Number, Number) Number
def add = fn(a, b) a + b
; `do` blocks allow you to write statements
ann foo = Fn(Number) Number
def foo = fn(a) do
def b = 2
def c = 3
return a + b + c
end
; tagged unions
def Something
= #one
| #two
| #three
| #four
def bar = #one
def barN =
case bar
when #one
1
when #two
2
when #three
3
when #four
4
end
; To say that something will maybe return a value
def Maybe<a>
= #just(a)
| #nil
; if expression
def a = if 1 == 1 then 1 else 2
; if statement
if 1 == 1 do
; ...
elseif 1 == 1 do
; ...
else
; ...
end
; while loops are pragmatic
while 1 == 1 do
; ...
end
There are no namespaces. Files are modules, similar to commonjs.
import "./file/path" * ; imports all variables exported
import "./some-file" (a as other, B) ; import just parts
def Type = #one | #two
def a = 1
export(a, Type)
In ecmaless:
import "./lib.js" (
; use `is` to annotate the type of the js object you import
add is Fn(Number, Number) Number
)
The goal is clarity. Ecmaless will be one of many languages you use. So it shouldn’t be too unfamiliar. It should be easy to read, understand, have consistent rules and that’s it. Consistent style is important. We can all learn to read a syntax. There are so many languages and coding styles. Learning a new syntax is frustrating at first, but then you get used to it. And eventually people start loving it and defending it.
Ecmaless will ship with a code formatter that is not configurable. Simply following the lead of gofmt and elm-format which do all the work to keep code formatted, consistent, and avoids pointless arguments. I also recommend prettier.
Ecmaless decidedly has very little syntactic sugar. Syntatic sugar creates more things a programmer needs to know and can create confussion.
This is NOT a matter of taste, unless you enjoy the aroma of ascii x09. I used tabs as indentation before. Then I changed. It’s not hard, you can too :)
The programming world is converging on spaces rather than tabs for indentation. Analysis of github repos definitely prove spaces are used more than tabs for indentation. Again by language and again.
There are lots of reasons why the software world is converging on using spaces for indentation.
Yes, the language go uses tabs but the important thing is they made a decision and the community simply adopts it. When I write go
code, I use tabs! Ironically, their docs says use “tabs for indentation and blanks for alignment.” For those who value simplicity, this is the case-in-point against tabs.
Tabs are dead! Let’s bury this one and move on with our lives!
!
is too terse; ecmaless uses not
instead. It’s too easy to overlook a !
and waste time not understanding a piece of logic.
For example:
if(!isConfirmed){}
looks almost like if isConfimred
Whereas if not isConfirmed
makes it harder to miss the not
This project uses lerna to manage several sub-packages.
packages/ecmaless-tokenizer
source code string -> token arraypackages/ecmaless-parser
token array -> ASTpackages/ecmaless-compiler
AST -> javascript EST and type informationpackages/ecmaless
the main cli that ties everything togetherUse npm run setup
instead of npm install
. This will use lerna to symlink each package together so changes are reflected between them as you develop.
Each package has it’s own tests. Run npm test -- -w
to watch files and run tests as you make changes.
The compiler is partially implemented. Take a look at the packages/ecmaless-compiler/test.js
to see what is supported so far.
The parser uses the Top Down Operator Precedence technique.
The code formatter will not use the parser, but rather the tokenizer directly. Here’s why
Ecmaless is a distillation of what I view as my ideal programming language. One that is minimal, pragmatic, and reliable. However, as of 2019 I’ve had a mindset change and decided the benefits of having an ideal programming language is not worth the cost. Elm and TypeScript have been “good enough” for my needs.
When creating software we produce two artifacts:
Your customers only care about #2. They want an application that solves their problem, is intuitive, reliable, fast, secure etc. They don’t care or even think about what language you used to get there. However, as programmers we are concerned with both the code and the running application. If code is messy it becomes increasingly costly and difficult to deliver a quality product.
How much should we invest in code quality vs user experience? Spending too much time on code quality causes us to loose focus on customers and results in a poor user experience and slow development time. Too much emphasis on building features may result in code that is messy, hard to maintain, and slows us down.
Balancing these concerns is not unique to programming. Stephen R. Covey calls it the “P/PC balance” Where P is production and PC is production capability. Striking this balance “is the very essence of effectiveness.” For more on this, I recommend the his book, 7 habits.
My thoughts on how to achieve a good balance are centered around beginning with the user experience and working backwards to technology.
goto
1Steps 1-4 involve no coding, but the decisions made there will save tremendous amounts of time. By the time you get to step 5 there is a fairly clear path to implement it. Bad planning makes bad code inevitable. Things like testing, static types, and consistent syntax help code quality a little bit. However, they are all tiny compared to proper design.
Here are some influences on my thinking:
MIT