Skip to content

pannous/angle.js

Repository files navigation

Angle script is the browser variant of the angle programming language, interpreting a modern syntax in javascript, compiling to native webassembly.

Angle is optionally speakable:
assert two minus 1½ equals 0.5

Angle is optionally typed:
x=1;number y=π²;int y=2; assert x,y,z are numbers string s;s=3;s=="3" save, because int x=cast "3" or throw

Angle has semantic indexing:
assert 3rd word in 'hi my friend' is 'friend'

Angle does what we call matching by type name

To delete mail:
  move that mail to trash folder
end

Here 'mail' acts as argument name and argument type at once.
No more Java style Mail mail=new Mail().getMail(); never again with angle!

Angle has contextual keywords it …:

for all mails by peter: 
   if its subject contains 'SPAM':
      mark it as read 

the last example translates to ruby:
mails(by: Peter).each{|it| it.mark(:read) if it.subject.match('SPAM')}

Angle uses mark as data and code format:

cat{
    size:3
    color:{r=1 g=0 b=0}
    form{
        dimensions = (3,size*2)
    }
    eat(){
      size++
    }
    hunger{
      strike=true #local variable is basically key:value pair
      if(strike)
        size--
    }
}

All code is data and all data can be 'executed': cat.eat().dimensions is (3,8) normal cat.size=5; cat.dimensions=(3,size*2) bound but not yet evaluated cat().dimensions == cat.dimensions() is (3,10) innovation

classes are maps of keys/names to properties/fields/functions/variable-references! symbols are names to references maps are lists of pairs (duples), implicit triples: (index,name?,value?) lists are maps of index to value g = “I'm a global” hash={ 1 to 'a' 2 : 'b' # careful with ints as keys! var c = '3' d = '4' # no need for 'var': keys are local variables by default global e = 5 # relatively ugly by design set f = 6 g = 7 # hmmm ... if(g>6) kill! #only invoked when hash! is invoked 8:return 'blocks are just maps of (hidden) line-numbers to statements goto 2 # oh yes;)

} hash() e == 5 f // error, not predefined g == 7 // now ok, but before??

internal block representation of hash == [ (0,1,'a') (1,2,'b') (2,c,'3') (3,d,'4') (4,e,5) # where are modifiers? global(e) wrapper? (5,ø,set(f,6)) (6,ø,if(g>6,kill!)) (7,8,return) ] hash[2]==hash.c=='3'

constant data is evaluated ('reduced') immediately.

These are the basics, some future refinements can be read [[later.md]]

Speakable lisp with less parentheses, brackets and optional sigils [({;$})] inspired by XTalk

everything acts is an expressions everything acts is an object

unified architecture combines blocks and lists and maps:

blocks {x+y,x>1} {1,2,3} are evaluated lazily

lists or tuples are evaluated immediately x=2;[1,2,x+x]==[1,2,4]

blocks are evaluated when used x=2;{1,2,x+x}==[1,2,4]

Why? simplicity is good in itself

maps look different to JavaScript!

(a:1,b:2,c:3)
(a=1,b=2,c=3)
{a:1,b:2,c:3}  // evaluated lazily, as ”code“!
(a,b,c)==(0:a,1:b,2:c) // like js 'objects'
(a,b,c)==[a,b,c] iff a,b,c are constant

blocks can be applied to blocks or evaluated via 'argument' maps:

a={x+x}
b={x=2}
c=(x=2)

a(b)=4
a(c)=4
a(x=2)=4
a{x=2}=4

blocks can be defined via ':='

a:=x+x
b={x+x}
a == b

when applying blocks all variables must be bound via context or arguments:

a(y=2) undefind / error unless x is available in the context
a(2) undefind / error unless 'it' keyword in block
a[2] acts as selector, not as evaluator !

the arguments of the cooling block can be accessed by name or number or 'it'

{print b}(a:1,b:2) == 2
{print $b}(a:1,b:2) == 2
{print $1}('a','b') == 'b'
{print it*2}(2) == 4

methods get evaluated immediately without brackets

to test:
    print 'ok'
test == 'ok'

methods can be (de)referenced via proceeding 'to' keyword, similar to #symbol in ruby or method.name in python

my_result=test // 'ok', invoked
my_funk=to test // the method

methods are passed as symbols to functions that expect acts or blocks

bigger = { $1 > $0 }
to sort array by block{…}
sort([3,2,1],bigger)
to act in number n seconds:
    sleep n
    act

what is the difference between functions, blocks, methods and acts? None really, just different names for synonyms.

keep in mind that blocks can be parameterized with arguments (see above). those are usually called methods or functions but that's just convention.

one nice way to think about 'blocks' is that they are blocking execution until needed:

x=2
a=x+x // eval on the spot
b:=x+x
c={x+x}
d={x+x}()

a == 4
b == ${x+x} == 4  // soft symbol
c == {x+x} // symbolical
c() == 4
d == 4

x=3
b == 6 // eval on the spot
c() == 6
e=(x=5){x+x}
e == 10
e(1) == 2

optional arguments give strictness to code

f=(){x+x}  error x is neither an argument nor a global
f2(){x+x}  error x is neither an argument nor a global
g={x+x}  // ok for now

all objects can act as classes (like js, really?)

x={a:1}
y extends x
y.a == 1
y.b = 2

Circle={number radius,area:radius*radius}
Circle(radius=3).area == 9 # no 'new'

Preferably '=' should be used for leaves and ':' for nodes with children. color=blue color:{blue dark} As in js, even lists and entity/maps can be unified:

[a b c]={1:a 2:b 3:c}
{a:1 b:2 c:3}=[a:1 b:2 c:3] // todo hash as list of pairs as in kotlin
{a b c}=[a b c]

A list is just a special entity/map in which its keys are numbers A map is just a special list in which its entries are pairs.

About

javascript version of the angle programming language

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published