Skip to content

inventions

pannous edited this page Apr 24, 2024 · 39 revisions

Adoptions

Not new inventions, but cherry-picking the most beautiful, powerful and sane features of other modern programming languages, especially Julia, Swift, Crystal and Kotlin but definitely not Java. Those adoptions include it keyword in closures, multiple dispatch, optional typing, self hosting (secondary goal to not bias language design)

Match by type name:

Merge the concept of type and variable (name) in simple functions:

To assign a photo to a contact:
contact.image = photo

Here both photo and contact act as matching types and as variable identifiers. What sounds pretty complicated is very obvious in code (see above).

The precise semantics of the above function can be specified later, for example by declaring a photo is an image given maybe image type is UIimage

As in other languages, class types are capitalized (not just by convention)

(In cases of ambiguity) one can explicitly access types as such:

image.kind = Photo
image.kind = photo type
image.kind = type of photo

type of photo resolves to Photo type regardless of whether a photo variable is in context or not.

Consistent grouping

newline groups harder than semicolon, therefore one liners like suffix operator ⁿ := c=it;while n-->0 : c*=it; c don't need braces.

Of keyword

Inverse dot: a.b is b of a
Also works in assignments and definitions:
square of number = it*it
Which is just the bracket less version of: square(number) = it*it

In fact this is the preferred way to define (property) methods out of scope. In scope it would look like this:

Smart scopes

Number {
 Square = it*it
}

Todo it ambiguity in nested scopes

Typed iteration

In contemporary dynamic programming languages there is often uncertainty what exactly a for loop iterates over:
for(x in y) or for(x of y) can mean:

for key in map: print it
for key, value in map: print key 
for pair in map: print pair.key 

Thus in angle loop iteration takes type hints:

for each byte in "Hello" : print byte
for each char in "你好" : print char
for codepoint1 in "你好" : print it

//how? simple: each takes a type as polymorphic argument:
string{ 
each(byte){return ...}
each(char){return ...}
each(grapheme){return ...}
}

x in y is an alias for y.x to access properties and functions. for is a function that takes a list or an iterator and a block: for(list, block):=i=list.size|while (i-->0) block(list [i])

Indexing by #number

Angle has the goal to be maximally welcoming to beginners,
yet mathematically sound and compatible to old programming languages where possible. Thus
{1 4 9}#3 is 9
which is identical to old style 0-based indexing
nums={1 4 9};nums[2] == 9

It keyword

The it keyword in closures was a great invention ( first seen in Kotlin?) we extend this to much wider user cases, in fact it becomes the catch all keyword for the current object, variable or result; where Julia has ans etc.

square of number = it*it

Often it is identical to this/self unless there is another object in scope, in which this/self are to be used. What might seem slightly complicated comes very naturally when applied.

In cases where there is an ambiguity we have

Compile time ambiguity resolution

Instead of throwing a compile error when faced with ambiguities, the compiler simply asks for the intended meaning and, if desired, writes that resolution to a cache, to a comment or even back to the source code.

To keyword

'to' keyword to define verb functions

To square a number: return it times it

Code completion on dispatch methods

To square a number: return it times it

3.squ<tab>
3.square is 9

Code completion on dispatch arguments

To square a number: return it times it

x is number 3
square of <tab>
square of x is 9

Keywords

Reserve all pronouns propositions and particles as Keywords Once a word is defined as class it becomes a semi keyword in that properties/methods get assigned to the class:

Integers are numbers
Number a = 3
square of number = it*it

Dangling symbols

In data, lists and certain execution contexts, symbols don't need to be quoted:

person {
  name: James
  age: 35
}

This format is more pleasant than json yet free of ambiguity

Indexing with '#'

Colors = red, green, blue
Color#1 is red

Indexing with 'in' 'of' 'from'

friends = { peter{wife:jule} karl{existent:false}}

  • peter from friends == friends[peter]
  • peter of friends == friends[peter]
  • peter in friends == friends[peter]
  • friends.peter == friends[peter]

Gap filling

Gap filling : Use local variables as missing arguments to functions

f(x):=x*x
x=7;f() # 7

Gap Feeding

Gap Feeding of missing arguments with locals in function calls

to integrate a function from a to b ...
from = 1
to = 2
integrate sin  # feeds locals as arguments

Bad idea?

universal in-place assignment

Each operator automatically works with assignment: x ⊛= b is always a shorthand for x = x ⊛ b.
If x was not mutable an error occurs at compile time.

plural

Since Angle is inspired by English, each type declaration generates a plural form with tailing 's': number => numbers==number[]==[number] (swift style)

's keyword: peter's friend == friend of peter == peter[friend]

universal broadcasting

All functions are automatically broadcasting on lists and pair values:

square number=number*number
square [1 2 3] == [1 4 9]

square [a:1 b:2 c:3] == [a:1 b:4 c:9]

delete file = run `rm $file.name`
delete files in ls /   # 🧐

Use allall keyword and polymorphism if fine-grained behavior is required:

print numbers = print "one at a time please"
print number  = printf("%d",d)

print [1 2 3] = "one at a time please"
print all [1 2 3] = "1" "2" "3"

Context sensitive is '='

In angle the is operator acts as assignment/declaration unless it appears in a condition or expression: a=123 if a=123 print "ok" print a=123 // true

transparent mutations

mutating modifying member functions are to be suffixed with an exclamation point (by the linter?)

class string{
  data chars
  void upper!{
    chars[0]=chars[0].upper()
  }

variables can be force mutated by adding an exclamation point

x="test"
x.upper! 
# same as x = x.upper()

The result of pure functions must be used or explicitly assigned to '_' as in rust.

Home

Philosophy

data & code blocks

features

inventions

evaluation

keywords

iteration

tasks

examples

todo : bad ideas and open questions

⚠️ specification and progress are out of sync

Clone this wiki locally