Navigation

JS Subset in WebPPL

Nonstochastic JS Test Cases in WebPPL

The text of this WebPPL-script file can be copied and run in the WebPPL-box which can be found here: webppl.org.

console.log("==============================================================================")
console.log("file: 'PCM20180310_JS_in_WebPPL' by PCM             *** version 2018/03/21 ***")
console.log("       This file contains JS test cases executable in WebPPL                  ")
console.log("       *** beware, array methods are not referential transparent ! ****                      ")
console.log("WebPPL is a pure functional DSL (= Domain Specific language) embedded in JS")
console.log("examples are similar but not identical to those in 'Core JavaScript',")
console.log("        ch.1.1 in David Flanagan 'JavaScript: The Definitive Guide', 2011. 6/e")
console.log("==============================================================================")
console.log("'console.log(...)' generates output in the browser's web console")
console.log("comment: anything following double slashes '//' is a comment")
console.log("")
console.log("the test template has this structure:")
console.log("  <stringOfTestDescription> '--->' <expression> <compOperator> <targetValue>")
console.log("")
console.log("<stringOfTestDescription>, ... an informal description of the test ")
console.log("'--->', symbol with meaning '<expression> (left) evaluates to <value> (right)'")
console.log("<expression>, ... a WebPPL-expression")
console.log("<compOperator>, ... a comparison operator ==, !=, ===, !==, <, >, ... ")
console.log("<compOperator> '==' means a 'test of equality' (beware of type coercion !)")
console.log("<compOperator> '===' means a 'test of strict equality'")
console.log("<targetValue>, ... an expected value; should not deviate from <value> !")
console.log("")
console.log("  ***important *** all tests should evaluate to ***true***")
console.log("==============================================================================")
console.log("variable: a variable is a symbolic name for a value")
console.log("var pi = 3.141")     // declare a variable named 'pi' with value '3.141'
var pi = 3.141
console.log("pi === 3.141 --->", pi === 3.141) // should be 'true'
console.log("------------------------------------------------------------")
console.log("numbers: integers")
console.log("var x = 1")
var x = 1                     // declare a variable 'x' with integer value '1'
console.log("x === 1 --->", x === 1) // should be 'true'
console.log("------------------------------------------------------------")
console.log("numbers: reals")
var x = 0.01                  // declare a new variable 'x' with real value '0.01'
console.log("x === 0.01 --->", x === 0.01) // should be 'true'
console.log("------------------------------------------------------------")
console.log("strings:")
console.log('var x = "hello"')
var x = "hello"               // strings of text in quotation marks
console.log('x === "hello" --->', x === "hello") // should be 'true'
console.log("var x = 'hello'")
var x = 'hello'              // single quote marks are also string delimiters
console.log("x === 'hello' --->", x === 'hello') // should be 'true'
console.log("------------------------------------------------------------")
console.log("booleans:")
console.log("var x = true")
var x = true                  // boolean value 'true'
console.log("x === true --->", x === true) // should be 'true'
console.log("var x = false")
var x = false                 // boolean value 'false'
console.log("x === false --->", x === false) // should be 'true'
console.log("------------------------------------------------------------")
console.log("special values:")
console.log("var x = null")
var x = null                  // 'null' is a special value that means 'no value'
console.log("x === null --->", x === null)   // should be 'true'
console.log("var x = undefined")
var x = undefined             // 'undefined' is similar to 'null' but returns no value
console.log("x === undefined --->", x === undefined) // should be 'true'
console.log("------------------------------------------------------------")
console.log("objects: are collections of name/value or string-value pairs")
console.log('var thisTutorial = {topic: "WebPPL", year: 2018}')
var thisTutorial = {          // object constructors are enclosed in curly braces
  topic: "WebPPL",            // the property ("slot") 'topic' has value "WebPPL"
  year: 2018                  // the property ("slot") 'year' has value 2018
}
console.log('thisTutorial !== {topic: "WebPPL", year:2018} --->',
            thisTutorial !== {topic: "WebPPL", year:2018}) // should give 'true'
console.log('thisTutorial != {topic: "WebPPL", year:2018} --->',
            thisTutorial != {topic: "WebPPL", year:2018})  // should give 'true'
console.log("object selectors: access the values of object properties")
console.log('thisTutorial.topic === "WebPPL" --->', thisTutorial.topic === "WebPPL")
console.log('thisTutorial["topic"] === "WebPPL" --->', thisTutorial["topic"] === "WebPPL")
console.log('thisTutorial.year === 2018 --->', thisTutorial.year === 2018)
console.log('thisTutorial["year"] === 2018 --->', thisTutorial["year"] === 2018)
console.log("------------------------------------------------------------")
console.log("arrays: are numerically indexed lists of values")
console.log("var primes = [2, 3, 5, 7]")
var primes = [2, 3, 5, 7]
console.log("primes !== [2, 3, 5, 7] --->", primes !== [2, 3, 5, 7])
console.log("primes != [2, 3, 5, 7] --->", primes != [2, 3, 5, 7])
console.log("primes[0] === 2 --->", primes[0] === 2)  // first element with index 0             
console.log("primes.length === 4 --->", primes.length === 4) // how many elements in array
console.log("primes[primes.length-1] === 7 --->",
            primes[primes.length-1] === 7) // last element
console.log("var empty = []")
var empty = []                // ==> create an empty array with 0 elements
console.log("empty !== [] --->", empty !== [])
console.log("empty != [] --->", empty != [])
console.log("empty.length === 0 --->", empty.length === 0)  // should be 'true'
console.log("------------------------------------------------------------")
console.log("nested objects:")
console.log('var myObject = {a:{c:"d"}, b:{e:"f"}}')
var myObject = {a:{c:"d"}, b:{e:"f"}}
console.log('myObject.b.e === "f" --->', myObject.b.e === "f")
console.log('myObject["b"]["e"] == "f" --->', myObject["b"]["e"] === "f")
console.log("------------------------------------------------------------")
console.log("nested arrays:")
console.log('var myArray = [["a", 11], ["b", 13]]')
var myArray = [["a", 11], ["b", 13]]
console.log('myArray !== [["a",11],["b",13]] --->', myArray !== [["a",11],["b",13]])
console.log('myArray != [["a",11],["b",13]] --->', myArray != [["a",11],["b",13]])
console.log('myArray[1][0]  == "b" --->', myArray[1][0]  == "b")
console.log('myArray[1][1]  == 13 --->', myArray[1][1]  == 13)
console.log("------------------------------------------------------------")
console.log("mixed objects:")
console.log("var myDataObject = {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]}")
var myDataObject = {          // an object with two properties
  trial1: [[1,2],[1,3]],      // the value of each property is an array
  trial2: [[2,4],[2,5]]       // the elements of the arrays are arrays
}
console.log("myDataObject !== {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]} --->",
           myDataObject !== {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]})
console.log("myDataObject != {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]} --->",
           myDataObject != {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]})
console.log("myDataObject.trial2[0][0] == 2 --->", myDataObject.trial2[0][0] == 2)
console.log("myDataObject.trial2[1][1] == 5 --->", myDataObject.trial2[1][1] == 5)
console.log("------------------------------------------------------------")
console.log("mixed arrays:")
console.log("var myPoints = [{x:0, y:0}, {x:1, y:1}]")
var myPoints =                // an array with two elements         
    [{x:0, y:0}, {x:1, y:1}]  // each element is an object
console.log('myPoints !== [{"x":0,"y":0},{"x":1,"y":1}] --->',
            myPoints !== [{"x":0,"y":0},{"x":1,"y":1}])
console.log('myPoints[1] !== {"x":1,"y":1} --->', myPoints[1] !== {"x":1,"y":1})
console.log('myPoints[1] != {"x":1,"y":1} --->', myPoints[1] != {"x":1,"y":1})
console.log('myPoints[0]["x"] == 0 --->', myPoints[0]["x"] == 0) // should be true
console.log("------------------------------------------------------------")
console.log("operators: operators act on values (= operands) to produce a value")
console.log("arithmetic operators:")
console.log("3 + 5 ===   8 --->", 3 + 5 ===   8)  // should be true
console.log("3 - 5 ===  -2 --->", 3 - 5 ===  -2)  // should be true
console.log("3 * 5 ===  15 --->", 3 * 5 ===  15)  // should be true
console.log("3 / 5 === 0.6 --->", 3 / 5 === 0.6)  // should be true
console.log("myPoints[0].y - myPoints[1].y === -1 --->",
            myPoints[0].y - myPoints[1].y === -1) // more complicated operands also work
console.log('"3" + "2" === "32" --->', "3" + "2" === "32") // overloading of '+'
console.log("------------------------------------------------------------")
console.log("equality and relational operators:")
console.log("var x = 2; var y = 3")
var x = 2; var y = 3
console.log("equality '=='")
console.log("not equality '!='")
console.log("strict equality '==='")
console.log("not strict equality '==='")
console.log("(x == y) === false --->", (x == y) === false) // should be true
console.log("inequality operator '!='")
console.log("(x != y) === true --->", (x != y) === true) // should be true
console.log("relational operator '<'")
console.log("(x < y) === true --->", (x < y) === true) // should be true
console.log("(x <= y) === true --->", (x <= y) === true) // should be true
console.log("(x > y) === false --->", (x > y) === false) // should be true
console.log("(x >= y) === false --->", (x >= y) === false) // should be true
console.log('("two" === "two") === true --->', ("two" === "two") === true) // should be true
console.log('("two" == "three") === false --->', ("two" == "three") === false) // sh. be true
console.log('("two" > "three") === true --->', ("two" > "three") === true) // should be true
console.log('("two" >= "three") === true --->', ("two" >= "three") === true) // sh. be true
console.log("(false == (x > y)) --->", (false == (x > y)) === true )
console.log("------------------------------------------------------------")
console.log("logical operators:")
console.log("((x == 2) && (y == 3)) === true --->", ((x == 2) && (y == 3)) === true)
console.log("((x > 2) || (y < 3)) === false --->", (x > 2) || (y < 3) === false)
console.log("!(x == y) === true --->", !(x == y) === true)
console.log("------------------------------------------------------------")
console.log("")
console.log("function: ... a named and parametrized block of code that can be invoked")
console.log("var myPlus1 = function (x) {x + 1}")
var myPlus1 = function (x) {x + 1}
console.log("myPlus1(y) === 4, where y=3 --->", myPlus1(y) === 4)
console.log("var mySquare = function(x) {x * x}")
var mySquare = function(x) {x * x}
console.log("mySquare(myPlus1(y)) === 16, where y=3 --->", mySquare(myPlus1(y)) === 16)
console.log("------------------------------------------------------------")
console.log("")
console.log("methods: all JS objects have methods")
console.log("var a = []")
var a = []    // length(a) = 1
console.log(" a.push(...) ---> length(a');  a' = augmented a")
console.log("a.push(1,4,9,16) === 4 --->", a.push(1,4,9,16) === 4)  // value = length(a') = 4
console.log(" array.pop() ---> removedElement(array)")              // length(a'') = 3
console.log("a.pop() === 16 --->", a.pop() === 16)        // value = removed element of array
console.log("a'' = ", a)  // length(a'') = 3 ; a'' = [1, 4, 9]
console.log("a[0] === 1 --->", a[0] === 1)  // first element of a'' === 1
console.log("(a[a.length-1]) === 9 --->", (a[a.length-1]) === 9) //last elmnt of a''[2] === 9
console.log("array.reverse() is an *inplace* reversal: array.reverse().reverse() ---> array")
console.log("a.reverse()[0] === 9 --->", a.reverse()[0] === 9) // *inplace* reversal: a'''
console.log("a''' = ", a)  // length(a''') = 3 ; a''' = [9, 4, 1]
console.log("a.reverse()[2] === 9 --->", a.reverse()[2] === 9)// *inplace* reversal, again
console.log("a'''' = a'' = ", a)  // length(a'''') = 3; a'''' = a''
console.log("a.shift() === 1 --->", a.shift() === 1)
console.log("a'''' = ", a)        // length(a'''') = 2 ; // a'''' = [4, 9]
console.log("a[0] === 4 --->", a[0] === 4)  // first element of a'''' === 4
console.log("(a[a.length-1]) === 9 --->", (a[a.length-1]) === 9)// last elmnt a''''[1] === 9
console.log("beware: a.push(1, 3, 7)[0] does not evaluate to a'''''[0] === 4 ")
console.log("                           but to length(a''''') === 5")
console.log("a.push(1, 3, 7)[0] === 5 --->", a.push(1, 3, 7) === 5) // a'''''= [4, 9, 1, 3, 7]
console.log("(a[a.length-1]) === 7 --->", (a[a.length-1]) === 7)// last el. of a'''''[4] === 7
console.log("a''''' ---> ", a)
console.log("a'''''[4] === 7 ---> ", a[4] === 7)
console.log("------------------------------------------------------------")
console.log("")
console.log("var myPointsDist = function(p1, p2) {   ")
console.log("  var a2 = Math.pow((p2.x - p1.x), 2) ")
console.log("  var b2 = Math.pow((p2.y - p1.y), 2) ")
console.log("  Math.sqrt(a2 + b2) ")
console.log("}")
console.log("var myPointsDist = function(p1, p2) {")
console.log("  var a2 = Math.pow((p2.x - p1.x), 2)")
console.log("  var b2 = Math.pow((p2.y - p1.y), 2)")
console.log("  Math.sqrt(a2 + b2)")
console.log("}")
var myPointsDist = function(p1, p2) { // because object methods are not allowed
  var a2 = Math.pow((p2.x - p1.x), 2) // this function has to be different from Flanagan's
  var b2 = Math.pow((p2.y - p1.y), 2) // object method
  Math.sqrt(a2 + b2)
}
console.log("myPointsDist(myPoints[0], myPoints[1]) == 1.4142135623730951 --->",
            myPointsDist(myPoints[0], myPoints[1]) == 1.4142135623730951)
console.log("------------------------------------------------------------")
console.log("")
console.log("conditional expressions:")
console.log("var myAbs = function(x) {(x >= 0) ? x : -x}")
var myAbs = function(x) {(x >= 0) ? x : -x}
console.log("myAbs(5) === 5 --->", myAbs(5) === 5)
console.log("myAbs(-5) === -5 --->", myAbs(-5) === 5)
console.log("===============================================================================")

Output JS in WebPPL

==============================================================================

file: 'PCM20180310_JS_in_WebPPL' by PCM             *** version 2018/03/21 ***

       This file contains JS test cases executable in WebPPL                  

       *** beware, array methods are not referential transparent ! ****                      

WebPPL is a pure functional DSL (= Domain Specific language) embedded in JS

examples are similar but not identical to those in 'Core JavaScript',

        ch.1.1 in David Flanagan 'JavaScript: The Definitive Guide', 2011. 6/e

==============================================================================

'console.log(...)' generates output in the browser's web console

comment: anything following double slashes '//' is a comment

the test template has this structure:

  <stringOfTestDescription> '--->' <expression> <compOperator> <targetValue>

<stringOfTestDescription>, ... an informal description of the test 

'--->', symbol with meaning '<expression> (left) evaluates to <value> (right)'

<expression>, ... a WebPPL-expression

<compOperator>, ... a comparison operator ==, !=, ===, !==, <, >, ... 

<compOperator> '==' means a 'test of equality' (beware of type coercion !)

<compOperator> '===' means a 'test of strict equality'

<targetValue>, ... an expected value; should not deviate from <value> !

  ***important *** all tests should evaluate to ***true***

==============================================================================

variable: a variable is a symbolic name for a value

var pi = 3.141

pi === 3.141 ---> true

------------------------------------------------------------

numbers: integers

var x = 1

x === 1 ---> true

------------------------------------------------------------

numbers: reals

x === 0.01 ---> true

------------------------------------------------------------

strings:

var x = "hello"

x === "hello" ---> true

var x = 'hello'

x === 'hello' ---> true

------------------------------------------------------------

booleans:

var x = true

x === true ---> true

var x = false

x === false ---> true

------------------------------------------------------------

special values:

var x = null

x === null ---> true

var x = undefined

x === undefined ---> true

------------------------------------------------------------

objects: are collections of name/value or string-value pairs

var thisTutorial = {topic: "WebPPL", year: 2018}

thisTutorial !== {topic: "WebPPL", year:2018} ---> true

thisTutorial != {topic: "WebPPL", year:2018} ---> true

object selectors: access the values of object properties

thisTutorial.topic === "WebPPL" ---> true

thisTutorial["topic"] === "WebPPL" ---> true

thisTutorial.year === 2018 ---> true

thisTutorial["year"] === 2018 ---> true

------------------------------------------------------------

arrays: are numerically indexed lists of values

var primes = [2, 3, 5, 7]

primes !== [2, 3, 5, 7] ---> true

primes != [2, 3, 5, 7] ---> true

primes[0] === 2 ---> true

primes.length === 4 ---> true

primes[primes.length-1] === 7 ---> true

var empty = []

empty !== [] ---> true

empty != [] ---> true

empty.length === 0 ---> true

------------------------------------------------------------

nested objects:

var myObject = {a:{c:"d"}, b:{e:"f"}}

myObject.b.e === "f" ---> true

myObject["b"]["e"] == "f" ---> true

------------------------------------------------------------

nested arrays:

var myArray = [["a", 11], ["b", 13]]

myArray !== [["a",11],["b",13]] ---> true

myArray != [["a",11],["b",13]] ---> true

myArray[1][0]  == "b" ---> true

myArray[1][1]  == 13 ---> true

------------------------------------------------------------

mixed objects:

var myDataObject = {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]}

myDataObject !== {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]} ---> true

myDataObject != {trial1:[[1,2],[1,3]], trial2:[[2,4],[2,5]]} ---> true

myDataObject.trial2[0][0] == 2 ---> true

myDataObject.trial2[1][1] == 5 ---> true

------------------------------------------------------------

mixed arrays:

var myPoints = [{x:0, y:0}, {x:1, y:1}]

myPoints !== [{"x":0,"y":0},{"x":1,"y":1}] ---> true

myPoints[1] !== {"x":1,"y":1} ---> true

myPoints[1] != {"x":1,"y":1} ---> true

myPoints[0]["x"] == 0 ---> true

------------------------------------------------------------

operators: operators act on values (= operands) to produce a value

arithmetic operators:

3 + 5 ===   8 ---> true

3 - 5 ===  -2 ---> true

3 * 5 ===  15 ---> true

3 / 5 === 0.6 ---> true

myPoints[0].y - myPoints[1].y === -1 ---> true

"3" + "2" === "32" ---> true

------------------------------------------------------------

equality and relational operators:

var x = 2; var y = 3

equality '=='

not equality '!='

strict equality '==='

not strict equality '==='

(x == y) === false ---> true

inequality operator '!='

(x != y) === true ---> true

relational operator '<'

(x < y) === true ---> true

(x <= y) === true ---> true

(x > y) === false ---> true

(x >= y) === false ---> true

("two" === "two") === true ---> true

("two" == "three") === false ---> true

("two" > "three") === true ---> true

("two" >= "three") === true ---> true

(false == (x > y)) ---> true

------------------------------------------------------------

logical operators:

((x == 2) && (y == 3)) === true ---> true

((x > 2) || (y < 3)) === false ---> true

!(x == y) === true ---> true

------------------------------------------------------------

function: ... a named and parametrized block of code that can be invoked

var myPlus1 = function (x) {x + 1}

myPlus1(y) === 4, where y=3 ---> true

var mySquare = function(x) {x * x}

mySquare(myPlus1(y)) === 16, where y=3 ---> true

------------------------------------------------------------

methods: all JS objects have methods

var a = []

 a.push(...) ---> length(a');  a' = augmented a

a.push(1,4,9,16) === 4 ---> true

 array.pop() ---> removedElement(array)

a.pop() === 16 ---> true

a'' =  1,4,9

a[0] === 1 ---> true

(a[a.length-1]) === 9 ---> true

array.reverse() is an *inplace* reversal: array.reverse().reverse() ---> array

a.reverse()[0] === 9 ---> true

a''' =  9,4,1

a.reverse()[2] === 9 ---> true

a'''' = a'' =  1,4,9

a.shift() === 1 ---> true

a'''' =  4,9

a[0] === 4 ---> true

(a[a.length-1]) === 9 ---> true

beware: a.push(1, 3, 7)[0] does not evaluate to a'''''[0] === 4 

                           but to length(a''''') === 5

a.push(1, 3, 7)[0] === 5 ---> true

(a[a.length-1]) === 7 ---> true

a''''' --->  4,9,1,3,7

a'''''[4] === 7 --->  true

------------------------------------------------------------

var myPointsDist = function(p1, p2) {   

  var a2 = Math.pow((p2.x - p1.x), 2) 

  var b2 = Math.pow((p2.y - p1.y), 2) 

  Math.sqrt(a2 + b2) 

}

var myPointsDist = function(p1, p2) {

  var a2 = Math.pow((p2.x - p1.x), 2)

  var b2 = Math.pow((p2.y - p1.y), 2)

  Math.sqrt(a2 + b2)

}

myPointsDist(myPoints[0], myPoints[1]) == 1.4142135623730951 ---> true

------------------------------------------------------------

conditional expressions:

var myAbs = function(x) {(x >= 0) ? x : -x}

myAbs(5) === 5 ---> true

myAbs(-5) === -5 ---> true

===============================================================================
We5rgbmasteruj (manuela.wuhkdb8estefeld@uol.ded6m1) (Changed: 2020-01-23)