Skip to content

Commit

Permalink
Remove stuff from d
Browse files Browse the repository at this point in the history
  • Loading branch information
davesnx committed Oct 11, 2023
0 parents commit f598a26
Show file tree
Hide file tree
Showing 3,970 changed files with 686,715 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.re linguist-language=Reason
*.rei linguist-language=Reason
61 changes: 61 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.DS_Store
/node_modules*

.merlin
.install
/lib/bs/
/lib/js/
/lib/ocaml/
*.log
.bsb.lock
_esy
*.install
*.bs.js

# Editor
/.idea/

_build
_opam

scripts/*.js

drafts/.git
drafts/.github
drafts/examples
drafts/scripts
drafts/coverage
drafts/assets
drafts/package-lock.json
drafts/yarn.lock
drafts/yarn-error.log
drafts/pnpm-lock.yaml
drafts/.npmignore
drafts/.gitattributes
drafts/.gitignore
drafts/.editorconfig
drafts/.node-version
drafts/.prettierignore
drafts/bsconfig.json
drafts/CONTRIBUTING.md
drafts/vite.config.js
drafts/lerna.json
drafts/.vscode
drafts/jest.config.js
drafts/babel.config.js
drafts/tsconfig.json
drafts/.screenrc
drafts/.changeset
drafts/.yarn
drafts/.circleci
drafts/.ci
drafts/azure-pipelines.yml
drafts/CODEOWNERS
drafts/CODE_OF_CONDUCT.md
drafts/Makefile
drafts/.bsb.lock
drafts/index.html
drafts/postcss.config.js
drafts/tailwind.config.js
drafts/tasks.json
drafts/circle.yml
46 changes: 46 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Contributing

Thanks for your interest! Below we describe reason-react development setup for the project.

```sh
git clone https://github.com/davesnx/bindings.git
cd bindings
```

## Installation

To set up a development environment using [opam](https://opam.ocaml.org/), run `make init` to set up an opam [local switch](https://opam.ocaml.org/blog/opam-local-switches/) and download the required dependencies.

## Developing

```sh
make dev ## Build in watch mode
```

Running `make help` you can see the common commands to interact with the project:

```sh
build-prod Build for production (--profile=prod)
build Build the project, including non installable libraries and executables
clean Clean artifacts
create-switch Create a local opam switch
dev Build in watch mode
format-check Checks if format is correct
format Format the codebase with ocamlformat
help Print this help message
init Create a local opam switch, install deps
install Update the package dependencies when new deps are added to dune-project
test-promote Updates snapshots and promotes it to correct
test-watch Run the unit tests in watch mode
test Run the unit tests
```
## Submitting a Pull Request
When you are almost ready to open a PR, it's a good idea to run the test suite locally to make sure everything works:
```sh
make test
```
If that all passes, then congratulations! You are well on your way to becoming a contributor 🎉
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 David Sancho

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
44 changes: 44 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
DUNE = opam exec -- dune

.PHONY: help
help: ## Print this help message
@echo "List of available make commands";
@echo "";
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}';
@echo "";

.PHONY: build
build: ## Build the project, including non installable libraries and executables
@$(DUNE) build @@default

.PHONY: build-prod
build-prod: ## Build for production (--profile=prod)
@$(DUNE) build --profile=prod @@default

.PHONY: dev
dev: ## Build in watch mode
@$(DUNE) build -w @@default

.PHONY: clean
clean: ## Clean artifacts
@$(DUNE) clean

.PHONY: format
format: ## Format the codebase with ocamlformat
@$(DUNE) build @fmt --auto-promote

.PHONY: format-check
format-check: ## Checks if format is correct
@$(DUNE) build @fmt

.PHONY: install
install: ## Update the package dependencies when new deps are added to dune-project
@opam install . --deps-only --with-test
@npm install

.PHONY: init
create-switch: ## Create a local opam switch
@opam switch create . 5.1.0 --no-install

.PHONY: init
init: create-switch install ## Create a local opam switch, install deps
119 changes: 119 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# bindings
Melange bindings repository for popular JavaScript libraries

- **Learn**: if it's the first time you bind, having a bunch of examples in one place, helps. If it's the 99th time you do, having a cheatsheet is also good.
- **Use them by owning them**: The usage of this repository is to copy/paster into you project. This way you own the bindings and you can change them if you need.
- **To collaborate and unify efforts**: most bindings become outdated, abandoned or unmaintained. Having a central place to collaborate and unify efforts is a good way to avoid this, and when newer versions of Melange get released we can update all the bindings at once.

## What are bindings
Bindings in Melange is the method to communicate with JavaScript and have some garanties on the type-checker. In other languages this is called FFI (Foreign Function Interface).

The other direction, calling Reason from JavaScript is explained here: https://melange.re/v2.0.0/communicate-with-javascript/#use-melange-code-from-javascript

```js
// file.js
export const add = (a, b) => a + b
```

Given a lovely `file.js`, the way to call the `add` function from Reason is to bind to it, by telling the compiler that each time you call `add` (in Reason files) it should be called with two integers and it will return an integer.

In this particular case, the proper binding should be:

![Binding explained with arrows](./binding-explained.png)

## Particularities of bindings

### 1) Bindings can be unsafe
If you lie (by having a mistake on the binding) to the compiler, this can cause a runtime crash.

### 2) Bindings are creative and subjective
There are very different approaches on how to bind a library. In simple cases, there's no room for creativity, but in more complex cases there are many ways to do it. This can vary from the level of safety, the "cost" of the binding or even the external API you want to provide.

### 3) Require knowledge about runtime representation
In order to bind a library, you need to know how Melange represents runtime data. This is not a big deal, but it's something to keep in mind. All information about runtime representation is available in the docs: https://melange.re/v2.0.0/communicate-with-javascript/#data-types-and-runtime-representation

### 4) Some dynamic JavaScript patterns aren't possible to bind (but workarounds are possible)
Some patterns from JavaScript aren't possible to represent in the type-checker. A silly example would be:

The following code is not possible to bind 1 to 1:

```js
export const add = (a, b) => a + b
add.one = (a) => add(a, 1)
```
You can't have a function and a property that is also a function in the same value in Reason. The workaround is often to bind differently than the original API.

In this case, you could have:

```reason
[@mel.module "./file.js"] external add: (int, int) => int = "add"
[@mel.module "./file.js"] [@mel.scope "add"] external addOne: int => int = "one"
```

### 5) The cost of the binding (runtime overhead vs zero-cost)

zero-cost bindings means to not have any runtime overhead. This is often preferred, but there are also cases where a small overhead is acceptable. For example, if you want to provide a more idiomatic API to Reason, you can have a small overhead by using a library.

This is a source of dicussion on other communities and we don't have a strong opinion on this. We think that both approaches are valid and we should have both approaches in the bindings repo.

In case of having the duality, it's a good idea to expose both approaches in the same package. For example:

```bash
/packeges/lodash_zero
/packeges/lodash_safe
```

Read the full https://melange.re/v2.0.0/communicate-with-javascript

## How it works

Copy and paste into your apps, own the bindings, change them if you need and contribute back the changes.

### What's the structure

```bash
├── packages/ # stable bindings, build in CI and compiles with latest melange
└── drafts/ # the unstable bindings, not build in CI, neither compiles with latest melange, can contain ReScript code, JSX2 code, etc.
```

If a package needs testing, documentation or any additional piece is probably a good idea to promote it as a separate repo under melange-community.

Inside each package we could specify different kinds of bindings depending on the safety level, the "cost" or even the library version. For example:

```bash
$ ls -d packages/lodash*
/packages/lodash_safe
/packages/lodash_zero
/packages/lodash_v2
```

### How to contribute

1. Fork the repo
2. Create a new branch
3. Add your bindings
4. Create a PR

## Tools to generate bindings

There has been a bunch of attemps at automatic generate bindings. Mostly 1) from TypeScript definitions, 2) from JavaScript code.

### From JavaScript

- https://github.com/jchavarri/rebind Automated generation of Reason/BuckleScript bindings from JavaScript code
- https://github.com/emnh/js-to-reasonml-transpiler JavaScript to ReasonML transpiler for small code examples
- https://github.com/chenglou/jeason crappy js-to-reason converter
- https://github.com/jaredly/rejs JavaScript to Reason transpiler

### From TypeScript

- https://github.com/ocsigen/ts2ocaml Generate OCaml bindings from TypeScript definitions via the TypeScript compiler API
- https://github.com/jsiebern/re-typescript An opinionated attempt at finally solving typescript interop for ReasonML / OCaml
- https://github.com/andrewray/DefinitelyMaybeTyped TypeScript to js_of_ocaml
- https://github.com/rrdelaney/ReasonablyTyped Converts Flow and TypeScript definitions to Reason interfaces
- https://github.com/Diullei/ts2reason Automatic generation of ReasonML bindings using TypeScript definitions
- https://github.com/joshaber/ts2re Convert TypeScript type declarations to Reason

### Using LLM

ChatGPT has been reported as being very helpful as starting point, but we haven't explored it yet.
Binary file added binding-explained.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions bindings.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
opam-version: "2.0"
license: "MIT"
homepage: "https://github.com/davesnx/bindings"
bug-reports: "https://github.com/davesnx/bindings/issues"
depends: [
"dune" {>= "3.9"}
"ocaml" {>= "5.1.0"}
"melange" {>= "2.0.0"}
"reason" {>= "3.10.0"}
"ocaml-lsp-server" {with-test}
"ocamlformat" {= "0.26.0" & with-dev-setup}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/davesnx/bindings.git"
31 changes: 31 additions & 0 deletions drafts/bs-Zarith/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Revision history for bs-zarith

## 3.2.0 -- 2022-12-01
* Drop print functions so it builds with the latest Rescript. These were likely seldomed used.

## 3.1.0 -- 2020-10-25

* Drop support for Nativeint. It is not supported by bs-platform 8.3.0 and above.

## 3.0.0 -- 2020-06-12

* New module Bigfloat. Experimental status.
* New module Natural.

## 2.0.0 -- 2020-06-04

* Support unsigned integers.

## 1.1.0 -- 2020-02-20

* Fix Bigint multiplication bug.

## 1.0.1 -- 2018-04-23

* Add warnings "+A-44" to bsconfig.json.

## 1.0.0 -- 2018-06-21

* Add Bigint module for arbitrary length integers.
* Add Z module for combining the operators of all integer types (int, Int32.t, Nativeint.t, Int64.t and Bigint.t).
* Add Q module for rational integers.
30 changes: 30 additions & 0 deletions drafts/bs-Zarith/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# bs-zarith

The API is stable, but there is not a lot of testing. Use with caution.

## Bigint

```OCaml
let x = Bigint.of_string "1000000000000000000000000000000000000000" in
let y = Bigint.of_int 1 in
let z = Bigint.(y + x) in
Js.log(Bigint.to_string(z));
```

## Z

```
let x = Z.Int64.of_string "230000232323322323" in
let y = Z.Int64.of_int 3 in
let z = Z.Int64.(x - y) in
Js.log(Z.Int64.to_string(z));
```

## Q

```
let x = Q.Int.of_string "1/2" in
let y = Q.Int.make (Z.Int.one) (Z.Int.of_int 2)
let z = Q.Int.sub x y
Js.log(Q.Int.to_string(z));
```
Loading

0 comments on commit f598a26

Please sign in to comment.