lambdaway
::
coding2
3
|
list
|
login
|
load
|
|
_h1 [[λ{sup calc}|?view=coding]] | λ{sup talk} | [[λ{sup tank}|?view=coding3]] {{block} {uncover data/bibliotheque_virtuelle.jpg 100 400 The lambdawaay project is opened to a huge library freely accessible on the web } _h2 introduction _p The goal of the previous page, [[λ{sup calc}|?view=coding]], was to give a gentle introduction to coding, highlighting the unicity of a mechanism used to evaluate expressions, which is nothing but a simple text replacement process. In the current page we will discover that {b lambdatalk} is not lost in an empty space. Hosted in {b lambdatank}, a small wiki installed on any web browsers, it takes benefit from powerful web technologies like HTML, CSS, SVG, DOM and Javascript. _ul introduction _ul 1) special forms _ul20 1.1) lambda _ul20 1.2) def _ul20 1.3) if _ul20 1.4) let _ul20 1.5) quote _ul20 1.6) macro _ul20 1.7) script _ul20 1.8) style _ul20 1.9) require _ul 2) data structures _ul20 2.1) words _ul20 2.2) strings _ul20 2.3) arrays _ul20 2.4) pairs, lists _ul 3) primitives _ul20 3.1) maths _ul20 3.2) html/css _ul20 3.3) graphics _ul20 3.4) miscellaneous _ul 4) libraries _ul20 4.1) lib_BN _ul20 4.2) ... _ul conclusion {center ((( See also [[computation as text rewriting|?view=oops]] )))} } {{block} {uncover {COCO}/t_vlcdetail.jpg 100 800 VLC{br}encre monotype sur papier 18x24cm} _h2 1) special forms _p Lambdatalk generally evaluates forms {b from inside out}. For instance {pre 0: '{sqrt {+ {* 3 3} {* 3 4}}} 1: '{sqrt {+ 9 16}} 2: '{sqrt 25} 3: 5 } _p But we have seen that it's not always the case. The {b IIFE}s we have explored in page [[coding]] are not evaluated from inside out. For instance in the following {b IIFE} {pre '{{lambda {x y} {sqrt {+ {* x x} {* y y}}}} {+ 1 2} {+ 1 3}} } _p the inline expression {b '{lambda {x y} {sqrt {+ {* x x} {* y y}}}}} is first evaluated as a whole and replaced by a word, the reference to a function added to the dictionary, say {b function_ref}, {pre '{function_ref {+ 1 2} {+ 1 3}} } _p which is a normal form evaluated from inside out {pre '{function_ref {+ 1 2} {+ 1 3}} -> '{function_ref 3 4} -> 5 } _p Lambdas are the first {b special forms} built in lambdatalk. In the page [[coding]] we have introduced a second special form, {b def}, useful to give names to expressions. There are in fact a total of {b nine special forms} which are not evaluated "from inside out" {center {code {b [ lambda def if let quote macro script style require ]}}} _p Moreover lambdatalk is implemented so that these special forms are evaluated {b before} normal forms, following this order: {pre 1) {b require}: call and include libraries 2) {b preprocess}: skip comments, built_in macros, cleaning, ... 3) {b macro}: apply user defined macros 4) {b script}: insert javascript code 5) {b style}: insert CSS rules 6) {b quote}: protect quoted expressions from evaluation 7) {b let}: replace by lambda special forms, IIFE 8) {b lambda}: create anonymous functions 9) {b if}: protect from evaluation 10) {b def}: give a name to expressions 11) {b forms}: evaluate normal forms, from inside out 12) {b postprocess}: display quoted expressions, cleaning, ... } _p The result is a sequence of words inserted in an HTML document sent to the web browser which displays the result. _h3 1.1) lambda {pre '{lambda {:var ...} expression} } _p The first part, [[coding]], has introduced lambdas in depth. We just give a simple example {pre '{lambda {:a :b} :b :a} -> {lambda {:a :b} :b :a} } _p where {b _LAMB_0} is the reference of a function added to the dictionary, whose arguments are {b :a & :b} and the body is the string "{b :b :a}". By convention arguments are prefixed by a colon. _p Lambdas can be used in {b IIFE}s like this {pre '{{lambda {:a :b} :b :a} james bond} -> {{lambda {:a :b} :b :a} james bond} } _p Most of the time lambdas, which are anonymous function, will be given a {b name} using the {b def} special form. _h3 1.2) def {pre '{def name expression} } _p where {b expression} is evaluated before being given a name. _p Examples {pre '{def JB james bond} -> {def JB james bond} '{JB} -> {JB} '{def swap {lambda {:a :b} :b :a }} -> {def swap {lambda {:a :b} :b :a }} '{swap james bond} -> {swap james bond} '{def φ {/ {+ 1 {sqrt 5}} 2}} // the expression is -> {def φ {/ {+ 1 {sqrt 5}} 2}} // evaluated once '{φ} -> {φ} } _h3 1.3) if {pre '{if bool then expression 1 // if bool is true else expression 2 // if bool is false } } _p This special form protects the evaluation of {b expression 1} and {b expression 2} until the predicate {b bool} is evaluated to true or false. Compare with the examples in page [[coding]], where {b IF} was a user defined function calling expressions which had to be protected {i manually} using lambdas. _p Examples {pre '{if true then yes, it's true else no, it's false} -> {if true then yes, it's true else no, it's false} '{def signOf {lambda {:n} {if {> :n 0} then the number :n is positive else {if {< :n 0} then the number :n is negative else the number :n is null}}}} -> {def signOf {lambda {:n} {if {> :n 0} then the number :n is positive else {if {< :n 0} then the number :n is negative else the number :n is null}}}} '{signOf -123} -> {signOf -123} '{def fac {lambda {:n} {if {< :n 1} then 1 else {* :n {fac {- :n 1}}}}}} -> {def fac {lambda {:n} {if {< :n 1} then 1 else {* :n {fac {- :n 1}}}}}} '{fac 6} -> {fac 6} } _h3 1.4) let _p The {b let} special form {pre '{let { {:var :val} ...} expression} } _p is a {i syntactic sugar} for an {b IIFE} {pre '{{lambda {:var ...} expression} val ...} } _p with the benefit of highlighting local variables and their assignments. As a first example this is a local context where two (local) variables are defined and an expression is computed {pre '{let { {:a 3} {:b 4} } {sqrt {+ {* :a :a} {* :b :b}}} } -> {let { {:a 3} {:b 4} } {sqrt {+ {* :a :a} {* :b :b}}} } } _p Here we compute directly the area of a triangle defined by its sides [{b a,b,c}], following the formula: {code area = √{span {@ style="border-top:1px solid;"}s*(s-a)*(s-b)*(s-c)} with s = (a+b+c)/2} {pre '{let { {:a 3} {:b 4} {:c 5} {:s {/ {+ 3 4 5} 2}} } {sqrt {* :s {- :s :a} {- :s :b} {- :s :c}}} } -> {let { {:a 3} {:b 4} {:c 5} {:s {/ {+ 3 4 5} 2}} } {sqrt {* :s {- :s :a} {- :s :b} {- :s :c}}} } } _p or via a named function easier to use everywhere {pre '{def area {lambda {:a :b :c} {let { {:a :a} {:b :b} {:c :c} // manual re-assignments {:s {/ {+ :a :b :c} 2}} } {sqrt {* :s {- :s :a} {- :s :b} {- :s :c}}} }}} -> {def area {lambda {:a :b :c} {let { {:a :a} {:b :b} {:c :c} {:s {/ {+ :a :b :c} 2}} } {sqrt {* :s {- :s :a} {- :s :b} {- :s :c}}} }}} '{area 3 4 5} -> {area 3 4 5} } _h3 1.5) quote {pre '{quote expression} } _p {b Words are not evaluated} and don't need any protection. The {b quote} special form protects sequences of expressions from any evaluation. Example {pre '{quote bla bla {+ 1 2} bla bla} -> {quote bla bla {+ 1 2} bla bla} } _p To protect a single expression, say {b '{+ 1 2}} it's simpler to write {b ''{+ 1 2}} alternative instead of {b '{quote {+ 1 2}}}. {pre bla bla ''{+ 1 2} bla bla -> bla bla '{+ 1 2} bla bla } _p During the postprocessing phase all quoted expressions are automatically unquoted. Before the end use the {b unquote} primitive {pre ''{+ 1 2} -> '{+ 1 2} '{unquote {quote {+ 1 2}}} -> {unquote '{+ 1 2}} } _p Useful when sentences have to be taken as a whole, for instance in a swap {pre '{swap {quote it's the first sentence} {quote it's the second sentence}} -> {swap {quote it's the first sentence} {quote it's the second sentence}} } _p Note that all code examples in this page are quoted to be shown. _h3 1.6) macro {pre '{macro regular_expression to lambdatalk_expression} } _p Example, writing {pre '{macro _H ([^\n]*)\n to {div {@ style="font:normal 3.0em optima; text-align:center;"}$1}} } _p replaces this expression, "{b _H hello world}" by {pre '{div {@ style="font:normal 3.0em optima; text-align:center;"} hello world} } _p More coming soon, meanwhile see page [[macro|http://lambdaway.free.fr/lambdaspeech/?view=macro]] _h3 1.7) script {pre '{script javascript code} } _p Any javascript code can ne embedded in a {b script} special form. For instance the area of triangle [a,b,c] computed via a user defined function in section {b 1.4) let} could be built as javascript primitive {pre LAMBDATALK.DICT['area'] = function() '{ var args = LAMBDATALK.supertrim( arguments[0] ).split(' '), a = args[0], b = args[1], c = args[2], s = (a+b+c)/2; return Math.sqrt( s*(s-a)*(s-b)*(s-c) ) } } _h3 1.8) style {pre '{style CSS rules} } _p The style of the current page is defined in {b style} special form containing the following CSS rules. {pre °° body { background:#444; } #page_frame { border:0; background:#444; width:600px; margin-left:0; } #page_content { background:transparent; color:#fff; border:0; width:7000px; box-shadow:0 0 0; font-family:papyrus, optima; } .page_menu { background:transparent; color:#fff; } a { color:red; } pre { box-shadow:0 0 8px #000; padding:5px; background:#444; color:#fff; font:normal 1.0em courier; } b { color:cyan; } h1 { font-size:4.0em; } h2 { font-size:3.0em; } h3 { font-size:2.0em; } °°} _h3 1.9) require {pre °°{°°require lib_page ...°°}°° } _p Contents can be shared between the wiki pages. Any text, constants, functions, javascript code, CSS rules can be stored in some wiki pages, called libraries, and included in other ones. For instance requiring {b lib_BN} includes a set of lambdatalk functions built on a javascript library allowing to compute big numbers {require lib_BN lib_math} {prewrap '{BN.* 123456789123456789123456789123456789 123456789123456789123456789123456789} -> {BN.* 123456789123456789123456789123456789 123456789123456789123456789123456789} } _p to be compared with the javascript answer limited to 15 digits {pre '{* 123456789123456789123456789123456789 123456789123456789123456789123456789} -> {* 123456789123456789123456789123456789 123456789123456789123456789123456789} } _p Requiring {b lib_math} includes a set o of functions allowing to display math formulas {pre '{\math x = {\frac {\cell -b ± {\sqrt b{sup 2} - 4ac}} {\cell 2a} }} -> {center {\math x = {\frac {\cell -b ± {\sqrt b{sup 2} - 4ac}} 2a}}} E = '{\math {\sigma i=0 ∞ 3}{\frac 1 i!} = {E}} -> {center E = {\math {\sigma i=0 ∞ 3} {\frac 1 i!} = {E}} } } _p and so on. } {{block} {uncover {COCO}/e_aok2.jpg 100 500 AOK.3{br}encre monotype sur papier 10x15cm} _h2 2) data structures _p Lambdatalk comes with several sets of primitives dealing with words, sentences (sequences of words), arrays, ... These primitives are built on the javascript functions given for free by the web browsers and are sometimes recalled in order to be used in a similar way, whatever may be the type. For instance: {center {table {tr {td operation} {td lambdatalk} {td javascript}} {tr {td first character of a word} {td '{W.first word}} {td word.charAt(0)}} {tr {td first word of a sentence} {td '{S.first sentence}} {td string.match( /[^\s]*\s/ )}} {tr {td first element of an array} {td '{A.first array}} {td array[0]}} }} {style td { width:190px; box-shadow:0 0 8px #000; text-align:center; padding:0 5px; } } _p See the page [[WSAP]] for more details. _h3 2.1) words _p Thanks to the way lambdatalk is implemented words can be written without any protection. {prewrap '{W.lib} -> {W.lib} '{def W hello} -> {def W hello} '{W} -> {W} '{W.equal? hello world} -> {W.equal? hello world} '{W.equal? hello hello} -> {W.equal? hello hello} '{W.empty? {W}} -> {W.empty? {W}} '{W.length {W}} -> {W.length {W}} '{W.get 1 {W}} -> {W.get 1 {W}} '{W.first {W}} -> {W.first {W}} '{W.rest {W}} -> {W.rest {W}} '{W.last {W}} -> {W.last {W}} '{W.slice 1 4 {W}} -> {W.slice 1 4 {W}} '{W.reverse {W}} -> {W.reverse {W}} '{W.sort < 53241} -> {W.sort < 53241} '{W.sort > 53241} -> {W.sort > 53241} '{W.sort before hello} -> {W.sort before hello} '{W.sort after hello} -> {W.sort after hello} } _p A small example: {pre '{def W.capitalizeInRed {lambda {:w} {span {@ style="text-transform:uppercase;color:red;"} {W.first :w}}{W.rest :w}}} -> {def W.capitalizeInRed {lambda {:w} {span {@ style="text-transform:uppercase;color:red;"} {W.first :w}}{W.rest :w}}} '{W.capitalizeInRed world} -> {W.capitalizeInRed world} } _h3 2.2) sentences _p Thanks to the way lambdatalk is implemented sentences can be written without any protection. {prewrap '{S.lib} -> {S.lib} '{def S a b c d e f g} -> {def S a b c d e f g} '{S} -> {S} '{S.empty? {S}} -> {S.empty? {S}} '{S.length {S}} -> {S.length {S}} '{S.first {S}} -> {S.first {S}} '{S.rest {S}} -> {S.rest {S}} '{S.last {S}} -> {S.last {S}} '{S.get 1 {S}} -> {S.get 1 {S}} '{S.slice 1 5 {S}} -> {S.slice 1 5 {S}} '{S.serie 0 10 2} -> {S.serie 0 10 2} '{S.map {lambda {:x} {* :x :x}} {S.serie 1 9}} -> {S.map {lambda {:x} {* :x :x}} {S.serie 1 9}} '{S.reduce * {S.serie 1 6}} -> {S.reduce * {S.serie 1 6}} '{S.replace x by brave in hello x new world} -> {S.replace x by brave in hello x new world} '{S.reverse hello brave new world} -> {S.reverse hello brave new world} '{S.sort < 4 3 5 2 1} -> {S.sort < 4 3 5 2 1} '{S.sort > 4 3 5 2 1} -> {S.sort > 4 3 5 2 1} '{S.sort before hello brave new world} -> {S.sort before hello brave new world} '{S.sort after hello brave new world} -> {S.sort after hello brave new world} } _p A small example {pre '{def S.capitalizeInRed {lambda {:s} {S.map W.capitalizeInRed :s}}} -> {def S.capitalizeInRed {lambda {:s} {S.map W.capitalizeInRed :s}}} '{S.capitalizeInRed hello brave new world} -> {S.capitalizeInRed hello brave new world} } _h3 2.4) arrays _p Arrays are indexed lists, mich more efficient and mutable. {prewrap '{A.lib} -> {A.lib} '{def A {A.new 1 2 3 4 5 6}} -> {def A {A.new 1 2 3 4 5 6}} '{A} -> {A} '{def B {A.new 7 8 9}} -> {def B {A.new 7 8 9}} '{B} -> {B} the following functions don't modify arrays '{A.join {A.new 1 2 3 4 5 6}} -> {A.join {A.new 1 2 3 4 5 6}} '{A.split 123456} -> {A.split 123456} '{A.equal? {A} {A}} -> {A.equal? {A} {A}} '{A.equal? {A} {B}} -> {A.equal? {A} {B}} '{A.array? {A}} -> {A.array? {A}} '{A.array? hello} -> {A.array? hello} '{A.null? {A}} -> {A.null? {A}} '{A.null?} -> {A.null?} '{A.empty? {A}} -> {A.empty? {A}} '{A.empty? {A.new}} -> {A.empty? {A.new}} '{A.in? 3 {A}} -> {A.in? 3 {A}} '{A.in? 9 {A}} -> {A.in? 9 {A}} '{A.length {A}} -> {A.length {A}} '{A.get 1 {A}} -> {A.get 1 {A}} '{A.first {A}} -> {A.first {A}} '{A.rest {A}} -> {A.rest {A}} '{A.last {A}} -> {A.last {A}} '{A.slice 1 5 {A}} -> {A.slice 1 5 {A}} '{A.duplicate {A}} -> {A.duplicate {A}} '{A.reverse {A}} -> {A.reverse {A}} '{A.concat {A} {B}} -> {A.concat {A} {B}} '{A.map b {A}} -> {A.map b {A}} '{A.map {lambda {:i} {* :i :i}} {A}} -> {A.map {lambda {:i} {* :i :i}} {A}} the following functions return the same array modified '{A.set! 1 _ {A.new 1 2 3 4 5}} -> {A.set! 1 _ {A.new 1 2 3 4 5}} '{A.addlast! _ {A.new 1 2 3 4 5}} -> {A.addlast! _ {A.new 1 2 3 4 5}} '{A.addfirst! _ {A.new 1 2 3 4 5}} -> {A.addfirst! _ {A.new 1 2 3 4 5}} '{A.subfirst! {A.new 1 2 3 4 5}} -> {A.subfirst! {A.new 1 2 3 4 5}} '{A.sublast! {A.new 1 2 3 4 5}} -> {A.sublast! {A.new 1 2 3 4 5}} '{A.reverse! {A.new 1 2 3 4 5}} -> {A.reverse! {A.new 1 2 3 4 5}} '{A.sort! > {A.new 3 1 5 4 2}} -> {A.sort! > {A.new 3 1 5 4 2}} '{A.sort! < {A.new 3 1 5 4 2}} -> {A.sort! < {A.new 3 1 5 4 2}} '{A.sort! before {A.new b c a z x}} -> {A.sort! before {A.new b c a z x}} '{A.sort! after {A.new b c a z x}} -> {A.sort! after {A.new b c a z x}} } _p There is no array primitive finding the maximal term in an array, let's build one {pre '{def A.max {def A.max.r {lambda {:a :m} {if {A.empty? :a} then :m else {if {> {A.first :a} :m} then {A.max.r {A.rest :a} {A.first :a}} else {A.max.r {A.rest :a} :m}}}}} {lambda {:a} {A.max.r {A.rest :a} {A.first :a}}}} -> {def A.max {def A.max.r {lambda {:a :m} {if {A.empty? :a} then :m else {if {> {A.first :a} :m} then {A.max.r {A.rest :a} {A.first :a}} else {A.max.r {A.rest :a} :m}}}}} {lambda {:a} {A.max.r {A.rest :a} {A.first :a}}}} '{A.max {A.new 4 3 12 0 -1 34 100 34 55}} -> {A.max {A.new 4 3 12 0 -1 34 100 34 55}} } _p Being mutable arrays can be used as a sandbox for iterative processes. For instance the {b fibonacci} function {prewrap algorithm: 1: [0,1] 2: [1,1] 3: [1,2] 4: [2,3] 5: [3,5] 6: [5,8] 7: [8,13] 8: [13,21] 9: [21,34] ... '{let { {:fib {lambda {:a :i} // local function {A.set! 1 {long_add {A.get 0 :a} {A.get 1 :a}} {A.set! 0 {A.get 1 :a} :a}} }} } {A.last {S.last {S.map {:fib {A.new 0 1}} // initialization {S.serie 2 1000}}}} // loop } -> {let { {:fib {lambda {:a :i} {A.set! 1 {long_add {A.get 0 :a} {A.get 1 :a}} {A.set! 0 {A.get 1 :a} :a}} }} } {A.last {S.last {S.map {:fib {A.new 0 1}} {S.serie 2 1000}} }} } } _p computed for big numbers without any sptack overflow _p And so on. _h3 2.3) pairs, lists _p ... {prewrap '{P.lib} -> PAIR: [7] [P.new|cons, P.left|car, P.right|cdr, P.pair?] '{def P {P.new hello world}} -> {def P {P.new hello world}} '{P} -> {P} '{P.pair? {P.new hello world}} -> {P.pair? {P.new hello world}} '{P.pair? hello} -> {P.pair? hello} '{P.left {P.new hello world}} -> {P.left {P.new hello world}} '{P.right {P.new hello world}} -> {P.right {P.new hello world}} } _p As a first example, {pre '{def P {P.new hello world}} -> {def P {P.new hello world}} '{P.left {P}} -> {P.left {P}} '{P.right {P}} -> {P.right {P}} } _p Let's build a list and related functions. Lists are nested pairs ending with {b nil}. {pre '{def L.new {lambda {:s} {if {W.equal? {S.rest :s} nil} then {P.new {S.first :s} nil} else {P.new {S.first :s} {L.new {S.rest :s}}}}}} -> {def L.new {def L.new.r {lambda {:s} {if {W.equal? {S.rest :s} nil} then {P.new {S.first :s} nil} else {P.new {S.first :s} {L.new.r {S.rest :s}}}}}} {lambda {:s} {L.new.r :s nil}}} '{def L {L.new a b c d}} -> {def L {L.new a b c d}} = {L} '{def P.nil? {lambda {:l} {W.equal? :l nil}}} -> {def P.nil? {lambda {:l} {W.equal? :l nil}}} '{def L.disp {lambda {:l} {if {P.nil? :l} then else {P.left :l} {L.disp {P.right :l}}}}} -> {def L.disp {lambda {:l} {if {P.nil? :l} then else {P.left :l} {L.disp {P.right :l}}}}} '{L.disp {L}} -> {L.disp {L}} '{def L.length {lambda {:l} {if {P.nil? :l} then 0 else {+ 1 {L.length {P.right :l}}}}}} -> {def L.length {lambda {:l} {if {P.nil? :l} then 0 else {+ 1 {L.length {P.right :l}}}}}} '{L.length {L}} -> {L.length {L}} '{def L.reverse {def L.reverse.r {lambda {:l1 :l2} {if {P.nil? :l1} then :l2 else {L.reverse.r {P.right :l1} {P.new {P.left :l1} :l2}}}}} {lambda {:l} {L.reverse.r :l nil}} } -> {def L.reverse {def L.reverse.r {lambda {:l1 :l2} {if {P.nil? :l1} then :l2 else {L.reverse.r {P.right :l1} {P.new {P.left :l1} :l2}}}}} {lambda {:l} {L.reverse.r :l nil}} } '{L.disp {L.reverse {L}}} -> {L.disp {L.reverse {L}}} '{def L.concat {def L.concat.r {lambda {:l1 :l2} {if {P.nil? :l1} then :l2 else {L.concat.r {P.right :l1} {P.new {P.left :l1} :l2}}}}} {lambda {:l1 :l2} {L.concat.r {L.reverse :l1} :l2}}} -> {def L.concat {def L.concat.r {lambda {:l1 :l2} {if {P.nil? :l1} then :l2 else {L.concat.r {P.right :l1} {P.new {P.left :l1} :l2}}}}} {lambda {:l1 :l2} {L.concat.r {L.reverse :l1} :l2}}} '{L.disp {L.concat {L} {L.reverse {L}}}} -> {L.disp {L.concat {L} {L.reverse {L}}}} } _h3 2.4) transtypage _p The [[lib_beta]] page contains a few more functions useful for transtypage {pre °° {W.char2code A} -> 65 {W.code2char 65} -> A {W.toS 123} -> 1 2 3 {W.toA 123} -> [1,2,3] {S.toW 1 2 3} -> 123 {S.toA 1 2 3} -> [1,2,3] {A.toW {A.new 1 2 3}} -> 123 {A.toS {A.new 1 2 3}} -> 1 2 3 °°} } {{block} {uncover {COCO}/e_aok2.jpg 100 500 AOK.3{br}encre monotype sur papier 10x15cm} _h2 3) primitives _p Lambdatalk comes with several sets of primitives built on numerous objects given for free by the web browsers, HTML, CSS, SVG, DOM, JAVASCRIPT. Lambdatalk brings to them a single and systematic syntax, and add new ones dealing with pictures display, turtle graphics, ... _h3 3.1) html/css _p ... {prewrap @, 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, input, iframe, audio, video, source, select, option, object, } {pre '{div {@ style="font:normal 3.0em optima; text-align:center; text-shadow:0 0 8px #000; transform:rotate(-5deg);"} hello world} -> } {div {@ style="font:normal 3.0em optima; text-align:center; text-shadow:0 0 8px #000; transform:rotate(-5deg);"} hello world} _p and so on. _h3 3.2) canvas, svg _p ... {prewrap canvas, svg, line, rect, circle, ellipse, polygon, polyline, path, text, g, mpath, use, textPath, pattern, image, clipPath, defs, animate, set, animateMotion, animateTransform, title, desc, } _p Let's plot the curve defined by {b p(t) = e{sup it} + {sup 1}/{sub 2}e{sup A*it} + {sup i}/{sub 3}e{sup B*it}} {pre p(t) = e{sup it} + 1/2e{sup Ait} + i/3e{sup Bit} -> x(t) = cos(t) + 1/2*cos(At) - 1/3*sin(Bt) -> y(t) = sin(t) + 1/2*sin(At) + 1/3*cos(Bt) // A and B are two random values: '{def A {floor {* 10 {random}}}} -> {def AA {floor {* 10 {random}}}} = {AA} '{def B {floor {* 5 {random}}}} -> {def BB {floor {* 5 {random}}}} = {BB} '{def CYCLIC {lambda {:t} {* 150 {+ {cos :t} {* {/ 1 2} {cos {* {A} :t}}} {* {/ 1 -3} {sin {* -{B} :t}}}}} {* 150 {+ {sin :t} {* {/ 1 2} {sin {* {A} :t}}} {* {/ 1 3} {cos {* -{B} :t}}}}} }} -> {def CYCLIC {lambda {:t} {* 150 {+ {cos :t} {* {/ 1 2} {cos {* {AA} :t}}} {* {/ 1 -3} {sin {* -{BB} :t}}}}} {* 150 {+ {sin :t} {* {/ 1 2} {sin {* {AA} :t}}} {* {/ 1 3} {cos {* -{BB} :t}}}}} }} } {{SVG 600} {g {AXES 600 600} {polyline {@ points="{S.map CYCLIC {S.serie -10 10 0.01}}" {stroke #fff 4}}} }} _p Under the cap this is the code to set the SVG frames and draw the axes {pre '{def rad // degrees to radians {def rad.PI {/ {PI} 180}} // computed once {lambda {:a} {* :a {rad.PI}} }} -> {def rad {def rad.PI {/ {PI} 180}} {lambda {:a} {* :a {rad.PI}}} } '{def SVG {lambda {:h} svg {@ width="600px" height=":hpx" style="background:#444"} }} -> {def SVG {lambda {:h} svg {@ width="600px" height=":hpx" style="background:#444"} }} '{def stroke {lambda {:col :w} stroke=":col" fill="transparent" stroke-width=":w" }} -> {def stroke {lambda {:col :w} stroke=":col" fill="transparent" stroke-width=":w" }} '{def AXES {lambda {:w :h} {@ transform="translate({/ :w 2},{/ :h 2}) scale(1,-1)"} {line {@ x1="-{/ :w 2}:w" y1="0" x2="{/ :w 2}" y2="0" stroke="red" fill="transparent"}} {line {@ x1="0" y1="-{/ :h 2}" x2="0" y2="{/ :h 2}" stroke="green" fill="transparent"}} }} -> {def AXES {lambda {:w :h} {@ transform="translate({/ :w 2},{/ :h 2}) scale(1,-1)"} {line {@ x1="-{/ :w 2}:w" y1="0" x2="{/ :w 2}" y2="0" stroke="red" fill="transparent"}} {line {@ x1="0" y1="-{/ :h 2}" x2="0" y2="{/ :h 2}" stroke="green" fill="transparent"}} }} } _h3 3.3) maths _p Essentially built on the {b Math} object. {prewrap +, *, -, /, %, <, >, <=, >=, = not, or, and, abs, floor, round, ceil, max, min acos, asin, atan, cos, sin, tan exp, log, pow, sqrt random, PI, E, date } _p Examples {pre '{+ 1 2} -> {+ 1 2} '{+ 1 2 3 4 5 6} -> {+ 1 2 3 4 5 6} ... '{< 1 2} -> {< 1 2} '{random} -> {random} '{round {* 100 {random}}} -> {round {* 100 {random}}} ... } _p Maths expressions can be displayed using the {b lib_math} library {require lib_math} {pre '{\math x = {\frac {\cell -b ± {\sqrt b{sup 2} - 4ac}} {\cell 2a} }} -> {\math x = {\frac {\cell -b ± {\sqrt b{sup 2} - 4ac}} {\cell 2a} }} '{\math E = {\sigma i=0 ∞ 3}{\frac 1 i!} = {E}} -> {\math E = {\sigma i=0 ∞ 3}{\frac 1 i!} = {E}} } _h3 3.4) miscellaneous _p ... wait & see ... {prewrap LS.display, LS.setItem, LS.getItem, LS.removeItem, LS.clear, unquote, include, lib, hide, prewrap, show_last_code, turtle, long_add, long_mult, uncover, drag, editable } _p For instance writing {pre '{uncover data/amelie_poulain.jpg 100 700 Amélie Poulain loves the lambada} } _p displays an extendable picture with a caption {uncover data/amelie_poulain.jpg 100 700 Amélie Poulain loves the lambada} _p A small lightshow very simple to build {pre '{PICT URL1 thumb_height show_width text1 ....} '{PICT URL2 thumb_height show_width text2 ....} ... '{SHOW} } _p Click on a picture to enlight it. {center {PICT http://lambdaway.free.fr/workshop/data/amelie_poulain.jpg 50 600 Amélie Poulain loves ze {b lambdaway}} {PICT http://lambdaway.free.fr/workshop/data/ava_gardner.jpg 50 800 Ava Gardner is beautiful} {PICT http://lambdaway.free.fr/workshop/data/montgomery_clift.jpg 50 800 Montgomery Clift does not like the lambada!} {PICT http://epsilonwiki.free.fr/epsilonwiki/data/chevaux_.jpg 50 1000 Chevaux libres en Camargue.} {PICT http://epsilonwiki.free.fr/epsilonwiki/data/roger_penrose.jpg 50 1000 Sir Roger Penrose OM FRS (born 8 August 1931) is an English mathematical physicist, mathematician and philosopher of science. He is the Emeritus Rouse Ball Professor of Mathematics at the Mathematical Institute of the University of Oxford, as well as an Emeritus Fellow of Wadham College.} {PICT http://epsilonwiki.free.fr/epsilonwiki/data/lepetitnicolas.jpg 50 400 Obviously, I am the best!} } {SHOW} {{hide} {def PICT {lambda {:url :h :w :txt} {img {@ class="thumb" src=":url" height=":h" title=":txt" onclick="SHOW.display(this, :w)"}} }} {def SHOW {div {@ id="show_grey" class="grey"}} {div {@ class="output" id="show_output" onclick="SHOW.hide()"} {img {@ src="" width="100%" onclick="return false"}} {div {@ onclick="return false"}.} }} } {script var SHOW = (function () { var display = function(id, w) { document.getElementById('show_grey').style.display = 'block'; var show = document.getElementById('show_output'); show.style.width = w + 'px'; show.style.marginLeft = -(w+20)/2 + 'px'; show.childNodes[0].src = id.src; show.childNodes[2].innerHTML = id.title; show.style.display = 'block'; }; var hide = function() { document.getElementById('show_grey').style.display = 'none'; document.getElementById('show_output').style.display = 'none'; }; return {display:display, hide:hide} })(); } {style .thumb { cursor:grab; box-shadow:0 0 8px #000; } .thumb:hover { box-shadow:0 0 8px #0ff; transform:scale( 1.1 ) } .grey { display:none; position:fixed; top:0; left:0; width:100%; height:2000px; background:#000; opacity:0.3; } .output { display:none; position:fixed; top:10px; left:50%; width:600px; margin-left:-310px; box-shadow:0 0 4px #000; background:#ddd; color:#000; padding:10px; text-align:center; font:italic 1.5em papyrus, courier; } } _p And finally if you write {pre '{arcwatch}} _p you get a watch {center {arcwatch}} {script var update = function () { document.getElementById("arcwatch").innerHTML = LAMBDATALK.eval_forms( "{watch.draw #f00 #0f0 #00f}" ) }; LAMBDATALK.DICT['arcwatch.init'] = function () { setTimeout( update, 10); setInterval( update, 1000); return '' }; } {{hide} {def arcwatch {arcwatch.init} {div {@ id="arcwatch"}} } {def watch.draw {lambda {:r :g :b} {svg {@ style="width:300px; height:300px;"} {let { {:r :r} {:g :g} {:b :b} {:t {date}} } {watch.path 150 150 100 20 :r 1 :t} {watch.path 150 150 120 20 :g 2 :t} {watch.path 150 150 140 20 :b 3 :t} {watch.digit :t} }}}} {def watch.path {lambda {:x :y :r :e :c :i :t} {path {@ d="{watch.arc :x :y :r {watch.time :i :t}}" fill="none" stroke=":c" stroke-width=":e"}} }} {def watch.arc {lambda {:x :y :r :t} {let { {:x :x} {:y :y} {:r :r} {:start {watch.pol2car :x :y :r :t}} {:end {watch.pol2car :x :y :r 0}} {:flag {if {<= :t 180} then 0 else 1}} } M {car :start} {cdr :start} A :r :r 0 :flag 0 {car :end} {cdr :end} }}} {def watch.time {lambda {:i :t} {if {= :i 1} then {/ {* 360 {% {S.get {+ :i 2} :t} 12}} 12} else {/ {* 360 {S.get {+ :i 2} :t}} 60} }}} {def watch.pol2car {lambda {:cx :cy :r :t} {let { {:cx :cx} {:cy :cy} {:r :r} {:T {* {- :t 90} {/ {PI} 180}}} } {cons {+ :cx {* :r {cos :T}}} {+ :cy {* :r {sin :T}}}} }}} {def watch.digit {lambda {:t} {text {@ x="50%" y="48%" base-line="middle" text-anchor="middle" font-size="2.0em" stroke="#000"} {S.get 0 :t}/{S.get 1 :t}/{S.get 2 :t} } {text {@ x="50%" y="58%" base-line="middle" text-anchor="middle" font-size="2.0em" stroke="#000"} {S.get 3 :t} : {S.get 4 :t} : {S.get 5 :t} } }} } _p Time to go ... } {{block} {uncover {COCO}/e_aok2.jpg 100 500 AOK.3{br}encre monotype sur papier 10x15cm} _h2 4) libraries _p Libraries open lambdatalk to the wide world web, rich of anything which can be coded in javascript and more. _p The following set of libraries can be extended (on line, directly from the browser) with external libraries and user defined functions or JS primitives stored in wiki pages and retrieved via the {b require} special form. {pre [[lib_math]] [[lib_BN]] [[lib_complex]] [[lib_matrix]] [[lib_list]] [[lib_hash]] [[lib_beta]] [[lib_agora]] [[lib_uncover]] [[lib_watch]] [[lib_sifr]] } _p « Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. » } {{block} {uncover {COCO}/e2_bvl232.jpg 100 500 bleu profond{br}EXTREME LENTEUR DANS L.ESPACE{br}encre monotype sur papier 18x24cm} _h2 conclusion _p {b Lambdatalk} is a {i dwarf on the shoulders of giants}, taking advantage of web technologies provided free of charge by web browsers, by means of a language with a unitary, systematic, coherent syntax which can be enriched on demand, directly from the browser. _p {i marty.alain at free.fr (2021/06/06)} _p [[HN|https://news.ycombinator.com/item?id=32200678]] _p Paintings from [[Colette|http://colette.cerda.free.fr]], in heaven since 2020/05/25. } {{hide} {def COCO http://colette.cerda.free.fr/coco.c/data} {def block div {@ style="display:inline-block; width:600px; vertical-align:top; padding:5px; "}} } {style body { background:#444; } #page_frame { border:0; background:#444; width:600px; margin-left:0; } #page_content { background:transparent; color:#fff; border:0; width:7000px; box-shadow:0 0 0; font-family:papyrus, optima; } .page_menu { background:transparent; color:#fff; } a { color:#f80; } pre { box-shadow:0 0 8px #000; padding:5px; background:#444; color:#fff; font:normal 1.0em courier; } b { color:cyan; } h1 { font-size:4.0em; margin-left:0;} h2 { font-size:3.0em; } h3 { font-size:2.0em; } }
lambdaway v.20211111