{lambda {www} factory} - λ way 2 .fr

Feb 18, 2018 - Software and its engineering~Functional languages. • Software and .... :a :b :c}}}. Now TREEs and LISTs can be automatically displayed. {def TREE. ..... an embedded spreadsheet[10] understanding {lambda talk} expressions.
1MB taille 2 téléchargements 47 vues
am +

{lambda {www} factory} Alain Marty Engineer Architect Villeneuve de la Raho, France

[email protected]

ABSTRACT The {lambda way} project is a web application built on two engines, {lambda talk} and {lambda tank}. {lambda talk} is a purely functional programming language unifying authoring, styling and scripting in a single and coherent Lisp-like syntax, working in {lambda tank}, a tiny wiki built as a thin overlay on top of any web browser. In this paper we progressively introduce the making of {lambda talk}.  We define a reduced set of rules [abstraction, application, definition] working on words as the foundations of {lambda talk}. Upon this invariant set we build data structures (pairs, trees, lists) and recursion constituting a first subset called {lambda word}. As an application we build a second subset called {lambda number} where natural numbers are defined as lists and their associated operators as recursive processes. Then, taking benefit of the powerful capabilities of modern browsers, we build a third set of primitives leading to {lambda web}, a programming language for the web. Finally we quickly show some extensions making {lambda talk} a programmable programing language on the web.

KEYWORDS • Information systems~Wikis • Theory of computation~Regular languages • Theory of computation~Lambda calculus • Software and its engineering~Functional languages • Software and its engineering~Extensible Markup Language

INTRODUCTION A wiki[1] is a web application which allows collaborative modification, extension, or deletion of its content and structure. Following the first wiki created in 1995 by Ward Cunningham[2] hundred of wikis have moved us fom simple consumers to creators of sharable informations. But these tools come generally with rather rudimentary and heterogeneous syntaxes to enter, enrich and structure texts. {lambda tank} comes with a true programming language, {lambda talk}, allowing not only to enter, enrich and structure text, but also to write code. Computer languages are generally introduced from a long enumeration of their syntaxic rules and via numerous examples. We can learn how to resolve problems not to understand the way languages have been conceived. There remains a great deal of mystery which can only be lifted by those who have had access to their fabrication. In order to  avoid grey areas, magical functions, abstract concepts, we are going to introduce {lambda talk} from the most elementary bricks. Nothing but words to assemble and

compose, which could theoretically be manipulated by hand, without any computer. So: • 1) we begin to define the smallest and strongest infrastructure on which can be built different superstructures leading to a programmable programming language, • 2) {lambda word} is an ultra-light superstructure gently introducing pairs, trees, lists and recursive processes working on words, • 3) {lambda number} is an extension of {lambda word} introducing natural numbers and their associate operators, • 4) {lambda web} is a more efficient superstructure taking benefit of the powerful capabilities of modern browsers and coming with an extended set of primitives (Math, HTML/CSS, SVG, ...) and libraries (big numbers, spreadsheet, graphics, ...). Let's introduce the foundations of {lambda talk}.

1. {LAMBDA TALK}'S FOUNDATIONS Imagine a machine understanding this question: replace "fruit" and "unknown"        in "The color of fruits is unknwon."        by "apple" and "green" and returns The color of apples is green. {lambda talk} is such a replacement machine where this question is formulated using a slightly different syntax: {{lambda {fruit unknown}             The color of fruits is unknown.}             apple green} This rather strange syntax is freely inspired by the {λ calculus}[3] created in the 1930s by Alonzo Church and uses the LISP Sexpressions introduced by John McCarthy in the 1950s[4]and used by all its dialects, ie SCHEME[5]. In {lambda talk} a valid expression is made of a reduced set of nested terms, [words,abstractions,applications] and is evaluated to words. More precisely: 1. a word is a group of any characters  except spaces and curly braces {}, and is 

not evaluated, 2. an abstraction, a special form written  {lambda {words} expression}, is evaluated  to a word referencing an anonymous function  selecting words (arguments) in expression  (body) to be replaced by some future given  words (values), 3. an application, a nested form written  {expression1 expression2}, first evaluates  expression1 to the reference of an  abstraction and expression2 to words2, from  inside out. This abstraction replaces its  arguments in its body by the given words2  and returns some words3, For convenience a second special form, definition, is added: 4. a definition, a special form written  {def word expression}, returns word (the  name) bound to expression (first evaluated  to words) in a dictionary initially empty. Abstractions and definitions are special forms evaluated in a call by name lazy mode. They can be nested. Applications are simple forms evaluated from inside out, in a call by value eager mode. Functions don't create closures but accept de facto partial calls, memorizing the given values and returning a new function waiting for the rest. It may be interesting to know that in {lambda talk} replacements of simple forms {first rest} are made through a window built on a single Javascript line while (code !=     (code = code.replace( regexp, apply))) ;

{{lambda {fruit unknown}            The color of fruits is unknown.}            apple green} partially replaces the first argument fruit by the value apple, generating the new call {{lambda {unknown}             The color of apples is unknown.}            green} replacing the second argument unknown by the value green, resulting in The color of apples is green. It's partial application made easy, nothing magic there! Everything could be done by hand, at least theoretically or, more seriously, can be coded and tested on any modern web browser, thanks to this small IDE, {lambda tank}. Nothing but words, abstractions and applications, and an empty dictionary! We are very close to the process translated in the 1930s by another student of Alonzo Church, Alan Turing[18], into the shape of an hypothetic machine made of a window and an infinite stripe.

With such an implementation and a reduced set of rules we have built the foundations of a Turing complete programming language, {lambda talk}. Let's explore some of its capabilities.

working on a single regular expression[17] regexp =      /\{([^\s{}]*)(?:[\s]*)([^{}]*)\}/g   following the syntax of a language created by Stephen Cole Kleene[7], a student of Alonzo Church. This is what Ward Cunningham wrote about this implementation: « I was surprised that the technique worked so well in so many cases. I knew that regex are highly optimized and the cpus themselves optimize sequential access to memory which the regex must have at its core. [..] Yes, this has at its heart the repeated application of a text transformation. The fact that it is repeated application of the same transformation makes it exceptional. [..] Repeated application of Regular Expressions can perform Touring Complete computations. This works because the needed "state" is in the partially evaluated text itself. » All is said! These regular expressions are also at the heart of lambdas which are nothing but machines to replace words by other words. Lambdas use arguments as regular expressions to successively replace occurences found in the function's body by the given values. For instance the expression

2. {LAMBDA WORDS} 2.1. basics Out of braces words are not evaluated. Quoting sequences of words is useless. Hello World   ­> Hello World Sequences of words can be given a name {def HI Hello World}   ­> HI  HI, I just say {HI}   ­> HI, I just say Hello World Note that writing HI displays HI. You must write {HI} to get its value, Hello World. Anonymous functions can be created and immediately called

{{lambda {fruit unknown}    The color of fruits is unknown.}      apple green}  ­> The color of apples is green. Anonymous functions can be given a name {def AFFIRMATION   {lambda {fruit unknown}    The color of fruits is unknown.}}  ­> AFFIRMATION  {AFFIRMATION apple green}  ­> The color of apples is green.  {AFFIRMATION banana yellow}  ­> The color of bananas is yellow.

2.2 data structures Lambdas can be nested and partially called, allowing to build data structures and their associated selectors, beginning with PAIRs {def PAIR {lambda {:x :y :z} {:z :x :y}}}     ­> PAIR  {def LEFT {lambda {:z}    {:z {lambda {:x :y} :x}}}}    ­> LEFT  {def RIGHT {lambda {:z}    {:z {lambda {:x :y} :y}}}}   ­> RIGHT  {def AP {PAIR Amélie Poulain}} ­> AP  {LEFT {AP}}    ­> Amélie  {RIGHT {AP}}   ­> Poulain A TREE is any combination of PAIRs. Note the lack of ending characters. {def FOOD   {PAIR     {PAIR fruit     {PAIR Apple           Banana}}    {PAIR vegetable     {PAIR Broccoli            Asparagus}}}}  ­> FOOD  {LEFT {LEFT {FOOD}}}         ­> fruit  {LEFT {RIGHT {LEFT {FOOD}}}} ­> Apple A LIST is a special combination of PAIRs list = {pair a {pair b ... {pair z \}}}  // the ending character \ can be any word  {def VEGETABLES   {PAIR broccoli 

  {PAIR asparagus \}}}   ­> VEGETABLES  {def FRUITS   {PAIR apple    {PAIR banana     {PAIR lemon      {PAIR grapes       {PAIR orange \}}}}}}   ­> FRUITS  {LEFT {VEGETABLES}}         ­> broccoli  {LEFT {RIGHT {VEGETABLES}}} ­> asparagus Note that a LIST is nothing but a complete unbalanced TREE. The next step will be to automatically display the elements of TREEs and LISTs. Here comes recursion!

2.3. recursion In a recursive process a function calls itself until some ending condition is reached. We need a predicate function testing this condition and add to the dictionary, initially empty, a single primitive function word? returning [LEFT|RIGHT]. {word? Apple}    ­> LEFT      // true  {word? {FRUITS}} ­> RIGHT     // false Thanks to this predicate function, PAIR data structures and lambdas introducing some lazy evaluation, we will build recursive processes following this scheme {def RECURSE   {lambda {:a :b :c}    {{{word? :a}        // if :a is a word     {PAIR      {lambda {:a :b :c} do ending case}      {lambda {:a :b :c}        {do something with :a :b :c}       {RECURSE on {RIGHT :a} and :b :c} }    }} :a :b :c}}} Now TREEs and LISTs can be automatically displayed {def TREE.DISP   {lambda {:t}    {{{word? :t}     {PAIR      {lambda {:t} :t}           {lambda {:t} ({TREE.DISP {LEFT :t}}                    {TREE.DISP {RIGHT :t}})}    }} :t}}}  ­> TREE.DISP  {def LIST.DISP   {lambda {:l}    {{{word? :l}     {PAIR      {lambda {:l} } // ending char omitted      {lambda {:l} {LEFT :l}                   {LIST.DISP {RIGHT :l}}} 

  }} :l}}}  ­> LIST.DISP  {TREE.DISP {AP}}   ­> (Amélie Poulain)  {TREE.DISP {FOOD}}   ­> ((fruit (Apple Banana)) (vegetable  (Broccoli Asparagus)))  {LIST.DISP {FRUITS}}   ­> apple banana lemon grapes orange We can reverse and append LISTs {def LIST.REVERSE   {lambda {:a :b}    {{{word? :a}     {PAIR      {lambda {:a :b} :b}      {lambda {:a :b}       {LIST.REVERSE {RIGHT :a}                     {PAIR {LEFT :a} :b}} }     }} :a :b}}}  ­> LIST.REVERSE  {def LIST.APPEND   {lambda {:a :b}    {{{word? :a}     {PAIR      {lambda {:a :b} :b}      {lambda {:a :b}       {LIST.APPEND {RIGHT :a}                    {PAIR {LEFT :a} :b}}}    }} :a :b}}}  ­> LIST.APPEND  {LIST.DISP {LIST.REVERSE {FRUITS} \}}   ­> orange grapes lemon banana apple   {LIST.DISP {LIST.APPEND {LIST.REVERSE  {FRUITS} \} {VEGETABLES}}}  ­> apple banana lemon grapes orange  broccoli asparagus We can even compute the nodes of a TREE or the length of a LIST ... in a numeral unary notation {def TREE.NODES   {lambda {:t}    {{{word? :t}     {PAIR      {lambda {:t} |}           {lambda {:t} {TREE.NODES {LEFT :t}}                    {TREE.NODES {RIGHT :t}} }    }} :t} }}  ­> TREE.NODES  {def LIST.LENGTH   {lambda {:l}    {{{word? :l}     {PAIR      {lambda {:l} }      {lambda {:l} | 

                 {LIST.LENGTH {RIGHT :l}}}    }} :l}}}  ­> LIST.LENGTH  {TREE.NODES {FOOD}}    ­> | | | | | | // 6  {LIST.LENGTH {FRUITS}} ­> | | | | |   // 5 It's time to introduce numbers!

3. {LAMBDA NUMBERS} Alonzo CHURCH defined a number N as a function iterating N times the application of a function f on a variable x. We will choose another way and define natural numbers as LISTs of any words, for instance pipes | N = {PAIR | {PAIR | ... n times ...}} With such a definition finding the SUCCessor and the PREDecessor of any number is straightforward {def SUCC {lambda {:n} {PAIR | :n}}}   ­> SUCC  {def PRED {lambda {:n} {RIGHT :n}}} The previous version of PRED returns an error when :n is a word and we will replace it by a new one returning :n in this case. {def PRED    {lambda {:n}    {{{word? :n}        {PAIR       {lambda {:n} :n}      {lambda {:n} {RIGHT :n}}    }} :n}}}  ­> PRED We begin to build the set of natural numbers {def ZERO .}              ­> ZERO   {def ONE {SUCC {ZERO}}}   ­> ONE  {def TWO {SUCC {ONE}}}    ­> TWO  {def THREE {SUCC {TWO}}}  ­> THREE  {def FOUR {SUCC {THREE}}} ­> FOUR  {def FIVE {SUCC {FOUR}}}  ­> FIVE  {def SIX {SUCC {FIVE}}}   ­> SIX    {def SEVEN {SUCC {SIX}}}  ­> SEVEN   {LIST.DISP {ZERO}}         ­>   {LIST.DISP {ONE}}          ­> |   {LIST.DISP {TWO}}          ­> | |   {LIST.DISP {PRED {FIVE}}}  ­> | | | |   {LIST.DISP {SUCC {FIVE}}}  ­> | | | | | | For convenience we will replace the primitive unary notation given by LIST.DISP by a modern decimal one {def DECIM   {def DECIM.rec    {lambda {:l :a}     {{{word? :l} 

    {PAIR       {lambda {:l :a} :a }       {lambda {:l :a}        {DECIM.rec {RIGHT :l} {+ :a 1}}}     }} :l :a} }}   {lambda {:l} {DECIM.rec :l 0} }}  ­> DECIM  {DECIM {ZERO}}         ­> 0  {DECIM {PRED {TWO}}}   ­> 1  {DECIM {TWO}}          ­> 2  {DECIM {SUCC {SEVEN}}} ­> 8     {DECIM {PRED {ZERO}}} ­> 0  // fixed to 0 Note that at this point we are not theoretically allowed to build a function using Javascript numbers and operators, but we will use DECIM for a better readability. We define some arithmetic operators, ADD, SUB, MUL, POW {def ADD   {lambda {:a :b}    {{{word? :b}     {PAIR      {lambda {:a :b} :a}      {lambda {:a :b}       {ADD {SUCC :a} {PRED :b}}}    }} :a :b}}}  ­> ADD  {def SUB   {lambda {:a :b}    {{{word? :b}     {PAIR      {lambda {:a :b} :a}      {lambda {:a :b}       {SUB {PRED :a} {PRED :b}}}    }} :a :b}}}  ­> SUB  {def MUL   {def MUL.rec    {lambda {:a :b :c}     {{{word? :b}      {PAIR       {lambda {:a :b :c} :a}       {lambda {:a :b :c}        {MUL.rec {ADD :a :c} {PRED :b} :c}}     }} :a :b :c}}}   {lambda {:a :b} {MUL.rec :a {PRED :b}  :a}}}  ­> MUL  {def POW   {def POW.rec    {lambda {:a :b}     {{{word? :b}      {PAIR       {lambda {:a :b} :a}       {lambda {:a :b}        {POW.rec {ADD :a :a} {PRED :b}}}     }} :a :b}}}   {lambda {:a :b} {POW.rec :a {PRED :b}}}} 

­> POW  {DECIM {ADD {TWO} {THREE}}} ­> 5  {DECIM {SUB {THREE} {TWO}}} ­> 1  {DECIM {MUL {TWO} {THREE}}} ­> 6  {DECIM {POW {TWO} {THREE}}} ­> 8 To define the DIV, MOD operators we use the Euclid algorithm a = b*q+r {def EUCLID   {def EUCLID.r    {lambda {:a :b :q :r}     {{{word? {SUB {MUL :b :q} :a}}      {PAIR       {lambda {:a :b :q :r}        {EUCLID.r :a :b                  {SUCC :q}                  {SUB :a {MUL :b :q}}}}       {lambda {:a :b :q :r}        {PAIR {PRED :q} :r} }       }} :a :b :q :r}}}   {lambda {:a :b}    {EUCLID.r :a :b {ZERO} :b}}}  ­> EUCLID  {def DIV {lambda {:a :b}    {LEFT {EUCLID :a :b}}}}   ­> DIV  {def MOD {lambda {:a :b}    {RIGHT {EUCLID :a :b}}}}   ­> MOD  {DECIM {DIV {FIVE} {TWO}}} ­> 2  {DECIM {MOD {FIVE} {TWO}}} ­> 1  {DECIM {DIV {SIX} {TWO}}}  ­> 3  {DECIM {MOD {SIX} {TWO}}}  ­> 0 Computing the factorial function n! = 1*2*3* ... *n is straightforward {def FAC   {lambda {:n}    {{{word? :n}     {PAIR      {lambda {:n} {ONE}}      {lambda {:n} {MUL :n {FAC {PRED :n}}}}    }} :n}}}  ­> FAC  {DECIM {FAC {SIX}}}   ­> 720   {DECIM {FAC {SEVEN}}} ­> max call stack Note that the implementation of numbers as LISTs and operators as recursive processes has a severe limit, long lists, for instance 7! = 5040, exceed the stack capacity. Obviously a very severe limit, at least for arithmetics! Here comes a zest of Y-combinator

{def Y {lambda {:g :n} {:g :g :n}}} ­> Y  {def ALMOST_FAC   {lambda {:g :n}    {{{word? :n}      {PAIR      {lambda {:g :n} {ONE}}      {lambda {:g :n}       {MUL :n {:g :g {PRED :n}}} }    }} :g :n}}}   ­> ALMOST_FAC  {DECIM {Y ALMOST_FAC {SIX}}} ­> 720 The Y-combinator and the ALMOST_FAC function can be composed leading to an IIFE, (Immediately Invoked Function Expression) {DECIM    {{lambda {:n}    {{lambda {:g :n} {:g :g :n}}      {lambda {:g :n}      {{{word? :n}        {PAIR        {lambda {:g :n} {ONE}}        {lambda {:g :n}         {MUL :n {:g :g {PRED :n}}} }      }} :g :n    }} :n}} {SIX}}}   ­> 720 In this last expression replacing constants by their definitions would lead to a complex combination made of 3 terms, [word, lambda, word?]. A cumbersome exercise! The mapping of a function on a list {def MAP   {def MAP.r    {lambda {:f :l :acc}     {{{word? :l}      {PAIR       {lambda {:f :l :acc} :acc}       {lambda {:f :l :acc}         {MAP.r :f {RIGHT :l}               {PAIR {:f {LEFT :l}}                      :acc}}}     }} :f :l :acc}}}   {lambda {:f :l} {MAP.r :f :l \}}}  ­> MAP  {def SERIE   {def SERIE.r    {lambda {:a :b :l}     {{{word? {SUB :b :a}}      {PAIR       {lambda {:a :b :l} {PAIR :b :l}}       {lambda {:a :b :l}        {SERIE.r {SUCC :a}                 :b {PAIR :a :l}}}     }} :a :b :l}}} 

 {lambda {:a} {SERIE.r {ONE} :a \}}}  ­> SERIE  {def POWER2   {lambda {:n} {DECIM {POW {TWO} :n}}}}  ­> POWER2  {def TEN {MUL {TWO} {FIVE}}} ­> TEN  {LIST.DISP {MAP DECIM {SERIE {TEN}}}}  ­> 1 2 3 4 5 6 7 8 9 10  {LIST.DISP {MAP POWER2 {SERIE {TEN}}}}  ­> 2 4 8 16 32 64 128 256 512 1024 As a last example we illustrate a double recursive process with the Towers of Hanoï {def MOVE   {lambda {:n :from :to :via}    {{{word? :n}     {PAIR      {lambda {:n :from :to :via} }      {lambda {:n :from :to :via}       {MOVE {PRED :n} :from :via :to}     move disc from [:from] to [:to], then        {MOVE {PRED :n} :via :to :from} }    }} :n :from :to :via}}}  ­> MOVE  {MOVE {FOUR} A B C} stop.   ­> move disc from [A] to [C], then move disc from [A] to [B], then move disc from [C] to [B], then move disc from [A] to [C], then move disc from [B] to [A], then move disc from [B] to [C], then move disc from [A] to [C], then move disc from [A] to [B], then move disc from [C] to [B], then move disc from [C] to [A], then move disc from [B] to [A], then move disc from [C] to [B], then move disc from [A] to [C], then move disc from [A] to [B], then move disc from [C] to [B], then stop.

Note how text and variables are easily mixed in the line "move disc from [:from] to [:to], then". Strings don't need to be protected by quotes and this is useful in a wiki context. And {lambda tank} is a wiki. At this point {lambda talk} is still supposed to be reduced to a couple of special forms [lambda, def] working on words and the dictionary contains the primitive word? and the user defined functions [ HI, AFFIRMATION, PAIR, LEFT, RIGHT, AP,  FOOD, VEGETABLES, FRUITS, TREE.DISP,  LIST.DISP, LIST.REVERSE, LIST.APPEND,  TREE.NODES, LIST.LENGTH, SUCC, PRED, ZERO,  ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,  DECIM.rec, DECIM, ADD, SUB, MUL.rec, MUL,  POW.rec, POW, EUCLID.r, EUCLID, DIV, MOD,  FAC, Y, ALMOST_FAC, MOVE ] Theoretically any computation can be done, for instance {LIST.DISP {FAC 50}} would display 3041409320171337804 3612608166064768844377641568960512000000000000 pipes. But if computing the factorial of 5 is relatively fast, computing the

factorial of 50 would still be too long! Probably thousands years. It's time to enter the real life!

4. {LAMBDA WEB} In fact - and fortunately - {lambda talk} can take benefit of the powerful functions of web browsers - JAVASCRIPT, HTML/CSS, DOM, SVG, ... - allowing to avoid re-inventing the wheel and to build much more efficient code. The set of special forms is extended to 9 [lambda def if let macro script style  require quote|'] The dictionary contains a first set of 200 built-in primitives DICTionary: (203) [ debug, browser_cache,  lib, eval, apply, , =, =,  not, or, and, +, ­, *, /, %, abs, acos,  asin, atan, ceil, cos, exp, floor, pow,  log, random, round, sin, sqrt, tan, min,  max, PI, E, date, serie, map, reduce,  equal?, empty?, chars, charAt, substring,  length, first, rest, last, nth, replace,  cons, cons?, car, cdr, cons.disp, list.new,  list, list.disp, list.null?, list.length,  list.reverse, list.first, list.butfirst,  list.last, list.butlast, array.new, array,  array.disp, array.array?, array.null?,  array.length, array.in?, array.get,  array.item, array.first, array.last,  array.rest, array.slice, array.concat,  array.set!, array.addlast!, array.push!,  array.sublast!, array.pop!,  array.addfirst!, array.unshift!,  array.subfirst!, array.shift!,  array.reverse!, array.sort!, @, div, span,  a, ul, ol, li, dl, dt, dd, table, tr, td,  h1, h2, h3, h4, h5, h6, p, b, i, u, center,  hr, blockquote, sup, sub, del, code, img,  pre, textarea, canvas, audio, video,  source, select, option, object, svg, line,  rect, circle, ellipse, polygon, polyline,  path, text, g, mpath, use, textPath,  pattern, image, clipPath, defs, animate,  set, animateMotion, animateTransform, br,  input, iframe, mailto, back, hide,  long_mult, turtle, drag, note, note_start,  note_end, show, lightbox, minibox,  editable, forum, lisp ]

   else {* :n {fac {­ :n 1}}}}}}  ­> fac  {fac 5}  ­> 120  {fac 50} ­> 3.0414093201713376e+64 The set of special forms and built-in primitives makes {lambda talk} an efficient programming language for the web. The current wiki page uses plenty of these functions to write titles and paragraphs, apply styles and so on. But, thanks to the script special form this set of primitives can be extended on demand. It's what we did when we defined the word? function to build the first subset {lambda word}. We can also, for instance, compensate the Javascript limitations on big numbers. We have noticed that {fac 50} returns a float number limited to 15 digits and not the exact value. Calling an appropriate library stored in the wiki, lib_BN, we can compensate the limitations of JavaScript numbers - 15 digits maximum - and build a {lambda talk} code computing the 65 digits of 50! {def fact   {lambda {:n}    {if { fact  {fact 50} ­>   3041409320171337804361260816606476884437764 1568960512000000000000 And finally we could simply call the predefined JS function BN.fac to quickly compute the 1120 digits of big numbers, say 500!. Here are some other applications/extensions using libraries stored in the wiki: • a set of functions to display maths without MathML[16]

(

∂ψ ih  (x,t) =  mc2α0 ­ ihc  ∂t

Σ αj ∂x∂ j ) ψ(x,t) 3

j=1

• an embedded spreadsheet[10] understanding {lambda talk} expressions

Thanks to the {if bool then one else two} special form giving for free the lazy evaluation laboriously coded in the previous recursive algorithms and using numbers and their associate operators - [+, -, *, /, ..., =, < , >, ...] - proposed by Javascript, we can now write more readable and efficient codes. For instance {def fac   {lambda {:n}    {if {= :n 0}     then 1 

• an Academic paper in ACM US format generated directly from the browser

{macro {SQR (\d+?|{.*?})} to {* €1 €1}}    {SQR 12} ­> 144  {SQR {+ 1 {* 2 3} 4}} ­> 121 Compared to a function, a macro is evaluated at "compile time", transforming the code string before the evaluation loop. It may save time when a function is called several times. As it can be seen, lambdatalk's macros are not Lisp's macros, they are built on the regular expressions syntax.

CONCLUSION

• 3D curves and surfaces, Turtle graphics

• Ray-tracing, the Mandelbrot set, ...

Upon a minimal set of rules any user can define a subset of {lambda talk} like we did with {lambda word}, {lambda number} and {lambda web}. New user functions can be stored in wiki pages used as libraries and called via the require special form. The set of primitives can be edited and extended via the script special form like we did with the function word?. The macro special form helps creating alternative syntaxes, the style special form allows the user to tune up pages style. {lambda talk} is fully extensible. The {lambda way} project adds on browsers a thin overlay, {lambda tank}, proposing a 100kb "Interactive Development Environment" without any external dependencies and thereby easy to download and install on any web account provider running PHP. {lambda talk} expressions are written in an editor frame, evaluated in real time, displayed in the wiki's viewer frame, then saved and published on the web. From any web browser, on any system, complex and dynamic web pages can be created, enriched, structured and tested in real time on the web. And it's free! It's exactly how the current wiki page was created. alain marty / http://lambdaway.free.fr / 2018/02/18

REFERENCES

All these examples can be tested in the {lambda way}'s workshop. Finally, {lambda talk} comes with the special form {macro regexp to target}, where regexp is a regular expression and target is a {lambda talk} expression. For instance if we want to use λ as an alias of lambda we simply write a short macro {macro {λ (.*?)} to {lambda €1}}    {{λ {x y} x*y = {* x y}} 3 4} ­> 3*4 = 12 We could replace the definition of a function sqr defined like this: {def sqr {lambda {:x} {* :x :x}}} ­> sqr  {sqr 12} ­> 144 by a macro SQR which will expand {SQR x} to {* x x}:

[1] The Wiki way:  http://dl.acm.org/citation.cfm?id=375211  [2] Ward_Cunningham:  http://ward.asia.wiki.org/view/testing­ microtalk   [3] A Tutorial Introduction to the Lambda  Calculus (Raul Rojas): http://www.inf.fu­ berlin.de/lehre/WS03/alpi/lambda.pdf  [4] Lisp:  http://www.cs.utexas.edu/~cannata/cs345/Cla ss%20Notes/06%20Lisp.pdf  [5] Arold Abelson and Gerald J. Sussman.  1996. Structure and Interpretation of  Computer Programs (2nd ed.). MIT Press,  Cambridge, MA, USA.  [6] Collected Lambda Calculus Functions:  http://jwodder.freeshell.org/lambda.html  [7] S. C. Kleene, “Representation of events  in nerve nets and finite automata”, in: C.  Shannon and J. McCarthy, (eds.) Automata  Studies, Princeton University Press, NJ,  1956, 3–41.  [9] Jonas Raoni Soares Silva  http://jsfromhell.com/classes/bignumber 

[10] Simon_Peyton_Jones:  https://www.microsoft.com/en­ us/research/people/simonpj/#  [16] google­subtracts­mathml­from­chrome:  https://www.cnet.com/news/google­subtracts­ mathml­from­chrome­and­anger­multiplies/  [17] Regular Expressions: 

http://blog.stevenlevithan.com/archives/rev erse­recursive­pattern  [18] Turing machines implemented in  JavaScript   http://www.turing.org.uk/book/update/tmjava r.html {λ way2} v.20170929