lambdaspeech
::
WSA3
1
|
list
|
login
|
load
|
|
{center [[kernel]] | [[WSA]] | [[WSA2]] | [[WSA3]] | [[WSA4]] | [[WSA5]]} _img http://epsilonwiki.free.fr/portail/data/rachel.jpg {center {i Rachel, the lovely replicant in Blade Runner, when AI comes true.}} {blockquote {@ style="padding:0 10px; font:italic 0.9em optima; "} _p I think that '{lambda talk} is now well established on a good foundation, (λ calculus and Lisp syntax), and that the 9 special forms ({b lambda, def, if, quote, let, macro, script, style, require}) are sufficient to code "comfortably", taking benefit of the powerful web technologies provided by web browsers. _p See more in {b [[kernel]]}. _p That said, the current dictionary of primitives has been built during random explorations of algorithms (quicksort, FFT, de Castlejau, big numbers, ...) and is rather "messy". A good cleaning is required! _p My challenge now is to "refactor" the dictionary to be as complete and coherent as possible, without introducing "esoteric" names and behaviours nobody would want to use. _p See also [[The Hundred Year Language, Paul Graham|http://www.paulgraham.com/hundred.html]] } _h1 words, sentences and arrays _p This is the current set of 62 lambdatalk functions working on characters, words, pairs, lists and arrays: {center {prewrap equal?, empty?, chars, charAt, length, first, rest, last, get, nth, substring, replace, serie, map, reduce, #.new, #.disp, #.join, #.split, #.array?, #.null?, #.empty?, #.in?, #.length, #.get, #.first, #.last, #.rest, #.slice, #.duplicate, #.reverse, #.concat, #.set!, #.addlast!, #.push!, #.sublast!, #.pop!, #.addfirst!, #.unshift!, #.subfirst!, #.shift!, #.reverse!, #.sort!, pair, cons, pair?, nil?, left, list.first, car, right, list.rest, cdr, pair.disp, list.new, list.disp, list.null?, list.length, list.reverse, list.butfirst, list.last, list.butlast }} _p Some functions are a close translation of javascript's ones, (charAt, substring, join, split, length, ...), some others come from the Lisp world, (cons, car, cdr, first, rest, ...). They have been added randomly, when needed during the exploration of numerous algorithms, (quicksort, FFT, de Casteljau, ...), and the whole is rather inconsistent. _p The goal is to {b refactor} this set into a more complete and coherent one. _p As an example, this is how we get the i{sup nth} character of a word, the i{sup nth} word of a sentence and the i{sup nth} value of an array using javascript, the current version of lambdatalk and the last one under construction: {pre {b type javascript '{lambda talk} current '{lambda talk} next} °° word: word.charAt(i) {charAt i word} {get i word} sentence: sentence.split(" ")[i] {nth i sentence} {get i sentence} array: array[i] {#.get array i} {get i array} °°} _p Even if we loose the proximity with javascript, the last version looks better, we gain clarity, the behaviour is similar on words, sentences and arrays, and we can reduce the number of functions from 62 to 35. It's a matter of balance between well known functions and new ones needing to become familiar with. _p In the last version (under construction) of '{lambda talk} the functions working on words, sentences and arrays are polymorphic. More precisely: {prewrap 1. a word is empty or a group of chars except spaces and braces () booleans and numbers are words and are never evaluated 2. a sentence is empty or a sequence of spaces separated words quotes are useless around words and sentences 3. an array is an ordered set of indexed values values can be words, sentences and arrays pairs and lists don't exist anymore, they are special arrays 4. this is the new set of 35 polymorphic functions: 4.1. translations between words, sentences and arrays (transtypage): {b w2s, w2a, s2w, s2a, a2w, a2s,} 4.2. predicates: {b type?, null?, empty?, equal?, isin?,} ... 4.3. input is unchanged {b display, length, get, slice, first, last, rest, butlast, reverse, sort, replace, concat, serie, map, reduce, feed} ... 4.4. input is modified {b set!, slice!, addfirst!, addlast!, subfirst!, sublast! reverse!, sort!, replace!,} ... } _p The term ({i concept of}) {b sentence}, a sequence of words, comes from [[Simply Scheme|https://people.eecs.berkeley.edu/~bh/ssch5/words.html]] written by Brian Harvey and Matthew Wright. Here is an excerpt from it: {blockquote {@ style="padding:0 10px; font:italic 0.9em optima;"} _p [...] A programming language should let you express your ideas in terms that match your way of thinking, not the computer's way. Technically, we say that {b words and sentences should be first-class data} in our language. This means that a sentence, for example, can be an argument to a procedure; it can be the value returned by a procedure; we can give it a name; and we can build aggregates whose elements are sentences. [...] } _p Furthermore, with '{lambda talk} we can write words and sentences without having to "escape" them in quotation marks: {pre hello brave new world -> hello brave new world '{first hello brave new world} -> {first hello brave new world} '{rest hello brave new world} -> {rest hello brave new world} '{last hello brave new world} -> {last hello brave new world} } _p Note that pairs and lists are no more special data types, they are implemented as arrays. Thanks to specific functions like {b first, rest, last}, LISP-like algorithms (forgetting indexes) can be written. The remaining types are words (numbers are words), unquoted sequences of words (we are in a wiki) and arrays. Nothing else. And functions work similarly on these three types of data. _p Primitives are defined in a Javascript global {b IIFE}, called {b WSA}, stored as a library in a wiki page. {b WSA} can be extended on demand, directly in the wiki's editor. And just write {code '{require. lib_WSA}} in the page to use it! _p Functions [{code w2s, w2a, s2w, s2a, a2w, a2s}] - meaning word-to-sentence, word-to-array, ... , array-to-sentence - create words, sentences and arrays ... from words, sentences and arrays. A kind of {i transtypage}. The form {code '{wsa.s2a sentence}} is generally used to create an array from a sequence of words. A useful improvement could be to replace this syntax by the well known standard one {code {b [a,b,c,d] -> array}}. But we are in a wiki and we want to write {b [hello world]} without generating any array. Choosing a less used bracketting symbols, for instance {b ≺ ≻}, we will ask a {b macro} to make the translation during the pre-processing phase: {center {pre '{macro ≺(.*?)≻ to {wsa.s2a €1}}}} _p and we will create arrays like this: {pre ≺a b c d≻ -> '{wsa.s2a a b c d} -> [a,b,c,d] ≺≻ -> '{wsa.s2a} -> [] } _p It's a matter of choice. _p In order to avoid conflicts with existing '{lambda talk} primitives, functions' names are prefixed with "{b wsa.}" . _h2 1) testing syntax {pre '{wsa.w2s abcd} -> {wsa.w2s abcd} '{wsa.w2a abcd} -> {wsa.w2a abcd} = {wsa.display {wsa.w2a abcd}} '{wsa.s2w a b c d} -> {wsa.s2w a b c d} '{wsa.s2a a b c d} -> {wsa.s2a a b c d}. = {wsa.display {wsa.s2a a b c d}} '{wsa.a2w {wsa.w2a abcd}} -> {wsa.a2w {wsa.w2a abcd}} '{wsa.a2s {wsa.s2a a b c d}} -> {wsa.a2s {wsa.s2a a b c d}} ==== '{wsa.type abcd} -> {wsa.type abcd} '{wsa.type a b c d} -> {wsa.type a b c d} '{wsa.type {wsa.s2a a b c d}} -> {wsa.type {wsa.s2a a b c d}} '{wsa.null?} -> {wsa.null?} '{wsa.null? x} -> {wsa.null? x} '{wsa.empty?} -> {wsa.empty?} '{wsa.empty? x} -> {wsa.empty? x} '{wsa.empty? {wsa.w2a}} -> {wsa.empty? {wsa.w2a}} '{wsa.empty? {wsa.w2a 1}} -> {wsa.empty? {wsa.w2a 1}} '{wsa.equal? x x} -> {wsa.equal? x x} '{wsa.equal? x y} -> {wsa.equal? x y} '{wsa.isin? c abcd} -> {wsa.isin? c abcd} '{wsa.isin? e abcd} -> {wsa.isin? e abcd} '{wsa.isin? c a b c d} -> {wsa.isin? c a b c d} '{wsa.isin? e a b c d} -> {wsa.isin? e a b c d} '{wsa.isin? c {wsa.s2a a b c d}} -> {wsa.isin? c {wsa.s2a a b c d}} '{wsa.isin? e {wsa.s2a a b c d}} -> {wsa.isin? e {wsa.s2a a b c d}} '{wsa.display abcd} -> {wsa.display abcd} '{wsa.display a b c d} -> {wsa.display a b c d} '{wsa.display {wsa.s2a a b c d}} -> {wsa.display {wsa.s2a a b c d}} ==== '{wsa.length hello} -> {wsa.length hello} '{wsa.length} -> {wsa.length} '{wsa.length hello brave new world} -> {wsa.length hello brave new world} '{wsa.length {wsa.s2a 1 2 3 4 5}} -> {wsa.length {wsa.s2a 1 2 3 4 5}} '{wsa.length {wsa.s2a}} -> {wsa.length {wsa.s2a}} '{wsa.reverse hello} -> {wsa.reverse hello} '{wsa.reverse hello brave new world} -> {wsa.reverse hello brave new world} '{wsa.reverse {wsa.s2a 1 2 3 4 5}} -> {wsa.reverse {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.reverse {wsa.s2a 1 2 3 4 5}}} '{wsa.concat hello world} -> {wsa.concat hello world} '{wsa.concat hello brave new world} -> {wsa.concat hello brave new world} '{wsa.concat {wsa.s2a 1 2 3} {wsa.s2a 4 5 6}} -> {wsa.concat {wsa.s2a 1 2 3} {wsa.s2a 4 5 6}} = {wsa.display {wsa.concat {wsa.s2a 1 2 3} {wsa.s2a 4 5 6}}} '{wsa.sort > hello} -> {wsa.sort > hello} '{wsa.sort > hello brave new world} -> {wsa.sort > hello brave new world} '{wsa.sort > {wsa.s2a 3 1 4 5 2}} -> {wsa.sort > {wsa.s2a 3 1 4 5 2}} = {wsa.display {wsa.sort > {wsa.s2a 3 1 4 5 2}}} '{wsa.feed w0 5} -> {wsa.feed w0 5} '{wsa.feed s0 5} -> {wsa.feed s0 5} '{wsa.feed a0 5} -> {wsa.feed a0 5} ==== '{wsa.get 1 hello} -> {wsa.get 1 hello} '{wsa.get 1 hello brave new world} -> {wsa.get 1 hello brave new world} '{wsa.get 1 {wsa.s2a 1 2 3 4 5}} -> {wsa.get 1 {wsa.s2a 1 2 3 4 5}} '{wsa.first hello} -> {wsa.first hello} '{wsa.first hello brave new world} -> {wsa.first hello brave new world} '{wsa.first {wsa.s2a 1 2 3 4 5}} -> {wsa.first {wsa.s2a 1 2 3 4 5}} '{wsa.first} -> {wsa.first} '{wsa.last hello} -> {wsa.last hello} '{wsa.last hello brave new world} -> {wsa.last hello brave new world} '{wsa.last {wsa.s2a 1 2 3 4 5}} -> {wsa.last {wsa.s2a 1 2 3 4 5}} '{wsa.last} -> {wsa.last} '{wsa.rest hello} -> {wsa.rest hello} '{wsa.rest hello brave new world} -> {wsa.rest hello brave new world} '{wsa.rest {wsa.s2a 1 2 3 4 5}} -> {wsa.rest {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.rest {wsa.s2a 1 2 3 4 5}}} '{wsa.rest} -> {wsa.rest} // modify input '{wsa.set! 2 x hello} -> {wsa.set! 2 x hello} '{wsa.set! 2 x hello brave new world} -> {wsa.set! 2 x hello brave new world} '{wsa.set! 2 x {wsa.s2a 1 2 3 4 5}} -> {wsa.set! 2 x {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.set! 2 x {wsa.s2a 1 2 3 4 5}}} '{wsa.set! 2 x } -> {wsa.set! 2 x} '{wsa.slice! 1 2 hello} -> {wsa.slice! 1 2 hello} '{wsa.slice! 1 2 hello brave new world} -> {wsa.slice! 1 2 hello brave new world} '{wsa.slice! 1 2 {wsa.s2a 1 2 3 4 5}} -> {wsa.slice! 1 2 {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.slice! 1 2 {wsa.s2a 1 2 3 4 5}}} '{wsa.addfirst! _ hello} -> {wsa.addfirst! _ hello} '{wsa.addfirst! _ hello brave new world} -> {wsa.addfirst! _ hello brave new world} '{wsa.addfirst! _ {wsa.s2a 1 2 3 4 5}} -> {wsa.addfirst! _ {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.addfirst! _ {wsa.s2a 1 2 3 4 5}}} '{wsa.addfirst! _} -> {wsa.addfirst! _} = {wsa.display {wsa.addfirst! _}} '{wsa.addlast! _ hello} -> {wsa.addlast! _ hello} '{wsa.addlast! _ hello brave new world} -> {wsa.addlast! _ hello brave new world} '{wsa.addlast! _ {wsa.s2a 1 2 3 4 5}} -> {wsa.addlast! _ {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.addlast! _ {wsa.s2a 1 2 3 4 5}}} '{wsa.addlast! _} -> {wsa.addlast! _} = {wsa.display {wsa.addlast! _}} '{wsa.subfirst! hello} -> {wsa.subfirst! hello} '{wsa.subfirst! hello brave new world} -> {wsa.subfirst! hello brave new world} '{wsa.subfirst! {wsa.s2a 1 2 3 4 5}} -> {wsa.subfirst! {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.subfirst! {wsa.s2a 1 2 3 4 5}}} '{wsa.subfirst!} -> {wsa.subfirst!} '{wsa.sublast! hello} -> {wsa.sublast! hello} '{wsa.sublast! hello brave new world} -> {wsa.sublast! hello brave new world} '{wsa.sublast! {wsa.s2a 1 2 3 4 5}} -> {wsa.sublast! {wsa.s2a 1 2 3 4 5}} = {wsa.display {wsa.sublast! {wsa.s2a 1 2 3 4 5}}} '{wsa.sublast!} -> {wsa.sublast!} '{wsa.replace new by old in hello brave new world} -> {wsa.replace new by old in hello brave new world} '{wsa.map u hello brave new world} -> {wsa.map u hello brave new world} '{wsa.reduce u hello brave new world} -> {wsa.reduce u hello brave new world} '{wsa.serie 0 20 2} -> {wsa.serie 0 20 2} } _h2 2) a sentence _p Reverse words in a sentence with randomized colors. {prewrap '{def randcol {lambda {:w} {span {@ style="color:rgb({round {* 255 {random}}}, {round {* 255 {random}}}, {round {* 255 {random}}})"}:w}}} -> {def randcol {lambda {:w} {span {@ style="color:rgb({round {* 255 {random}}}, {round {* 255 {random}}}, {round {* 255 {random}}})"}:w}}} '{def text A programming language should let you express your ideas in terms that match your way of thinking, not the computer's way. Technically, we say that words and sentences should be first-class data in our language. This means that a sentence, for example, can be an argument to a procedure; it can be the value returned by a procedure; we can give it a name; and we can build aggregates whose elements are sentences.} -> {def text A programming language should let you express your ideas in terms that match your way of thinking, not the computer's way. Technically, we say that words and sentences should be first-class data in our language. This means that a sentence, for example, can be an argument to a procedure; it can be the value returned by a procedure; we can give it a name; and we can build aggregates whose elements are sentences.} '{wsa.map randcol {map wsa.reverse {wsa.reverse {text}}}} -> {wsa.map randcol {map wsa.reverse {text}}} } _p And so on... _h2 3) quicksort _p From an array of random numbers we create a sorted tree where nodes are arrays {code [data,left,right]} and finally we walk the canopy. {prewrap 1. adding a leaf to the tree: '{def BT.add {lambda {:x :t} {if {wsa.empty? :t} then {wsa.s2a :x {wsa.s2a} {wsa.s2a}} else {if {= :x {wsa.get 0 :t}} then :t else {if {< :x {wsa.get 0 :t}} then {wsa.s2a {wsa.get 0 :t} {BT.add :x {wsa.get 1 :t}} {wsa.get 2 :t}} else {wsa.s2a {wsa.get 0 :t} {wsa.get 1 :t} {BT.add :x {wsa.get 2 :t}} }}}}}} -> {def BT.add {lambda {:x :t} {if {wsa.empty? :t} then {wsa.s2a :x {wsa.s2a} {wsa.s2a}} else {if {= :x {wsa.get 0 :t}} then :t else {if {< :x {wsa.get 0 :t}} then {wsa.s2a {wsa.get 0 :t} {BT.add :x {wsa.get 1 :t}} {wsa.get 2 :t}} else {wsa.s2a {wsa.get 0 :t} {wsa.get 1 :t} {BT.add :x {wsa.get 2 :t}} }}}}}} 2. creating the tree from an array of numbers: '{def BT.create {def BT.create.rec {lambda {:a :t} {if {wsa.empty? :a} then :t else {BT.create.rec {wsa.rest :a} {BT.add {wsa.first :a} :t}} }}} {lambda {:a} {BT.create.rec :a {wsa.s2a}} }} -> {def BT.create {def BT.create.rec {lambda {:a :t} {if {wsa.empty? :a} then :t else {BT.create.rec {wsa.rest :a} {BT.add {wsa.first :a} :t}} }}} {lambda {:a} {BT.create.rec :a {wsa.s2a}} }} 3. walking the canopy -> sorting in increasing order: '{def BT.sort {lambda {:t} {if {wsa.empty? :t} then else {BT.sort {wsa.get 1 :t}} {wsa.get 0 :t} {BT.sort {wsa.get 2 :t}} }}} -> {def BT.sort {lambda {:t} {if {wsa.empty? :t} then else {BT.sort {wsa.get 1 :t}} {wsa.get 0 :t} {BT.sort {wsa.get 2 :t}} }}} } {h4 Testing} {prewrap 1. generating an array of random numbers: '{def numbers {wsa.s2a {wsa.map {lambda {:n} {floor {* {random} 100000}}} {wsa.serie 1 100}}}} -> {def numbers {wsa.s2a {wsa.map {lambda {:n} {floor {* {random} 100000}}} {wsa.serie 1 100}}}} = {wsa.display {numbers}} 2. creating the tree is the main work: '{def tree {BT.create {numbers}}} -> {def tree {BT.create {numbers}}} 3. walking the canopy is fast: '{BT.sort {tree}} -> {BT.sort {tree}} 4. walking with new leaves is fast: '{BT.sort {BT.add -1 {tree}}} -> {BT.sort {BT.add -1 {tree}}} '{BT.sort {BT.add 50000 {tree}}} -> {BT.sort {BT.add 50000 {tree}}} '{BT.sort {BT.add 100000 {tree}}} -> {BT.sort {BT.add 100000 {tree}}} } _h2 4) addition & multiplication on big integers _p One of the tasks defined by [[www.rosetta.org|http://www.rosettacode.org/wiki/Long_multiplication]] is to compute the exact value of {code 2{sup 128}}: {center {code 2{sup 128} = {replace , by in 340,282,366,920,938,463,463,374,607,431,768,211,456}}} _p Numbers are nothing but words made of 10 digits [0 1 2 3 4 5 6 7 8 9]. We could {b but we have not to} translate a number into an array (see for instance [[ADD_MUL2]]) to process every digits using the set of functions in {b lib_WSA}, {code [wsa.first, wsa.rest, wsa.empty?,...]}. Thanks to the polymorphic behaviour of these functions we can {b process directly} numbers as words. _p In the following algorithms numbers are prefixed by a {b #} used in the recursive test: {b '{wsa.equal? number #}}. {prewrap '{def w.add {def w.add.r {lambda {:a :b :c :d} {if {wsa.equal? :a #} then {if {wsa.equal? :d 1} then 1 else}{wsa.butlast :c} else {let { {:a :a} {:b :b} {:c :c} {:d {+ :d {wsa.last :a} {wsa.last :b} }} } {w.add.r {wsa.butlast :a} {wsa.butlast :b} {wsa.last :d}:c {if {wsa.equal? {wsa.length :d} 1} then 0 else 1}} }}}} {lambda {:a :b} {{lambda {:a :b :n} {w.add.r #{wsa.feed w0 {- :n {wsa.length :a}}}:a #{wsa.feed w0 {- :n {wsa.length :b}}}:b # 0} } :a :b {max {wsa.length :a} {wsa.length :b}}} }} -> {def w.add {def w.add.r {lambda {:a :b :c :d} {if {wsa.equal? :a #} then {if {wsa.equal? :d 1} then 1 else}{wsa.butlast :c} else {let { {:a :a} {:b :b} {:c :c} {:d {+ :d {wsa.last :a} {wsa.last :b} }} } {w.add.r {wsa.butlast :a} {wsa.butlast :b} {wsa.last :d}:c {if {wsa.equal? {wsa.length :d} 1} then 0 else 1}} }}}} {lambda {:a :b} {{lambda {:a :b :n} {w.add.r #{wsa.feed w0 {- :n {wsa.length :a}}}:a #{wsa.feed w0 {- :n {wsa.length :b}}}:b # 0} } :a :b {max {wsa.length :a} {wsa.length :b}}} }} '{def w.mul {def w.muln {lambda {:a :b :n} {if {< :n 1} then :b else {w.muln :a {w.add :a :b} {- :n 1}} }}} {def w.mul.r {lambda {:a :b :c :n} {if {wsa.equal? :b #} then :c else {w.mul.r :a {wsa.butlast :b} {w.add {w.muln :a 0 {wsa.last :b}}{wsa.feed w0 :n} :c} {+ :n 1}} }}} {lambda {:a :b} {w.mul.r :a #:b 0 0} }} -> {def w.mul {def w.muln {lambda {:a :b :n} {if {< :n 1} then :b else {w.muln :a {w.add :a :b} {- :n 1}} }}} {def w.mul.r {lambda {:a :b :c :n} {if {wsa.equal? :b #} then :c else {w.mul.r :a {wsa.butlast :b} {w.add {w.muln :a 0 {wsa.last :b}}{wsa.feed w0 :n} :c} {+ :n 1}} }}} {lambda {:a :b} {w.mul.r :a #:b 0 0} }} } _p Testing {prewrap '{w.add 999 1} -> {w.add 999 1} '{w.mul 999 2} -> {w.mul 999 2} '{w.mul 123456789123456789123456789123456789 987654321} -> {w.mul 123456789123456789123456789123456789 987654321} to be compared with '{* 123456789123456789123456789123456789 987654321} -> {* 123456789123456789123456789123456789 987654321} '{def 2^32 {pow 2 32}} -> {def 2^32 {pow 2 32}} = {2^32} '{def 2^64 {w.mul {2^32} {2^32}}} -> {def 2^64 {w.mul {2^32} {2^32}}} = {2^64} '{def 2^128 {w.mul {2^64} {2^64}}} -> {def 2^128 {w.mul {2^64} {2^64}}} = {2^128} to be compared with '{pow 2 128} -> {pow 2 128} } _p A variant using {b serie map reduce} {pre '{wsa.reduce w.mul {wsa.map {lambda {_} 2} {wsa.serie 1 128}}} -> 340282366920938463463374607431768211456 } _p In the factorial's code we just replace "{b *}" by "{b w.mul}": {prewrap '{def w.fac {lambda {:a :b} {if {= :b 1} then :a else {w.fac {w.mul :a :b} {- :b 1}}}}} -> {def w.fac {lambda {:a :b} {if {= :b 1} then :a else {w.fac {w.mul :a :b} {- :b 1}}}}} '{w.fac 1 50} -> 30414093201713378043612608166064768844377641568960512000000000000 } _p In this wiki page all code examples have been computed in real time (about 500ms) following the same process: {i from the long main string, special forms create {b abstractions}, a tree of {i independant} shorter sub-strings where, in an incessant up and down, will be processed {i independant} {b applications} of this single "blade runner"} {div {@ style="font:normal 1.5em courier new; color:#000; width:100%; text-align:center; "} °° /\{([^\s{}]*)(?:[\s]*)([^{}]*)\}/g °°} _p simply replacing deeply nested forms {code '{first rest}} by bare {b words}. ;; {center {i « That's one giant step for me, one small leap for mankind. » }} {center {blockquote These days I'm (re)exploring [[factory|?view=factory_201902_paper]], [[kernel]], [[prime_pattern]], [[convolution]], ... {br}Your opinion is welcome in [[agora]]. Please don't be evil.}} _p {i Alain Marty 2019/12/05} {img {@ src="https://www.cineclubdecaen.com/cinepho/realisat/scott/bladerunner/bla121.jpg" style="width:100%; height:150px; object-fit:cover;"}} {center {i Rachel, in [[Blade Runner|https://www.cineclubdecaen.com/realisat/scott/bladerunner.htm]], a masterpiece of deep learning conceived in 1982.}} {style ;; pre { box-shadow:0 0 8px #000; padding:5px; } } {script ;; var FOO = (function() { var WSA = {}, WSA_num = 0; var isWord = function (z) { return (z !== '' && z.substring(0,5) !== '_WSA_' && z.indexOf(" ") === -1) }; var isString = function (z) { return (z !== '' && z.substring(0,5) !== '_WSA_' && z.indexOf(" ") !== -1) }; var isArray = function (z) { return (z !== '' && z.substring(0,5) === '_WSA_') }; var new_ARR = function (a) { var name = '_WSA_' + WSA_num++; WSA[name] = a; return name; }; LAMBDATALK.DICT["wsa.w2s"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return a.split("").join(" ") }; LAMBDATALK.DICT["wsa.w2a"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return (a==="")? [] : new_ARR( a.split("") ) }; LAMBDATALK.DICT["wsa.s2w"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return a.split(" ").join("") }; LAMBDATALK.DICT["wsa.s2a"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return new_ARR( (a==="")? [] : a.split(" ") ) }; LAMBDATALK.DICT["wsa.a2w"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return WSA[a].join("") }; LAMBDATALK.DICT["wsa.a2s"] = function() { var a = LAMBDATALK.supertrim(arguments[0]); return WSA[a].join(" ") }; LAMBDATALK.DICT['wsa.type'] = function() { var args = LAMBDATALK.supertrim(arguments[0]); if (isWord(args)) return 'word' else if (isString(args)) return 'string' else if (isArray(args)) return 'array' }; LAMBDATALK.DICT['wsa.null?'] = function() { // '' or "" or _WSA_n var args = LAMBDATALK.supertrim(arguments[0]); return (args === "")? "true" : "false" }; LAMBDATALK.DICT['wsa.empty?'] = function () { // '' or "" or _WSA_n var args = arguments[0].trim(); if (args === "") return "true" else if (!isArray(args)) return "false" else return (WSA[args].length < 1)? "true" : "false" }; LAMBDATALK.DICT['wsa.equal?'] = function() { // var args = LAMBDATALK.supertrim(arguments[0]).split(" "); return (args[0] === args[1])? "true" : "false" }; LAMBDATALK.DICT['wsa.isin?'] = function() { // (isin? v x) var args = LAMBDATALK.supertrim(arguments[0]).split(' '), val = args.shift(), s = args.join(" "); if (isWord(s)) { s = s.split(""); return (s.lastIndexOf(val) !==-1)? "true" : "false" } else if (isString(s)) { s = s.split(" "); return (s.lastIndexOf(val) !==-1)? "true" : "false" } else if (isArray(s)) { return (WSA[s].lastIndexOf(val) !==-1)? "true" : "false" } }; LAMBDATALK.DICT['wsa.feed'] = function() { var args = LAMBDATALK.supertrim(arguments[0]).split(" "), tval = args[0], val = tval.split(""), type = tval[0], val = tval[1], n = parseInt(args[1]); for (var i=0, s = ""; i < n; i++) s += val; if (type==="w") return s; if (type==="s") return s.split("").join(" "); if (type==="a") return s.split(""); }; //// LAMBDATALK.DICT['wsa.display'] = function() { var args = LAMBDATALK.supertrim(arguments[0]); if (isWord(args)) return "'"+args+"'" else if (isString(args)) return '"'+args+'"' else if (isArray(args)) return "["+WSA[args]+"]" }; LAMBDATALK.DICT['wsa.length'] = function() { var args = LAMBDATALK.supertrim(arguments[0]); if (args==="") return 0; if (isWord(args)) return args.length else if (isString(args)) return args.split(" ").length else if (isArray(args)) return WSA[args].length }; //// LAMBDATALK.DICT['wsa.reverse'] = function () { var args = LAMBDATALK.supertrim(arguments[0]); if (isWord(args)) return args.split("").reverse().join("") else if (isString(args)) return args.split(" ").reverse().join(" ") else if (isArray(args)) { var name = '_WSA_' + WSA_num++; WSA[name] = WSA[args].reverse(); return name; } }; LAMBDATALK.DICT['wsa.concat'] = function () { var args = LAMBDATALK.supertrim(arguments[0]).split(' '); if (args.length === 0) return '' else if (args.length === 1) return args[0] else if (args.length === 2) { if (isWord(args[0]) && isWord(args[1])) return args[0]+args[1] else if (isArray(args[0]) && isArray(args[1])) { var name = '_WSA_' + WSA_num++; WSA[name] = WSA[args[0]].concat(WSA[args[1]]); return name; } } else return args.join(" ") }; LAMBDATALK.DICT['wsa.sort'] = function () { // (sort comp words) var args = LAMBDATALK.supertrim(arguments[0]).split(' '); comp = args.shift(), s = args.join(' '); if (isWord(s)) { if (comp === '>') return s.split('').sort( function(a,b) { return a > b } ).join('') else return s.split('').sort( function(a,b) { return a < b } ).join('') } else if (isString(s)) { if (comp === '>') return s.split(' ').sort( function(a,b) { return a > b } ).join(' ') else return s.split(' ').sort( function(a,b) { return a < b } ).join(' ') } else if (isArray(s)) { var res = []; if (comp === '>') res = WSA[s].slice().sort( function(a,b) { return a - b } ) else res = WSA[s].slice().sort( function(a,b) { return b - a } ) var name = '_WSA_' + WSA_num++; WSA[name] = res; return name } }; //// LAMBDATALK.DICT['wsa.first'] = function() { // 'hello' "hello brave new world" _WSA_n var args = LAMBDATALK.supertrim(arguments[0]); if (args === "") return ""; if (isWord(args)) return args.charAt(0) else if (isString(args)) return args.split(" ")[0] else if (isArray(args)) return WSA[args][0] }; LAMBDATALK.DICT['wsa.last'] = function() { // 'hello' "hello brave new world" _WSA_n var args = LAMBDATALK.supertrim(arguments[0]); if (args === "") return ""; if (isWord(args)) return args.charAt(args.length-1) else if (isString(args)) { var arr = args.split(" "); return arr[arr.length-1] } else if (isArray(args)) return WSA[args][WSA[args].length-1] }; LAMBDATALK.DICT['wsa.rest'] = function() { // 'hello' "hello brave new world" _WSA_n var args = LAMBDATALK.supertrim(arguments[0]); if (args === "") return ""; if (isWord(args)) return args.substring(1) else if (isString(args)) return args.split(" ").slice(1).join(" "); else if (isArray(args)) { var name = '_WSA_' + WSA_num++; WSA[name] = WSA[args].slice(1); return name; } }; LAMBDATALK.DICT['wsa.butlast'] = function() { // 'hello' "hello brave new world" _WSA_n var args = LAMBDATALK.supertrim(arguments[0]); if (args === "") return ""; if (isWord(args)) return args.substring(0,args.length-1) else if (isString(args)) return args.split(" ").slice(0,-1).join(" "); else if (isArray(args)) { var name = '_WSA_' + WSA_num++; WSA[name] = WSA[args].slice(0,-1); return name; } }; LAMBDATALK.DICT['wsa.get'] = function() { var args = LAMBDATALK.supertrim(arguments[0]).split(' '), i = parseInt(args.shift()), s = args.join(' '); if (isWord(s)) return s.charAt(i) else if (isString(s)) return s.split(" ")[i] else if (isArray(s)) return WSA[s][i] }; LAMBDATALK.DICT['wsa.set!'] = function() { // (set i char string) var args = LAMBDATALK.supertrim(arguments[0]).split(' '), i = parseInt(args.shift()), v = args.shift(), s = args.join(" "); if (isWord(s)) { s = s.split(""); s[i] = v; return s } else if (isString(s)) { s = s.split(' '); s[i] = v; return s } else if (isArray(s)) { var name = '_WSA_' + WSA_num++; WSA[name] = WSA[s].slice(); WSA[name][i] = v; return name } }; // LAMBDATALK.DICT['wsa.slice!'] = function() { // i0 i1 'hello' | "hello brave new world" | _WSA_n var args = LAMBDATALK.supertrim(arguments[0]).split(' '), i0 = parseInt(args.shift()), i1 = parseInt(args.shift()), args = args.join(' '); if (isWord(args)) return args.substring(i0,i1+1) else if (isString(args)) return args.split(" ").slice(i0,i1+1).join(" ") else if (isArray(args)) { WSA[args] = WSA[args].slice(i0,i1+1) return args } }; LAMBDATALK.DICT['wsa.addfirst!'] = function() { // val 'hello' "hello brave new world" _WSA_n var args = LAMBDATALK.supertrim(arguments[0]).split(" "); if (args.length===1) return new_ARR( [args[0]] ); var val = args.shift(), args = args.join(" "); if (isWord(args)) return val + args else if (isString(args)) return val + " " + args else if (isArray(args)) { WSA[args].unshift(val); return args; } }; LAMBDATALK.DICT['wsa.addlast!'] = function() { var args = LAMBDATALK.supertrim(arguments[0]).split(" "); if (args.length===1) return new_ARR( [args[0]] ); var val = args.shift(), args = args.join(" "); if (isWord(args)) return args + val else if (isString(args)) return args + " " + val else if (isArray(args)) { WSA[args].push(val); return args; } }; LAMBDATALK.DICT['wsa.subfirst!'] = function() { var args = LAMBDATALK.supertrim(arguments[0]); if (isWord(args)) return args.substring(1) else if (isString(args)) return args.substring(1) else if (isArray(args)) { WSA[args].shift(); return args; } }; LAMBDATALK.DICT['wsa.sublast!'] = function() { var args = LAMBDATALK.supertrim(arguments[0]); if (isWord(args)) return args.substring(0,args.length-1) else if (isString(args)) return args.substring(0,args.length-1) else if (isArray(args)) { WSA[args].pop(); return args; } }; //// REPLACE SERIE MAP REDUCE // throw an error to fix (maybe in replace() ) LAMBDATALK.DICT['wsa.replace'] = function () { // (replace one by two in text) var str = LAMBDATALK.supertrim(arguments[0]); // one by two in text var index = str.indexOf('by'); var one = str.substring(0,index).trim(); str = str.substring(index+2).trim(); index = str.indexOf('in'); var two = str.substring(0,index).trim().replace(/€/g,"$"); two = (two !== 'space')? two : ' '; str = str.substring(index+2).trim(); str = str.replace( RegExp(one,'g'), two ); return str; }; LAMBDATALK.DICT['wsa.serie'] = function () { // {serie start end [step]} var args = LAMBDATALK.supertrim(arguments[0]).split(' '); var start = parseFloat( args[0] ), end = parseFloat( args[1] ), step = parseFloat( args[2] || 1), str = ''; if (step == 0) return start; step = Math.abs(step); if (start < end) for (var i=start; i<=end; i+= step) { str += i + ' '; } else if (start > end) for (var i=start; i>=end; i-= step) { str += i + ' '; } return str.substring(0, str.length-1); }; LAMBDATALK.DICT['wsa.map'] = function () { // {map func serie} var args = LAMBDATALK.supertrim(arguments[0]).split(' '); var func = args.shift(); var str = ''; if (LAMBDATALK.DICT[func] !== undefined) { for (var i=0; i< args.length; i++) str += LAMBDATALK.DICT[func].call( null, args[i] ) + ' '; } return str.substring(0, str.length-1); }; LAMBDATALK.DICT['wsa.reduce'] = function () { // {reduce func serie} var args = LAMBDATALK.supertrim(arguments[0]).split(' '); var func = args.shift(); // * var r = args[0]; // [1,2,3,4] for (var i=1; i< args.length; i++) // {* r args[i]} r = LAMBDATALK.DICT[func].call(null, (r + " " + args[i])); return r }; //// end WORDS, STRINGS, ARRAYS LAMBDATALK.DICT['WSA?'] = function () { return "WSA is defined." }; LAMBDATALK.DICT["wsa.lib"] = function() { var str = "", index = 0; for (var key in LAMBDATALK.DICT) { if (LAMBDATALK.DICT.hasOwnProperty(key) && key.substring(0,4) === "wsa.") { str += key + ", "; index++; } } return "WSA: [" + index + "] [" + str.substring(0, str.length - 2) + "]"; }; })(); // end script }
lambdaspeech v.20200126