lambda talk - epsilonwiki

Nov 29, 2016 - set[15] which doesn't work in Chrome, and can be used to ..... It's a free software under the ... PDF version generated from this wiki page. - ... - .
1MB taille 2 téléchargements 382 vues
29/11/2016

{λ way}

+

{λ way} :: krakow

{lambda talk} alain marty | engineer ECL architect DPLG | france [email protected]

abstract The {lambda way} project is built on two engines: 1. {lambda talk}, a purely functional language unifying writing, styling and scripting in a single and coherent notation, 2. {lambda tank}, a tiny wiki easy to install as a thin overlay on top of any web browser, allowing  a  collaborative  work  between  authors, web designers and coders for creating and sharing rich documents on the web.

context «  But  there  are  hundred  of  wiki  engines  and hundred  of  languages!  Why  yet  another  wiki  and another  language  nobody  will  ever  want  to  use?  » Let's talk about it! Web  browsers  give  everybody  an  easy  access  to  a plethora  of  rich  documents  created  by  people mastering HTML, CSS, JS, PHP... What is less known, web  browser  can  give  everybody  a  small  window  to write HTML/CSS/JS code and so add informations to web pages. Wikis[1] belong to this category: « A wiki is  a  web  application  which  allows  collaborative modification,  extension,  or  deletion  of  its  content  and structure. »

Writing  HTML/CSS/JS  code  being  rather  complex and  at  least  tiresome,  intermediate  syntaxes,  for instance  WikiText[2],  have  been  created  to  make things a bit easier. And it's exactly what people use in blogs  and  wikis.  The  best  known  of  wikis  is Wikipedia,  full  of  rich  documented  pages  written  by people supposed not to be web designers or coders. Everything works well but the underlying code is a very  obfuscated  text,  difficult  to  write,  read,  edit  and maintain.  In  fact,  the  WikiText[2]  syntax  is  not intended for writing rich documents. Works have been done  to  build  enhanced  syntaxes  in  order  to  unify writing,  styling  and  coding,  for  instance,  not  to mention  desktop  tools  like  LaTeX[3],  PDF[4],  web tools  like  CURL[5],  LML[6],  Skribe[7],  Scribble[8], SXML[9], LAML[10], Pollen[11] ... But these tools are definitively  devoted  to  coders,  not  to  web  designers and even less to beginners. Hence the {lambda way} project ... In  this  paper  we  will  focus  on  {lambda  talk}, following two steps: 1. using {lambda talk}, a gentle introduction via simple examples, 2. {lambda talk} more deeply, structure, evaluation, implementation, frequently asked questions.

1. using {λ talk} 1.1 words http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

Words  are  written  in  a  code  editor  frame  and displayed in real time in the wiki page, following some 1/11

29/11/2016

{λ way}

predefined styling rules. For instance: Hello brave new World 

Hello brave new World

{sqrt 2}  {sqrt {+ {* 3 3} {* 4 4}}}  code

view

Sometimes  styling  rules  have  to  be  modified  here and there. In a standard text editor, applying some bold style  on  a  sequence  of  words  needs  two  steps,  1) selecting with the mouse and 2) applying a command via  some  button  [B],  or  via  some  key  combination [^C+B]. In {lambda talk} the sequence select/apply is based  on  a  unique  shorthand  notation  {first rest}, so­called form, where: 1)  curly braces {} are used to select a sequence of words and forms, 2) first is a word referencing a function belonging to a given dictionary and applied to rest, 3) rest is any sequence of words and forms. This is a very simple example: Hello {b brave new} World 

Hello brave new World

code

view

view

Some words can be seen as numbers and {lambda talk} becomes a pocket calculator code

{div   {@ style="color:cyan"}   Hello World  } 

{img    {@ src="data/mustangs.jpg"       width="98%"      title="Mustangs at Las Colinas  ©Robert Glen"      style="       padding:5px 5px 35px 5px;       border:1px solid white;       background:white;       box­shadow:0 0 8px black"  }}   

code

view

code

view

Sounds  familiar  to  any  web  designer,  you  can simply  copy/paste  chunks  of  standard  HTML/CSS code.  But  smart  web  designers  will  say  «  It's  a  bad practice to mix structure and style! » Ok it's right, it's time to introduce constants and functions.

cyan

You  can  put  all  the  "ugly"  constant  HTML/CSS stuff  under  a  name  and  call  it  later.  For  instance  you can  define  the  name  cyan  and  apply  it  later  on different words:

http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

The  set  of  HTML  tags  is  not  infinite.  Thanks  to CSS  rules  this  set  can  be  extended  ad  libitum.  For instance  you  could  apply  some  cyan  color  to  words like this:

{{cyan}Hello brave new World}  {{cyan}Goodbye poor old World} 

1.4 constants

2) and call: 

1.3 styles

Or display a picture on a shadowed box like this:

1.2 numbers

1) define:  {def cyan    span {@ style="color:cyan"}} 

marvelous world of mathematics.

code

You  are  in  the  holy  world  of  nested  prefixed expressions!  In  fact,  the  {lambda  talk}  syntax  is  a shorthand  for  the  standard  HTML  syntax.  whose evaluation will lead to a sequence of words embedded in  a  valid  HTML/CSS  code  sent  to  the  browser's engine for the final display. Remember that in {lambda talk} out of curly braces words are not evaluated.

{+ 1 2 3}  {+ 1 {* 2 3} 4}   

view

For instance, the expression {sqrt {+ {* 3 3} {* 4 4}}} is successively replaced by  {sqrt {+ 9 16}}, then by {sqrt 25} and finally by 5. It's the hypotenuse of  a  right  angle  triangle  [3,4].  You  are  entering  the

Hello World

This one is more convoluted: {b Hello   {sup World,    {sub is     {sup there      {sub anybody       {sup out        {sub there         {sup ???}}}}}}}}  ?????? Hello World, is there anybody out there 

6 11 1.4142135623730951 5

code

view

Hello brave new World Goodbye poor old World Giving  a  name  to  the  messy  HTML/CSS  stuff defining  the  previous  picture  in  a  shadowed  box,  a friendly  coder  could  help  you  to  hide  HTML/CSS code.  Better  he  could  externalize  it  in  another  wiki 2/11

29/11/2016

{λ way}

page  behaving  as  a  library,  extending  the  concept  of CSS  stylesheet  and  opening  a  way  towards  more powerful capabilities.

The name  hypo  is  nothing  but  an  alias  to  {lambda {a b} {sqrt {+ {* a a} {* b b}}}} and it's rather easy to understand that {hypo 3 4} is first replaced by

You  can  give  math  expressions  a  name,  provided they are evaluable:

{{lambda {a b} {sqrt {+ {* a a} {* b b}}}} 3 4}, where  a and  b will be replaced by  3 and  4, leading to this evaluable expression  {sqrt {+ {* 3 3} {* 4 4}}}, finally replaced by 5, as we have seen before.

1) define:  {def Φ   {/ {+ 1 {sqrt 5}} 2}  }   {def 1*2*...*100    {* {serie 1 100}}  } 

code

Mixing text and numbers is easy, provided you take some care: 1) define:  {def cute_add    {lambda {:a :b}    {b :a+:b      {sup is equal to}       {u {+ :a :b}}}}} 

2) and call:  {Φ}  {1*2*...*100} 

Φ 1*2*...*100

view

1.618033988749895 9.33262154439441e+157

code 1) define  {def color    {lambda {myColor}    span {@ style="color: myColor;"}}} 

view

Hello World Hello World We  have  seen  that  the  expression  {sqrt {+ {* 3 3} {* 4 4}}}  is  evaluated  to  5,  the  hypotenuse  of  a right  angle  triangle  [3,4].  Using  a  function  we  can delay  the  evaluation  of  {sqrt {+ {* a a} {* b b}}}  containing  undefined  arguments  a  and  b  until they get their values: code

http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

1.6 fibonacci numbers    {def fibonacci   {def fibonacci.rec     {lambda {:a :b :c}     {if { "3+:b is equal to {+ 3 :b}"  3) and a new function    {lambda {:b}     3+:b is equal to {+ 3 :b}}      is returned for a future call.

Note:  In  order  to  avoid  substitution  conflicts,  the string  replacement  process  used  by  lambdas  implies arguments  to  be  prefixed  by  a  distinctive  char,  say  a colon. In the example shown this precaution obviously prevents the word equal to be replaced by equ3l! For a total  security,  it  should  be  better  to  escape  arguments between  two  colons,  :local_name:,  with  the  added benefit  of  enlighting  them  as  local  variables,  to  be compared  with  global  constants  called  between  curly braces, {global_name}.

{λ way}

2.3.4 Do lambdas create closures? No they don't! This weakness is partially balanced by the fact lambdas accept a number of values different from  their  arity,  (partial  application  with memorization,  currying).  As  a  useful  application  of this  capability,  this  is  how  can  be  defined  derivatives of  a  function  f(x):  f'(x),  f''(x),  f'''(x),  ...,  which  are functions of x and not values at a given x: • 1) we define the derivative function: {def D {lambda {:f :h :x}    {/ {­ {:f {+ :x :h}} {:f {­ :x :h}} }       {* 2 :h}}}}   ­> D

• 2) we create the 1st, 2nd and 3rd derivatives of the function log for a given value of :h and as functions of :x: {def log'   {lambda {:x} {D log   0.01 :x}} }   ­> log'  {def log''   {lambda {:x} {D log'  0.01 :x} }}   ­> log''   {def log'''   {lambda {:x} {D log'' 0.01 :x} }}   ­> log'''

• 3) we can now call the 1st, 2nd and 3rd derivatives of log on a given value of x: {log'   1} ­> 1.0000333353334772  // 1  {log''  1} ­> ­1.0002000533493427 // ­1 {log''' 1} ­> 2.0012007805464416  // 2

Another  application  of  this  capability  is  that  any agregate  data  can  be  built  with  lambdas,  for  instance pairs, lists, arrays, R/C numbers, 2D/3D vectors, ....  We  have  seen  an  application  of  pairs, lists  in  part  1).  This  is  how  could  be  built  the  cons, car, cdr functions usually associated to pairs:

{def cons    {lambda {:a :b :m} {{:m :a} :b}}}  {def car    {lambda {:p} {:p {lambda {:x :y} :x}}}}  {def cdr    {lambda {:p} {:p {lambda {:x :y} :y}}}}

Because  they  are  so  useful,  pairs  ­  and  lists  and arrays ­ are actually built as primitives in the {lambda talk}'s dictionary.

2.3.4 Do lambdas create 2.3.5 Can special forms be nested? Yes you can! • defs can be nested. But inner defs are not local to the outer def. There are no nested environments. So, in order to prevent names http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

conflicts, a good practice - mimicking the OOP paradigm - is to prefix inner-defined names with the outer-defined names. For instance in the following example hypo.square can be considered as a property of hypo: {def hypo   {def hypo.square    {lambda {:x} {* :x :x}}}   {lambda {:a :b}    {sqrt {+ {hypo.square :a}  7/11

29/11/2016

           {hypo.square :b}}}}}  ­> hypo  {hypo 3 4}  ­> 5  {hypo 1 1}  ­> 1.4142135623730951

• ifs can be nested, leading to conditional sequences, for instance:

{λ way}

factorial n! {def !   {lambda {:a :b}    {if { !  {! 6}  ­> 720

{def inside?    {lambda {:x :a :b}    {if {equal? {+ 1 :x} NaN}      then {u :x} is Not a Number else    {if { false  {inside? 2 1 10}  ­> true  {inside? 11 1 10} ­> false  {inside? foo 1 10}    ­> foo is Not a Number

and  the  Euler's  number  2.718281828459045 defined as an infinite serie: E = Σi=0∞[1/1*2*..*i]

• lambdas can be nested. This is an example where we want to compute the area of a right angle triangle [a,b,c] given by this formula: area = √s*(s-a)*(s-b)*(s-c) where s= (a+b+c)/2: 1) using lambdas:   {{lambda {:a :b :c}    {{lambda {:a :b :c :s}     {sqrt      {* :s {­ :s :a} {­ :s :b} {­ :s :c}}     }} :a :b :c {/ {+ :a :b :c} 2}     }} 3 4 5}   ­> 6  2) using let:  {{lambda {:a :b :c}    {let { {:a :a} {:b :b} {:c :c}            {:s {/ {+ :a :b :c} 2} }}    {sqrt     {* :s {­ :s :a} {­ :s :b} {­ :s :c}}    }}} 3 4 5}   ­> 6

• Note that, because lambdas don't create closures, inner lambdas have no access to the outer lambdas arguments. This is why :a :b :c must be duplicated in the above both versions. This workaround could be seen as a manual closure ... which could be automatized in a next version of lambdatalk. Wait and see!

2.3.6 What about iterative processes? Theoretically  recursion  can  be  used  to  build  every iterative  processes.  For  instance  the  well  known

2.3.9 What about styles? CSS rules applied to the entire wiki are externalized as CSS files in the skins folder and can be selected in the  lambdatank's  top­left  menu.  The  current  skin  can http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

{* {serie 1 20}}   ­> 2432902008176640000

{def euler    {lambda {:n}     {+ 1 {reduce {lambda {:a :b} {+ :a :b}}          {map {lambda {:i} {/ 1 {* {serie 1 :i          {serie 1 :n}}}}}}  ­> euler  {euler 17}  ­> 2.7182818284590455

2.3.7 What about mutability? Defined  values  can't  be  modified,  lambdatalk  is purely  functional  and  has  no  set!  special  form. Mutations  are  exclusively  made  via  functions' arguments.

2.3.8 Why is lambdatalk easy to use by web designers? In  Part  1)  we  have  seen  how  a  the  {lambda  talk} syntax  built  over  the  HTML/CSS  syntaxes  can  stay familiar to a web designer. However it's noticeable that the {@ ...} form breaks the previously claimed syntax unicity, there are no clean forms in it and to many ugly quoted  strings  used  by  HTML  attributes  and  CSS rules!  It  was  a  matter  of  design  choice,  in  order  to avoid any pollution of the dictionary with a myriad of CSS  rules  and  giving  web  designers  an  access  to standard  HTML  attributes  and  CSS  rules  they  are familiar with. And we have seen that any coder is able to hide behind names all those ugly things.

be  analyzed  in  the  file  skins/newone/CSS.css.  Local CSS  rules  can  be  applied  to  a  page  using  the  {style ...}  form.  For  instance  in  this  page,  a  few  tags  have been overloaded like this:

8/11

29/11/2016

{style   body {   background:#fff;   normal 1.0em Times New Roman;  }  #title {   color:#fff; text­shadow:0 0 0;   }  #frame_view {    width:100%; padding:0; border:0 solid;  box­shadow:0 0 0; background:#fff;   color:#000;  }  h1, h2, h3, h4, h5, h6 {   margin­top:10px; margin­bottom:0px;  }  h1 { font­size:3.0em; color:black; }   h2 { font­size:2.6em; color:red; }   h3 { font­size:2.2em; color:green; }   h4 { font­size:1.8em; color:blue; }   h5 { font­size:1.4em; color:magenta; }  h6 { font­size:1.0em; color:cyan; }   }

2.3.10 What about scripts? The primitive  {input ...} can easily embed short scripts via any onEvent attribute. For instance: {input    {@ id="smart_hello"       type = "text"       placeholder = "Enter your name"       onkeyup =    "getId('yourName').innerHTML = 'Hello '    + getId('smart_hello').value + ' !'"  }}   {h1 {@ id="yourName"}}

{λ way}

{script    function start() {    document.chrono = window.setInterval(      function() {       getId('output').innerHTML = 'time: '        + LAMBDATALK.eval_forms({date}');      }, 1000 );   }   function stop() {   window.clearInterval( document.chrono )   }  }

displays a digital watch:

time: 2016 11 29 11 40 47 start

stop

2.3.11 What about libraries? Sets of user variables and functions can be stored in wiki  pages  and  called  elsewhere  via  a  (require library)  call.  Thus,  the  primitive  dictionary  can  be extended as necessary with coherent modules carefully built  to  avoid  name  conflicts.  For  instance,  functions defined in some  lib_SVG_clock page can be used via a (require ...) to display a stylized clock: {center {{svg.clock 300 300}    {svg.path 150 150 100 20 red 1}    {svg.path 150 150 120 20 green 2}    {svg.path 150 150 140 20 blue 3}    {svg.digit}   }}

displays this text field in which you can enter your name: Joe

Hello Joe !

11 39 28

The primitive  {script ...}  can  be  used  to  insert more complex scripts. For instance: {div {@ id="output" style="..."}time: } {input {@ type="submit" value="start"    onclick="start()"}}  {input {@ type="submit" value="stop"    onclick="stop()"}} 

2.3.12 What about macros? Macros  in  lambdatalk  bring  the  power  of  regular expressions  directly  in  the  language.  As  an  example, this  is  how  we  define  an  array  of  ten  numbers  and display them squarred using the lambdatalk syntax: {def A {array {serie 1 10}}}  ­> A  http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

{map   {lambda {:i}    {* {array.nth {A} :i}       {array.nth {A} :i}}}    {serie 0 {­ {array.length {A}} 1}}}  ­> 1 4 9 16 25 36 49 64 81 100

It's rather difficult to read. Thanks to a small set of helper functions and a single macro {def K.disp   {lambda {:arr} {array.disp {:arr}}  9/11

29/11/2016

{λ way}

}} ­> K.disp  {def K.nth   {lambda {:arr :i}    {array.nth {:arr} :i}  }} ­> K.nth  {def K.range   {lambda {:arr}    {serie 0 {­ {array.length {:arr}} 1}  }}} ­> K.range  {macro ([\w:]+?)\[([\w:]*?)\]         to {if {empty? €2}           then {K.disp €1}           else {if {equal? €2 range}                then {K.range €1}                else {K.nth €1 €2}}}}

we  can  write  the  previous  expression  in  a  more readable way: {map {lambda {i}         {* A [i] A [i]}} A [range]}   ­> 1 4 9 16 25 36 49 64 81 100

In this example it's easy to see a regular expression based  syntax  before  the  word  to  and  a  lambdatalk based syntax after with a nested  if then else control structure. {lambda talk} comes with a predefined small set of useful  macros  allowing  writing  titles,  paragraphs  and item lists without curly braces: _h1 TITLE cr     stands for {h1 TITLE}    and alike for h2, h3, h4, h5, h6  _p Some paragraph ... cr     stands for {p Some paragraph ...}  _ul list item 1 cr  _ul list item 1 cr  _ul list item 1 cr    stands for  {ul   {li list item 1}   {li list item 2}   {li list item 3}  }

These simplified alternatives, avoiding curly braces as much as possible, are fully used in this document.

2.3.13 Where does lambdatalk come from? Not exactly from Lisp, built on List Processing, but from  the  lambda  calculus[17]  defined  by  Alonzo Church  in  the  thirties  and  built  on  words  substitution. Following  the  lambda  calculus  a  {lambda  talk} expression could be defined like this: expression ::=   word | abstraction | application

Where 1. a word is any sequence of chars except spaces and {}, and is evaluated to itself, 2. an abstraction is a form {lambda {words} expression}, and is evaluated to the reference of an anonymous function, 3. an application is a form {abstraction expression}, and is evaluated to a sequence of words. At this point {lambda talk} knows nothing but text substitutions. For instance: 1) words  Hello World  ­> Hello World  2) abstraction  {lambda {o a} oh happy day!}   ­> lambda_1234  3) application  {{lambda {o a} oh happy day!}    oOOOo aaAAaa}   ­> oOOOoh haaAAaappy daaAAaay!

Amazingly  nothing  more  is  needed  to  compute expressions such 6! = 1*2*3*4*5*6 = 720: {{λ {:n} {{λ {:p} {:p {λ {:x :y} :y}}}  {{:n {λ {:p} {{λ {:a :b :m} {{:m :a}  :b}} {{λ {:n :f :x} {:f {{:n :f} :x}}}  {{λ {:p} {:p {λ {:x :y} :x}}} :p}} {{λ  {:n :m :f} {:m {:n :f}}} {{λ {:p} {:p  {λ {:x :y} :x}}} :p} {{λ {:p} {:p {λ  {:x :y} :y}}} :p}}}}} {{λ {:a :b :m}  {{:m :a} :b}} {λ {:f :x} {:f :x}} {λ  {:f :x} {:f :x}}}}}} {λ {:f :x} {:f {:f  {:f {:f {:f {:f ... total 6  times}}}}}}}}  ­> {λ {:f :x} {:f {:f {:f {:f {:f {:f  ... total 720 times}...}

where λ stands for lambda to be short. Read more in calc2talk[18]. Usually  the  lambda  calculus  comes  with  the Church  numbers  and  a  set  of  operators,  [def, succ, add, mul, succ, power, cons, car, cdr, pred, subtract, ..., Y-combinator] to make things easy

to  write  and  read.  And  theoretically,  we  could  go  on this  way  to  build  the  majority  of  {lambda  talk}'s functionalities. But in order to bring a bit of humanity ­ and  make  coding  much  more  easy  ­  it's  more reasonable  to  play  with  readable  defined  names  and populate  the  dictionary  with  some  useful  primitive functions  built  on  the  browser's  foundations, Javascript's  numbers,  Math  operators  and  functions, HTML  tags,  CSS  rules,  and  some  others.  With  an augmented  set  of  special  forms,  [lambda,  def,  if,  let, quote,  ...],  all  these  "improvements"  lead  to  a  more usable and effective language, {lambda talk}.

conclusion conclusion http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

10/11

29/11/2016

The {lambda way}  project  is  essentially  built  on  a 30kb  PHP  file  and  a  60kb  JS  file.  It's  free  of  any external dependancies, {lambda talk}  can  be  used  out of  {lambda  tank}  and  embedded  in  any  other environment.  The  underlying  PHP+JS  code  is  small and easy to read, edit and improve. It's a free software under the GNU GPL licence. Its 100kb archive is easy to  download  &  install  on  any  web  account  running PHP. {lambda  talk}  is  a  small  but  complete programmable  programming  language  offering  tools which can be used, in any modern web browser and on any device (from desktop PCs to smartphones) at three levels of increasing complexity: with a handful of basic commands any author can easily create minimally structured documents made of words and pictures, any web designer can find a full set of HTML tags and CSS rules to enrich them, and  any  coder  can  fit  specific  needs  and  make pages  compositing  more  easy  by  extending  the language's built­in functionalities. Everybody  sharing  a  clear,  unique  and  coherent notation  allowing  to  produce  rich  and  dynamical documents  in  a  true  collaborative  work.  Commenting this  work,  somebody  wrote  this:  «  Reminds  me  of John  McCarthy's  lament  at  the  W3C's  choice  of SGML as the basis for HTML: "An environment where the  markup,  styling  and  scripting  is  all  s­expression based would be nice." » This was the goal of the lambdaway project[19]. Villeneuve de la Raho, 2016/11/22

references

{λ way}

- [1] https://en.wikipedia.org/wiki/Wiki - [2] https://en.wikipedia.org/wiki/Wiki_markup - [3] http://epsilonwiki.free.fr/lambdaway/? view=latex - [4] http://epsilonwiki.free.fr/lambdaway/? view=PDF - [5] http://epsilonwiki.free.fr/lambdaway/? view=curl - [6] http://epsilonwiki.free.fr/lambdaway/? view=LML - [7] http://epsilonwiki.free.fr/lambdaway/? view=skribe - [8] http://docs.racket-lang.org/scribble/ - [9] http://epsilonwiki.free.fr/lambdaway/? view=SXML - [10] http://people.cs.aau.dk/~normark/laml/papers/webprogramming-laml.pdf - [11] http://docs.racket-lang.org/pollen - [12] https://fr.wikipedia.org/wiki/Suite_de_Fibonacci - [13] https://en.wikipedia.org/wiki/De_Casteljau's_algorithm - [14] https://en.wikipedia.org/wiki/Simon_Peyton_Jones - [15] https://www.cnet.com/news/googlesubtracts-mathml-from-chrome - [16] https://en.wikipedia.org/wiki/Ward_Cunningham - [17] http://jwodder.freeshell.org/lambda.html - [18] http://epsilonwiki.free.fr/lambdaway/? view=calc2talk - [19] http://epsilonwiki.free.fr/lambdaway/ - ... - PDF version generated from this wiki page - ... - ... {λ way} v.20160608

http://epsilonwiki.free.fr/lambdaway/index.php?view=krakow

11/11