GithubHelp home page GithubHelp logo

brendanberg / l Goto Github PK

View Code? Open in Web Editor NEW
18.0 3.0 1.0 963 KB

The L Programming Language

JavaScript 94.75% Lex 0.25% PEG.js 5.00%
programming-language functional-languages concurrency-primatives gradual-typing pattern-matching

l's People

Contributors

brendanberg avatar dependabot[bot] avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

Forkers

nasser

l's Issues

Matching fails when variants are used

>> {{ (Boolean.True) -> { 't' }, (Boolean.False) -> { 'f' } }}(0 == 0)
ReferenceError: AST is not defined
    at capture (/Users/berg/Documents/projects/L/src/context.js:217:31)
    at capture (/Users/berg/Documents/projects/L/src/context.js:99:12)
    at Context.match (/Users/berg/Documents/projects/L/src/context.js:231:12)
    at Context.extend (/Users/berg/Documents/projects/L/src/context.js:27:22)
    at Record.FunctionCall.eval (/Users/berg/Documents/projects/L/src/ast/functioncall.js:47:29)
    at /Users/berg/Documents/projects/L/src/ast/evaluate.js:29:40
    at /Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4418:31
    at List.__iterate (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:2206:13)
    at List.reduce (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4413:12)
    at Record.Evaluate.eval (/Users/berg/Documents/projects/L/src/ast/evaluate.js:28:23)

Parse Error Using Records in a Template Match

I expect a template match to destructure a record.

Actual Result:

> p1 :: Point(x: 5, y: 5)
  [.p1: Point(x: 5, y: 5)]
> Point(px, py) :: p1
  ParseError: did not consume all tokens in expression

Expected Result:

> p1 :: Point(x: 5, y: 5)
  [.p1: Point(x: 5, y: 5)]
> Point(px, py) :: p1
  [.px: 5, .py: 5]

Equality comparisons in match blocks don't work

>> true :: 0 == 0
[$true: True]
>> false :: 0 != 0
[$false: False]
>> abs :: (x) -> { {{ (true) -> { x }, (false) -> { -x } }}(x > 0) }
[$abs: (x) -> {
    {{
        (true) -> {
            x
        }
        (false) -> {
            -x
        }
    }}(x > 0)
}]
>> abs(3)
3
>> abs(-3)
-3
>> {{ (true) -> { 't' }, (false) -> { 'f' } }}
{{
    (true) -> {
        't'
    }
    (false) -> {
        'f'
    }
}}
>> {{ (true) -> { 't' }, (false) -> { 'f' } }}(0 == 0)
't'
>> {{ (true) -> { 't' }, (false) -> { 'f' } }}(0 != 0)
't'

Types should not use global namespace

Look into how to make type extensions explicit.

>> () -> {
 -   List x ('%': y) -> { {{
 -     ([h]) -> { [h % y] }
 -     ([h, t...]) -> { [h % y] + (t % y) }
 -   }} (x) }
 -   (1 .. 20) % 6
 - }()
[1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1]
>> (1 .. 20) % 6
[1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1]

Alternate syntax for objects?

point : [x, y] =>
    __plus__ : [other] =>
        point [= x + other x, = y + other y]
    __incr__ : [other] =>
        x +:= other x
        y +:= other y
    __str__ : =>
        "point [{x}, {y}]" format self

p1: = point [4, 3]
p2: = point [6, 7]

p3: = p2 + p1

console out <- p3 x
console out <- p3 y

Notes:

  • This introduces weirdly exhibitionistic closures. We may introduce getters and setters or a concept of explicitly exposing a closed-over variable.
  • We've also eliminated the __init__ method from the original example, since we are populating the hash map with the contents of the list being applied.
  • Finally, a potential notation for writing to the console is introduced as passing messages to console out (or just console?)

Add guard expressions to match blocks

Design syntax and semantics for guard clauses to add conditions to a matched predicate

odd :: {{
    (0) -> { False }
    (n)(if: n > 0) -> { even(n - 1) }
    (n)(if: n < 0) -> { even(n + 1) }
}}

Move project to yarn

CircleCI uses yarn by default. Why not just move off of npm and over to yarn?

Empty parens need a better error message

>> ()
TypeError: Cannot read property 'map' of null
    at /Users/berg/Documents/projects/L/src/ast/block.js:60:16
    at updateInDeepMap (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:1971:22)
    at updateInDeepMap (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:1980:23)
    at Record.Map.updateIn (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:1278:26)
    at Record.Map.update (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:1270:14)
    at Record.Block.transform (/Users/berg/Documents/projects/L/src/ast/block.js:59:19)
    at Record.Block.eval (/Users/berg/Documents/projects/L/src/ast/block.js:55:14)
    at Record.Immediate.eval (/Users/berg/Documents/projects/L/src/ast/immediate.js:25:30)
    at REPLServer.eval (/Users/berg/Documents/projects/L/src/repl.js:218:7)
    at bound (domain.js:301:14)

Prefix operators should bind tighter than call

The + prefix operator needs to bind before the method call.

>> +1(sqrt.)
   NameError: the Decimal '1.000000000000' does not have a method matching the selector '('+')'
>> (+1)(sqrt.)
   1.000000000000

Specify date formatting library

Go has a [decent model for date formatting] (https://gosamples.dev/date-time-format-cheatsheet/)based on the date 01/02 03:04:05PM '06 -0700. Each number in the string corresponds to a particular field:

  • 01 - month
  • 02 - day
  • 03 - hour (12h)
  • 04 - minute
  • 05 - second
  • 06 - year
  • 07 - time zone offset

The date 2001-02-03 04:05:06.007PM -0800, however, has fields sorted by duration and therefore is less ambiguous.

  • 01, 2001 - year (2 digit or 4 digit)
  • 02, 2, Feb, February - month (with or without leading zero, abbreviated or full name)
  • 03, 3 - day (with or without leading zero)
  • 04, 4 - hour (12h, with or without leading zero)
  • 16 - hour (24h) (TODO how do you get 24h time without a leading zero)
  • 05 - minute
  • 06 - second
  • 007 - millisecond
  • -0800 - UTC offset

For example:

  • February 3, 2001 4:05 PM
  • 03 Feb 01 16:05:06
  • 3/2/01 4:05 PM

VM as OS Concepts

Just some rambling thoughts per our conversation

Web-Based Architectures

  • complex interactions between multiple pieces of software
  • often an expert is required to "harden" a system with so many moving parts

VMs

  • necessary for write once run everywhere
  • multiple vms can compete for resources in ways that hide resource needs of individual processes (threads) contained within them

VM as OS

  • Runs only on one combination of hardware as exposed by VirtualBox (or some other VM)
  • Custom linux installation, missing significant software as compared to a standard linux system.
  • login() which usually owns all other processes after boot, will be replaced with a ‘system()’ program which forks into an ‘aREPL’, asynchronous REPL, and an nginx (or some other webserver) implementation
  • The system presents configuration options via the standard monitor output channels, these can be serialized to disk in between runs, eventually this can be exposed as a secure ncurses interface
  • the ‘expert level’ configuration is provided by the language developers, potential flaw: each 0-day explit effects all systems
  • the webserver reads a request an http put request to http://foo.bar/eval that looks like:
    {
    souce: Byte array representing source input string
    }

and returns a JSONs that looks like:
{
out: standard output channel
err: standard input channel
}
whenever the output buffer size is reached

The byte array source is passed to the aREPL where it’s read, evaluated and when nevessary things are printed back

Tying systems together

L should implement many web-spec. functions as basic language constructs implemented in C and linked against the standard libraries that provide those functions, things like:

scp, sendEmal, get, put, post, update, delete (by no means exhaustive)

as well as all the language features given in the spec

provide a modular way of loading new “sys-tasks” into the language

Function application chaining either breaks the stack or misapplies

>> Y :: (f) -> {
 -   (x) -> {
 -     f((y) -> { x(x)(y) })
 -   }((x) -> {
 -     f((y) -> { x(x)(y) })
 -   })
 - }
[$Y: (f) -> {
    (x) -> {
        f((y) -> {
            x(x)(y)
        })
    }((x) -> {
        f((y) -> {
            x(x)(y)
        })
    })
}]
>> fact :: (fn) -> {{
 -   (0) -> { 1 }
 -   (n) -> { n * fn(n - 1) }
 - }}
[$fact: (fn) -> {
    (0) -> {
        1
    }
    (n) -> {
        n * fn(n - 1)
    }
}]
>> Y(fact)
(n) -> {
    n * fn(n - 1)
}
>> Y(fact)(5)
RangeError: Maximum call stack size exceeded
    at List.first (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4782:19)
    at capture (/Users/berg/Documents/projects/L/src/context.js:99:39)
    at Context.match (/Users/berg/Documents/projects/L/src/context.js:231:12)
    at Context.extend (/Users/berg/Documents/projects/L/src/context.js:27:22)
    at Record.FunctionCall.eval (/Users/berg/Documents/projects/L/src/ast/functioncall.js:39:24)
    at Record.FunctionCall.eval (/Users/berg/Documents/projects/L/src/ast/functioncall.js:31:27)
    at /Users/berg/Documents/projects/L/src/ast/evaluate.js:29:40
    at /Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4418:31
    at List.__iterate (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:2206:13)
    at List.reduce (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4413:12)
>> curry :: (f)->(x)->(y)->{ f(x, y) }
[$curry: (f) -> (x) -> (y) -> {
    f(x, y)
}]
>> add :: (a, b) -> { a + b }
[$add: (a, b) -> {
    a + b
}]
>> add3 :: curry(add)(3)
[$add3: (y) -> {
    f(x, y)
}]
>> add3(2)
TypeError: Cannot read property 'apply' of undefined
    at Record.<anonymous> (/Users/berg/Documents/projects/L/src/dispatch.js:5:28)
    at Record.Invocation.eval (/Users/berg/Documents/projects/L/src/ast/invocation.js:80:17)
    at Record.InfixExpression.eval (/Users/berg/Documents/projects/L/src/ast/infixexpression.js:34:66)
    at /Users/berg/Documents/projects/L/src/ast/evaluate.js:29:40
    at /Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4418:31
    at List.__iterate (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:2206:13)
    at List.reduce (/Users/berg/Documents/projects/L/node_modules/immutable/dist/immutable.js:4413:12)
    at Record.Evaluate.eval (/Users/berg/Documents/projects/L/src/ast/evaluate.js:28:23)
    at Record.FunctionCall.eval (/Users/berg/Documents/projects/L/src/ast/functioncall.js:75:42)
    at /Users/berg/Documents/projects/L/src/ast/evaluate.js:29:40

First thoughts

I figured this would be as good a place as any to collaborate for now, and it seems like opening tickets is an easier way to pass notes back and forth than committing into the repo. Here's a brief list of things I'm thinking about:

  • Conditional expressions -- I think the semantics of it will change a bit. It should always use short-circuit eval, but I think it should be clear what the overall expr. evaluates to.
  • Control flow -- I think that the sequence functions (map, fold, filter, etc.) eliminate the need for a for statement. (Can for even be an expression? It doesn't even make sense.)
  • Fold -- In addition to foldl and foldr, there should be a folda (associative fold) that can be easily parallelized since the order of ops wouldn't matter.

More later as I go though old notes.

Infix method invocations on union instances resolve incorrectly

>> Shape << .Circle(Decimal) | .Square(Decimal) | .Rectangle(Decimal, Decimal) >>
   Shape << .Circle(Decimal) | .Square(Decimal) | .Rectangle(Decimal, Decimal) >>
>> paper :: Shape.Rectangle(21.0, 29.7)
   [.paper: .Rectangle(21.0, 29.7)]
>> paper
   .Rectangle(21.0, 29.7)
>> paper @ 0
   .Rectangle(@: 0)

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.