brendanberg / l Goto Github PK
View Code? Open in Web Editor NEWThe L Programming Language
The L Programming Language
>> {{ (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)
I started working on EBNF grammar for an L parser. For now, it's living in a private gist: https://gist.github.com/870fa50bc860951bf2b5
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]
>> 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'
The transcript below should raise a MatchError
instead of silently ignoring the second elipsized identifier.
>> [0, f..., g...] :: [0, 1, 1, 2]
[.g: 2, .f: [1, 1]]
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]
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:
__init__
method from the original example, since we are populating the hash map with the contents of the list being applied.console out
(or just console
?)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) }
}}
Factor's visual REPL
Mathematica's inline graphics and images
CircleCI uses yarn by default. Why not just move off of npm and over to yarn?
>> ()
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)
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
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
- month02
- day03
- hour (12h)04
- minute05
- second06
- year07
- time zone offsetThe 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
- minute06
- second007
- millisecond-0800
- UTC offsetFor example:
Just some rambling thoughts per our conversation
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
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
>> 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
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:
map
, fold
, filter
, etc.) eliminate the need for a for
statement. (Can for
even be an expression? It doesn't even make sense.)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.
The expression [a] :: []
should result in _
instead of throwing a JS TypeError.
>> 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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.