Code Monkey home page Code Monkey logo

tiny-calc's Introduction

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

tiny-calc'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

Watchers

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

tiny-calc's Issues

API: Consider separate contracts for Maps/Records

Some potential differences between maps/records that may motivate a separate contract:

  • The set of keys in a map is dynamic (i.e., no fixed schema)
  • It is not an error to read non-existent keys (returns undefined)
  • You can test for the presence of a key, get a count of entries, and enumerate map entries, key, values.
  • You can delete keys and clear a map.

I think we could probably expose these as an extension of the record interfaces:

interface IMapReader<TKey, TValue> extends IReader<Record<TKey, TValue | undefined>> {
    has(key: TKey): boolean;
    entries(): IEnumarable<[TKey, TValue]>;
    keys(): IEnumarable<TKey>;
    values(): IEnumarable<TValue>;
    readonly size: number;
}

interface IMapWriter<TKey, TValue> extends IWriter<Record<TKey, TValue>> {
    delete(key: TKey): void;
    clear(): void;
}

Sheetlet v2

  • Add cell refs to the parser and ast structure.
  • Switch formula evaluator to interpreter.
  • Implement row/col insertion and deletion.

Nano-calc v2

Items for the next iteration of nano.

  • Quoted field names like A.{Foo Bar Baz} #42
  • Tree-based interpreter. #44
  • Tracing and effects refactor. #43
  • Better error handling. #44
  • Build out more examples. #45
  • First cut and explicit API for core properties like value and stringify. #43 (more work to be done).

Gracefully handle missing in current parser sink.

Currently a missing node will cause the compiler to throw an exception.

Alternatives include:

  • interpret missing as a value
  • catch the error and return undefined
  • call back into the parser error handler if such an API was exposed; related: #15.

Common interfaces for reading, writing, and observing changes in structured data

One seemingly simple thing that I think would benefit the JavaScript ecosystem in general are a set of standard contracts for observable data types that allow reactive systems to interoperate (e.g., a standard mechanism for an ObservableMap implementer to notify observers when keys are added, removed, or changed.)

@jack-williams and I have been slowly refining a set of such interfaces for Tiny-Calc, and I've made a first attempt at describing our thinking here.

I'd be interested in @taylorsw04, @CraigMacomber's thoughts/suggestions on the design (or improving the README. I feel like it sounds more complex than it is when I try to describe it.)

API: IVectorShapeWriter.splice() is inconsistent with Array.splice()

Array.splice() accepts a set of items to insert, where IVectorShapeWriter takes a number of default items / holes to insert.

Array.splice(start: number, deleteCount: number, ...items: T[]): T[];
IVectorShapeWriter.splice(start: number, deleteCount: number, insertCount: number): void;

The motivations for this inconsistency were:

  1. The spread operator ('...items[]') can lead to stack exhaustion when the number of items inserted is large on v8 (v12 x64).
  2. Providing the items up front encourages potentially unnecessary array allocations/copies.
  3. Philosophically, IVectorShapeWriter should be agnostic to the type of items stored (i.e., should not have a generic T param)

(Issues 1 & 2 have proven to be real concerns for IMatrix, which has similar spliceRows/Cols APIs)

However, in practice this API difference has proven to be error-prone for IVector. This is because when T=number, both signatures will accept '.splice(0, 0, 3)', which Array would interpret as insert '3' and IVector interprets as insert 3 holes.

(It's also just clunky/annoying to have to call splice() and then use setItem() to fill in the holes.)

My current thinking is that we should rename IShapeWriter.splice to avoid confusion (and perhaps reintroduce a compatible splice on I*Writer.)

...if only I could think of a good name... The best I have so far is 'resize()', but that might be a discovery issue as 'resize()' is usually used for modifying length only.

PS - There is a second inconsistency where IVectorShapeWriter.splice() returns void instead of an array of the removed items, but I believe here there is far more upside.

API design & conventions

Researching various API nits to see if I can find a compelling majority. (Feel free to comment/add).

Conventions

Intervals expressed as start/count?

Currently I use start/count because it's unambiguous wrt. if the 'end' is inclusive/exclusive.

insertRows(startRow: number, numRows: number);
  • Excel does the same.
  • Math.js uses inclusive start / exclusive end.
  • Most modern JavaScript APIs use start / end (exclusive).

Points, intervals, etc. are open-coded as numbers (as opposed to arrays, objects, etc.)

This was done out of fear of hidden array/object allocations, but never verified.

read(rowStart: number, colStart: number, rowCount: number, colCount: number);

Vector, Matrix, etc. are distinct types.

Related to the above, if we were to pass coordinates/sizes as arrays, we could generalize vectors, matrices, etc. to n-dimensional arrays.

Naming

'col' as an abbreviation for column?

insertCol(col: number, numCols: number);

'numRows' as an abbreviation for 'number of rows'?

  • Excel uses 'rowCount', which is probably easier to discover in Intellisense.
  • Math.js has a single '.size' property that returns a [number, number].
  • ndarray has a single '.shape' property that returns a 'number[]'.

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.