lambdaspeech
::
array
1
[
pages
][
login
][
load
]
_h1 array _p Following [[mozilla/Array|following: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array]], '{lambda speech} comes with a set of {b array} functions built on the powerful JS arrays: {pre {@ style="white-space:pre-wrap"} '{def ARR {#.new a b c d}} -> {def ARR {#.new a b c d}} '{#.disp {ARR}} -> {#.disp {ARR}} '{#.array? {ARR}} -> {#.array? {ARR}} '{#.array? hello} -> {#.array? hello} '{#.null? {ARR}} -> {#.null? {ARR}} // should be right '{#.null? {#.new}} -> {#.null? {#.new}} // should be left '{#.length {ARR}} -> {#.length {ARR}} '{#.empty? {ARR}} -> {#.empty? {ARR}} '{#.in? {ARR} b} -> {#.in? {ARR} b} '{#.in? {ARR} x} -> {#.in? {ARR} x} '{#.get {ARR} 1} -> {#.get {ARR} 1} '{#.first {ARR}} -> {#.first {ARR}} '{#.last {ARR}} -> {#.last {ARR}} '{#.rest {ARR}} -> {#.rest {ARR}} // a new array '{#.slice {ARR} 1 3} -> {#.slice {ARR} 1 3} // a new array '{#.concat {ARR} {ARR}} -> {#.concat {ARR} {ARR}} // a new array } _p The following functions modify the given array {pre '{#.set! {#.new hello world} 0 goodbye} -> {#.set! {#.new hello world} 0 goodbye} '{#.set! {#.new hello world} 1 moon} -> {#.set! {#.new hello world} 1 moon} '{#.addlast! {#.new a b c d} e} -> {#.addlast! {#.new a b c d} e} // equiv #.push! '{#.sublast! {#.new a b c d}} -> {#.sublast! {#.new a b c d}} // equiv #.pop!, '{#.addfirst! {#.new a b c d} e} -> {#.addfirst! {#.new a b c d} e} // equiv #.unshift! '{#.subfirst! {#.new a b c d}} -> {#.subfirst! {#.new a b c d}} // equiv #.shift!, '{#.reverse! {#.new a b c d}} -> {#.reverse! {#.new a b c d}} '{#.sort! < {#.new 23 12 57 37 0 67}} -> {#.sort! < {#.new 23 12 57 37 0 67}} '{#.sort! > {#.new 23 12 57 37 0 67}} -> {#.sort! > {#.new 23 12 57 37 0 67}} and some more to come } _h3 example _p {b 1. array-like}: we display array's elements using {code '{#.get array index}} primitive {pre '{def adisp {def adisp.r {lambda {:a :i0 :i1} {if {< :i1 :i0} then else {#.get :a :i0} {adisp.r :a {+ :i0 1} :i1}}}} {lambda {:a} {adisp.r :a 0 {- {#.length :a} 1}}}} -> {def adisp {def adisp.r {lambda {:a :i0 :i1} {if {< :i1 :i0} then else {#.get :a :i0} {adisp.r :a {+ :i0 1} :i1}}}} {lambda {:a} {adisp.r :a 0 {- {#.length :a} 1}}}} '{adisp {#.new 12 34 56 78 90}} -> {adisp {#.new 12 34 56 78 90}} } _p {b 2. list-like}: we display array's elements using the {i list-like} [{code #.first, #.rest}] primitives {pre '{def ldisp {lambda {:a} {if {< {#.length :a} 1} then else {#.first :a} {ldisp {#.rest :a}} }}} -> {def ldisp {lambda {:a} {if {< {#.length :a} 1} then else {#.first :a} {ldisp {#.rest :a}} }}} '{ldisp {#.new 12 34 56 78 90}} -> {ldisp {#.new 12 34 56 78 90}} } _p It's a matter of choice. _h3 state _p '{lambda speech} is purely functional and has no {code set!} operator. But {b arrays can be mutated} and we can model successive operations stored in a growing array, for instance inputs/outputs in a bank account: {pre '{def account.new {lambda {:m} {#.new :m}}} -> {def account.new {lambda {:m} {#.new :m}}} '{def account.operation {def account.operation.rec {lambda {:a :i :s} {if {< :i 1} then {if {< :s 0} then :s€ {b oops!!!} else :s€} else {account.operation.rec :a {- :i 1} {+ :s {#.get :a :i}} } }}} {lambda {:a :i :m} {b op #:i}: :m€ | {b balance}: {account.operation.rec {#.push! {:a} :m} :i 0} }} -> {def account.operation {def account.operation.rec {lambda {:a :i :s} {if {< :i 0} then {if {< :s 0} then :s€ {b oops!!!} else :s€} else {account.operation.rec :a {- :i 1} {+ :s {#.get :a :i}}}}}} {lambda {:a :i :m} {b op #:i}: :m€ | {b balance}: {account.operation.rec {#.push! {:a} :m} :i 0} }} } _p Test: {pre '{def K {account.new 100}} -> {def K {account.new 100}} '{account.operation K 1 -10} -> {account.operation K 1 -10} '{account.operation K 2 +50} -> {account.operation K 2 +50} '{account.operation K 3 -15} -> {account.operation K 3 -15} '{account.operation K 4 -50} -> {account.operation K 4 -50} '{account.operation K 5 -95} -> {account.operation K 5 -95} } _p Even if the array {code K} is growing with the successive operations until the final state, {code {K}}, the successive calls {code '{account.operation K i value}} return different results according to {code i} and not because the initial amount {code M=100} mutates. _p This is the standard syntax for arrays: {pre '{def A {#.new 12 34 56 78}} -> {def A {#.new 12 34 56 78}} '{#.disp {A}} -> {#.disp {A}} '{#.get {A} 0} -> {#.get {A} 0} '{#.get {A} 1} -> {#.get {A} 1} '{#.get {A} 2} -> {#.get {A} 2} '{#.get {A} 3} -> {#.get {A} 3} '{#.get {A} 4} -> {#.get {A} 4} } _h3 a useful macro _p With a single macro we can replace {b '{#.get {A} i}} by the C-like {b A[{span}i]} {pre '{macro ([:\w\d]+?)\[([\w]*)\] to {if {equal? {substring 0 6 €1} _ARRA_} then {#.get €1 €2} else {#.get {€1} €2} }} } {macro ([:\w\d]+?)\[([\w]*)\] to {if {equal? {substring 0 6 €1} _ARRA_} then {#.get €1 €2} else {#.get {€1} €2} }} {pre A[{span}0] -> A[0] A[{span}1] -> A[1] A[{span}2] -> A[2] A[{span}3] -> A[3] A[{span}4] -> A[4] } _p Inside a function {pre °°{def interpol {lambda {:p0 :p1 :t} {#.new {+ {* :p0°°{span}°°[0] {- 1 :t}} {* :p1°°{span}°°[0] :t}} {+ {* :p0°°{span}°°[1] {- 1 :t}} {* :p1°°{span}°°[1] :t}} } }}°° -> {def interpol {lambda {:p0 :p1 :t} {#.new {+ {* :p0[0] {- 1 :t}} {* :p1[0] :t}} {+ {* :p0[1] {- 1 :t}} {* :p1[1] :t}} } }} '{interpol {#.new 100 100} {#.new 200 300} 0.5} -> {interpol {#.new 100 100} {#.new 200 300} 0.5} } _p See also [[map]], [[decasteljau]], [[yyy]], ...
lambdaspeech v.20180812