• Stars
    star
    7
  • Rank 2,222,955 (Top 46 %)
  • Language
    Julia
  • Created almost 9 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An alternative module system for Julia

Kip

Kip is an alternative module system for Julia with the goal of being more robust and easier to use. With Kip packages don't have names. Instead modules are identified by the file they are in. So you can have several versions of the same package without them overwriting each other. Also it favours putting dependency info inline rather than in a REQUIRE file. This reduces indirection and works well at the REPL. The final key difference is that it installs dependencies at runtime. So you never have to think about if a package is installed or not. Though you should run Kip.update() occasionally to update Kip's local cache of packages which are just plain Git repositories.

Installation

Pkg.clone("https://github.com/jkroso/Kip.jl.git")

Then add this code to your ~/.julia/config/startup.jl

import Pkg
using Kip
haskey(ENV, "ATOM_HOME") && @use "github.com/jkroso/Rutherford.jl"

Now it's like Kip was built into Julia. It will be available at the REPL and in any files you run

API

Kip's API consists of just one macro to import modules. And one function to update all the 3rd party repositories you use

@use(pkg::String, imports::Symbol...)

@use takes a path to a package and a list of symbols to import from that package. If you want to use a different name locally for any of these symbols your can pass a Pair of symbols like @use "./thing" a => b. This will import a from the local package "./thing" and make it available as b.

Now I just need to explain the syntax of the path parameter. In this example I'm using a relative path which is resolved relative to the REPL's pwd(). Or if I was editing a file it would be the dirname() of that file. This should be familiar for people who use Unix machines. Now, assuming we are at the REPL, what @use does under the hood is check for a file called joinpath(pwd(), "./thing"). If it exists it will load it. Otherwise it tries a few other paths joinpath(pwd(), "./thing.jl"), joinpath(pwd(), "./thing/main.jl"), and joinpath(pwd(), "./thing/src/thing.jl"). This just enables you to save a bit of typing if you feel like it.

There are a couple other types of paths you can pass to @use:

  • Absolute: @use "/Users/jkroso/thing"

  • Github: @use "github.com/jkroso/thing"

    This syntax is actually pretty complex since it also needs to enable you to specify which ref (tag/commit/branch) you want to use. Here I haven't specified a ref so it uses the latest commit. If I want to specify one I put it after the reponame prefixed with an "@". e.g: @use "github.com/jkroso/thing@1" This looks like a semver query so it will be run over all tags in the repo and the latest tag that matches the query is the one that gets used. Finally, if the module we want from the repository isn't called "main.jl", or "src/$(reponame).jl" then we will need to specify its path. e.g: @use "github.com/jkroso/thing@1/thing". And path completion will also be applied just like with relative and absolute paths.

update()

Runs git fetch on all the repositories you have @use'd in the past. So that next time you @use them you will get the latest version

Native Julia module support

If the module you require is registered in Pkg.dir("METADATA") then it will be installed and loaded using the built in module system. So @use "github.com/johnmyleswhite/Benchmark.jl" compare is exactly equivalent to import Benchmark: compare. This reduces the likelihood of ending up with duplicate modules being loaded within Kip and Pkg's respective caches. Especially while Julia doesn't provide any good way to load non-registered modules.

Kip also supports non-registered modules by looking at the contents of the file you are requiring to see if the only thing in it is a Module. When that's the case it will unbox it from the wrapper Kip normally uses. If Julia ever provides good support for non-registered modules itself then Kip will Pkg.clone the module and import it to match its handling of registered modules.

Running arbitrary code on another machine

Since dependencies are declared in the code you can pipe arbitrary code into a machine running Julia and have the results piped back. Or on the other hand you could curl $url | julia to run remote code on your local machine. Here is an example of running some code through a docker instance (BTW so long as you have docker installed you can run this)

$ echo '@use "github.com/coiljl/URI" encode; encode("1 <= 2")' | docker run -i jkroso/kip.jl
"1%20%3C=%202"

Example projects

This demonstrates mixed use of native modules and Kip modules. It also shows how nice Kip is for writing CLI programs. Since its dependencies will be installed at runtime Jest's CLI script only needs to be downloaded and put in the user's $PATH.

Here Kip enabled me to put my benchmark code directly in this projects Readme.ipynb file since I didn't need to worry about installing the dependencies.

Prospective features

Automatic reloading of modules

While at the REPL it could listen to changes on the modules you require and automatically reload them into the workspace.

Dependency tree linting

Kips ability to load multiple versions of a module at the same time is a double edged sword. The upside is package developers can make breaking changes to their API's without instantly breaking all their dependent projects. The downside is that if you and your dependencies have dependencies in common and they load different versions of these modules to you then you might run into issues if you passing Type instances back and fourth between your direct dependencies. This is a subtle problem which can be hard to recognise. Especially if you not aware that it can happen. A good solution to this might be to use a static analysis tool to check your dependency tree for potential instances of this problem. It would make sense to make it part of a linting tool.

More Repositories

1

parse-duration

convert a human readable duration to ms
JavaScript
239
star
2

parse-svg-path

A minimal svg path parser
JavaScript
88
star
3

normalize-svg-path

"simplify" an svg path
JavaScript
49
star
4

flowtype

keep font-size in proportion with its containers size
HTML
41
star
5

packin

A better npm install
Julia
24
star
6

satellite

A DOM element which can be told to position itself around another element
JavaScript
21
star
7

abs-svg-path

redefine an svg path with absolute coordinates
JavaScript
20
star
8

computed-style

getComputedStyle() with fallback
JavaScript
15
star
9

Rutherford.jl

Figuring out how to do generic UIs
Julia
13
star
10

equals

Check if two values are deeply equivalent
JavaScript
11
star
11

move

Pure JS DOM animation
JavaScript
11
star
12

position

utilities for working with positioned DOM elements
JavaScript
10
star
13

easy-style

A convenience wrapper for free-style
HTML
9
star
14

buildfresh

Automatically run a command and reload your browser when files change
JavaScript
9
star
15

string-tween

tween strings
JavaScript
8
star
16

edn.js

An EDN reader and an EDN writer for JS
JavaScript
7
star
17

atom-browser-refresh-on-save

A plugin for Atom which reloads assets in the browser as soon as you save them
CoffeeScript
7
star
18

free-variables

Get a list of free variables used in a JS program
JavaScript
7
star
19

now

performance.now() x-browser
JavaScript
6
star
20

contextmenu

A contextmenu interface
JavaScript
6
star
21

timeline

orchestrate a group of animations
JavaScript
5
star
22

untar

unpack the contents of a tar file to a directory
JavaScript
4
star
23

rename-variables

Safely rename JS variables
JavaScript
4
star
24

serialize-svg-path

JavaScript
4
star
25

eslint-plugin-jsx

JSX specific linting rules for ESLint
JavaScript
3
star
26

SourceGraph

Pull your modular project into memory so you can get fancy with it
JavaScript
3
star
27

progress-svg

Circular progress indicator using SVG
JavaScript
3
star
28

component-set

JavaScript
3
star
29

dom-event

Low level helper for creating DOM events
JavaScript
3
star
30

JSX-to-JS

A JSX transpiler that at least tries to do it properly
JavaScript
3
star
31

Destructure.jl

Destructuring assignment macros
Julia
3
star
32

Emitter.jl

An event emitter for julia
Julia
3
star
33

eval-as-module

Eval a JS string as if it was a file being required
JavaScript
3
star
34

big-executable

inline a modules dependencies to reduce startup IO
JavaScript
2
star
35

DOM.jl

Julia
2
star
36

fs-plates

a cli tool for rendering project boilerplate
Shell
2
star
37

Units.jl

experimental unit support for Julia
Julia
2
star
38

fs-equals

test pieces of the file system for equality
JavaScript
2
star
39

map-ast.js

The boring part of any JS source transform
JavaScript
2
star
40

Promises.jl

A lazy evaluation primitive for Julia
Julia
2
star
41

alias-property

create robust aliases for an object's properties
JavaScript
2
star
42

lift-result

lift functions so they can handle results as if they were plain values
JavaScript
2
star
43

transducer.js

A really simple transducers implementation
JavaScript
2
star
44

animation

A base class for animations
JavaScript
2
star
45

babel-plugin-runtime

Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals.
JavaScript
2
star
46

forEach

iterate over key value pairs (async/sync)
JavaScript
2
star
47

respict

A dictionary which respects its inheritance chain
JavaScript
1
star
48

Jest.jl

Enables embedded tests
Julia
1
star
49

Sequences.jl

Linked lists and lazy streams
Julia
1
star
50

classes

x-browser class manipulation
JavaScript
1
star
51

Electron.jl

Provides easy access to atom/electron from Julia
Julia
1
star
52

coerce.jl

Aggresively convert values of one type to another
Julia
1
star
53

rel-svg-path

Define SVG path data using only relative points
JavaScript
1
star
54

EDN.jl

Supports reading and writing the edn format
Julia
1
star
55

typed-stream

dramatically simpler streams through specialization
JavaScript
1
star
56

node-cp-r

cp -R for node
JavaScript
1
star
57

ast-children

get the children of an AST node
JavaScript
1
star
58

SimpleCLI.jl

Epically sexy CLI scripts in Julia
Julia
1
star
59

mana

A prettier virtual DOM library
JavaScript
1
star
60

viewport

Represents the browsers view port and emits events when it changes state
HTML
1
star
61

dom-emitter

Manage the events of a DOM element
JavaScript
1
star
62

atom-inc

An Atom package to quickly tweak simple value types
JavaScript
1
star
63

tree-each

higher order iteration for trees
JavaScript
1
star
64

pico-button.c

A debounced button for Raspberry Pico
CMake
1
star
65

pico-i2c-driver.c

Enables you to talk to I2C slaves from any computer with a USB port
CMake
1
star
66

topograph

A graph data-structure
JavaScript
1
star