Giter Club home page Giter Club logo

reason's People

Contributors

anmonteiro avatar barkmadley avatar bsansouci avatar chenglou avatar cristianoc avatar davesnx avatar dwwoelfel avatar dxu avatar eduardorfs avatar freebroccolo avatar iwankaramazow avatar jaredly avatar jordwalke avatar kassens avatar kayceesrk avatar let-def avatar manasjayanth avatar ncihnegn avatar ohadrau avatar pvolok avatar rgrinberg avatar rickyvetter avatar ryyppy avatar sanderspies avatar sansthesis avatar tekknolagi avatar ulrikstrid avatar vramana avatar yunxing avatar zploskey avatar

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  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

reason's Issues

Parsing issue with nested patterns

The following ml

type bcd = B | C | D
type a = A of bcd

let nested_match = function | A (B | C | D) -> 3

gets formatted as

type bcd = | B | C | D;

type a = | A of bcd;

let nested_match = fun | A (| | B | C | D) => 3;

and also removing the double bar, it does not parse. Looks like a parse/print combo of issues.

[ExplicitArity] [pprinter] Generated OCaml is not compilable

In Reason, if we have a constructor that takes a single tuple as parameter

type t = | C of (int, int);

let a = C (1, 1);

The generated code will look like:


type t =
  | C of (int* int)
let a = ((C ((1, 1)))[@explicit_arity ])

, which generates compiler errors:

Error: The constructor C expects 1 argument(s),
       but is applied here to 2 argument(s)

One possible solution could be removing @explicit_arity when the length of the argument list is 1.

Fix Merlin Locate pull request

You can see in the issue here, my pull request didn't test correctly.

I know I tested this case, so I'm not sure what happened (maybe another pull request that was accepted disrupted something). We have to resubmit after fixing the issue they observed.

ocaml/merlin#474 (comment)

Recovering Parser.

Frederic (main author of Merlin) and I agreed on a protocol for Merlin to alloc custom syntaxes. This is really great! He has pushed his works in progress to this branch:

https://github.com/the-lambda-church/merlin/commits/experimental-refactor

Not only will this give us a ton of additional features (like incremental type checking on invalid parses - like a real IDE), but it will also cut out a ton of the work we have to do in each editor. To get Reason to where it is right now, it involved a bunch of throwaway code in VimScript,EmacsLisp, and JavaScript. Getting first class support in merlin makes a lot of that go away.

This is very early, but it's enough to begin the work to integrate Reason. The primary challenge is making the Reason parser "recover" from errors. I suspect this will be relatively simple because Reason is a very "typical" syntax in that there's clear places to recover from (semicolons etc).

For this github issue, it will involve

  1. Learning how to make recoverable parsers in yacc.
  2. Make the Reason AST recover. Simply delete problematic ranges of the text until the parse is valid, with the goal of deleting the fewest/smallest possible ranges - really anything is better than what we do right now which is to essentially "delete the entire AST" (fail on first parse error).
  3. Replace those regions with something in the AST - either an "extension attribute", or a dummy unit expression. To make this work with merlin, we'll need to replace that region of the AST with something specific as required by merlin.

This will be much easier to land after tomorrow(ish) because I'm going to be sending out a huge diff/refactoring of the parser to support ppx extensions and objects.

Ppx extensions help us insert placeholders for invalid parses in the recovered AST.
Recovered AST helps us integrate with merlin.
Merlin helps us get much better emacs/vim/atom support with minimum effort.

Support Coerce :>

I was going through this large refactor and making a note of the things that still not be supported. The only one remaining will be coercion - which is really easy. Just making a note of it to keep track.

Unary minus requires space

The following

let r = ref 3;
let b = - !r;

gets formatted as

let r = ref 3;
let b = -!r;

which does not parse.

Issue when undescore matches constructor arguments.

This ml program

type t = A of int * int
let f = function | A _ -> 34

is converted to Reason

type t = | A of int int;

let f =
  fun | A _ => 34;

which does not type check:

Error: The constructor A expects 2 argument(s),
       but is applied here to 1 argument(s)

parser for construtor_declaration is incorrect

Formatting this:

type term _ = | Int of /*var arg */ int;

Gives us

type term _ = | Int of /*var arg */ int;

, which is good.

However, formatting this (without a space before int):

type term _ = | Int of /*var arg */int;

gives us :

type term _ = | Int of int;

/*var arg */

Ambiguity in ML -> Reason conversion

Assuming you have a ML program that looks like this:

match a with
  | C (c, d) -> 1
;;

What information about arguments do you get from constructor C? Is it a constructor that takes a tuple? or is it a constructor that takes two arguments? The compiler has to use heuristics to figure it out but we don't have that information at the parsing time.

So here is the solution we are thinking about using:

When translate from ML to Reason, we can provide an ambiguous syntax thats support both cases. The reason ambiguous syntax will be compilable. The user later on has to decide which case he intends to use and gradually migrate from the ambiguous syntax to a specific Reason syntax.

As an example, when an user first convert the above code from ML to Reason. It will be something like this:

  switch a {
    | C (TODO_REMOVE_AMBIGUITY__ f x __TODO_REMOVE_AMBIGUITY) -> 1
  }

The above syntax will be valid and he can start compiling it, the pretty printer is idempotent for this code segment.

Later on he has to decide which interpretation to convert to, it is either:

  switch a {
    | C (f, x) -> 1
  }

Or

switch a {
    | C f x -> 1
}

I will send out a diff about this soon.

Reason project helper

This area has a lot of unknowns. Just writing down some of the goals that we would like to achieve and potential solutions.

We want to have a reason project helper tool which:

Issue with polymorphic variant taking one pair.

The following ml declaration

let match_tickx = function
  | `X (3, 4) -> ()

Gets translated to reason as

let match_tickx =
  fun | `X 3 4 => ();

which does not parse.

The same program with a non-polymorphic variant is formatted as

let match_x =
  fun | X 3 4 => ();

And parses.

Formatting If/else chains wraps test conditions with too high of a priority.

See the following example. The test conditions should be breakable, but with a lower priority than they currently are.

  let get jsonObj key => {
    let fieldVal = Js.Unsafe.get jsonObj "key";
    if (Js.Unsafe.fun_call _arrayIsArray [|fieldVal|]) {
      JsonArray (Js.to_array fieldVal)
    } else if (
      Js.Unsafe.fun_call _isString [|Js.Unsafe.inject fieldVal|]
    ) {
      JsonString (Js.to_string fieldVal)
    } else if (
      Js.Unsafe.fun_call _isBool [|Js.Unsafe.inject fieldVal|]
    ) {
      JsonBool (Js.to_bool fieldVal)
    } else if (
      Js.Unsafe.fun_call _isNumber [|Js.Unsafe.inject fieldVal|]
    ) {
      JsonNum (Js.to_float fieldVal)
    } else if (
      Js.Unsafe.fun_call _isNull [|Js.Unsafe.inject fieldVal|]
    ) {
      JsonNull
    } else {
      Empty
    };

The function should be wrapped as:

  let get jsonObj key => {
    let fieldVal = Js.Unsafe.get jsonObj "key";
    if (Js.Unsafe.fun_call _arrayIsArray [|fieldVal|]) {
      JsonArray (Js.to_array fieldVal)
    } else if (Js.Unsafe.fun_call _isString [|Js.Unsafe.inject fieldVal|]) {
      JsonString (Js.to_string fieldVal)
    } else if (Js.Unsafe.fun_call _isBool [|Js.Unsafe.inject fieldVal|]) {
      JsonBool (Js.to_bool fieldVal)
    } else if (Js.Unsafe.fun_call _isNumber [|Js.Unsafe.inject fieldVal|]) {
      JsonNum (Js.to_float fieldVal)
    } else if (Js.Unsafe.fun_call _isNull [|Js.Unsafe.inject fieldVal|]) {
      JsonNull
    } else {
      Empty
    }
  };

Update docs.zip

  • Create doc branch
  • Remove docs.zip in master
  • Fix github link
  • Copy paste error in mlCompared.html#Various_Improvements session
  • Remove trailing semicolons in block syntax

Cannot find module 'number-is-nan'

  1. Launch Atom
  2. Immediate error box

Atom Version: 1.2.4
System: Mac OS X 10.11.1
Thrown From: ide-reason package, v1.0.0

Stack Trace

Failed to activate the ide-reason package

At Cannot find module 'number-is-nan'

Error: Cannot find module 'number-is-nan'
  at Module._resolveFilename (module.js:336:15)
  at Function.Module._resolveFilename (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/module-cache.js:383:52)
  at Function.Module._load (module.js:286:25)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/node_modules/repeating/node_modules/is-finite/index.js:2:19)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/node_modules/repeating/index.js:2:16)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/traversal/scope/index.js:24:18)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/traversal/path/index.js:28:14)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/traversal/context.js:16:13)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/traversal/index.js:13:16)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/plugin-pass.js:19:18)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/plugin.js:16:19)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/transformer.js:12:15)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/file/plugin-manager.js:20:20)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/pipeline.js:12:26)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/transformation/index.js:12:17)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/lib/api/node.js:25:23)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/babel-core/index.js:1:97)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/node_modules/nuclide-node-transpiler/lib/babel-cache.js:14:13)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/node_modules/nuclide-service-parser/lib/main.js:17:43)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/lib/service-manager.js:5:29)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/node_modules/nuclide-client/lib/main.js:10:16)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/AutoComplete.js:14:21)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/ide-reason.coffee:2:16)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/ide-reason.coffee:1:1)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .coffee] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at Package.module.exports.Package.requireMainModule (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:661:34)
  at Package.module.exports.Package.activateConfig (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:188:14)
  at Package.module.exports.Package.activateNow (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:166:14)
  at /opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:784:28
  at Emitter.module.exports.Emitter.emit (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/node_modules/event-kit/lib/emitter.js:86:11)
  at PackageManager.module.exports.PackageManager.triggerActivationHook (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package-manager.js:528:41)
  at Object.module.exports.LanguageReason.activate (/Users/jjb/src/reason/editorSupport/language-reason/lib/language-reason.coffee:16:21)
  at Package.module.exports.Package.activateNow (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:170:19)
  at /opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:150:32
  at Package.module.exports.Package.measure (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:92:15)
  at /opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:143:26
  at Package.module.exports.Package.activate (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package.js:140:34)
  at PackageManager.module.exports.PackageManager.activatePackage (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package-manager.js:512:21)
  at /opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package-manager.js:495:29
  at Config.module.exports.Config.transact (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/config.js:311:16)
  at PackageManager.module.exports.PackageManager.activatePackages (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package-manager.js:490:19)
  at PackageManager.module.exports.PackageManager.activate (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/package-manager.js:474:46)
  at AtomEnvironment.module.exports.AtomEnvironment.startEditorWindow (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/atom-environment.js:671:21)
  at Object.<anonymous> (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/initialize-application-window.js:38:8)
  at Object.<anonymous> (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/initialize-application-window.js:49:4)
  at Module._compile (module.js:434:26)
  at Object.defineProperty.value [as .js] (/opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:190:21)
  at Module.load (module.js:355:32)
  at Function.Module._load (module.js:310:12)
  at Module.require (module.js:365:17)
  at require (module.js:384:17)
  at setupWindow (file:///opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/static/index.js:79:5)
  at window.onload (file:///opt/homebrew-cask/Caskroom/atom/1.2.4/Atom.app/Contents/Resources/app.asar/static/index.js:35:9)

Commands

Config

{
  "core": {
    "themes": [
      "one-light-ui",
      "solarized-light-syntax"
    ],
    "disabledPackages": [
      "tree-view",
      "deprecation-cop",
      "fuzzy-finder",
      "incompatible-packages",
      "metrics",
      "styleguide",
      "timecop"
    ]
  },
  "ide-reason": {
    "pathToReasonfmt": "/Users/jjb/.opam/4.02.3/bin/reasonfmt",
    "pathToCompiler": "/Users/jjb/.opam/4.02.3/bin/ocamlc"
  }
}

Installed Packages

# User
fb-analytics-client, v1337.0.0-17826179
fb-analytics-reporter-settings, v1337.0.0-17826179
fb-biggrep-provider, v1337.0.0-17826179
fb-codegraph-providers, v1337.0.0-17826179
fb-diffs-and-tasks, v1337.0.0-17826179
fb-error-reporting, v1337.0.0-17826179
fb-file-a-bug, v1337.0.0-17826179
fb-graphql, v1337.0.0-17826179
fb-handle-url, v1337.0.0-17826179
fb-hg-smartlog, v1337.0.0-17826179
fb-home, v1337.0.0-17826179
fb-logging-helper, v1337.0.0-17826179
fb-login, v1337.0.0-17826179
fb-nuclide-file-creation, v1337.0.0-17826179
fb-nuclide-file-creation-ios, v1337.0.0-17826179
fb-nuclide-installer, v0.1.11
fb-package-manager, v1337.0.0-17826179
fb-phabricator-comments-client, v1337.0.0-17826179
fb-rating, v1337.0.0-17826179
fb-slog-viewer, v1337.0.0-17826179
fb-snippets, v1337.0.0-17826179
fb-test-runner-t-client, v1337.0.0-17826179
haskell-grammar, v0.4.0
highlight-selected, v0.11.1
hyperclick, v1337.0.0-17826179
ide-reason, v1.0.0
language-babel, v2.5.2
language-ini, v1.14.0
language-ocaml, v1.1.2
language-reason, v0.0.0
language-thrift, v1.0.2
nuclide-arcanist, v1337.0.0-17826179
nuclide-blame, v1337.0.0-17826179
nuclide-blame-provider-hg, v1337.0.0-17826179
nuclide-blame-ui, v1337.0.0-17826179
nuclide-buck-files, v1337.0.0-17826179
nuclide-busy-signal, v1337.0.0-17826179
nuclide-clang-atom, v1337.0.0-17826179
nuclide-code-format, v1337.0.0-17826179
nuclide-code-highlight, v1337.0.0-17826179
nuclide-debugger-atom, v1337.0.0-17826179
nuclide-debugger-hhvm, v1337.0.0-17826179
nuclide-debugger-lldb, v1337.0.0-17826179
nuclide-diagnostics-store, v1337.0.0-17826179
nuclide-diagnostics-ui, v1337.0.0-17826179
nuclide-diff-view, v1337.0.0-17826179
nuclide-file-tree, v1337.0.0-17826179
nuclide-file-watcher, v1337.0.0-17826179
nuclide-find-references, v1337.0.0-17826179
nuclide-flow, v1337.0.0-17826179
nuclide-fuzzy-filename-provider, v1337.0.0-17826179
nuclide-hack, v1337.0.0-17826179
nuclide-hack-symbol-provider, v1337.0.0-17826179
nuclide-health, v1337.0.0-17826179
nuclide-hg-repository, v1337.0.0-17826179
nuclide-home, v1337.0.0-17826179
nuclide-language-hack, v1337.0.0-17826179
nuclide-objc, v1337.0.0-17826179
nuclide-ocaml, v1337.0.0-17826179
nuclide-open-filenames-provider, v1337.0.0-17826179
nuclide-quick-open, v1337.0.0-17826179
nuclide-recent-files-provider, v1337.0.0-17826179
nuclide-recent-files-service, v1337.0.0-17826179
nuclide-remote-projects, v1337.0.0-17826179
nuclide-test-runner, v1337.0.0-17826179
nuclide-toolbar, v1337.0.0-17826179
nuclide-type-hint, v1337.0.0-17826179
tool-bar, v0.1.9

# Dev
No dev packages

Comprehensive coverage of attributes and attribute payloads.

This is a fairly large task, but I'm currently updating the printer to include a lot of the attribute printing features. After that is done, it will be much easier to finish the remaining work which entails going through the history of parser.mly for the last year and making sure that we have every new feature that has snuck into upstream.

Among other known features/gaps:

  • Add signatures to payload: parsing of attributes.
  • Test cases for all the ways which attributes can be applied.

Then, as a follow up, we can do some really good things with attributes.

  1. Store the comments as documentation within the AST directly inside of attributes. This is good because some tools are under development that will autogenerate documentation based on these without having to use ocamldoc.
  2. We can then build awesome async support using lwt_ppx.

Make/opam times have increased due to editorSupport

I believe the folders in editorSupport are causing make and pin times to be significantly greater. (They appear to be scanning/copying the entire directories over etc - which includes all of the node_modules ).

Failed to activate the ide-reason package

  1. Open Atom
  2. Open reason file
  3. Change language from regular expression to reason
  4. Observe crash report

Atom Version: 1.0.18
System: Mac OS X 10.11.1
Thrown From: ide-reason package, v1.0.0

Stack Trace

Failed to activate the ide-reason package

At Cannot find module 'nuclide-client'

Error: Cannot find module 'nuclide-client'
  at Module._resolveFilename (module.js:334:15)
  at Function.Module._resolveFilename (/Applications/Atom.app/Contents/Resources/app.asar/src/module-cache.js:383:52)
  at Function.Module._load (module.js:284:25)
  at Module.require (module.js:363:17)
  at require (module.js:382:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/AutoComplete.js:14:21)
  at Module._compile (module.js:428:26)
  at Object.defineProperty.value [as .js] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:169:21)
  at Module.load (module.js:353:32)
  at Function.Module._load (module.js:308:12)
  at Module.require (module.js:363:17)
  at require (module.js:382:17)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/ide-reason.coffee:2:16)
  at Object.<anonymous> (/Users/jjb/src/reason/editorSupport/ide-reason/lib/ide-reason.coffee:1:1)
  at Module._compile (module.js:428:26)
  at Object.defineProperty.value [as .coffee] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:169:21)
  at Module.load (module.js:353:32)
  at Function.Module._load (module.js:308:12)
  at Module.require (module.js:363:17)
  at require (module.js:382:17)
  at Package.module.exports.Package.requireMainModule (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:761:34)
  at Package.module.exports.Package.activateConfig (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:263:14)
  at Package.module.exports.Package.activateNow (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:241:14)
  at /Applications/Atom.app/Contents/Resources/app.asar/src/package.js:917:28
  at Emitter.module.exports.Emitter.emit (/Applications/Atom.app/Contents/Resources/app.asar/node_modules/event-kit/lib/emitter.js:82:11)
  at PackageManager.module.exports.PackageManager.triggerActivationHook (/Applications/Atom.app/Contents/Resources/app.asar/src/package-manager.js:502:41)
  at Object.module.exports.LanguageReason.activate (/Users/jjb/src/reason/editorSupport/language-reason/lib/language-reason.coffee:16:21)
  at Package.module.exports.Package.activateNow (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:245:19)
  at /Applications/Atom.app/Contents/Resources/app.asar/src/package.js:226:30
  at Package.module.exports.Package.measure (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:169:15)
  at Package.module.exports.Package.activate (/Applications/Atom.app/Contents/Resources/app.asar/src/package.js:218:14)
  at PackageManager.module.exports.PackageManager.activatePackage (/Applications/Atom.app/Contents/Resources/app.asar/src/package-manager.js:486:21)
  at /Applications/Atom.app/Contents/Resources/app.asar/src/package-manager.js:469:29
  at Config.module.exports.Config.transact (/Applications/Atom.app/Contents/Resources/app.asar/src/config.js:324:16)
  at PackageManager.module.exports.PackageManager.activatePackages (/Applications/Atom.app/Contents/Resources/app.asar/src/package-manager.js:464:19)
  at PackageManager.module.exports.PackageManager.activate (/Applications/Atom.app/Contents/Resources/app.asar/src/package-manager.js:445:46)
  at Atom.module.exports.Atom.startEditorWindow (/Applications/Atom.app/Contents/Resources/app.asar/src/atom.js:670:21)
  at Object.<anonymous> (/Applications/Atom.app/Contents/Resources/app.asar/src/window-bootstrap.js:12:8)
  at Object.<anonymous> (/Applications/Atom.app/Contents/Resources/app.asar/src/window-bootstrap.js:23:4)
  at Module._compile (module.js:428:26)
  at Object.defineProperty.value [as .js] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:169:21)
  at Module.load (module.js:353:32)
  at Function.Module._load (module.js:308:12)
  at Module.require (module.js:363:17)
  at require (module.js:382:17)
  at setupWindow (file:///Applications/Atom.app/Contents/Resources/app.asar/static/index.js:82:25)
  at window.onload (file:///Applications/Atom.app/Contents/Resources/app.asar/static/index.js:35:9)

Commands

Config

{
  "core": {
    "themes": [
      "one-light-ui",
      "solarized-light-syntax"
    ],
    "disabledPackages": [
      "tree-view",
      "deprecation-cop",
      "fuzzy-finder",
      "incompatible-packages",
      "metrics",
      "styleguide",
      "timecop"
    ]
  },
  "ide-reason": {
    "pathToReasonfmt": "/Users/jjb/.opam/4.02.3/bin/reasonfmt",
    "pathToCompiler": "/Users/jjb/.opam/4.02.3/bin/ocamlc"
  }
}

Installed Packages

# User
fb-analytics-client, v1337.0.0-17826179
fb-analytics-reporter-settings, v1337.0.0-17826179
fb-biggrep-provider, v1337.0.0-17826179
fb-codegraph-providers, v1337.0.0-17826179
fb-diffs-and-tasks, v1337.0.0-17826179
fb-error-reporting, v1337.0.0-17826179
fb-file-a-bug, v1337.0.0-17826179
fb-graphql, v1337.0.0-17826179
fb-handle-url, v1337.0.0-17826179
fb-hg-smartlog, v1337.0.0-17826179
fb-home, v1337.0.0-17826179
fb-logging-helper, v1337.0.0-17826179
fb-login, v1337.0.0-17826179
fb-nuclide-file-creation, v1337.0.0-17826179
fb-nuclide-file-creation-ios, v1337.0.0-17826179
fb-nuclide-installer, v0.1.11
fb-package-manager, v1337.0.0-17826179
fb-phabricator-comments-client, v1337.0.0-17826179
fb-rating, v1337.0.0-17826179
fb-slog-viewer, v1337.0.0-17826179
fb-snippets, v1337.0.0-17826179
fb-test-runner-t-client, v1337.0.0-17826179
haskell-grammar, v0.4.0
highlight-selected, v0.11.1
hyperclick, v1337.0.0-17826179
ide-reason, v1.0.0
language-babel, v2.5.2
language-ini, v1.14.0
language-ocaml, v1.1.2
language-reason, v0.0.0
language-thrift, v1.0.2
nuclide-arcanist, v1337.0.0-17826179
nuclide-blame, v1337.0.0-17826179
nuclide-blame-provider-hg, v1337.0.0-17826179
nuclide-blame-ui, v1337.0.0-17826179
nuclide-buck-files, v1337.0.0-17826179
nuclide-busy-signal, v1337.0.0-17826179
nuclide-clang-atom, v1337.0.0-17826179
nuclide-code-format, v1337.0.0-17826179
nuclide-code-highlight, v1337.0.0-17826179
nuclide-debugger-atom, v1337.0.0-17826179
nuclide-debugger-hhvm, v1337.0.0-17826179
nuclide-debugger-lldb, v1337.0.0-17826179
nuclide-diagnostics-store, v1337.0.0-17826179
nuclide-diagnostics-ui, v1337.0.0-17826179
nuclide-diff-view, v1337.0.0-17826179
nuclide-file-tree, v1337.0.0-17826179
nuclide-file-watcher, v1337.0.0-17826179
nuclide-find-references, v1337.0.0-17826179
nuclide-flow, v1337.0.0-17826179
nuclide-fuzzy-filename-provider, v1337.0.0-17826179
nuclide-hack, v1337.0.0-17826179
nuclide-hack-symbol-provider, v1337.0.0-17826179
nuclide-health, v1337.0.0-17826179
nuclide-hg-repository, v1337.0.0-17826179
nuclide-home, v1337.0.0-17826179
nuclide-language-hack, v1337.0.0-17826179
nuclide-objc, v1337.0.0-17826179
nuclide-ocaml, v1337.0.0-17826179
nuclide-open-filenames-provider, v1337.0.0-17826179
nuclide-quick-open, v1337.0.0-17826179
nuclide-recent-files-provider, v1337.0.0-17826179
nuclide-recent-files-service, v1337.0.0-17826179
nuclide-remote-projects, v1337.0.0-17826179
nuclide-test-runner, v1337.0.0-17826179
nuclide-toolbar, v1337.0.0-17826179
nuclide-type-hint, v1337.0.0-17826179
tool-bar, v0.1.9

# Dev
No dev packages

Strange formatting of variant case:

@cristianoc found that this formatting case results in strange indentation:
Our formatting changed from:

| ImplOK of (
    list check, 
    Sil.subst, 
    Sil.subst, 
    list Sil.hpred, 
    list Sil.atom, 
    list Sil.hpred, 
    list Sil.hpred, 
    list Sil.hpred, 
    list (Sil.exp, Sil.exp), 
    list (Sil.exp, Sil.exp)
  );

to:

| ImplOK of (
              list check,
              Sil.subst,
              Sil.subst,
              list Sil.hpred,
              list Sil.atom,
              list Sil.hpred,
              list Sil.hpred,
              list Sil.hpred,
              list (Sil.exp, Sil.exp),
              list (Sil.exp, Sil.exp)
            );

I think somehow, the easyformat list is docked to the wrong label.

'instanceas' vs 'instance as'

In the lexer, The token INSTANCEAS is defined as 'instanceas'.

However, in the printer, it is printed as 'instance as'.

@jordwalke What was the original idea in your mind?

Have every test ensure formatting is idempotent

Parsing/printing text twice should always be the same as parsing/printing once.

/* If format is a function that formats source text: */
let format text => print (parse (text));

/* The the following must be true for all valid source text */
format(format(text)) == format (text);

Off-topic:
There are likely a couple of other requirements that we should solidify and document regarding what it means to be a valid parser/AST-printer pair - as well as justification for why Reason meets that criteria, but simply ensuring this idempotent property holds for everything in the formatTest directory is a good practical start and catches errors.

Some other ideas for requirements:

  • Every valid base-language AST must be expressible in your syntax: (Your syntax must be comprehensive).
  • Your parser may never produce an AST that could not have been produced via your base-language parser (for example, imagine if Reason constructed an AST with an identifier named "match").
  • Formatting must be idempotent.

There might be a concise way to express all of that in a way that can be conveniently verified against test cases (and large code bases):

Example: For any two parsing/printing pairs P1=(Parse1, Print1), P2=(Parse2, Print2) (where P1 might be P2):

// For all valid text1
Print1(Parse1(text1)) == Print1(Parse2(Print2(Parse1(text1))))
// For all valid text2
Print2(Parse2(text1)) == Print2(Parse1(Print1(Parse2(text2))))

Remove GPL licensed files

Looks like currently only spacemacs files and flycheck-reason are GPL lincesed. We can remove both of them since:

  1. spaceamcs support is not on our critical path
  2. functionality of flycheck-reason is already covered in merlin

Resizing terminal crashes rtop:

Stack trace: obtained with "OCAMLRUNPARAM=b rtop
Looks like the failure is in utop.

Fatal error: exception Unix.Unix_error(Unix.EINTR, "select", "")
Raised by primitive operation at unknown location─┬───────┬────────┬──────┬────┐
Called from file "src/unix/lwt_engine.ml", line 388, characters 26-60uffer│Byte│
Called from file "src/unix/lwt_engine.ml", line 329, characters 8-39──────┴────┘
Called from file "src/unix/lwt_main.ml", line 41, characters 8-82
Called from file "src/lib/uTop_main.cppo.ml", line 610, characters 4-465
Called from file "src/lib/uTop_main.cppo.ml", line 1319, characters 8-17
Called from file "src/lib/uTop_main.cppo.ml", line 1334, characters 4-15

See this issue
cc @jvillard

[Speculation] Make records memory representation compatible with objects.

I believe it could be relatively straightforward to do the following:
(These are unorganized ideas - writing them for posterity).

  • Make any record with fields {x, y} type compatible with any closed object of type {x, y}.
  • At creation time, if record r and object o have the exact same fields, their layout should be identical - the layout should be deterministic based on an ordering on their labels. If you have constrained an argument to be a closed object type with those fields, then you know exactly where those fields must be, just as you do with a record argument. (Inheritance may/may not cause additional difficulties in doing this). There is no need to invoke the runtime "send" function in C for closed object types, and you may pass records as any argument that had been constrained to be the appropriate closed object type.
  • Public methods should reside in the "front" of the block of memory in that deterministic order, in the exact offset that they would exist in a similar record.
  • A record may be explicitly constrained (:>) to fit some less specific type, and in doing so must generate the proper lookup table that an would be used by the object runtime's send.

A much simpler approach might be to:

  1. Optimize memory alignment and exploit that deterministic ordering when any function has annotated an argument as closed. Annotations on function arguments aren't required - but they will make your code run faster, as it can bypass send within that function.

[Atom][LOWPRI] Report Merlin Errors Beautifully.

The errors that we report in the Reason docked toolbar should match the organization and style of the Atom "find in files" results window. See the screenshot. The only difference is that we'd likely highlight using a red color.

screen shot 2016-01-31 at 2 49 06 am

Attribute syntax to follow programming language trends.

Rust chose to make their "attributes" syntax follow that of C#.

It turns out that OCaml has recently added attributes (they're really good - they are intended to be used for more powerful features than Rust's attributes (full on macro/AST rewriting)), and they have their own syntax. It would be trivial to change the syntax of Reason's attributes to match that of C# and (now) Rust:

In OCaml

  • [@attribute] applies to an inline syntactic construct (typically).
  • [@@attribute] applies to the preceding syntactic construct such as module item, class item.
  • [@@@attribute] applies to the containing syntactic construct.

In Rust,

  • #[attribute] applies to the following syntactic construct.
  • #![attribute] applies to the containing syntactic construct.

https://doc.rust-lang.org/reference.html#attributes

This is another one of those things that really doesn't matter to most of us, but why not change it since it's trivial? (I don't have any code that uses attributes, and I believe none of us do either, so this is lower pri).

Support 4.03

The newest OCaml compiler has a few changes in the AST that make the parser incompatible. I'll update this issue with things I observe, though there aren't many changes that are difficult to adapt to.

  1. The ? in optional named arguments, has been improved so that the question mark doesn't become a part of the name itself (which would then later be used to interpret it as optional) - instead, it is modeled using a variant type appropriately.

Multiline strings can exceed line length after formatting.

Using multiline strings (whose existence I only discovered recently), one can get arbitrarily long lines after formatting.
E.g.

let long_string = "start here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx
continue here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx
and end here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx";

formats as

let long_string = "start here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx\ncontinue here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx\nand end here xxxx xxxx xxxx xxxx xxxxx xxxxxx xxxxxx xxx";

Spacing cleanup:

Here's three somewhat related tasks that make a nice unit of work. None of them are particularly difficult:

  • Separate module items according to convention: #41
  • Trim whitespace in printer: #53
  • Reindent comments correctly when formatting: #44

[Printer] Group items in file according to convention.

Right now, when you print source files, they are always separated by spaces.
I'll propose a very simple convention that is better than this, though not perfect (team specific conventions would likely want to refine this).

If a comment is a "doc block" comment, it should have two total spaces above it. If it is a regular comment, it should have one space above it.

All other items in a structure/signature should be grouped together by their kind - so let bindings with let bindings, and type bindings with type bindings - open with open etc.

open Foo;
open Bar;

type t = {x: int, y: int};
type t3 = (int, int);

let oneSpaceAboveThis = 100;
let anotherRegularLetBinding = "hi"
and yetAnotherBinding = "bye";

/**
 * let regular comment.
 */
let item = 0;


/**
 * docBlock comment.
 */
let anotherItem = 10;

Nested OR patterns aren't preserved.

The following:

let reasonDoubleBarNested = fun
  | X | Y _ _ _ | (Z _ _ | Q)  => true
  | _ => false;

Is printed as:

let reasonDoubleBarNested =
  fun | X
      | Y _ _ _
      | Z _ _
      | Q => true 
      | _ => false;

Properly re-indent comments.

One issue that's going to come up when converting code from OCaml, and also when indenting your own code (but less likely), is that comments now begin in a new column, and therefore must be shifted over.

Right now, we just copy the entire comment including newlines, but shift the starting column over. See the screenshot for how that will lead to improperly indented comments.

screen shot 2016-01-13 at 11 12 21 pm

We should indent the entire comment over by the same amount that we are shifting the first line.

Here's an example of the formatter running on an existing comment.

[LOWPRI] Unify class "instance types" with anonymous object types.

There is a totally different syntax for anonymous object types and class instance types:
(Ptyp_object and Pcty_sig respectively). One is used to define types of object without knowing their classes, and the other is to define the return value of a constructor ("instance types"). They are unified by the type system seamlessly, but their type definitions use a different syntax.
I'm in the middle of sending out a parser update that improves them independently but they are not unified yet. There's no reason why they can't be unified, as the Ptyp_object syntactically only includes methods, whereas Pcty_sig includes that and much more. Just one more thing that unnecessarily gives objects a bad reputation.

Syntax Proposal: Hash Tags - a way to think about polymorphic variants.

Okay, this admittedly of little consequence because I wouldn't really encourage the use of polymorphic variants for anyone but experts, but it might be a good idea, so I'll write it down:

First, some background on polymorphic variants.

  1. Both regular variants and polymorphic variants are both considered "tagged variants". Their names are kind of like name tags, and this is well established terminology.
  2. Polymorphic variants do not require type definitions even though you can chose to define types for them. Otherwise, you are free to just start using them like myVar = (HeyThere, Goodbye); without any type definition.
  3. They are still checked against pattern matching just like regular variants, so they are very type safe.

Now, much later on, I would also later suggest the following: Change the back tick to # and introduce them as "hash tags".

type regularVariant = {
   | CaseOne of argOne argTwo
   | Case Two
};

type someHashTags = {
   | #Yolo
   | #NoFilter of url
};

Now hear me out. I'm genuinely not trolling you all, and it's not just a random cheeky topical reference to social media. The way polymorphic variants work, is that their runtime representation is literally a hash of their tag text - this enables efficient separate compilation among other things. But there is also a parallel to common notion of "hash tags" today. Here's a summary of my justification.

  • Polymorphic variants are literally hashed tags. On that basis alone, it would not be a horrible name for them.
  • The single backtick is troublesome because in github/phabricator source comments, you can't express a single backtick without googling the special convention (I had to in order to figure out how to give the backtick examples at the very top).
  • They do have a conceptual link and similarity to "Hash tags" as used in social media, in that they aren't things that need to be predefined anywhere - they're both symbols that gain meaning simply by the act of being expressed. The fact that there is a conceptual parallel to a familiar concept, as well as a familiar visual/syntactical style makes them easy to remember and easier to introduce to people.

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.