
Security News
Crates.io Implements Trusted Publishing Support
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
A language that makes building webapps as easy as finite-state machines
A language that makes building webapps (and more!) as easy as building finite-state machines.
Status: First compile and run of Hello World works—and absolutely nothing else. Help wanted!
Mechanical source code:
State counter = 0
-- JSX-like view syntax:
View: "#app" <div>
<p>{counter}</p>
<button @increment>+1</button>
</div>
-- Event handler:
When receive increment.Click:
Change counter to counter + 1
Compiles to clean, readable JavaScript:
render_view("#app", <div>
<p>{counter}</p>
<button {...{ "mech-name": "increment" }}>+1</button>
</div>)
const increment = {
Click: event_stream("increment", "click"),
}
increment.Click.subscribe(() => {
counter += 1
p.textContent = counter
})
Install:
npm install mechanical
Run the compiler:
npx mechc some_file.mech
Which will output: some_file.js
Mechanical-specific extensions to JS expression syntax (which only make sense with Mechanical semantics, and wouldn't make sense for JS:
(TODO) Cmd { ... }
(TODO) Hashtagged values #tag value
and pattern-matching match tagged {...}
Let x = Current switch_state ? #on 72 : #off "sleeping for the night"
// expression-form pattern-matching:
Let y = match x { #on temp -> temp; #off message -> 68 }
// statement-form pattern-matching:
Match x:
#on temp ->
Change color to #green
Change temperature_dial to temp
#off message ->
Change display_message to message.slice(from: 0, to: 100)
Extensions to JavaScript features:
Multiline strings
Both string literals (""
and ''
) can have newlines in them, but
subsequent lines must be indented to at least the same level as the
open-quote; that indentation is then omitted from the result:
When button.Click:
Let valid_string = "first line
second line
third line" // == "first line\nsecondline\n third line"
When button2.Click:
Let invalid_string = "first line
second line" // error!
(TODO) Alternate string interpolation syntax $`text {expression} text`
In addition to JS template literal syntax (e.g.
`text ${expression} text`
), Mechanical supports an alternative
string interpolation syntax where you prefix the string with $
:
$`text {expression} text`
$'text {expression} text'
$"text {expression} text"
// are all equivalent to:
`text ${expression} text`
This is similar to C# but without support for format specifiers.
The expression syntax is based on JavaScript's, with a few deliberate incompatibilities in edge cases that I think JavaScript syntax is confusing:
Identifiers may only have single, interstitial underscores
this_is_totally_valid
_foo
, foo__bar
, foo_
, $foo
Exponentiation isn't chainable
2**3**2
be (2**3)**2 = 64
, or 2**(3**2) = 512
? JS and Python
both say 512
, but I think that's confusing because it's the other way
around for other non-associative operators, e.g. 2/3/4 = (2/3)/4
.
In Mechanical, 2**3**2
is a syntax error-2**2
is also a syntax error. This actually differs from
Python, where -2**2 = -(2**2) = -4
, but that's confusing because it
look like it could be (-2)**2 = 4
)Comparisons are chainable
3 > 2 > 1
is false, which is confusing. In Mechanical, not only
does a > b > c
behave as expected, but so does a > b >= c == d
, or
a == b < c == d < e == f
. This feature is inspired by Python, however
unlike Python, constructions like a < b > c
are prohibited (they have
to point the same way), and !=
can't be chained at all.!=
can't be chained because should 1 != 2 != 1
be true or false?)No holes in arrays (trailing commas are allowed though)
// valid:
[ 1, 2 ]
[ 1, 2, ]
[
1,
2,
]
// invalid:
[ 1, , 2 ]
[ 1, 2,, ]
Mechanical records are much more restricted than JS objects. Field names must be valid identifiers, not arbitrary strings or numerals, and cannot be quoted. They also cannot be computed, cannot be [method definitions], and there are no getters or setters. Trailing commas are allowed though!
// valid
{ valid_identifier: 1 }
// invalid
{
invalid__ident: 1,
_invalid: 2,
$invalid: 3,
"not an identifier at all": 4,
5: 6,
[compute(7, 8)]: 9,
method() {
Return 10
},
}
Only arrow function expressions (e.g. x => 2*x
) are supported (no
function (x) { return 2*x }
-style function expressions), functions must
take at least one argument (all functions are pure, so what would a
no-argument function do?), and trailing commas aren't allowed
(TODO: method-calling syntax/UFCS, named args when >2 params)
// valid
x => 2*x
(x, y) => sqrt(x**2 + y**2)
// invalid
() => 1
(x, y,) => sqrt(x**2 + y**2)
function (x) { return 2*x }
No bitwise operators
~
, &
, |
, <<
, >>
, >>>
built-in, but I hope to
introduce a built-in macroJS-specific things that don't make sense with Mechanical semantics:
===
/!==
. Regular in/equality ==
/!=
is
already strict++
/--
in
or instanceof
relations=
, +=
, -=
, *=
, /=
, etcYou may use Mechanical under either of our permissive licenses, the highly readable Blue Oak Model License, or the more standard MIT license.
FAQs
A language that makes building webapps as easy as finite-state machines
The npm package mechanical receives a total of 2 weekly downloads. As such, mechanical popularity was classified as not popular.
We found that mechanical demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
Research
/Security News
Undocumented protestware found in 28 npm packages disrupts UI for Russian-language users visiting Russian and Belarusian domains.
Research
/Security News
North Korean threat actors deploy 67 malicious npm packages using the newly discovered XORIndex malware loader.