Giter VIP home page Giter VIP logo

lambda's People

Contributors

71104 avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

Forkers

itburnswhenip

lambda's Issues

Compilation of literal nodes may fail with cyclic objects

Current implementation:

LiteralNode.prototype.compileExpression = function () {
    return JSON.stringify(this.value.marshal());
};

LiteralNode.prototype.compileStatement = function () {
    return 'return ' + JSON.stringify(this.value.marshal()) + ';';
};

The JSON.stringify cannot encode cyclic objects.

`module` and `require` not available

They should be available when running from the REPL, but they aren't (not sure why).

This is secondary if the main use of the language is to transpile to JavaScript.

Syntax error

The following valid code produces a syntax error:

console.dir []

Unmarshal of variadic functions?

Native functions are currently unmarshalled based on their length.

This is weak because the native code may still use the arguments array to receive extra arguments.

Also, there is no solution for calling variadic functions except reflection, e.g. f.apply null {x1, x2, ...}.

The latter is a syntax limitation of the language and I don't think it's going to be fixed.

Unmarshalling floating point numbers

JavaScript numbers are always unmarshalled to FloatValues, even though an IntegerValue is sometimes expected.

This bug is irrelevant for now because the implementations of IntegerValue and FloatValue are structurally identical (although the problem may still be detected through the use of is / instanceof).

Implement `typeof`

Even though Lambda will be strictly typed, typeof might still be useful, e.g. to analyze values returned by native APIs.

Syntax ambiguity

In this case:

{ x, y }

x, is started being parsed as a lambda.

Undesirable workaround:

{ (x), y }

global command `lambda` doesn't work

The following errors are shown after installing the package lambda globally and running it using the lambda command:

/usr/bin/lambda: line 1: syntax error near unexpected token `('
/usr/bin/lambda: line 1: `var Lambda = require('./lambda.js');'

`then` keyword and promises

then is a keyword in Lambda, which prevents support for promises and thenables.

Maybe we could introduce a loose policy on keyword usage and allow them as field names.

Try statements catch internal errors

Try statements must only catch user errors thrown by a Lambda throw statement or errors thrown by native code.

Programming errors of the interpreter often result in JavaScript exceptions that must not be caught by try/catch statements.

Memory management

This:

console.dir let x.x = 5 in x

Prints {}, while it should definitely print the same as this:

let x.x = 5 in console.dir x

Which is { x: 5 }.

Implement native objects

Extend the domain with a new type of value, the "native object", which is basically a wrapper for an object that comes from native JavaScript rather than being generated by Lambda code.

This type of value makes sense only in the interpreter, while the compiler will generate code that just accesses objects.

There are two important use cases for this feature:

  1. avoiding to unmarshal and re-marshal the this parameter of native methods, and
  2. avoiding marshaling operations on native objects altogether, which fixes #27.
    #27 was already fixed by using a dictionary that prevents visiting objects more than once when unmarshaling, but the code is complicated and this new feature will let us get rid of the dictionary.

TypeError when a user exception is thrown

Run on bash:

$ echo "throw 0" | lambda

Output:

net.js:633
    throw new TypeError('invalid data');
          ^
TypeError: invalid data
    at WriteStream.Socket.write (net.js:633:11)
    at Socket.<anonymous> (/usr/lib/node_modules/lambda/bin/Main.js:32:19)
    at Socket.emit (events.js:129:20)
    at _stream_readable.js:908:16
    at process._tickCallback (node.js:355:11)

The expected output is a string representation of the thrown exception.

Implement `reverse` and `sort` in array prototype

Examples:

{1, 2, 3, 4, 5}.reverse
# { 5, 4, 3, 2, 1 }

{3, 2, 5, 1, 4}.sort <=
# { 1, 2, 3, 4, 5 }

Notes:

  • reverse is evaluated lazily.
  • sort accepts one argument, a partial order relationship. This differs from JavaScript.

Fix operators

The current implementation of operators doesn't allow to type expressions with operators.

Implement the correct typing and possibly overload resolution so as to make them more efficient and not test RTTI at runtime.

Parse hex and octal literals

Example hex literal: 0x0a1B2c3D

Example octal literal: 0123

Invalid octal literal: 089

They will all produce integer values.

Lexer improvement

At the current state of the project, the asterisk lexical symbol can be merged to symbol.

Use prototype inheritance instead of cloning entire contexts

Example implementation of Context.add:

Context.prototype.add = function (name, value) {
    function Hash() {}
    Hash.prototype = this.hash;
    var hash = new Hash();
    hash[Context.PREFIX + name] = value;
    var context = new Context();
    context.hash = hash;
    return context;
};

But this requires that existence checks are not based on hasOwnProperty any more. This won't cause collision problems because now all the keys have the prefix.

Parser bug

The current parser won't work with this:

x x -> x

Array literals often confused with subscripts

When writing this intuitive expression:

console.log [1, 2, 3]

A syntax error is produced because the parser interprets it as a subscript node with a weird index. Even worse, this is successfully mistaken for a subscript node:

console.log [1]

For now it is necessary to disambiguate the syntax using parens:

console.log ([1, 2, 3])

But a better solution would probably use curly brackets instead of square brackets for array literals, e.g.:

console.log { 1, 2, 3 }

JavaScript errors aren't caught

Try this:

try x.x catch 5  # x is not defined

Only user errors (those thrown by throw) are currently caught by the try statements, but the user should be able to catch any exception.

Allow expandos?

What are the effects of the following?

let console.expando = "lol" in console.log console.expando

Coerce complex numbers to strings

The binary plus operator (+) must coerce complex numbers to string when adding to strings.

Example:

+ 3i 'hello'

must type to string and produce the string value 0+3ihello.

Contexts don't allow `hasOwnProperty` and possibly other predefined names

The expression hasOwnProperty produces a closure (the hasOwnProperty method of the context's hash, unmarshalled), but this is wrong.

Moreover, this crashes the interpreter:

let hasOwnProperty = 0 in hasOwnProperty

Because the interpreter becomes unable to use the hasOwnProperty method of the context's hash since it has been redefined.

This problem only occurs in interpreted code, not compiled code, and may extend to other names if Object's prototype is extended.

Lazy terms

Possible implementation as no-arg functions.

Example:

let greet = () -> console.log "hello" in greet

The body of the let statement prints hello to the console.

Some native objects are unavailable again

For some braindead reason, unmarshalling native Node objects such as process causes exceptions in getters.

Not worth fixing, as the problem only happens in the interpreter and the main goal of the project is the compiler.

Passing objects

Objects must be managed by contexts and sub-contexts during evaluation because we need a stack for each field, otherwise we would not be able to execute the following correctly:

let x.x = 'a' in + (let x.x = 'b' in x.x) x.x # must return 'ab', not 'bb'

This means we cannot pass native JavaScript values around. But we still have to pass native JavaScript values when applying to an unknown and wrap their result back to managed values. Major complexity arises when the passed value is a function accepting other parameters.

An analogous solution is also needed for compilation.

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.