Code Monkey home page Code Monkey logo

inch_ex's Introduction

Inch for Elixir Inline docs

Inch for Elixir provides a Mix task to give you hints where to improve your inline docs. One Inch at a time.

Inch CI is the corresponding web service that provides continuous coverage analysis for open source projects.

What can it do?

Inch for Elixir is a utility that suggests places in your codebase where documentation can be improved.

If there are no inline-docs yet, Inch for Elixir can tell you where to start.

Installation

Add Inch for Elixir as a dependency in your mix.exs file.

defp deps do
  [
    {:inch_ex, github: "rrrene/inch_ex", only: [:dev, :test]}
  ]
end

After you are done, run this in your shell to fetch the new dependency:

$ mix deps.get

Usage

To run Inch, simply type

$ mix inch

and you will get something like the following:

$ mix inch

# Properly documented, could be improved:

┃  B  ↑  Foo.complicated/5

# Undocumented:

┃  U  ↑  Foo
┃  U  ↗  Foo.filename/1

Grade distribution (undocumented, C, B, A):  █  ▁ ▄ ▄

Philosophy

Inch was created to help people document their code, therefore it may be more important to look at what it does not do than at what it does.

  • It does not aim for "fully documented" or "100% documentation coverage".
  • It does not tell you to document all your code (neither does it tell you not to).
  • It does not impose rules on how your documentation should look like.
  • It does not require that, e.g."every method's documentation should be a single line under 80 characters not ending in a period" or that "every class and module should provide a code example of their usage".

Inch takes a more relaxed approach towards documentation measurement and tries to show you places where your codebase could use more documentation.

The Grade System

Inch assigns grades to each module, function, macro or callback in a codebase, based on how complete the docs are.

The grades are:

  • A - Seems really good
  • B - Properly documented, but could be improved
  • C - Needs work
  • U - Undocumented

Using this system has some advantages compared to plain coverage scores:

  • You can get an A even if you "only" get 90 out of 100 possible points.
  • Getting a B is basically good enough.
  • Undocumented objects are assigned a special grade, instead of scoring 0%.

The last point might be the most important one: If objects are undocumented, there is nothing to evaluate. Therefore you can not simply give them a bad rating, because they might be left undocumented intentionally.

Priorities ↑ ↓

Every class, module, constant and method in a codebase is assigned a priority which reflects how important Inch thinks it is to be documented.

This process follows some reasonable rules, like

  • it is more important to document public methods than private ones
  • it is more important to document methods with many parameters than methods without parameters
  • it is not important to document objects marked as @doc false

Priorities are displayed as arrows. Arrows pointing north mark high priority objects, arrows pointing south mark low priority objects.

No overall scores or grades

Inch does not give you a grade for your whole codebase.

"Why?" you might ask. Look at the example below:

Grade distribution (undocumented, C, B, A):  ▄  ▁ ▄ █

In this example there is a part of code that is still undocumented, but the vast majority of code is rated A or B.

This tells you three things:

  • There is a significant amount of documentation present.
  • The present documentation seems good.
  • There are still undocumented methods.

Inch does not really tell you what to do from here. It suggests objects and files that could be improved to get a better rating, but that is all. This way, it is perfectly reasonable to leave parts of your codebase undocumented.

Instead of reporting

coverage: 67.1%  46 ouf of 140 checks failed

and leaving you with a bad feeling, Inch tells you there are still undocumented objects without judging.

This provides a lot more insight than an overall grade could, because an overall grade for the above example would either be an A (if the evaluation ignores undocumented objects) or a weak C (if the evaluation includes them).

The grade distribution does a much better job of painting the bigger picture.

Further information

I will point you to the Inch for Ruby README for more information about the Inch project.

Contributing

  1. Fork it!
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Author

René Föhring (@rrrene)

Credits

The first version of Inch for Elixir owed its existence to the extensive study and "code borrowing" from ExDoc.

License

Inch for Elixir is released under the MIT License. See the LICENSE file for further details.

inch_ex's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inch_ex's Issues

Trying to add inch CI to project, got cryptic reference to the movie "war games" instead.

Tried running the mix inchci.add command and got this:

ebay-elixir git:(master) ✗ MIX_ENV=docs mix inchci.add

                         Adding project to Inch CI ...                          

Compiling 1 file (.ex)
Generated ebay app
warning: Mix.Utils.camelize/1 is deprecated, use Macro.camelize/1 instead
  (mix) lib/mix/utils.ex:250: Mix.Utils.camelize/1
  lib/mix/tasks/inch.ex:35: Mix.Tasks.Inch.run/4
  lib/mix/tasks/inchci_add.ex:28: Mix.Tasks.Inchci.Add.add_to_inch_ci/0
  (mix) lib/mix/task.ex:294: Mix.Task.run_task/3
  (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2

> Greetings, Professor Falken.

> _

** (MatchError) no match of right hand side value: nil
    lib/inch_ex/setup/readme_badge.ex:26: InchEx.Setup.ReadmeBadge.extract_url/1
    lib/inch_ex/setup/readme_badge.ex:11: InchEx.Setup.ReadmeBadge.run/1
    lib/inch_ex/setup.ex:11: InchEx.Setup.run/1
    (mix) lib/mix/task.ex:294: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2

Pulled out wireshark and figured out that's what you see with you visit https://inch-ci.org/api/v1/builds

Followed the TCP stream and got the full request/response since the client makes the request over HTTP instead of HTTPS.

Request:

POST /api/v1/builds HTTP/1.1
content-type: application/json
content-length: 1412
te: 
host: inch-ci.org
connection: keep-alive

{"shell":true,"revision":"58818d84b63e8581aadf908d02a8c41f52233fff","objects":[{"type":null,"source":"lib/ebay.ex:2","object_type":"ModuleObject","moduledoc":...

Response:

HTTP/1.1 301 Moved Permanently
Date: Tue, 31 Jan 2017 04:11:35 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d2e733ac5536c3c2db10b8349b065c1a51485835895; expires=Wed, 31-Jan-18 04:11:35 GMT; path=/; domain=.inch-ci.org; HttpOnly
Location: https://inch-ci.org/api/v1/builds
Server: cloudflare-nginx
CF-RAY: 329a520881480d19-ATL

b8
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.2.1</center>
</body>
</html>

0

Come to find out, I believe the core of the issue is that these requests are being made over HTTP instead of HTTPS, and the package is not handling the 3xx response.

Soooo... I'm going to file a PR with what I think are the corrections, but I'm not sure of the implications of the changes, because I don't know if there is a good reason for them to be just plain HTTP.

Not detecting @doc for defmacro

I can see in ex_docs the generation of the documentation and it's working perfectly but for inch_ex it's not:

# Exampple.Router.iq/2                                                                                            
┃ lib/exampple/router.ex:274
┃ ----------------------------------------------------------------------------------------------------------------
┃ ----------------------------------------------------------------------------------------------------------------
┃ Score (min: 0, max: 100)                                  0     0

This is not getting anything. The code is this:

  @doc """
  Specify a route block where we can add the different routes. This could
  have the base namespace or not. This is based on the `iq` stanza type.
  """
  defmacro iq(xmlns_partial \\ "", do: block) do

Maybe it's broken because of the do: block?

Wrong branch name on Travis

on merge_metadata/1, branch_name is Git.branch_name() which is always HEAD on Travis since it checks out specific commit hash (resulting in detached HEAD branch)

Add code occurrences of a function to its priority

@rrrene we discussed this in person at Code Beam Light last week. I'm transcribing my thoughts here.

It's a hard question which functions are more important to document, and I think that functions that are "used" a lot are more important to document. It's not obvious how measure "usage" of functions. The number of calls in a test suite (or in production) is hard (or impossible) to calculate/estimate without simply running the test suite.

My opinion here is that the number of calls to a function is not that important as a measure for documentation priority because it depends so much on the way the code is called. Instead, I think the number of occurrences in the code is the relevant measure. Why? I'm assuming that typically, a programmer will read through existing code and every now and then encounter a function that they don't know, and need to look up. If it's defined in another module in the same project, it should better have some inline documentation. The frequency of this situation is probably proportional to the number of occurrences of said function in the whole project.

Extreme case: A util function that is called from most other modules should have a concise and good documentation. A private function in one module that is only called once by another function is not so important to document.

Local Inch set-up....

The documentation is quite vague when it comes to this. INCH_PATH to inch... It does not mention where to get the executable from though.
Not everyone would like to connect to an external service to obtain a report - let's consider it as a privacy issue ;)

Module Error is not available

Hi,

I wanted to use this tool. However, I get following error:

$ MIX_ENV=docs mix inch.report
** (UndefinedFunctionError) undefined function: Error.exception/1 (module Error is not available)
    Error.exception([message: "module IElixir.HMAC was not compiled with flag --docs"])
    lib/inch_ex/docs/retriever.ex:83: InchEx.Docs.Retriever.verify_module/1
    lib/inch_ex/docs/retriever.ex:70: InchEx.Docs.Retriever.get_module/2
    (elixir) lib/enum.ex:1043: anonymous fn/3 in Enum.map/2
    (elixir) lib/enum.ex:1385: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir) lib/enum.ex:1043: Enum.map/2
    lib/inch_ex/docs/retriever.ex:49: InchEx.Docs.Retriever.docs_from_modules/2
    lib/inch_ex.ex:39: InchEx.generate_docs/4
23:58:38.860 [error] Error in process <0.47.0> with exit value: {#{'__exception__'=>true,'__struct__'=>'Elixir.UndefinedFunctionError',arity=>1,function=>exception,module=>'Elixir.Error',reason=>nil},[{'Elixir.Error',exception,[[{message,<<53 bytes>>}]],[]},{'Elixir.InchEx.Docs.Retriever',verify_module... 
Done. Your build exited with 0.

My first idea was about old OTP version. I tried many different OTPs and problem still occurs. Here's sample build: https://travis-ci.org/pprzetacznik/IElixir/builds/75265410

I test it on feature/inch-ci branch: https://github.com/pprzetacznik/IElixir/tree/feature/inch-ci

Would you mind to take a look at this error and tell me where I should look for the answer?

inch is mistaken about some `@typedoc` instances

In my project code base (https://github.com/RichMorin/PA_all; e4df341), I put all of the @type statements into separate files (e.g., types.ex) and invoke them by means of alias statements (e.g., alias Common.Types, as: CT) and explicit references (e.g., CT.schema).

Inch seems to be unable to detect some @typedoc statements in my types.ex files. So, it reports problems even when they do not exist. Here is an example:

[U] → Common.Types.schema/0 (lib/types.ex:59)

@typedoc """
A schema is like an `item_map`, except that it allows strings
as top-level values.
"""

@type schema      :: %{ atom => item_part | String.t }

Impossible to make inch_ex working

When running mix inchci.add command, it fails:
This feature is not supported in Inch 2.0 (yet).
When running mix inch.report it seems succeed by giving me the proper inch-ci URL but doesn't have any impact in fact.

My repository : scorsi/umbra.

Thanks !

inchci.add doesn't work with multiple push URL

inchci.add doesn't work with multiple push URL when GitHub isn't the first URL. Initially, I set my local repo to have origin URL to non GitHub. an then I add GitHub as the second URL to origin with this command

git remote set-url --add origin [email protected]:<username>/<repo>.git

When I execute inchci.add, I get @not_github_error error message even though the repo exist on GitHub.

Make git branches for inch.report configurable

Would love to use something like CIRCLE_BRANCH to identify the branch you're wanting to report for. I don't really want reporting on every branch that's pushed to GitHub, especially prior to them becoming a pull request. I just want, say, develop (my default branch) to be the single source of truth for my documentation status.

If I could configure the branches in my settings and additionally have the default branch on GitHub be the only branch that reports (unless I say otherwise), that would really cut down on a lot of the extraneous reporting that needs to happen on Inch itself, cut down slightly on my build times, would be good for the environment, etc etc.

What do you think?

Marking child_spec from GenServer

In my project: github.com/altenwald/exampple ; I'm getting this output:

# Proper documentation present                                                                                    
┃
┃ [B] → Exampple.Client.child_spec/1 (lib/exampple/client.ex:44)
┃ [B] → Exampple.DummyTcp.child_spec/1 (lib/exampple/dummy_tcp.ex:3)
┃ [B] → Exampple.Component.child_spec/1 (lib/exampple/component.ex:16)

The problem is those lines are:

use GenServer

or:

use GenStateMachine

It's not a bad grade, but I guess it shouldn't be an error because it's not part of my code so, out of scope for me. How could I ignore them?

issue with README

When running mix inch, if you follow the prior descriptions, you must run MIX_ENV=docs mix inch

inch.report exits with `InchEx skipped.`

I'm trying to run Inch's reporting feature on Circle. In my circle.yml:

test:
  post:
    - mix inch.report

I just get InchEx skipped. when doing so. Not sure what else I should be doing here.

check for doctest presence?

It's quite possible to insert doctests in the code base, but neglect to set up the corresponding doctest commands in the test files. Might there be a way to check for this?

Unable to exclude methods brought in by dependencies

Hi there! 👋🏼

First of all, thanks so much for building this tool. I've used it on plain elixir projects and it's been great. However, I'm running it on a new project with a phoenix app and there are a lot of methods that I can't or don't want to document. I know that methods can be excluded with @doc false, but it seems like inch is reporting on methods I don't have access to.

For example, there are quite a few methods in the Gettext module which are undocumented. As far as I can tell, these are brought in via use Gettext, but I'm not sure how to exclude them from the report.

Any tips would be appreciated. Thanks!

# Undocumented:
�  U  �  PhoenixDemoWeb.Gettext.dngettext/5
�  U  �  PhoenixDemoWeb.Gettext.lngettext/6
�  U  �  PhoenixDemoWeb.Gettext.ngettext/4
�  U  �  PhoenixDemoWeb.Endpoint
�  U  �  PhoenixDemoWeb.Gettext.handle_missing_bindings/2
�  U  �  PhoenixDemoWeb.Application.config_change/3
�  U  �  PhoenixDemoWeb.Endpoint.broadcast_from!/4
�  U  �  PhoenixDemoWeb.Router.Helpers.page_path/3
�  U  �  PhoenixDemoWeb.Router.Helpers.page_path/2
�  U  �  PhoenixDemoWeb.Router.Helpers.page_url/2
�  U  �  PhoenixDemoWeb.Gettext.gettext_comment/1
�  U  �  PhoenixDemoWeb.Endpoint.broadcast_from/4
�  U  �  PhoenixDemoWeb.Router.Helpers.page_url/3
�  U  �  PhoenixDemoWeb.Gettext.dngettext_noop/3
�  U  �  PhoenixDemoWeb.Gettext.dgettext_noop/2
defmodule PhoenixDemoWeb.Gettext do
  @moduledoc """
  ...

  See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage.
  """
  use Gettext, otp_app: :phoenix_demo_web
end

inch.report not found

Hi,

I am trying to use your inch_ex and inch-ci.org service, but with no luck so far. Let's see what could be wrong:

In travis:

$ MIX_ENV=docs mix deps.get
Resolving Hex dependencies...
Dependency resolution completed:
  bunt 0.2.0
  certifi 0.4.0
  credo 0.8.8
  earmark 1.2.3
  ex_doc 0.18.1
  excoveralls 0.5.5
  exjsx 3.2.0
  hackney 1.6.1
  idna 1.2.0
  inch_ex 0.5.6
  jsx 2.6.2
  metrics 1.0.1
  mimerl 1.0.2
  poison 3.1.0
  ssl_verify_fun 1.1.0
All dependencies up to date
after_script.2
$ MIX_ENV=docs mix inch.report
Compiling 12 files (.ex)
Generated ex_image_info app
** (Mix) The task "inch.report" could not be found

Links to the travis build, the repo github and the inch-ci.

Thanks.

module XXX was not compiled with flag --docs

I get the message from the subject when running mix inch.

$ elixir --version
Erlang/OTP 21 [erts-10.0.8] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Elixir 1.7.3 (compiled with Erlang/OTP 21)
$ cat mix.lock | grep inch
  "inch_ex": {:hex, :inch_ex, "1.0.0", "18496a900ca4b7542a1ff1159e7f8be6c2012b74ca55ac70de5e805f14cdf939", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},

Publish a version compatible with Elixir 1.7 to Hex

Unfortunately, InchEx 1.x does not support Elixir version above 1.6.x, since the documentation format has changed with Elixir 1.7.0.

If you want to try Inch with Elixir >= v1.7.0, just set the Inch dep to

    {:inch_ex, github: "rrrene/inch_ex"}

Rather than forcing me to use the Github version, I would really like to see a Hex version to be published because I can't publish my packages to Hex.

Macros do not seem to be documented.

If you look at hahuang65/beaker, the macros defined there are not showing up in InchCI.

The macros are:

Beaker.Gauge.time/2
Beaker.TimeSeries.time/2

Detailed suggestions?

When I do run a mix inch.report and then open an item on the projects inch-ci page, I do get a detailed description of what I can exactly improve.

When I am using the local mix inch it seems as if "please improve Mod.fun/1" is as best as I can get.

Pushing every single commit and then re-reporting/waiting for travis is not really a nice option. So is there any way to get some report that is detailed as the one from inch-ci-page?

Tests failing on elixir 1.11 and 1.12 ?

While attempting to get rid of warnings in when building inch_ex
I noticed tests failing (with elixir 1.11 and 1.12) :

  1) test json read (InchExTest)
     test/inch_ex_test.exs:10
     ** (FunctionClauseError) no function clause matching in InchEx.CodeObject.children/2
2) test eval() works as expected /1 (InchEx.CodeObjectTest)
     test/inch_ex/code_object_test.exs:4
     ** (ArgumentError) argument error
     code: result = [input] |> InchEx.CodeObject.eval() |> List.first()
  3) test eval() works as expected /2 (InchEx.CodeObjectTest)
     test/inch_ex/code_object_test.exs:40
     ** (FunctionClauseError) no function clause matching in InchEx.CodeObject.children/2

I wondered if someone knew why / had any hints on how to fix them ?
I had a quick look, but I cant figure it out what the code should be doing just yet...

Mark files without docs chunk as undocumented

It seems v2 of inch is currently failing for files it cannot retrieve a documentation chunk. I've a erlang file in my project and rebar does afaik not support creating the docs chunk by now. I'm all for putting out a warning, but failing basically prevents me from using inch for all the other elixir files I have.

Inch cannot invoke numeric function names

I originally raised this in phoenixframework/phoenix#5331 as I thought it was a bug in Phoenix.

If function names are numeric (e.g. ErrorHTML.404/1) then inch fails:

(EXIT from #PID<0.94.0>) an exception was raised:
    ** (SyntaxError) nofile:1:4: syntax error before: '('
    |
  1 | 404(assigns)
    |    ^
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object/roles.ex:118: anonymous fn/1 in InchEx.CodeObject.Roles.fun_params/1
        (elixir 1.14.2) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object/roles.ex:117: InchEx.CodeObject.Roles.fun_params/1
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object/roles.ex:72: InchEx.CodeObject.Roles.parameters/1
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object/roles.ex:32: InchEx.CodeObject.Roles.run/1
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object.ex:53: InchEx.CodeObject.evaluate/1
        (inch_ex 2.1.0-rc.1) lib/inch_ex/code_object.ex:37: InchEx.CodeObject.transform/1

If anyone else encounters this, the issue in the Phoenix repo has a workaround.

Missing histogram characters in output

Trying out InchEx for an umbrella app. I am expecting to see histogram characters output in the "Grade distribution" section, but instead I'm seeing this:

screen shot 2017-02-23 at 10 42 37 am

I couldn't find any information relating to this in the readme. I tried changing terminal fonts, but that didn't seem to help. Any ideas?

Does not work with Circle CI

The $TRAVIS_PULL_REQUEST env variable is hardcoded into the valid? method, so if you're building on a CI other than Travis the docs will never get pushed. Maybe we could check if the env variable exists and is false instead of just checking for the false value?

How do I get rid off 'Describe the parameter "map".' ?

Not sure what inch_ex wants me to do, I tried a couple of things and was not available to get rid off that warning/suggestion. A help with how to fix suggestions per language would be very helpful.

project: http://inch-ci.org/github/PragTob/benchee

inch_ci report:


Benchee.Statistics.statistics/1
Parsed documentation:
View on GitHub

Takes a job suite with job run times, returns a map representing the
statistics of the job suite as follows:

  * average       - average run time of the job in μs (the lower the better)
  * ips           - iterations per second, how often can the given function be
    executed within one second (the higher the better)
  * std_dev       - standard deviation, a measurement how much results vary
    (the higher the more the results vary)
  * std_dev_ratio - standard deviation expressed as how much it is relative to
    the average
  * std_dev_ips   - the absolute standard deviation of iterations per second
    (= ips * std_dev_ratio)
  * median        - when all measured times are sorted, this is the middle
    value (or average of the two middle values when the number of times is
    even). More stable than the average and somewhat more likely to be a
    typical you see.

## Parameters

* `suite` - the job suite represented as a map after running the measurements,
  required to have the run_times available under the `run_times` key

## Examples

    iex> run_times = [200, 400, 400, 400, 500, 500, 700, 900]
    iex> suite = %{run_times: [{"My Job", run_times}]}
    iex> Benchee.Statistics.statistics(suite)
    [{"My Job",
      %{average:       500.0,
        ips:           2000.0,
        std_dev:       200.0,
        std_dev_ratio: 0.4,
        std_dev_ips:   800.0,
        median:        450.0}}]

Suggestions:

    Describe the parameter "map".

method:

  def statistics(%{run_times: run_times}) do
    Enum.map run_times, fn({name, job_run_times}) ->
      {name, Statistics.job_statistics(job_run_times)}
    end
  end

Thanks + cheers,
Tobi

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.