-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocs.lcpp
More file actions
799 lines (786 loc) · 24.2 KB
/
docs.lcpp
File metadata and controls
799 lines (786 loc) · 24.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
//NEED_UPDATE UNFINISHED
//comments '//' '/**/' :
//Comments word the same as in the programming language called 'C'
//single-line comment
/*
multi-line
comment
*/
//white space is not used as syntax except for separating sertain words symbols. White space is also not ignored in "strings"
//keywords & symbols :
( @ ) > \ λ $ :: < = , == === => <= . <=> { } ¬ [ ] # ; " " : ?
//blocks
()//context
[]//array
{}//object
//patterns :
//syntax pattern names:
expression
longExpression
param
params
multiParam
label
number//literal
string//literal
propertyChain
2ArgumentOperator
type
//param:
//word or symbol with an optional type
//params:
//a list of param separated by spaces and/or ','s
param
params param
//multiParam:
param
[ params ]
{ params }
//2ArgumentOperator:
+
-
*
/
**
%
&
|
^
&&
||
^^
==
===
//longExpression:
//list of expressions
expression
longExpression expression
//can be stopped by ',' or appropriate ending/starting brackets
//e.g.
( longExpression )
, longExpression
longExpression ,
//label:
//a value defined somewhere else
//references a parameter or a defined value
//propertyChain
//expression followed be a list of labels
expression . label
expression . expression
propertyChain . label
propertyChain . expression
//assignment
=
<=
=>
<=>
//type
()
[]
(@)
""
(#)
(types)
label
{params}
[types] //tuple
//types
type
types , type
//assignment
//expression (all patterns):
label
( longExpression )
longExpression expression
multiParam > longExpression
multiParam :: param > longExpression
multiParam ? > longExpression
multiParam :: param ? > longExpression
λ longExpression
\ longExpression
? λ longExpression
? \ longExpression
$ number
number
expression :: longExpression
longExpression < $ number
longExpression < label
longExpression < label $ number
property
multiParam = longExpression
multiParam => longExpression
multiParam <= longExpression
multiParam <=> longExpression
multiParam . = longExpression
multiParam . => longExpression
multiParam . <= longExpression
multiParam . <=> longExpression
multiParam ? = longExpression
multiParam ? => longExpression
multiParam ? <= longExpression
multiParam ? <=> longExpression
multiParam ? . = longExpression
multiParam ? . => longExpression
multiParam ? . <= longExpression
multiParam ? . <=> longExpression
propertyChain = longExpression
longExpression ,
, longExpression
longExpression , longExpression
( params )>
( params )=
( params )<=
( params )<=>
expression : type
()
expression 2ArgumentOperator expression
{}
{ longExpression }
¬ label
longExpression ¬ label expression
[]
[ longExpression ]
# keyword longExpression ;
# longExpression
( @ longExpression )
"string"
//lambdas '>' , 'λ' , '(a)' , 'a' :
//basic lambda calculus:
//'>' declars a single argument function;
//functions can be called by using the 'function argument' paturn
//expressions can separated using brackets '()', which also help with scoping (but that's for another section)
//everything after a lambda '>' is part of said lambda
//e.g.
f>x> f (f a>a x) (a>b>x (x a)) x
//A lambda function can be made using the 'a >' paturn or the 'λ' paturn
//pattern 'a >' :
//'>' is just like arrow functions '=>' in javascript.
//They have 1 parameter on the left and when, called evaluate the expression on the right
//Expressions are evaluated just like normal lambda calculus
//e.g.
a > a a //Y_ish combinator
f > x > f(f x) // 2
f > (f(x x))(f(x x))// Y combinator
//'λ' , '\' and pattern '$ 3' :
//Syntax similar to the De_Bruijn_index is also supported
//https://en.wikipedia.org/wiki/De_Bruijn_index
//This can be done using the 'λ' and '$3' patterns.
//The only difference from De_Bruijn_index is that we count from 0 and put a '$' before the number.
//e.g.
λλ$0 //false
\λ$1 //true
λ λ $ 1($1($ 1 $ 0)) //3
//'λ' and '\' :
//about '\' :
//'\' is interchangable with 'λ'
//'\' may be used instead of 'λ' as it is easier to find on keyboards.
//'λ' is an alternative to using '>'.
//'λ' acts almost like '>'. The only difference is that 'λ' does not have a named parameter.
//i.e. you can use 'λ' instead of 'a >'
//e.g.
a>λ a //true
a>b>a //true
λ b>b //false
a>b>b //false
//'$' :
//The parameters in '>' and 'λ' can be referenced via index using indexing.
//'$3' is the paturn for lambda indexing.
//parameter indexes are made up of s '$' followed by a number.
//Integers '2' :
//Integer literals can be used.
//e.g.
123
5
3 (x>bool>bool (a>a a) x) (a>a)//makes an array of 3 Y_ish combinators
//Can also use 0x and 0b to make integers
//e.g.
0x123
0b1101
//They can be used as church numerals, (which can be used for iteration)
//It is possible to convert regular lambda functions to Integers.
//This may be desirable since integers run faster:
//They don't take up as must stack space, since they use iterasion instead of recursion.
//and can have inbuilt optimisations
//Integer is its own data type, although they are meant to also look and act like normal lambda functions.
//regular lambda functions can be converted into integers by taking advantage of the recursion system.
//e.g.
(bool>bool 1 bool>bool 2 bool>bool 3)
53
1
//assignment '=' , '()' , ',' :
//',' :
//',' can be used to group things similar to '()'.
//','s can be used to get back to the local '()' level.
//It can be used to exit '>' and '='
//In some cases it can be used instead of '()'
//e.g.
(foo1> arg1> foo2> arg2> (a>b> foo1 arg1,foo2 arg2))
//is the same as
(foo1> arg1> foo2> arg2> ((a>b>foo1 arg1)(foo2 arg2))
//e.g.
(a>A>b>B>c>C>(a A a,b B b,c C))
//is the same as
(a>A>b>B>c>C>((a A a)(b B b)(c C)))
//Note: it is pointless to put this on the last expression
//e.g.
(a> (a a ,a))
//is the same as
(a> ((a a) (a)))
//is the same as
(a> a a a)
//e.g.
(a> b> f>x> (a, b f x)), //add
(a> a a (a, a a) a, a a),
//pattern 'a =' :
//Similar to haskell, constants can be assigned using the 'a =' pattern, where 'a' is a label for a constant.
//constants are assigned to into their local scope, only ignoring blocks created by ','s.
//This is so ','s can be used to have and use multiple assigned values in the same scope.
//e.g.
(b a b a=(x>x),b=(x>y>y a))
//Also similar to haskell, labels can be used before they are defined
//implementation:
//'a =' patterns are processed before lambda evaluation.
//When referencing a label, the value is looked for:
//First in the previous definision of a label. (excluding parent assignment patterns)
//Next in the first definision of a label within the same scope.
//Finally in the parent scope using the above 2 rules.
//e.g.
(a a a=a>a)
//errors:
//loops of label definitions are not allowed:
//e.g.
(
a = b, //recursive reference ERROR: 'a', 'b' are in a definision loop
b = a,
)
//self referencing is also not possible with this
//e.g.
(//assume this is global scope
a = a //ERROR: 'a' is not declared. This error will not happen if 'a' is defined else where.\
)
//If the same value is defined multiple times then it uses the most recent one
//e.g.
(a,a=1,a,a=2,a)
//is the same as
(1 1 2 a = 2)
//Just like '>' and 'λ', everything on the right side is part of the assignment, excluding ')' and ','
//The new label can be used anywhere in side the same '()'
//Labels cannot reference themselves in their definision.
//e.g.
(a = a) //ERROR 'a' is not defined
//Instead, a Y combinator can be used for self referencing.
//Note that the 'a =' pattern is ignored from the final code, and so can be put in the middle of lambda expressions without affecting them
//Note using multiple 'a =' without ',' is possible:
//multiple values can be assigned
//e.g.
(((add > add a b) b = 2) a = 1)
//e.g.
(four (a>b>b a a) four = 2 2)
(true = a> b> a)
(//note that this
++ = a> f>x>f(a f x),
a = 1,
a = ++a,//2
a = ++a,//3
)
//'()' :
//This pattern is also known as a context or a block scope.
//Contexts can contain a single main lambda function and labels inside it.
//If no lambda is pressent then the context will through an error if it is called.
//e.g.
() a>a //ERROR cannot call a context
//They can contain their own labels.
//These scopes are also made by other patterns such as 'a = ...' and 'a> ...'
//e.g.
const_four = (a>b b) b=2,//Here the 'b' value only exists inside the context of the first '='.
//is the same as
const_four = ((a>b b) b=2),
//e.g.
(a = 2, a> a, b = 3, a)//Y_ish combinator with 2 extra labels
(a = 2,\ a b,b = 3)
square = (x> two x two = f>x>f (f x))
//using the syntax together we can make block scopes
//e.g.
(
a = 2,
b = a,
a = pow a 3,
a = add a b,
(n> a n),
add = a>b>f>x> (a f, b f x),
pow = a>b>b a,
)
//assignment types '<=>' :
//Operator choices '<=' '<=>' '=>' :
//These are a list of notes to help remember which operator does what.
//The '=>' arrows point towards the value that is added to the blocks return value.
//'a <= b' adds the property 'a' to the final value, because it points towards the label.
//'a => b' adds expression 'b' as an argument onto the final value, because it points towards the expression.
//'a <=> b' adds both the label 'a' and the expression 'b' because it points to both arguments.
//'=>' use and define
//e.g.
(a => 2)
//is the same as
(a = 2, a)
//'<=' define public label
//e.g.
obj = (a<=2),
obj.a,//2
//public labels are assigned to the output of a block
//e.g.
foo = ((a>a a) a<=2),
foo.a,//2
foo 3,//27 (because 3^3=3*3*3=27)
//'<=>' use & define public label
//e.g.
two = number <=> 2,
twoSquared = two two.number,
//operators:
//symbols
+ - * / ** %
++ --
& | ~ ^ >> << >>>
>= != (<=)
!
&& || ^^
<- -> (<->)
(>) (<) (=) (==)
//equallity '==' , '===' :
//'==' :
//checks if 2 lambdas as combinators are the same. Also checks types
is0 = n>n==0,
//'===': checks if 2 lambdas are the same reference.
//can be used to check to see where a lambda comes from.
//note that the raw, normal functions can be obtained by putting symbols in brackets on their own.
//This may be done to use symbols such as '>' as an operator instead of a lambda declaration.
//This may also be done to use operaters as normal functions
//e.g.
add = a>b> (a (++) b)
//is not the same as
not_add = a>b> (a ((++) b))
pow_increment = a>b> (a ++b)//(b+1)**a
//is the same as
same_pow_increment = a>b> (a (++b))
//Operators are special type of variable since they can be used for infix operations
//Different operators have different priorities for when they are evaluated.
//These operators are evaluated before any function calls
//Being labels they can be used as parameters.
//Operators have default values which are the operations one would expect in other languages
//e.g.
//polyfill for 'add'
//note this code wouldn't work as self references for '(+)', can't be done directly.
+ = floatA> floatB>(
a = floatA,
b = floatB,
a == () (b == () (+)(b > (+) [a b]))
(b == () (a > (+) [a b])
(//a and b exist
//test for operator overloading
a.[+] ==
)
)
),
//pattern 'a + b'
//e.g.
a + b,
(||>sub>|| 4,sub 5 2)(+)(-),//(4 + (5 - 2)) = 4 + 3 = 7
add_5 = +5,
add = +,
3_sub_x = 3-,
hypot = a>b>a*a+b*b,
a * a + b * b
//custom operators '¬=' :
//Makes a custom infix operator value.
//These labels are special since they are infix.
//Custom operator cannot presserve their operator status if passed into a function.
//e.g.
(
add ¬= [a b]> f>x> a f (b f x),
1 add 3,
)
//arrays '[]':
//pattern '[ ]' :
//Works similar to a '()' block except the first expression isn't used as a function.
//Instead all expressions are joined together into an array.
//implementation :
[11 22 33]
//is the same as the pure lambda function
endOfList > bool > bool 11 bool > bool 22 bool > bool 33 endOfList
//However '[ ]' has the array type and can be optimised more by the compiler.
//concatnation
//Arrays can be combined by using '*'.
//This is because '*' can be written as 'a>b>f>a (f b)' which can concatnate this array type
//e.g.
[1 2] * [3 4]
//returns
[1 2 3 4]
//indexing:
//can use 'array.number' or 'array.[label]'. This is the same system used for retreaving properties from objects.
[11 22 33].1 //22
[11 22 33].[1 + 1] //33
//Arrays are it's own datatype.
//Arrays have the array properties as pecified later on
//note:
[a b c]
//e.g.
[1 2 3]
[1 [2 3] 4]
[1] * [2] * [3]
push = array > item > newArray => array * [item],
//meta&non-meta '#' '@' '""' '[]' :
//pattern '# ... ;' , '#( ... )' , '(# ...)':
//end with a ';', an appropriate closing bracket or contains a single bracket.
//These brackets can be of any kind.
//The
//Defines a meta block.
//The functional syntax applies in these blocks.
//array types [], "", '@':
//';':
//';' is similar to ',' except ';' also exits all '#' and '@' scopes, into the local blacket scope.
//strings '"a"' :
//similar properties to an array
//can use "" '' `` for strings
//characters in strings can be escaped with backslashes
//e.g.
"\"123\"\nab\c"
'123'
//pattern '@ ... ;' , '(@ ...)' :
//Defines a block of non-meta code.
//The block is then stored as a tree (similar to '[]') containing non-meta values.
//Since the syntax tree system is the same with the meta code, all the white space is removed (i.e. abstracted away), and is added back towards the end of compilation.
//These non-tree values are similar to strings
//Default white space rules for (@).toString():
//- Spaces are added between everything.
//- New lines are added after every ';'
//'@', '$', '#' can be done as non-meta code by using '\@','\$','\#'.
//concatnation rules:
//If 2 non-meta blocks are joined together then extra white space may be added to make sure words & symbols don't join.
//otherwise If a string is joined with a non-meta block or another string, then no extra white space is added to the final code.
//The resulting type os the same as the type of the function (string or non-meta block) being called.
//properties:
//length
//depth:
//Returns the recursion depth of a tree.
//Always returns 1 for a string.
//array methods:
//reduce
//map
//mapRecur
//toArray:
//converts assembly to a array tree
//converts string to a list of strings of length 1
//toString
//toAssembly:
//can convert array trees or parse strings into assembly syntax trees
//group:
//e.g.
["a" "A" "," "b" "B" "," "c" "C"].group ","// [["a" "A"] "," ["b" "B"] "," ["c" "C"]]
//same as
("", (@a a,b B,c C).group ",") //
//split
//splice
//flat
//array/object parameters '[ ]>' :
//pattern '[a b c]>'
//e.g.
[1 2 3].map [v i]>i v,
//is the same as
[1 2 3].map a>a.1 a.0,
([a b]> a b) [1 2 3],
//allows a function to take in parameters from an array or object
//This functionality could be done without using this syntax
//e.g.
[1 2 3].map (a>(v>i>i v)a[0] a[1]),
//array/object assignment '[ ]=' :
//pattern '[a b] = '
//e.g.
[a b] = [1 3],
//is the same as
a = [1 3].0,
b = [1 3].1,
//pattern '{a b} = '
//works similar to '[ ] =' except with namespaces instead of lists
//'[ ] =>' and '{ } =>'
//These pattern 'multi assign and use as code' return a new expression based on the left side of the '='
//e.g.
(
[a b] => [1 2 3],
//is the same as
[a b] = [1 2 3],[a b],
)
//assigns multiple labels at once.
//In the case where the appropriate datatype is not provided, or the properties/indexes don't exist on the array/object, then the labels are assigned the null value '()' aka empty context.
//e.g.
[a] = [],//a == ()
[a] = (a>a),//a == ()
//e.g.
[a b] = [1 3].map [v]>f>x>f(v f x),
//reassignment '.='
//UNFINISHED: It is unsertain what symbol should be used for this pattern. '.=' is a good place holder, although it may become part of the final syntax design.
//More general version of 'a+=b' in other C-like languages
//Similar to the assignment patterns except it calls the right side expression with the left side label.
//e.g.
(a>b>
a .= x > x - b,//r = f>a>b>f b a
a + 2
)
//is the same as
(a>b>
a = (x > x - b) a,
)
//This can be done with the other assignment patterns such as: '[ ]=' , '{ }=' , '=>' and '<=>'
//e.g.
a>b> [a b].=> [x0 x1]>x0+x1
//using & with '( )>' '( )=' :
//using '( )>' :
//this pattern takes in a list of label refences on the left and an expression on the right.
//This pattern does not change how the code functions, only allows for performance gains and can throw errors from undefined labels.
//These contain a scope on the right side of the '( )>' expression
//"using" blocks can not use any parameters or labels defined outside them.
//The only outside labels that can be used are the ones given to them inside the '( )' part of the '()>'
//pattern '(a b c)>' :
//They are useful for making functions even more contained or limiting what mutable values are allowed inside a function
//e.g.
(a> b> (a b)> a, b)
(a> b> (a)> a, b)//ERROR: 'b' is not defined. The 'b' outside cannot be reached
(a?> b?> (b)>b)
()>(
add5 => (add)> a> add a 5,
add = a>b>f>x>(a f,b f x),
((state1)>
set1 = value?>state1.a?=value,
get1 = ?λstate1.a,
get1_atAState = ?λ
λstate1.a,//This pure function does not need to copy 'state2' since it can't be accessed inside the use block
get_first_value = value>state1.a,
)
state1?=(a<=1),
state2?=(a<=1),
)
//with '( )=':
//note this pattern can not come after a '.' since what would conflict with the 'a.[b]' syntax.
//Gets all the properties of the objects in the '( )' and uses them as local values in the inner scope.
//pattern '( )= ' :
//e.g.
((a<=1,b<=2,+<=a>b>f>x>a f (b f x)))= (+) a b,
//The source of all non-property labels should be known at 'label compile time'
//all the labels definitions and references throughout the entire program are worked out before any functions are evaluated.
//An error will be thrown if the input to a with pattern is not knowable before any lambdas have been evaluated.
//This means that the following cannot be put inside a with pattern:
//1. lambda parameters
//e.g.
(
a>
(a)=f>x>x//reference ERROR: label 'a' references an object that is not known before the lambda evaluation phase.
),
(
a> b>
foo = (a a,b<=2),
(foo)=f>x>x,//this still throws a similar error since 'foo' uses properties in 'a' that are not known before lambda evaluation phase
),
(
a> b>
foo = (\a a,b<=2,c<=3),
(foo)=f>x>x,//This is legal code since all the properties of foo ('b' and 'c') are knowable even without knowing the values of parameters 'a' and 'b'.
),
//Alternatively '( )<=' can be used to make all the labels public and assign them to the final expression.
//This one does not have the error that comes with '( )=' as it's properties are not evaluated before the expression is.
//This can be used to join objects together
//e.g.
joinObjects = objA>objB> (objB)<=objA
//e.g.
//To use operators inside a use statement, they must be parsed into it.
//In a '()=>' this can be done by passing in any operator into it.
//e.g.
//e.g.
()>1+2, //reference error: '+' cannot be reached inside the use block.
(+)>1+2, //no error
(*)=>(a>a)1+2,//no error. returns '(+ 1 2)'
//e.g.
(add>
obj = (a<=1,b<=2,c<=3),
(obj) = add b c, //5
(obj) <= a>a a, //(a>a a a<=1,b<=2,c<=3)
)(a>b>f>x>a f (b f x)),
(
obj = (
{a b c},
a<=1,
b<=2,
c<=3,
),
(obj)<=λ$0 b c,//([a b c]<=[1 2 3],λ$0 b c)
(obj)= λ$0 b c,//(λ$0 2 3)
),
//the two types of blocks can be combined 'use with' '( )=>' and 'use with as public' '( )<=>'
//both blocks use the same syntax rules as '( )='
//e.g.
(a=2,b = {c<=(a>a)},(b)=>c a)//throws an error since a cannot be reached outside the '( )=>' block
//note: It may be useful to use both a '( )>' followed by a '()='
//e.g.
(state)>(state)=
//type system & properties '{ }' :
//tuples '{ }' :
//{} marks a struct. it contains a list of labels that represent item numbers in a tuple.
//type annotations ':' :
//using ':' symbol
//Can be put a type annotation infront of a pattern to make sure labels and expressions have sertain types.
//pattern ': type'
//e.g.
//basic types:
//array '[]'
//lambda 'λ' or '\' //This includes every object
//null '()'
//context '{}'
//string '""'
//assembly block '(@)'
//meta block '#'
//number '0'
//can be mutated '?'
//can mutate state '?'
//e.g.
a:{} = {prop <= f>x>f(f x)},//strongly typed label
a:[] > a.0 + a.2,//typed function
//impure patterns '?' :
//mutable '?':
//The patterns used for mutations are:
//'a ? =' : Making a mutable object.
//'a?>' or '?λ' : A function that allows mutating properties.
//mutating 'a.b ? =' : Actuall mutating of existing properties.
//note: 'a.[ ] ? = ' : is allowed and mutates existing properties.
//Mutating: can not be used inside a pure function. Can only be used in global or scopes that allow mutating objects.
//e.g.
//In order to mutate something both the mutator and the mutatee must both allow for mutations.
//Rule: Once inside a pure function the state is set and even calling mutable functions doesn't change the state in the pure one.
//'#' and global scopes are impure by default.
//Note: properties can be mutated not labels directly
//Note: new mutable properties are NOT allowed to be added using the mutable operator.
//e.g.
#(
a ? = {b=2},
? \ (
getFoo = a?>a.b,
getFoo,//returns 2
a.b?=3,
getFoo,//returns 3
)
\(
,
a.b?=3
)
)
//blocks types :
(1 2 3), //normal block
[1 2 3], //array block
{a=1,b=2,c=3} //object block
//inbuilt object 'global' :
//'global' is an object that contains things that allow the language to interact with other systems, such as IO, or log to the console.
//Here is some pseudocode for a polly-fill of 'global':
global ? = {
do ? <= a ? > b ? > a,//all functions that would otherwise return `void` instead use this structure.
log ? <= do,
import <=,
},
//'do'
//This function is for
//e.g.
{input} = global;
//tests
#helloWorld = (
print (@r0)(λλ$1) "hello world",
print = reg>regIs0>str> (
regIs0 (reg (@ = 0;))"",
str.map [v]>(@send)reg v,(@;)
),
(
print = print(@r0)0,
print "hello world",
),
(λ@let print(reg,is0,str){
repeat !!is0:%reg=0;
let i=0;
repeat {@;
send %reg str.[i];
#i+=1;
}
})
);
#var = (
a>a a,
(self_class>
self = self_class self_class,
static>λ(self, static @0)
),
);
#classes=(
Z = f>(a>a a)(x>f(λ x x)),
monads = ((Z)>
Monad = monadFoo>Z (//Monad:<value>λZ()
//monadFoo:λλvalue
self>//:Monad
x>//:value
foo>(//:λvalue
foo == (), x,
self λ$0,monadFoo foo x
)
)λ$0,
maybe = Monad f>x>
(x == null)
()
(f x)
null = ()
,
(λmaybe 2,
x>x.a,
x>x.b + 2, //λ$0.b + 2,
x>x.c,
x>x.d<$1,
)(λ $ 0)
),
Y_combinator = (
Y = f>(a>a a)(x>f(x x)),
(
Lazy = f>x>f x,
(
(
(
(
(
(
x>(is0 x 1,f,--x)
f = (Lazy\x x)
)
)
x = x>f(x x)
)
(Lazy\--x)
)
x = 3
)
f = Lazy \x x x = x>f(x x)
)
f = f>x>(is0 x 1,f,--x)
)
),
class = f>Z f λ $0,
vec2 = class vec2>(//Vector2:Class
x>y>(//
get <= (
x <= x,// main λλ$1,
y <= y,// main λλ$0,
main => main λλ$1,
),
set <= (
x <= v>vec2 v y,// main λλ$1,
y <= v>vec2 x v,// main λλ$0,
main => main λλ$0,
)
main => get_set>x_y>
get_set
(x_y x y)
(x_y (val>vec2 val y) (val>vec2 x val))
,
),//[get=>[x y] set=>[x y]]
),
vec2 1 2
);