Git Product home page Git Product logo

dot's Introduction

kotct/dot Build Status Coverage Status

Dot is a collective configuration system which contains configurations for programs like Emacs and zsh, but also (potentially) Vim. Dot is written under the following principles:

  • Configurations should only be run if necessary—that is, if the user wants it.
  • Configurations should be as lean, modular, and standalone as possible, utilizing autoload and byte compilation mechanisms whenever possible and only running what is necessary.
  • Configurations should be clean, well-documented, and consistently-written throughout.
  • Configurations should have a focus on truly excellent support for everything.
  • Configurations should also have clear error messages handling common PEBKAC errors.

Installation

You can use this command to install our configuration. (Ruby must be installed for this to work, so make sure you have done that.)

$ \ruby -e "$(\curl -fsSL https://raw.githubusercontent.com/kotct/dot/master/scripts/install)"

This script will interactively ask you if there are any conflicts or decisions to be made, but will immediately start installing the configuration, so make sure that you are sure of what you want to do.

This script assumes a fairly regular system with the requisite software installed, so if you are in an esoteric environment, you can plan on manually installing this by symlinking into ~. If something breaks down on a normal system, (like Ubuntu, Fedora) please open an Issue and we will get back to you ASAP.

If your system is running an older version of a dependency software, (i.e. Emacs < 25.1, Ruby < 2.4) please do your best to update to the latest version directly available from your package manager. If an issue is not reproducible on our system, we cannot fix it.

It is worth noting that you should be able to simply simlink the respective files and directories into your HOME directory.

You can do this by cloning this repository, then running:

$ bundle install
$ rake install

This is effectively what the above script does, except it allows you to clone to your own desired location.

Emacs

The Emacs configuration is the primary focus of this project and is the defining feature of this project. Most of the work done here will be done on the Emacs configuration, as the primary goal in writing this configuration is and was to write a robust, fast, and efficient Emacs configuration.

Below is included the discussion about the rewrite of the Emacs configuration, which will take place in this repository.

Goals

Create fast configurations for common developer tools with a clean, unified style, that has IDE-level support for many languages.

In addition, the following guidelines apply to our Emacs configuration:

  • Autoload things as much as possible—that is, load as little as possible on startup so as to minimize start-up time.
  • Automatically byte-compile on start.
  • Use a clean, consistent EmacsLISP style.
  • Have a focus on excellent support for individual languages.
  • Make sure everything is well-thought-out and well-documented.
  • Have clear error messages handling most user fuck-ups.

Personal Configs

To create a personal config, create a personal, public GitHub repo called .emacs. Emacs may prompt you to add a "personal config" on start. If your emacs is already up and running, and no longer prompts you as such, you can add your personal config by doing M-x kotct/user-set-default-username. Emacs will automatically grab your config from GitHub and load it. The clone that emacs uses is stored in a directory named after your GitHub username in .emacs.d/lisp/user/users/.

To update the clone of your personal config, do M-x kotct/user-update-config. In addition, to switch to another user config, do C-x C-z.

Structure

Within the base .emacs.d directory, the only checked-in emacs lisp file is init.el. This file contains any code that must be loaded before the elisp hubs and any code that manages loading, autoloading, or byte compilation.

All other codes is organized into directories based on language. For instance, all emacs lisp code goes into the lisp directory, and ruby or python code goes into the ruby and python directories, respectively.

The lisp directory contains a directory for each "hub". Within each hub directory is a <hub-name>-hub.el directory containing the hub definition (using the kotct/hub function). Each file within the hub that is loaded at startup should provide a feature with a simple name (e.g. "startup", "backup", or "recentf-c"). If the file is configuring another package, name it <package>-c (as in "recentf-c" above), with "c" standing for "configuration." Try to avoid this "-c" suffix when possible.

Autoloading

Autoloading custom features

Autoloaded files should contain at least one function or other symbol whose definition is preceded by an autoload token (;;;###autoload).

At the top of the file, include the following comment:

;;; THIS FILE IS NOT LOADED AT STARTUP.
;;; This file is autoloaded on the following symbols:
;;;  kotct/function1
;;;  kotct/function2

To make sure the file is checked for autoloads, ensure that in the hub file's call to kotct/hub, the final argument is 'autoloads.

Calls to autoload will be automatically generated and saved in lisp/kotct-loaddefs.el and loaded on startup.

Preserving package autoloads

Generally, calls to require should be avoided, since these calls will sometimes force loading of features that would otherwise be autoloaded. Cases can occur in which a require is appropriate, for instance, if the package does not have autoloads or an autoload will be triggered later in the file anyway.

If an autoloaded package needs configuration, instead of using require to load the package in order to configure it, wrap the configuration in a with-eval-after-load block so that it will only be loaded after the package is autoloaded.

Byte compilation

All files are automatically bytecompiled asynchnonously after emacs starts. This aims to be a totally hands-off experience. That said, any files more than one subdirectory below the lisp/ directory need to be manually added to kotct/files-to-compile, which keeps track of all the files that are to be byte compiled.

Keybindings

Keybindings should be located at whatever places makes sense. Most commonly, they will be located after the definition of the function they are binding, or after relevant configuration.

To globally bind a key, use a line such as:

(global-set-key (kbd "C-x C-r") #'kotct/ido-recentf-open)

At the top of any file with keybindings, add a comment like the following for each keybinding:

;;; C-x C-r: find recent files and directories using recentf

Portability

The only assumptions we can make about our environment are that we are using a certain minimum version of emacs (tbd) and we have all package dependencies installed (although we should handle the case at startup where not all dependencies are installed).

Things we CANNOT assume:

  • We are using a POSIX-compliant OS.
  • We have external dependencies installed (such as Ruby or Python).
  • The user is not an idiot.

Up for debate:

  • Can we assume we are not running from a terminal (i.e. can we design so that some functionality may not be present when running from a terminal)?

Emacs lisp style guide

  • Prefix all global function or variable names with kotct/, as in kotct/ido-recentf-open or kotct/hub-names.
  • Always use setf instead of setq. setq should never be used in this project.
  • When referencing a function name, always use a function quote (#') instead of a regular quote ('). This function quote (or funquote) translates to a call to function instead of quote.
  • As described in the Autoloading section, avoid require and use with-eval-after-load.
  • Make sure all defuns, defvars, and defmacros (and any other global definitions) have docstrings that are properly formatted.
  • Comment when it's not immediately clear what the code is doing.
  • Write modular, clean, and fast code.

License

dot is released and distributed under the terms of the MIT license. See LICENSE for more information.

dot's People

Contributors

cg505 avatar dependabot[bot] avatar rye avatar samontea avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

cooperc0 cg505

dot's Issues

Revamp CONTRIBUTING file

As part of the discussion in #57, it seems we've decided on a good branching scheme. I mentioned that we should probably go ahead and toss the scheme there into the CONTRIBUTING.md file, but in looking at the current version of this file, it seems less welcoming and more verbose than I'd hope for.

I think the opener can be a bit less terse and more friendly, and the "Options" section can probably be refactored to reduce the number of bullet points.

I'm just opening this issue for tracking, feel free to provide feedback.

Notify user if dot, their personal config, or their packages are out of date

This has been floating around my head for a while, and since we've been throwing a bunch of shit on the board lately, I thought I might as well get it out there.

The idea is basically that after we start we spin off a few processes that check to see if

  1. any emacs packages need updating
  2. dot is out of date
  3. the loaded user config is out of date

If any of these are true, insert the results in a comment in *scratch*.

Thoughts @rye @samontea?

Task List:

  • #66 Updating kotct/packup UI
  • Creating kotct/dotup a dot function for updating dot configs with the UI from #66
  • Creation of a unified update function kotct/up for both packages and dot configurations

Shell Configuration

One aspect of this project that we haven't really covered is shell configurations.

My plan is to imitate what we did with Emacs, but this time for a shell configuration.

Generally, the process to implement this is as follows:

  • We would implement something like a ~/.profile file meant to be loaded independently of by which app, to normalize environment variables.
    • From this, we would move on to implementing a smarter and smarter configuration system so that it is more dynamic and smart.
    • We could consider implementing this with a large number of debugging traces that we can turn off when we're done but still use for testing.
  • From this, we would implement some (much smaller) configurations for each of the different shells we use.

A question to be answered by @cg505, (also @Sammidysam, and @samontea):

  • Should we set PS1? Or should that be user-configured locally?
    • If it should be set by the user, how? (cc #30)

helm

I have not used helm and I was wondering if anyone else has. It seems like it does many of the same things as ido but in many cases it does them better. I was considering creating a branch to try it out.

Startup Prompts Don't Work When Started Headless

We do several prompts on startup (especially the first time) such as asking if packages want to be installed, asking about a default config, etc. These currently don't work when emacs starts headless (e.g. $ emacsclient -c -a "").

This is not a simple issue to solve, and thus is pretty low-priority. We would have to do something like stop startup, and put all remaining starup on after-make-frame-functions, and remove the hook it after it runs.

Themes are not loaded correctly in daemon mode

If and only if emacs is started in daemon mode, the initial theme is not loaded correctly, even if the user switches to another theme and back to the first. The issues are small: colors off, etc. I noticed when using material-theme as used in my config.
This is probably something to do with loading the theme before we have any connection to X or something. I have not had much time to investigate the issue.

kotct/user-switch-username Fails If Previous User Switch Failed

If I switch to a user configuration hub and then back to my own with a syntax error, things break and Emacs complains that, for example if I switch from my own broken hub to cg505's, then try to switch to my own broken hub,

cg505-hub is not a currently loaded feature

Symbol's function definition is void: package-initialize

I have gotten the following warning since switching back to Emacs' development version.

Warning (package): Unnecessary call to ‘package-initialize’ in init file

It seems that our call of this is unnecessary.

The reason automatic package loading occurs after loading the init file is that user options only receive their customized values after loading the init file, including user options which affect the packaging system. In some circumstances, you may want to load packages explicitly in your init file (usually because some other code in your init file depends on a package). In that case, your init file should call the function package-initialize. It is up to you to ensure that relevant user options, such as package-load-list, are set up prior to the package-initialize call. This will automatically set package-enable-at-startup to nil, to avoid loading the packages again after processing the init file. Alternatively, you may choose to completely inhibit package loading at startup, and invoke the command M-x package-initialize to load your packages manually.

Given that we require any dependencies that we need to configure before configuring them, do we still need this call? Emacs is saying no.

dot/.emacs.d/init.el

Lines 6 to 7 in 61b9eb5

;; Initialize the package repository.
(package-initialize)

Add sh-mode customizations

It seems we haven't added support for sh-mode yet. That is a thing that should be done.

Known issues needing fixed:

  • Spaces are always used

Testing and CI

I think we should really look into improving some of the ways we interact with users. We should try to deal with edge cases in a smarter way, and generally clean up our code. How do we feel about using CI and tests? Testing our existing code might evoke good change in our codebase.

Task List:

  • #61 Add testing framework and integration with Travis CI, using buttercup
  • #75 Add coverage support and reporting to Coveralls using undercover
  • Write tests for existing code
  • Add linting support, fix linting issues, and check linting in Travis CI

fastest TRAMP method???

we use ssh, as per emacswiki. but TRAMP itself claims scp is faster. who's right?

also TIL tramp supports adb, lol

Web-mode indentation is not very consistent

It seems that we have not set up tracking on this to make variable values consistent. Nor have we set up SQL support, which is part of web-mode.

Since web development is such a big part of my life, it's a damn shame that I haven't fixed this to this point.

Set load-prefer-newer globally

load-prefer-newer tells load to pick the .el file if it is newer than the .elc (and vice versa, of course). This can incur a speed penalty. We need this on for emacs lisp that we write, since there is no guarantee that the compiled version is the most recent. We have been let-binding load-prefer-newer to t when loading hubs to avoid this issue. However, it seems likely that that binding does not affect autoloads. I don't see any simple/non-hacky way to deal with correctly loading the right version of autoloaded files in our config without simply setting load-prefer-newer globally. I don't expect the speed penalty to be significant. Thoughts?

Licensing

As this becomes a more major project with actual potential for wider usage, it would be good to set up our licensing and everything correctly.

Machine-Local Configuration

Provide some way to have a machine-specific config. Could be used for things like setting executable locations.

Assess status of EditorConfig support

In #51 we concluded we were not correctly warning the user when they did not have have the EditorConfig executable installed. This was fixed in PR #52. However, I think this needs reevaluated. The main reason is that the emacs package for EditorConfig has fallback parsing support that doesn't depend on the binary and seems to be fully functional. If we have the binary, we should use it, but it doesn't seem to make sense to me to warn the user every time they start up if they don't have a binary that they don't even really need.

Other relevant issues/PRs: #10 #18.

LSP?

One of the stated goals of our Emacs configuration is to:

  • Have a focus on excellent support for individual languages.

The problem of supporting many languages is a complicated one. For the community, the workload required to support m languages on n editors is O(m n), as you might expect.

LSP, the Language Server Protocol, aims to turn this from O(m n) to O(m + n), by offloading general tasks to a separate process that is implemented for the specific language. In this way, an editor only needs to implement bindings to connect to a language server and handle its responses, and the language server can be provided by those who are familiar with the language.

Is there interest in adopting lsp-mode? It has nice integrations with flycheck and company-mode too.

Here's an example of what lsp-ui presents in rust-mode. Quite rich!

image

Remote Self-Checking; Packaging

Version self-checking against a remote is a feature that we should add to this project going forward, and the ability to do this quickly and asynchronously is critical to implementing a clean user-facing interface.

In general, I want to implement a suite of configuration files and shell scripts in this project for self-checking the current version installed against some remote. In the event of an outdated installation, the user would be prompted to update. This brings about the following questions:

  • Do we want to support non-standard installation of dot? I say no, and I'm pretty sure all of the other collaborators would agree. Anyone who does not install the project through a standard installation vector assumes their own responsibility for keeping things running stably. Standard installation vectors are as follows:

    1. git clone-ing our project onto a client machine. (--shallow is within the realm of possibility, which may result in loss of tags.)
    2. Downloading a tarball of the project at a given release.
    • In both cases above, the installation will include a full bundle of the .emacs.d tree and any shell configurations we bring in, as well as the central VERSION file at the root of the project. This can be a good fallback.
  • When do we want to prompt people to update dot? I say: every time the user starts a dot component, this self-check should execute, and in long-running situations e.g. Emacs being open for days on end, daily timers should be run also. We should store the last update check timestamp in a readable file that everything can easily parse, so that multiple checks don't happen on top of each other.

  • How do we want to execute remote scripts?

Recentf Save Gets Blocked by Interlocking

In my daily life, I walk around a lot. Emacs opens recentf a bunch, but it seems like it never really writes it to disk. (Evidenced by the fact that #recentf# is always left over in ~/.emacs.d except when the 5-minute #'recentf-save-list timer gets run.)

This is bad, because Emacs has support for preventing simultaneous edits, and when I change networks my hostname changes. Emacs then blocks my workflow and asks me if I want to steal the lock from myself. This is highly frustrating.

So, should we: (a) disable interlocking support entirely, via setting create-lockfiles to nil globally, or (b) do something more intelligent? I'm going to leave this to @cg505 because I have never used recentf before.

Versioning

We should start thinking about versioning this using SemVer. The two questions I can think of are:

  • Do we want to version this project? Or should this be rolling-release?
    • If so, what will be our indication that we are ready to release version 1?

This might affect our update-checking strategy for #56; users could also use a variable to decide whether they only want to use the latest release or the Git HEAD. (master in our case)

If we decide that we already passed a point where the project could be considered at v0.x.y, we can go back and make releases now for those points in history, and I can do that.

kotct/user-update-config: Always ask for a username

I'm thinking M-x kotct/user-update-config should behave a lot like C-x C-z in that it should ask the user for a username to fetch rather than just doing the current one. I could be wrong about this one, however.

Transition from linum to built-in line numbers

See the help for variable display-line-numbers in emacs 26.

At this point we should maintain compatibility with emacs 25, but if we can use the builtin line numbers, we should, since they are faster and better.

ace-jump split between files?

There's ace-jump stuff in both behavior/text.el and behavior/ace-jump.el. We need to consolidate. Personally, I think we should go for text.el.

Packup UI update

Making the packup buffer interactive to allow for the user to more easily select a subset of the packages that they wish to update.

It would also help us prepare for the work necessary to complete #56. This can be considered party of that issue.

Acceptance Criteria:

  • Must allow for user to select packages to update w/i a read only buffer
  • Must provide help instructing users how to interact w/ the read only buffer

key combo for dired

By default dired is unbound to a keycombo in emacs. I think we should bind it to C-x C-d because list list-directory is just a less useful version of dired. Any opposition?

kotct/load-corresponding fails when file requires something

I think the ability to write easy tests is important.

lisp/code/languages/sh.el requires indentation, because it uses some features from lisp/code/indentation.el. However, when the tests were run in a sterile environment, (i.e. presumably with a bad load-path) there were problems.

So kotct/load-corresponding calls kotct/quietly-load-file and loads the file directly. It's just a matter of features being unable to be loaded. Can we set load-path somehow so that it covers all possible things that our tests can require?

Make README less verbose

The README file is a little bit verbose. Ideally, it should just include some basic stuff. Principles could be extracted to the Wiki or to another .md file.

Open to feedback and ideas.

User Configurations/Hubs

Let's think about user configurations—they were a key feature of kotct.emacs because they enabled people to quickly switch configurations.

We should think about how we're gonna do this here. @cg505, got any ideas?

I think I'm against having all of this stuck here in this repository, though. I think having local hubs in a local emacs directory is a good plan—they could be git submodules of a shared but separate git repository which could get updated by an emacs command, for instance.

packup does not respect `package-archive-priorities`

This needs more investigation, but it seems like our current approach in packup for checking/installing updates disregards package-archive-priorities (set in lisp/package/repositories.el). Namely, I see many packages on my system are installed from MELPA despite also being available in MELPA Stable (which has a higher priority).

This may be best wrapped into #84 (which would be lovely to finally get finished up when someone has a change).

Newlines at EOF

Emacs currently seems configured to add newlines at EOF sometimes, but not to all files. I think we should make it add newlines to all (text) files, since all text files will get griped-about by Git/VC if they don't have newlines at the end.

That's also a pretty standard thing, too.

Acceptance Criteria:

  • Files are saved with a newline at EOF by default

Make font setting functions more fault-tolerant

As it stands, the font setting functions are not fault-tolerant at all. If a font does not exist on the system, there is simply no error except the one raised by Emacs itself, which then halts the init process. For instance, the default font in my configuration is Fira Code, but this font is not installed on some machines that I work on, and I have to make local changes to my configuration to prevent a failure in loading.

I intend to work on this one—it will involve defining a pre-defined font hierarchy alist—as users add fonts, they can prepend to this list cons cells of the form ("Font Family Name" . default-size). We can also write defuns for interacting with this list.

fish configuration

This project intends to be a wide-ranging set of dotfiles. Currently it only contains emacs (although that's doing a pretty good job). As my primary shell, I use fish and hope to move the base of my configuration into this repo. Fish configuration doesn't really work in the same way emacs does in that you can configure it from the CLI instead of from mostly static config files (think set -U). I also use fisherman which work by creating symlinks into your config directory instead of creating a separate system that is loaded by your config (like in emacs with the elpa directory). These all pose challenges to a dot-style fish config that I am not sure how to solve. I don't even know if anyone else using this project also uses fish.

Better Labels

Our labels are somewhat unspecific and sad. If we can break things up into more component-wise labels and have priority labels, and use a labelling scheme like Hyper's, I think it'd be much easier to label issues.

Below are listed the different labelling groups and label names which I have created.

Concerns

The Concerns set of labels is used for demarcating the scope of the Issue or Pull Request to which they are assigned.

  • Concerns: Dot
    • For Issues concerning the project as a whole
  • Concerns: Emacs Configuration
    • For Issues concerning the Emacs Configuration as a whole (but not the entire project, Dot.)
  • Concerns: Emacs/tree/behavior
    • For Issues concerning stuff in the behavior tree of the Emacs configuration
  • Concerns: Emacs/tree/code
    • For Issues concerning stuff in the code tree of the Emacs configuration
  • Concerns: Emacs/tree/file
    • For Issues concerning stuff in the file tree of the Emacs configuration
  • Concerns: Emacs/tree/package
    • For Issues concerning stuff in the package tree of the Emacs configuration
  • Concerns: Emacs/tree/user
    • For Issues concerning stuff in the user tree of the Emacs configuration
  • Concerns: Emacs/tree/visual
    • For Issues concerning stuff in the visual tree of the Emacs configuration

Is

The Is set of labels is used to describe the status or quality of the Issue or Pull Request to which they are assigned.

  • Is: Blocked
    • For Issues or Pull Requests that cannot be continued until another Issue or Pull Request is resolved
  • Is: Deferred
    • For Issues or Pull Requests that are side-lined until further notice (see: Is: On Hold for another option)
  • Is: Duplicate
    • For Issues or Pull Requests whose scope and concerns match an extant Issue or Pull Request that has not yet been resolved
  • Is: Invalid
    • For Issues or Pull Requests that are poorly-written or otherwise deemed invalid
  • Is: Not Fixable
    • For Issues which cannot be fixed
  • Is: On Hold
    • For Issues or Pull Requests that are side-lined but may be resumed soon (see: Is: Deferred for another option)
  • Is: Question
    • For Issues that are formulated as questions and are not direct requests
      • A Question label might be used for something hypothetical, but a separate issue should be opened once a decision is reached to specifically track the progress towards resolving the decision.
    • Note: This is not a label of the Type set because that set is specifically designated for

Needs

The Needs set of labels is used to describe is used to describe those Issues or Pull Requests which need further action in order to proceed.

  • Needs: Discussion
    • For Issues or Pull Requests that need discussion in order to proceed
  • Needs: Implementation
    • For Issues or Pull Requests that need (further) implementation to take place in order to proceed
  • Needs: Investigation
    • For Issues or Pull Requests that need (further) investigation to take place in order to proceed
  • Needs: Refactoring
    • For Issues or Pull Requests that need (further) refactoring to take place in order to proceed
  • Needs: Research
    • For Issues or Pull Requests that need (further) research to take place in order to proceed

Priority

The Priority set of labels is used to describe the approximate priority of the Issue or Pull Request to which they are assigned.

  • Priority: Critical
    • For Issues or Pull Requests considered to be at extremely high priority
      • e.g. Issues or Pull Requests where direct action is required to solve problems
  • Priority: High
    • For Issues or Pull Requests considered to be at high priority
      • e.g. Issues or Pull Requests where direct action is strongly preferred over other Issues or Pull Requests
  • Priority: Medium
    • For Issues or Pull Requests considered to be at medium priority
      • e.g. Issues or Pull Requests where direct action is weakly preferred over other Issues or Pull Requests
  • Priority: Low
    • For Issues or Pull Requests considered to be at low priority
      • e.g. Issues or Pull Requests where direct action is not preferred over other Issues or Pull Requests

Type

The Type set of labels is used to describe the type of thing that is concerned by the Issue or Pull Request to which they are assigned.

  • Type: Bad Code Style
    • For Issues concerning bad code style
  • Type: Bad Feature
    • For Issues concerning bad features (see: Type: Bug for another option)
      • e.g. Issues or Pull Requests where existing code improperly uses the system
  • Type: Bad Implementation
    • For Issues concerning bad implementation of a feature
  • Type: Bad Performance
    • For Issues concerning bad performance
  • Type: Bug
    • For Issues concerning bugs (see: Type: Bad Feature for another option)
      • e.g. Issues or Pull Requests where the system influences bad behavior in the codebase

Ungrouped

These labels are specifically ungrouped so that they can be searchable by API bots.

  • Help Wanted
    • Anything where outside help is wanted

kotct/switch-to-theme does not allow for customizations to fonts prior to load

If a theme has already been loaded, kotct/switch-to-theme just disables the current theme and enables the new one.

This is problematic, because then kotct/switch-to-theme will always just re-enable the current theme. If, for instance, someone wants to customize solarized, (like turning off the variable-pitch in headings, as I prefer) they have no way of doing this. This could be rectified by adding an optional argument to kotct/switch-to-theme that always loads the theme.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.