npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

voidc

v0.6.0

Published

Void is a high performance WebAssembly language with an emphasis on full stack web development.

Downloads

6

Readme

Void

Void is a high performance WebAssembly language with an emphasis on full stack web development.

https://justforfunnoreally.dev/

fn fib(n: i32) -> i32
  if n < 2 then:
    n
  else:
    fib(n - 1) + fib(n - 2)

fn main() -> void
  for n in range(15)
    print fib(n)
fn app() -> JSX::Element
  let todo_items = ["wake up", "eat", "code", "sleep"]
  <div>
    <h1>TODO</h1>
    <ul>
      {todo_items.map i => <li>{i}</li>}
    </ul>
  </div>

Disclaimer

Void is in it's very early stages of development. Void is not ready for public announcement or use. Some core syntax and semantics are subject to change. Expect frequent breaking changes. In addition, many documented features are not yet implemented.

Features:

  • Functional
  • Hybrid Nominal & Structural type system
  • Algebraic effects
  • First class wasm support
  • Macros and language extensions
  • Uniform function call syntax
  • Homoiconic
  • Pythonesque syntax that de-sugars into a lisp like dialect
    • Parenthesis can be elided in most cases
    • Infix notation and standard function call notation support

Guiding Principles:

  • Fun to write and read.
  • Predictability
  • Hackability
  • Balance a great developer experience with performance
  • Play nice with others

Getting Started

Install

npm i -g voidc

Usage

voidc path/to/code.void

Requirements

Currently requires node v22

# Or nvm
fnm install v22

Overview

Comments

// Comments are single line and are marked with a c style slash slash

Primitive Types

true // Boolean
false // Boolean
1 // i32 by default
1.0 // f32 by default
"Hello!" // String, can be multiline, supports interpolation via ${}
[1, 2, 3] // Array literal
(1, 2, 3) // Tuple literal
{x: 2, y: 4} // Object literal

Variables

// Immutable variable
let my_immutable_var = 7

// Mutable variable
var my_var = 7

Functions

A Basic function:

fn add(a: i32, b: i32) -> i32
  a + b

In most cases the return type can be inferred

fn add(a:i32, b:i32) = a + b // The equal sign is used when the function is written on one line

To call a function, use the function name followed by the arguments in parenthesis

add(1, 2)

Void also supports uniform function call syntax (UFCS), allowing functions to be called on a type as if they were methods of that type.

1.add(2)

Labeled arguments

Labeled arguments can be defined by wrapping parameters you wish to be labeled on call in curly braces.

fn add(a: i32, {to: i32}) = a + to

add(1, to: 2)

By default, the argument label is the same as the parameter name. You can override this by specifying the label before the argument name.

fn add(a: i32, {to:b: i32}) = a + b

add(1, to: 2)

Labeled arguments can be thought of as syntactic sugar for defining a object type parameter and destructuring it in the function body[1]:

fn move({ x: i32 y: i32 z: i32 }) -> void
  // ...

// Semantically equivalent to:
fn move(vec: { x: i32 y: i32 z: i32 }) -> void
  let { x, y, z } = vec
  // ...

move(x: 1, y: 2, z: 3)

// Equivalent to:
move({ x: 1, y: 2, z: 3 })

This allows you to still use object literal syntax for labeled arguments when it might be cleaner to do so. For example, when the variable names match the argument labels:

let [x, y, z] = [1, 2, 3]

// Object field shorthand allows for this:
move({ x, y, z })

// Which is better than
move(x: x, y: y, z: z)

[1] The compiler will typically optimize this away, so there is no performance penalty for using labeled arguments.

Control flow

If statements

if 3 < val then:
  "hello" // true case
else:
  "bye" // false case (optional)

Ifs are expressions that return a value

let x = if 3 < val then: "hello" else: "bye"

Loops

Basic loops repeat until returned from

var a = 0
loop
  if a > 10
    return a
  a += 1

Loops can be labeled

var a = 0
loop name: "increment"
  if a > 10
    return_from "increment" a
  a += 1

Useful constructs from looping through iterables

for item in iterable
  print item

Match Statements

Match statements are used for type narrowing

obj Animal
obj Cat extends Animal
obj Dog extends Animal

let dog = Dog {}

match(dog)
  Dog: print "Woof"
  Cat: print "Meow"
  else:
    print "Blurb"

Closures

let double = n => n * 2

array.map n => n * 2

Dot Notation

The dot is a simple form of syntactic sugar

let x = 4

x.squared

// Translates to
squared(x)

Generics

fn add<T>(a: T, b: T) -> T
  a + b

With trait constraints

fn add<T: Numeric>(a: T, b: T) -> T
  a + b