{λy}
primitives
libraries
{www}
it's me
the {λy} project
( S-expression based writing, styling & coding hypertext editor )
alain marty | marty•alain@free•fr
last update: 2025/03/22

Note: This wiki page is a lambdatalk program evaluated in realtime (about 50ms on my MacBook Air, iPad Pro, or smartphone). Please, don’t be disoriented by this page splitted in narrow columns lost in a large format. Like any spreadsheet (Excel, ...) it can be comfortably consulted and edited on any screens, wide and narrow, just use zooms +/- or dblclicks, sliders and fingers, it's easy and safe.

Pour les francophones, cette page concepts pourrait être une bonne lecture introductive. A moins de prendre un chemin de traverse.

You are welcome in the {lambda way} project, a light framework built on a wiki, {lambda tank}, and a programming language, {lambda talk}, working in any web browser. In other words lambdaway is an « S-expression based writing, styling & coding hypertext editor ».

At the end of the 70's I bought a HP67 pocket calculator and discovered that adding 1 and 2 was done using the strange reverse Polish notation, "1 2 +". Much later I came across LISP and discovered prefixed parenthesized expressions., (+ 1 2), i.e. the normal Polish notation in parentheses.

Then, thanks to Steven Levithan, I discovered (on July 2011) that an HTML expression like

<b><i><u>Hello World</u></i></b>
-> Hello World

requiring that closing brackets be written in the reverse order, could be better written in a LISP style (… Lot of Insane and Silly Parenthesis …)

{b {i {u Hello World}}}
-> Hello World

without boring anymore with the order of closing brackets. It is interesting to know that the transition between this expression and the HTML expression (which the browser knows how to evaluate) is easy and fast using a single javascript function passing and passing over the text a single regular expression.

Finally, thanks to the javascript language coming with any web navigator, I could extend the HTML syntax with mathematical properties, for instance writing {* 1 2 3 4 5 6}, where * is defined as the product operator, displays the product, "720", writing {u {i {* 1 2 3 4 5 6}}} displays "720" in italic and underline styles, and much more ... making easy and coherent the mixing of text, style and code.

This made me want to write an hypertext editor with a programming language and its current state is in this wiki.

Let's remember that the father of LISP, John McCarthy, lamented 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. » Answers like BBcode or SexpCode solve part of the problem. The {lambda way} project could be a better one, a small wiki easy to install with a true programming language.

A detailed introduction to the {lambda way} project can be found in

λ-calc, λ-talk, λ-tank

where

• 1) in λcalc, the core, using only an extremely reduced core of its features, (words, abstractions, applications), and an empty dictionary, (no primitives, no numbers, nothing), I build and progressively discover some essential data structures, (booleans, pairs, lists, numbers), as well as a tool to deal with them, recursion ;
• 2) in λtalk, special forms & primitives, I introduce a list of 9 special forms, (lambda, def, if, let, quote, macro, script, style, require), making the code faster and easier to write, as well as a set of about 200 primitives, (words, numbers, arrays, html, svg, ...), and a first set of libraries, (big numbers, complex numbers, ...), opening the language to the rich ecosystem provided for free by web browsers ;
• 3) in λtank, the environment, I present the IDE, interactive development environment, the wiki lambdatank and its installation on any web browser, as a dwarf on the shoulders of giants.

You could see also the homepage of the previous workshop lambdaspeech, pages {λy}, whynot, concepts, function, simply, digest, imerir, reflexions_20201219, essais, ... and also a gentle introduction in 5 pages in prime_pattern. Or lambdatalk at rosettacode.org and its popularity, 100th of 926 languages. Please, take a few minutes to read one of them, depending on your preferences, before you venture into the labyrinth of this current workshop, called lambdawalks, and for ever under construction...

You can download the engine, test lambdatalk safely in the sandbox page, write a message in the agora page or send me an email at marty.alain_at_free.fr.

( 2025 03 29 05 58 05 )
Open to the huge WWW library ...

short in time

« I have always wished for my computer to be as easy to use
as my telephone; my wish has come true because
I can no longer figure out how to use my telephone.
»
(Bjarne Stroustrup)

If you are short in time, here is in a few words the core of the syntax.

You are in a wiki called lambdatank. Now, look at the title of this wiki page: lambdaway :: start

• 1) Click on the word start to open the text editor's frame
• 2) Write some words and see how they are displayed in real time in the wiki page's frame.

What kind of words? Let's go on more precisely:

1) words

A word is any group of characters except spaces and curly braces. Away from curly braces words are just words.

Hello World              // input   (in the text editor frame)
-> 
Hello World              // output  (in the wiki page)

So, you write words as they are and you get them unchanged as in a standard text editor. You are not writing in a "programming console" where words must be quoted and strings concatenated using some "print()" function.

Let's go further, words can be assembled in more or less complex expressions.

2) expressions

In lambdatank you wont find the [B], [I], [U], ... buttons to boldify, italicize, underline words. Yo will use expressions to do so and much more. Expressions are written in a prefixed parenthesized notation using curly braces, {}.

{u Hello World}                 // underline words
-> Hello World

{+ 1 2}                         // compute 1+2
-> 3

{sqrt {+ {* 3 3} {* 4 4}}}      // compute √32+42
-> 5 

{/ {+ 1 {sqrt 5}} 2}            // (1+√5)/2
-> 1.618033988749895            // the golden ratio Φ

{u {* 1 2 3 4 5 6}}             // underline 1*2*3*4*5*6
-> 720

2+3 is {u equal} to {+ 2 3}     // mixing words & expressions
-> 2+3 is equal to 5

{* {S.serie 1 20}}              // product of 1 to 20
-> 2432902008176640000

A coherent and uniform syntax making mixing text and calculus easy. And everything is evaluated and displayed in realtime, allowing the greatest interactivity.

Expressions are evaluated from inside out. Let's follow the evaluation of the third nested expression computing the diagonal of a triangle rectangle whose sides are 3 & 4, ( yes you do know that it's 32+42, and yes, the lambdatalk syntax is easy to read, just say « take the square root of the sum of the product of 3 by 3 and the product of 4 by 4 ». )

0: {sqrt {+ {* 3 3} {* 4 4}}}
1: {sqrt {+ 9 16}}
2: {sqrt 25}
3: 5

Note that [+, *, sqrt, u] are lambdatalk primitive functions allowing to add and mutltiply numbers, take the square root of a number, underline words, ... And {S.serie 1 20} just outputs the sequence 1 2 3 ... 19 20. These primitives are stored in a dictionary and this dictionary can be extended on demand.

Note for geeks: It may be interesting to know that the lambdatalk evaluator is built on a single line of javascript using this single regular expression:

/\{([^\s{}]*)(?:[\s]*)([^{}]*)\}/g

More about that in « Less is more! »

3) functions

Sometimes an expression can be unevaluable, for instance

{sqrt {+ {* a a} {* b b}}}
-> NaN

The result is NaN, a gentle error message meaning Not a Number, because sqrt, *, + are waiting for numbers and a & b are not numbers. One would like to be able to write such an expression without having to define once and for all the values of a & b and be able to assign numerical values to them as needed. Functions are created for this purpose.

In lambdatalk functions are created with lambda and named with def, using this syntax

{def myfunction
 {lambda {words}
       expression
}}
-> myfunction

were words are "slots", called variables, waiting for future words, called values. For instance

{def hypo
 {lambda {:a :b}
  {sqrt {+ {* :a :a} {* :a :b}}} 
 }
}                                
-> hypo

{def smart_hypo 
 {lambda {:a :b}
  The hypotenuse of a right triangle with sides :a and :b
  is equal to {hypo :a :b}
 }
}
-> smart_hypo

It's a good practice to prefix variables by a special character, say a colon ":". If you didn't do so in the smart_hypo function you would get strange results. Try it!

If you find this way of declaring a function strange, here is how we write the hypo & smart_hypo functions in JavaScript:

var hypo =
 function(a,b) {
  return sqrt(a*a+b*b);
 };

var smart_hypo =
 function(a,b) {
  return "The hypotenuse of a right triangle with sides "
         +a+" and "+b+" is equal to "+hypo(a,b);
 };

Just a matter of choice! Writing arithmetic operators is certainly not familiar in lambdatalk, but note how unreadable the concatenation of portions of text and function calls is in javascript. Making it easy to mix text and calculations guided the design of lambdatalk. A good thing for a web page!

Constants can be created too

{def HW Hello World}
-> HW

{def Φ {/ {+ 1 {sqrt 5}} 2}}    // evaluated once
-> Φ                            // the golden ratio

Function's names and constants are added to the dictionary, extending the existing set of primitives and can be used the same way

{HW}
-> Hello World

{Φ}
-> 1.618033988749895

{hypo 3 4}
-> NaN

{hypo 1 1}
-> NaN

{smart_hypo 3 4} 
-> The hypotenuse of a right triangle with sides 3 and 4 is equal to NaN

You are welcome in lambdatalk, the programming language of this wiki, lambdatank.

Technical note

Not only lambdatalk functions accept partial application but most of them accept an undefined number of values. For instance

{def HI
 {lambda {:a :b} 
  My name is :b, :a :b
}}
-> HI

is a function waiting for two words.

• 1) when only 1 word is given an anonymous function is created and returned, memorizing this word and waiting for the missing one
{HI James}
-> _LAMB_30       // reference of an anonymous function

This anonymous function, {lambda {:b} James :b} can be applied to a second word

{{HI James} Bond}         // equivalent to {_LAMB_25 Bond}
-> My name is Bond, James Bond   // now it's OK
• 2) when 2 words are given everything works as expected
{HI James Bond}                  
-> My name is Bond, James Bond
• 3) when more than 2 words are given the last variable simply takes all the rest, here :b will take "Duchess of Windsor"
{HI Wallis Duchess of Windsor}      
-> My name is Duchess of Windsor, Wallis Duchess of Windsor

Partial application and variadicity are two strong points of the lambdatalk functions.

4) forks

Sometimes you have to make choices, to do something according to some condition. Lambdatalk comes with a third special form, if

{if condition 
 then do this ...
 else do that ...
}

and a set of functions returning true or false, for instance =, <, >, ... allowing to build some useful functions, for instance

{def sign
 {lambda {:n}
  {if {< :n 0}
   then :n is negative
   else {if {> :n 0}
         then :n is positive
         else :n is nul
}}}}
-> sign

{sign -123}
-> -123 is negative

{sign 123}
-> 123 is positive

{sign 0}
-> 0 is nul

Note that ifs can be nested and how mixing words and numbers is done in a natural way.

5) loops

« Iteration is human, recursion is divine.

Sometimes it is necessary to repeat an action and you will use either iteration or recursion.

• 1) To repeat an action a certain number of times and so build an iterative process you can use the S.map and S.serie primitives, for instance
{S.map sqr {S.serie 1 16}}  
-> 

{S.map sqrt 1 2 3 4 5}      
-> 1 1.4142135623730951 1.7320508075688772 2 2.23606797749979
• 2) To repeat an action under a certain condition you will preferably build a recursive function, calling itself until the problem is solved (or not), dividing the problem into a sub-problem easier to solve until it can be solved. The divide & conquer method.

For instance here is the well known factorial function computing the product of numbers form 1 to n defined this way

factorial(n) =
   if n > 1
   then n * factorial( n-1 )   // n * (do it again on n-1)
   else 1                      // the product of 1 by 1 is 1

immediately translated into this lambdatalk code

{def factorial
 {lambda {:n}
  {if {> :n 1}
   then {* :n {factorial {- :n 1}}}
   else 1
}}}
-> factorial

{factorial 6}
-> 720

{factorial 20}
-> 2432902008176640000

6) let it be

Let's go back to the expression

{sqrt {+ {* 3 3} {* 4 4}}}
-> 5

abstracted as a function

{def hypo
 {lambda {:a :b}
  {sqrt {+ {* :a :a} {* :b :b}}}
}}
-> hypo

and applied like this

{hypo 3 4}
-> 5

In fact this last expression is an easy way to write

{{lambda {:a :b} {sqrt {+ {* :a :a} {* :b :b}}}} 3 4}
-> 5

where an anonymous function - here we don't give it a name - is created and immediately applied to two values. We call IIFE this expression, Immediately Invoked Function Expression, whose general form is the following

{{lambda {vars} expression} values}

Basically a lambdatalk code is nothing but a sequence of IIFEs.

IIFEs being rather dificult to write and read, lambdatalk provides a fourth special form, let

{let { {variable_1 value_1}
       {variable_2 value_2}
        ...
     } expression
}

which is a syntactic sugar of an IIFE, highlighting the binding between variables and values and introducing what is called a local context where expression is evaluated.

For instance {{lambda {:a :b} {sqrt {+ {* :a :a} {* :b :b}}}} 3 4} can be rewritten as

{let { {:a 3}
       {:b 4}
     } {sqrt {+ {: a :a} {* :b :b}}}
}

where we understand that we define two variables :a and :b, we assign them two values 3 and 4 and we use them in an expression.

From now on, when you will meet some javascript code like this IIFE

let c = (function(a,b) {            // an anonymous function
    return Math.sqrt( a*a + b*b )   // immediately applied
} ) (3,4);                          // to two values

or like this sequence of local definitions and assignments

let a = 3,
    b = 4,
    c = Math.sqrt( a*a + b*b );

which is its "syntaxtic sugar" equivalent, you should not be surprised ... and even you could fall in love with s-expressions revealed in LISP, Lot of Insane and Silly Parentheses.

See this page closure to learn more about local contexts.

7) and so what?

And that's it for the most part! That's all is needed to build a programming language and to explore lots of algorithms.

Let's look at some of them.

... a small text editor ...

on the road

« Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.
»
(Kent Beck)

1) hilbert

For instance let's draw the Hilbert curve, which fills a square

{def left
 {lambda {:d :n}
  {if {< :n 1}
    then
    else T90      {right :d {- :n 1}}
         M:d T-90 {left  :d {- :n 1}}
         M:d      {left  :d {- :n 1}}
         T-90 M:d {right :d {- :n 1}}
         T90
}}}
-> left
{def right
 {lambda {:d :n}
  {if {< :n 1}
    then
    else T-90    {left  :d {- :n 1}}
         M:d T90 {right :d {- :n 1}}
         M:d     {right :d {- :n 1}}
         T90 M:d {left  :d {- :n 1}}
         T-90
}}}
-> right

The word rotates the drawing direction of a pen from θ degrees and the word Md moves it on d pixels. Writing {left 18 5} produces 2387 words begining with [T90 T-90 T90 T-90 T90 M10 T-90 M10 T-90 M10 T90 M10 T90 T-90 M10 T90 M10 T90 M10 T-90 M10 T-90 M10 T90 M10 T90 M10 T-90 T90 M10 T90 M10 T-90 M10 T-90 ...] which are sent to a graphic primitive, turtle, which draws the curve in a SVG context.

2) hanoï

Let's play with the Towers of Hanoï

{def hanoi
 {lambda {:n :from :to :temp}
  {if {= :n 0}
   then stop
   else {hanoi {- :n 1} :from :temp :to}
        {br}move :n from :from to :to
        {hanoi {- :n 1} :from :temp :to}}}}
-> hanoi 

{hanoi 4 A B C}
->  
move 1 from A to C
move 2 from A to B
move 1 from A to C
move 3 from A to C
move 1 from A to C
move 2 from A to B
move 1 from A to C
move 4 from A to B
move 1 from A to C
move 2 from A to B
move 1 from A to C
move 3 from A to C
move 1 from A to C
move 2 from A to B
move 1 from A to C

3) cyclics

and draw beautiful cyclic curves that randomly change shape each time the page is refreshed. Try it out!

P(t) = eit + 1/2eA*it + i/3eB*it, where A = 4 & B = 2

4) love

You may be a poet, not a mathematician, and you don't know how to declare your love to a "fair lady". Lambdatalk can help you:

{def inject
 {lambda {:x :a}
  {if {A.empty? :a}
   then {A.new {A.new :x}}  
   else {let { {:c {{lambda {:a :b}
                     {A.concat {A.new {A.first :a}} :b}} :a}}
               {:d {inject :x {A.rest :a}}}
               {:e {A.concat {A.new :x} :a}}
             } {A.concat {A.new :e} {A.map :c :d}}}}}} 
-> inject

{def permut
 {lambda {:a}
  {if {A.empty? :a}
   then {A.new :a}
   else {let { {:c {{lambda {:a :b}
                            {inject {A.first :a} :b}} :a}}
             } {A.reduce A.concat {A.map :c :d}}}}}}
-> permut

{def A.reduce
 {lambda {:f :a}
  {if {A.empty? :a}
   then {A.new}
   else {:f {A.first :a} {A.reduce :f {A.rest :a}}}}}}
-> A.reduce

{S.replace (\[|\]) by in 
 {S.replace \]\s\[ by {br} in
  {S.replace , by space in 
   {S.replace \],\[ by space in 
    {A.disp
     {permut
      {A.new {A.new Fair lady}
             {A.new your sweet eyes} 
             {A.new make me die} 
             {A.new of love}
}}}}}}}
-> 
Fair lady your sweet eyes make me die of love
your sweet eyes Fair lady make me die of love
your sweet eyes make me die Fair lady of love
your sweet eyes make me die of love Fair lady
Fair lady make me die your sweet eyes of love
make me die Fair lady your sweet eyes of love
make me die your sweet eyes Fair lady of love
make me die your sweet eyes of love Fair lady
Fair lady make me die of love your sweet eyes
make me die Fair lady of love your sweet eyes
make me die of love Fair lady your sweet eyes
make me die of love your sweet eyes Fair lady
Fair lady your sweet eyes of love make me die
your sweet eyes Fair lady of love make me die
your sweet eyes of love Fair lady make me die
your sweet eyes of love make me die Fair lady
Fair lady of love your sweet eyes make me die
of love Fair lady your sweet eyes make me die
of love your sweet eyes Fair lady make me die
of love your sweet eyes make me die Fair lady
Fair lady of love make me die your sweet eyes
of love Fair lady make me die your sweet eyes
of love make me die Fair lady your sweet eyes
of love make me die your sweet eyes Fair lady

5) mandel

You can play interactively in a canvas with the mandelbrot set or draw it directly in the wiki page as a string of "o" and "."

. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . o o o . . . . . . . . . . . . . . 
. . . . . . . . . . . . . o o o o o . . . . . . . . . . . . . 
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . 
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . 
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . 
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . 
. . . . . . . . . o o o o o o o o o o o o o . . . . . . . . . 
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . 
. . . . . . . . . . o o o o o o o o o o o . . . . . . . . . . 
. . . . . . . . . . . o o o o o o o o o . . . . . . . . . . . 
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . 
. . . . . . . . . . . . o o o o o o o . . . . . . . . . . . . 
. . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . 
. . . . . . o . o o o o o o o o o o o o o o o . o . . . . . . 
. . . . . . o o o o o o o o o o o o o o o o o o o . . . . . . 
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . 
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . 
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . 
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . 
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . 
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . 
o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o 
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
o . o o o o o o o o o o o o o o o o o o o o o o o o o o o . o 
. . o o o o o o o o o o o o o o o o o o o o o o o o o o o . . 
. . . o o o o o o o o o o o o o o o o o o o o o o o o o . . . 
. . o . o o o o o o o o o o o o o o o o o o o o o o o . o . . 
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . 
. . . . o o o o o o o o o o o o o o o o o o o o o o o . . . . 
. . . . o o o o o o o o o o o . o o o o o o o o o o o . . . . 
. . . . o . . . o o o o o o . . . o o o o o o . . . o . . . . 
. . . . . . . . o . . o o . . . . . o o . . o . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

with

{S.map {lambda {:i} {br}                           // loop on y
  {S.map {{lambda {:i :j}                          // loop on x
    {mandel 20 :i :j}} :i}                         // compute with iter=20
  {S.serie 0 30}}}                                 // x resolution
{S.serie 0 40}}                                    // y resolution

{def mandel
 {def mandel.r
  {lambda {:iter :cx :cy :norm :x :y :count}
   {if {> :count :iter}                            // then norm < 4
    then o                                         // inside the set
    else {if {> :norm 4}                           // then iter > max
    then .                                         // outside the set
    else {let { {:cx :cx} {:cy :cy} {:iter :iter}  // remember...
                {:X {+ {* :x :x} -{* :y :y} :cx}}  // compute
                {:Y {+ {* 2 :x :y} :cy}}           // z = z^2+c
                {:count {+ :count 1}}
              } {mandel.r :iter :cx :cy            // unchanged
                          {+ {* :X :X} {* :Y :Y}}  // new norm
                          :X :Y                    // new x & y
                          :count} }}}}}            // next count
 {lambda {:iter :cx :cy}
  {mandel.r :iter
            {+ {* :cx 0.05} -1.50}                 // centering the set
            {+ {* :cy 0.05} -0.75}                 // inside the frame
            0 0 0 0} }}

6) dirac

And a beautiful equation, the dirac equation, for the fun:

ih
∂ψ
∂t
(x,t) = (mc2α0 - ihc
3
Σ
j=1
αj
∂xj
) ψ(x,t)

writing

{div
 {@ style="font:italic 1.2em georgia; 
           text-align:center;"}
i{del h}{quotient 30 ∂ψ ∂t}(x,t) = 
{paren 3 (}mc{sup 2}α{sub 0} -
i{del h}c {sigma 30 j=1 3} α{sub j} {quotient 30 ∂ ∂x{sub j}}
{paren 3 )} ψ(x,t)
}

where quotient, sigma and paren are three user defined functions playing with standard HTML/CSS

{def quotient 
 {lambda {:s :num :denom}
  {table {@ style="width::spx; display:inline-block; 
                   vertical-align:middle; text-align:center;"}
   {tr {td {@ style="border:0 solid; border-bottom:1px solid;"}:num}}
   {tr {td {@ style="border:0 solid;"}:denom}}
}}} 
-> quotient

{def sigma 
 {lambda {:s :one :two}
  {table {@ style="width::spx; display:inline-block;
                   vertical-align:middle; text-align:center;"}
 {tr {td {@ style="border:0 solid;"}:two}}
 {tr {td {@ style="border:0 solid; font-size:2em; line-height:0.7em;"}Σ}}
 {tr {td {@ style="border:0 solid;"}:one}}
}}} 
-> sigma

{def paren
 {lambda {:s :p} 
  {span {@ style="font:normal :sem arial; 
                  vertical-align:-0.15em;"}
        :p}
}}
-> paren

Nothing but standard HTML/CSS code whose rules are explained in deep anywhere on the web. Pages like pocket_calculator and pub should help you to think you are a smart webdesigner ... ~¿~

7) continuous fractions

Continuous fractions are a monument of mathematics. I never tire of contemplating it. The most remarkable of the continued fractions contains only 1

φ = [1;1,1,1,1,...]
  = 1 + 1
        1 + 1
            1 + 1
                1 + 1
                    1 + ...
bt)

and is nothing other than the golden ratio, φ = 1.618033988749895. This one is no less so

π = 4
    1 + 12
        2 + 32
            2 + 52
                2 + 72
                    2 + 92
                        2 + ...

leading to π = 3.141592653589793, the strangest of transcendental numbers whose decimals are totally randomly distributed, (high entropy), and captured in a beautiful, perfectly determined serie, (high neguentropy). Our (decimal) representation of numbers is decidedly poor and one could imagine that in the noosphere minds use continued fractions to manipulate them ... why not?

8) sierpinsky's carpet

As a last example this is how to draw a Sierpinsky's carpet written with two primitives, S.replace & S.map.

{def sierpinsky 

 {def sierpinsky.r
  {lambda {:n :w}
   {if {= :n 0}
    then :w
    else {sierpinsky.r 
          {- :n 1}
          {S.map {lambda {:x} :x:x:x} :w}
          {S.map {lambda {:x} :x{S.replace ■ by o in :x}:x} :w}  
          {S.map {lambda {:x} :x:x:x} :w} }}}}

 {lambda {:n}
  {h2 S:n}{S.replace o by space in 
            {S.replace \s by {div} in 
             {sierpinsky.r :n ■}}}{div}}}
-> sierpinsky

{S.map sierpinsky 0 1 2 3} ->

whose result is the following long formated sequence of chars

S0
.
.
S1
.
■■■
■ ■
■■■
.
S2
.
■■■■■■■■■
■ ■■ ■■ ■
■■■■■■■■■
■■■ ■■■
■ ■ ■ ■
■■■ ■■■
■■■■■■■■■
■ ■■ ■■ ■
■■■■■■■■■
.
S3
.
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■ ■■■■■■ ■■■■■■ ■■■
■ ■ ■ ■■ ■ ■ ■■ ■ ■ ■
■■■ ■■■■■■ ■■■■■■ ■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■ ■■■■■■■■■
■ ■■ ■■ ■ ■ ■■ ■■ ■
■■■■■■■■■ ■■■■■■■■■
■■■ ■■■ ■■■ ■■■
■ ■ ■ ■ ■ ■ ■ ■
■■■ ■■■ ■■■ ■■■
■■■■■■■■■ ■■■■■■■■■
■ ■■ ■■ ■ ■ ■■ ■■ ■
■■■■■■■■■ ■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■ ■■■■■■ ■■■■■■ ■■■
■ ■ ■ ■■ ■ ■ ■■ ■ ■ ■
■■■ ■■■■■■ ■■■■■■ ■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■
.

Yes, it's a sequence of words, ■, and not pictures.

9) watch

Or just write this expression {linear_watch} to display a linear watch

It's endless. And you are welcome in the marvelous world of code.

... to write and code in a coherent & simple way.

the workshop

« Perfection is finally attained
not when there is no longer anything to add,
but when there is no longer anything to take away.
»
(Saint Exupery)

1) special forms

Currently lambdatalk comes with 9 special forms making it a true programming language

lambda, def, let, if, quote, macro, style, script, require

You could see interesting things about the first four special forms in the page concepts.

2) primitives

Accompanying the set of special forms there is an extendable set of primitives dealing with words, sentences, arrays, maths, html/css, the dom and a few more things:

DICT: [180] [unquote, include, lib, @, div, span, a, ul, ol, li, dl, dt, dd, table, tr, td, h1, h2, h3, h4, h5, h6, p, b, i, u, center, br, hr, blockquote, del, sup, sub, code, img, pre, textarea, audio, video, source, select, option, object, canvas, svg, line, rect, circle, ellipse, polygon, polyline, path, text, g, mpath, use, textPath, pattern, image, clipPath, defs, animate, set, animateMotion, animateTransform, title, desc, input, iframe, hide, prewrap, +, *, -, /, %, <, >, <=, >=, =, not, or, and, abs, acos, asin, atan, ceil, cos, exp, floor, pow, log, random, round, sin, sqrt, tan, min, max, PI, E, date, W.equal?, W.empty?, W.length, W.get, W.first, W.rest, W.last, W.slice, W.reverse, W.sort, W.lib, S.equal?, S.empty?, S.length, S.first, S.rest, S.last, S.get, S.slice, S.serie, S.map, S.reduce, S.replace, S.reverse, S.sort, S.lib, A.new, A.disp, A.join, A.split, A.array?, A.null?, A.empty?, A.in?, A.equal?, A.length, A.get, A.first, A.last, A.rest, A.slice, A.duplicate, A.reverse, A.concat, radic, A.map, A.set!, A.addlast!, A.sublast!, A.addfirst!, A.subfirst!, A.reverse!, A.sort!, A.swap!, A.lib, P.new, cons, P.pair?, P.left, car, P.right, cdr, P.disp, P.lib, LS.display, LS.setItem, LS.getItem, LS.removeItem, LS.clear, show_last_code, turtle, long_add, long_mult, uncover, drag, editable]
Please click on Amélie Poulain to see the 180 primitives.

everything built on the underlying powerful tools coming with any web browsers and opening lambdatalk to the huge library of the World Wide Web.

3) libraries

Lambdatalk comes with an extensible set of libraries dealing with complex numbers, big numbers, 3D graphics, ... the essential point being that theoretically any free HTML/CSS/DOM/JS libraries found on the web can be used in lambdatalk via interfaces easy to implement.

4) explorations

In this workshop I'am going on, continuously exploring various algorithms with a unique goal: « synthesize all the exploratory work in a stronger language's core, more coherent sets of primitives and better designed libraries. »

So, starting again, I'm refactoring everything, randomly as usual, dispatched in more than 1000 pages. Amongst others, you might have a look to these recent pages, the last one being the most recent created or edited.

lambda factory, fromroots2canopy, λy, book, coding, lambda, crypt, fibonacci, FFT, pub, bilingue, meta10, lambdacode, iife, oops, oops4, oops6, pablo_rauzy, Ycombinator, binary_digit, scheme, fr2c, exponent, stairs, prime_pattern, block_edit, reflexions_20201219, WSAP, castel, coques, eric_dobbs, divine_recursion, pict, fr2c, fun calc, story, trampoline, tromp, timegoeson, details, radotages, Y, coder, meta5, BN, scratch, binaries, bigint, traverse, habiter, nostalgie, fractions, rationals, scramble, pocket_calculator, match, janus, racket, funstacker2, florilège, even_odd, string_sort, bezier_3, intersection, simpson, textanddraw, perm3, replace, binary_search, string_matching, fac2iife, words_numbers, essais, concepts, cyclics, scheme, pforms5, RISC, janus, lib_plot, simply, ... fast fourier transform, de casteljau algorithm, quicksort, big numbers in lambda-calculus, scratch, pforms, story3, thelambdawayproject, pocket_calculator, pub, pforms5, levithan, story, rationals, IA, rationals, relativite_complexe, insomnies, break, janus, barycentre, horner, trombinoscope, poo, randomwalk, function, partition, janus, sierpinsky3, unclosure, musical_scales, sierpinsky_compare, viewing_trees, concepts, verlet, towards oop, gamma, laura, lib_plot, simply, bigint, curzon_numbers, reduce3, simply_scheme, erato3, agm, middle_square, rare_numbers, powerset, fr2c, scheme, happy_number, pell, euler_constant, primes, counter2, spigot, harshad, ASCII, loop_increments, catalan_numbers, hamming_numbers3, super_ellipse, anti_primes, semiprime, lcs, additive_primes, matrix3, egyptian_division2, cuboid, find_in_unixdict, line_intersection, modular_inverse, tablesort, babbage, root_mean_square, factorions, kernel, deceptive, haversine, median, stack & queue, hanoi4, concepts | divine_recursion, florilege, from Y to Ω, reflexions_20201219, pablo_rauzy, color_bar_display, chatGPT, quicksort5, noosphere, ceci-nest-pas-une-pipe, jules_verne, whynot, musique, echelle, intrication_quantique, divine_recursion, abstraction_application, acceleration, essais, fr2c, barycentre, concepts, meta3, kids don't need tools for kids, bilingue, RISC, quantique, acceleration, essais, question, wooden_picts, animation, BOOK, invariants, tableau, function, tinyjpg, ELS_2018, yanlecun, ...

Les dernières explorations sont dans ces pages : relativite_complexe, pf_2025, pf, pForms, raytrace, the_roots_of_coding, hilbert_chatgpt, chatgpt_langue, chatmag, divine_recursion, jean_charon, rc'fibrée, fibres_spatiotemporelles, divine_recursion, ...

See also more than 200 tasks solved using lambdatalk in rosettacode.org. Once again, for a global presentation see lambdaspeech and λ-calc, λ-talk, λ-tank.

Remember that all algorithms presented in this wiki are active and evaluated in real time, which allows everyone to test them at will, to understand them thoroughly and, why not, to improve them.

5) and so what?

Good news: {lambda talk} can live outside its alma mater, {lambda tank}, and is recently hosted in a wiki v2.0, ustawi.wiki, led by the father of wikis, Ward Cunningham, making a small place for itself there.

And finally you should know that this wiki page - like all others - is a lambdatalk program, the text that composes it is written in lambdatalk, the titles, paragraphs, images and of course every code examples are lambdatalk code, evaluated in real time. This page is computed in less than 100ms on my iPad Pro.

You can safely enter the page editor (click on the word "start" at the top left of the page) and modify what you want, test algorithms, modify values. Just try it. It's by "tinkering" with the code that you'll eventually understand it. You can at least test anything in the sandbox. Feel free to tell me your opinion in the agora or via an e-mail.

You can download the {lambda way} project for free. You can analyse the {lambda talk}'s JS engine, and the {lambda talk} code of this page clicking on the name "start" on top of this page.

You are welcome in my playground, full of funny colors.

rgba

These eight primary colors are displayed writing

{div
  {@ style="position:relative;
            top:0; left:0;
            width:310px; height:310px;
            margin:auto;
            background:#000;"}
 {rgba 90 10 200 200 #0f0}
 {rgba 50 90 200 200 #00f}
 {rgba 10 50 200 200 #f00}
 {rgba 50 90 160 160 #f0f}
 {rgba 90 50 40 120 #ff0}
 {rgba 210 90 120 40 #0ff}
 {rgba 90 90 120 120 #fff}
}

where

{def rgba
 {lambda {:y :x :w :h :c}
  {div
   {@ style="position:absolute;
             top::ypx; left::xpx;
             width::wpx; height::hpx;
             background::c;
             border:5px solid #000;"
}}}}

And thanks to Aude Picault, without Flash's burden, a sweetened version, yet so fun to orchestrate. And if you have annoying neighbors that you want to move, have fun all night long by turning the sound up to the max...

La fanfare, the brass band
 tuba
 trompette
 grosse caisse
 caisse claire
 soubassophone
 trombone
instrument

Nothing but HTML/CSS plus a few small ingredients.

... and javascript is always there for you :

• to build some MATRIX display

to play with pForms

to play with raytrace

And more ...

Représentation de l'interaction de quatre lignes d'univers en pelures d'oignon dans un espace quadri-dimensionnel complexe, avec son code générateur. Image crée en utilisant les Formes Pascaliennes, combinaisons de formes multilinéaires, récursives, barycentriques, définies dans un espace affine, sans métrique, à 4 dimensions
Escher hands

conclusion

« Live as if you were to die tomorrow.
Learn as if you were to live forever.

(Gandhi)

What to think of the lambdaway project?

This is what Ward Cunningham told me on March 29, 2014:

« I am impressed with this work and understand its uniqueness better now. I have also rambled through other pages you have made, many as experiments I would guess, and have been summarized by you in this single work. Bravo. »

And also, a few months later:

« 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!

and more recently (19/07/2020)

« I’ve always admired your work, both the interpreter and your exploration of its capabilities. In the wiki tradition it offers clear passage into the networking and graphic capabilities of the browser. Thompson sees it as a philosophical artifact rooted in history and uncovered anew by you. »

You could read some other more or less positive comments on the lambdaway project, for instance here and there. This one was premonitory

« Oh please nooooo! There are hundred of wiki engines and hundred of languages! Why yet another wiki and another language nobody will ever want to use? »

This other one was more kind

« I like it when I find this simple yet powerful ideas implemented, these are the things that when you see them you think, Why didn't I think of that? » (reddit/maufdez)

and this one too

« This is brilliant by the way. Definitely show it to more people and get feedback, it is so outside of the norm that it will take time for the idea to spread. »

This guy had therefore seen right, this project is probably very outside of the norm ... and the idea has no yet found where to spread.

This is a recent one:

« I’m not quite sure how to describe {lambda way}. It’s a wiki based on a very simple programming language written in JS which looks like a lisp (it does have macros) but based on term rewriting (I think it’s just implemented using regular expressions, which is why it doesn’t have closures) that outputs HTML. If you press the start button (on top of this page) you can see that the pages of this wiki are {lambda talk} programs that can be edited in real time.

It’s a very idiosyncratic project, but it has a lot of interesting ideas. »

I couldn't say better!

A short email exchange:

Dear Alain Marty

As per lambdatalk – I'm afraid it will never become popular enough to see any widespread usage. The reason is simple – the common programmer's aversion towards functional programming, and even more towards lambda calculus. People like programming languages which mimick natural language. As a side note, this is precisely the reason why object-oriented programming is so popular, and will be for a long time.

--Dick de Bill (talk) 13:35, 29 May 2020‎ (UTC)

and my answer:

Dear Dick de Bill,

I understand the aversion one can have to functional programming when reading some codes in Haskell or even Javascript. I understand that one can run away from "academic and/or obscure" presentations of lambda-calculus. I understand that some Lisp codes cluttered with parentheses may look like a dish of spaghetti.

I thought I escaped that with lambdatalk. I guess not, or at least the first impression repulses the reader who fears to find an nth Lispian avatar with a functional and lambda-calculus sauce. This is probably the case.

I remember the Hypertalk language as a rather successful - and rather cumbersome - attempt at syntax close to natural language. I thought that lambdatalk was pretty close, just adding (grey) brackets in the background. I think that anyone can understand that if you ask somebody to

replace :x & :y 
     in hello :x :y world 
     by brave & new

the answer will be hello brave new world.

And I thought that anyone could guess that rhe following expression

{{lambda {:x :y} 
          hello :x :y world
        } brave new}

is a code which can be used to "talk" to a computer in order to get the same answer. It's a kind of lambda-calculus at level zero. But I'm probably wrong.

Thank you for your attention.

-- Alain Marty

Finally, I remember that, 7 years ago, for the SCHEME & FUNCTIONAL PROGRAMMING WORKSHOP 2017 | OXFORD UK | 2017/09/03, I could directly generate from a wiki page, used as a workshop, a PDF paper, and the slides for the presentation. Without any return, neither good nor bad. Nada!

Well, I'll deal with that, and the show will go on, even if the theater is empty. Even if I am alone, I enjoy the trip, exploring algorithms of anything. The quest of minimalism is endless.

The quest of minimalism is endless.
« Less is more » (Mies van der Rohe)
The Nyls house (AM architect)
These days, most of the time, I'm working in the noosphere
Goodbye.
HN
block HMS linear_watch PICT AA BB CYCLIC SVG AXES stroke