Is there a way to insert raw javascript in parenscript code? - common-lisp

The following code inserts third-party generated javascript as a string which will need to be eval'ed.
(ps (let ((x (lisp (json:encode-json-alist-to-string
'((:a . 1) (:b . 2))))))))
"(function () {
var x = '{\"a\":1,\"b\":2}';
return null; })();"
Is there a way to tell parenscript to insert a string unquoted?

Added this to parenscript's non-cl.lisp file:
(define-expression-operator lisp-raw (lisp-form)
`(ps-js:escape
,lisp-form))
(defun lisp-raw (x) x)
Result:
(ps (let ((x (ps::lisp-raw (json:encode-json-alist-to-string
'((:a . 1) (:b . 2))))))))
"(function () {
var x = {\"a\":1,\"b\":2};
return null;
})();"

Related

Ramdajs - how to combine pipe and function to update an object

I have a function that accepts two parameters.
const myfunction = (xyz) => async(param) => {
return "some value " + xyz + param.a;
}
and a pipe with an object as parameter,
R.pipe(
)({"a":"a value"});
How to add new attribute to the object with the function returned value?
Expected output:
{
"a": "a value",
"b": "some value xyz a value"
}
Tried the below, but parameter error
R.pipe(
R.assoc("b", myfunction("xyz")),
)({ "a" :"a value"});
R.pipe(
R.assoc("b", myfunction("xyz")(R.identity)),
)({ "a" :"a value"});
I don't think there's anything really built into Ramda for this. We can write it atop several Ramda functions, like this:
const myfunction = (xyz) => async (param) => {
return "some value " + xyz + param .a
}
const foo = (param) =>
myfunction ('xyz') (param) .then (flip (assoc ('b')) (param))
foo ({a: 'a value'}) .then (console .log)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {flip, assoc} = R </script>
But it's not at all clear that this is in any way better than a vanilla JS version such as this:
const foo = (param) =>
myfunction ('xyz') (param) .then (v => ({...param, b: v}))
(and I'm a founder and big fan of Ramda; it simply doesn't try to solve all problems.)
However, there is an interesting abstraction of either of these, to create our own combinator which handles the overall flow of (f, g) => (x) => f (x) .then (g (x)). As it feels relatively close to pipeing and because there is a strong tradition of naming combinators after birds, I will call this piper, short for "sandpiper". Abstracting out that, we can simplify foo to look like this:
const piper = (f, g) => (p) => f (p) .then (g (p))
const myfunction = (xyz) => async (param) => {
return "some value " + xyz + param .a
}
const foo = piper (myfunction ('xyz'), flip (assoc ('b')))
foo ({a: 'a value'}) .then (console .log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {flip, assoc} = R </script>
This can be a very powerful technique, abstracting out the logical skeleton of our function to be used in multiple places. Of course it adds nothing to just a single function like this, but it lets us find commonalities with future code.

Dafny predicate isBinarySearchTree

I have to write a little BST (binary search tree) class in Dafny.
I begin with Dafny then write a class and an insert method was the easiest part.
I tried multiple time to write a recursive predicate which can check if the tree passed as argument is a BST (without balancing condition, a simple binary tree following the rule left.value < node.value && right.value > node.value).
I found in another StackOverflow post a way to do it passing a function in a predicate and the main recursives check are in the function but it doesn't seem to work.
The error is basically 'A pre-condition for this call might not hold'.
Here is the code:
datatype Tree = Nil | Node(left: Tree, value: int, right: Tree)
class TreeADT{
function isBST(tree: Tree): bool
decreases tree
{
match tree
case Nil => true
case Node(_,_,_) =>
(tree.left == Nil || tree.left.value < tree.value)
&& (tree.right == Nil || tree.right.value > tree.value)
&& isBST(tree.left) && isBST(tree.right)
}
predicate isBinarySearchTree(tree: Tree)
{
isBST(tree)
}
method insert(tree: Tree, value: int) returns (toAdd: Tree) //maybe remove
requires isBinarySearchTree(tree)
decreases tree;
// ensures isBinarySearchTree(toAdd) //same error appear here
{
if(tree == Nil) {return Node(Nil, value, Nil);}
else{
if(value == tree.value) {return tree;}
var temp: Tree;
if(value < tree.value){
temp := insert(tree.left, value);
toAdd := Node(temp, tree.value, tree.right);
}else{
temp := insert(tree.right, value);
toAdd := Node(tree.left, tree.value, temp);
}
return toAdd;
}
}
method printOrderedTree(tree:Tree)
decreases tree
{
if tree == Nil {}
else {
printOrderedTree(tree.left);
print tree.value, ", ";
printOrderedTree(tree.right);
}
}
method Main() {
var t := insert(Nil, 5);
var u := insert(t, 2); // error on pre-condition here
print t, "\n";
print u, "\n";
printOrderedTree(u);
var b:bool := isBST(u);
}
}
I also tried to do it entirely in the predicate but the recursive check seems to doesn't work anyway.
Any idea to get recursion check instead of loop check in a predicate?
Thanks for reading.
Edit:
Following James's answer i modified my code
datatype Tree = Nil | Node(left: Tree, value: int, right: Tree)
predicate isBinarySearchTree(tree: Tree)
decreases tree
{
match tree
case Nil => true
case Node(_,_,_) =>
(tree.left == Nil || tree.left.value < tree.value)
&& (tree.right == Nil || tree.right.value > tree.value)
&& isBinarySearchTree(tree.left) && isBinarySearchTree(tree.right)
&& treeMin(tree.value, tree.right) && treeMax(tree.value, tree.left)
}
predicate treeMax(max: int, tree: Tree)
decreases tree
{
match tree
case Nil => true
case Node(left,v,right) => (max > v) && treeMax(max, left) && treeMax(max, right)
}
predicate treeMin(min: int, tree:Tree)
decreases tree
{
match tree
case Nil => true
case Node(left,v,right) => (min < v) && treeMin(min, left) && treeMin(min, right)
}
method insert(tree: Tree, value: int) returns (toAdd: Tree) //maybe remove
requires isBinarySearchTree(tree)
decreases tree;
ensures isBinarySearchTree(toAdd)
{
if(tree == Nil) {return Node(Nil, value, Nil);}
else{
if(value == tree.value) {return tree;}
var temp: Tree;
if(value < tree.value){
temp := insert(tree.left, value);
toAdd := Node(temp, tree.value, tree.right);
}else{
temp := insert(tree.right, value);
toAdd := Node(tree.left, tree.value, temp);
}
return toAdd;
}
}
method printOrderedTree(tree:Tree)
decreases tree
{
if tree == Nil {}
else {
printOrderedTree(tree.left);
print tree.value, ", ";
printOrderedTree(tree.right);
}
}
method Main() {
var t := insert(Nil, 5);
var u := insert(t, 2);
print t, "\n";
print u, "\n";
u := insert(u, 1);
u := insert(u, 3);
u := insert(u, 7);
u := insert(u, 6);
u := insert(u, 4);
printOrderedTree(u);
}
But same problem occurs in requires and ensures statement, I now check if all value at left side are lesser and all at right side are greater but this error occurs again
A postcondition might not hold on this return path.
And if I comment out the ensures statement I get the following error:
A precondition for this call might not hold.
All constructives ideas and dafny tips will be read with attention.
Thanks.
There are several issues with your code.
(1) What is the purpose of the TreeADT class? In Dafny, classes are usually used to represent mutable objects, but your class has no fields or mutator methods, and you use a datatype to hold the data, so you can just get rid of the class altogether.
(2) Your definition of isBST is wrong. Here is an example:
method UhOh()
ensures isBST(Node(Node(Nil, 3, Node(Nil, 7, Nil)), 5, Nil))
{}
This tree is not a binary search tree because 7 is greater than 5 but 7 is in the left subtree of 5. But your definition allows this tree.
(3) The concrete problem you are running into is that Dafny cannot prove that the variable t in Main is a binary search tree. I see you have that postcondition of insert commented out. Why? You will need that postcondition.
I'm also not sure what you meant by "passing a function in a predicate". You have a useless (though harmless) wrapper predicate isBST. In Dafny, the word predicate is nothing but an abbreviation for a function whose return type is bool.
Your edited code looks much better. Now these two additional postconditions to insert are enough to finish the proof:
ensures forall x :: treeMin(x, tree) && x < value ==> treeMin(x, toAdd)
ensures forall x :: treeMax(x, tree) && x > value ==> treeMax(x, toAdd)
After adding few assert statements you can see what dafny is unable to verify.
if (value < tree.value) {
temp := insert(tree.left, value);
toAdd := Node(temp, tree.value, tree.right);
assert treeMax(tree.value, temp);
}
else {
temp := insert(tree.right, value);
toAdd := Node(tree.left, tree.value, temp);
assert treeMin(tree.value, temp);
}
Dafny is unable to verify added assert holds. Way to think about why dafny is unable to verify is it looks abstractly all method with given pre and post conditions forgetting implementation. insert method precondition is input is valid binary search tree and postcondition is output is valid binary tree. So insert method which always return below tree for example is valid implementation.
Now it is not hard to see why treeMax or treeMin will not hold when temp is always Tree(Tree(Nil, 1, Nil), 3, Tree(Nil, 5, Nil)).
Looking back bigger issue is there is no link between input tree and output tree provided by ensures.

Can I apply CPS (continuation passing style) in numeric analysis/method?

Using functional continuation in ReasonML, can I apply CPS in numeric analysis/method? e.g. euler method, finite difference method.
let factorial3 = n => {
let rec cont = (n, func) =>
if (n <= 1) {
func();
} else {
cont(n - 1, () => n * func());
};
cont(n, () => 1);
};
The question has already been answered in the question body. You can apply CPS in Reason for anything that you'd like.
You provided yourself an example of a function using CPS.
One thing I wanted to add is that on your example, it would be preferable to just use an accumulator parameter instead like this:
let factorial = n => {
let rec cont = (n, tot) =>
if (n <= 1) {
tot;
} else {
cont(n - 1, n * tot);
};
cont(n, 1);
};
as it avoids allocating a new lambda on every recursion while your function remains tail-recursive. I think that CPS would be better left for more involved examples where your have more than one recursive calls per function call but would still like your function to remain tail recursive.
This article contains examples where CPS is a more appropriate tool (written in F#): https://www.gresearch.co.uk/article/advanced-recursion-techniques-in-f/

How is it possible to call a locally defined function from its symbol?

According to the CLHS, FUNCALL argument is a function designator, which can be a symbol denoting a function defined in the global environment. I am looking for a way to do this locally, like in this example:
(defun test ()
(let ((name 'local-function))
(flet ((local-function ()
'hello))
(funcall name))))
I am looking for a way to get the function definition from the local environment. Is it possible with Common Lisp?
If you're just trying to call a local function using funcall, note that a function designator can also be the function object, and you can get that by using the (function name) == #'name notation. I.e., you can do:
(defun test ()
(flet ((local-function ()
'hello))
(funcall #'local-function)))
You can return this value, too, and so let the local function “escape” outside. E.g., you could implement a counter:
(defun make-counter (init)
(flet ((counter ()
(incf init)))
#'counter))
; This case is simple, and could have been:
;
; (defun make-counter (init)
; (lambda ()
; (incf init)))
(let ((counter (make-counter 3)))
(list (funcall counter)
(funcall counter)
(funcall counter)))
;=> (4 5 6)
As uselpa pointed out though, you won't be able to get the function object via a symbol, much in the same way that there's no association at runtime between the symbol named "X" and the lexical variable x in
(let ((x 'foo))
x)
The lexical variables don't have any association at run time with the symbols that named them in the source code.
According to this, no. It doesn't work with eval either. I suppose that at run-time there is no trace left of the local function's name.
Also, my understanding is that if the function designator is a symbol, then symbol-function is used, which is not defined for local functions.

recursive function return using block not working

[solved]
I have something similar with these four functions: base, init, func and some. The func is recursive and calls itself: in the "stop case" it would call some and return its value, then it should return control back to "init", wherefrom it is invoked; the latter being once called from base.
base
-> init
-> func
-> init
-> func
-> some
|
_________+
|
v
; should continue from here (in `func`)
[not anymore]
Instead, after the first call to some, the control is yielded directly to base, skipping what I would expect to be the intermediate (init,func) pair call(s).
I actually tried several simpler cases using block, return and recursion (e.g., "mutual tail-recursive factorial"), and all worked well. I mention that func uses a test helper function that catch a throw (but I tried even an example with (catch 'test (throw 'test 0)), and it was ok); just so whatever could my real program have something causing the issue.
This is elisp: each defun commences with block, and all functions use return, as in the following.
[I switched from using "defun/block" to "defun*"]
(defmacro 4+ (number)
"Add 4 to NUMBER, where NUMBER is a number."
(list 'setq number (list '1+ (list '1+ (list '1+ (list '1+ number))))))
(defmacro 4- (number)
"Subtract 4 from NUMBER, where NUMBER is a number."
(list 'setq number (list '1- (list '1- (list '1- (list '1- number))))))
(defun mesg (s &optional o)
"Use ATAB to tabulate message S at 4-multiple column; next/prev tab if O=1/0."
(when (null o) (setq o 0))
(case o (0 (4- atab)) (1 nil))
(message (concat "%" (format "%d" (+ atab (length s))) "s") s)
(case o (0 nil) (1 (4+ atab))))
(defun* base ()
(let (pack)
(setq atab 0)
(mesg "base->" 1)
(setq pack (init))
(mesg "<-base")))
(defun* init ()
(mesg "init->" 1)
(return-from init (progn (setq temp (func)) (mesg "<-init") temp)))
(defun* func (&optional pack)
(mesg "func->" 1)
(when (not (null pack)) (return-from func (progn (mesg "<+func") pack)))
(when (< 0 (mod (random) 2)); stop case
(return-from func (progn (setq temp (some)) (mesg "<-func") temp)))
(setq pack (init))
(case (mod (random) 2)
(0 (return-from func (progn (mesg "<0func") pack)))
(1 (return-from func (progn (setq temp (func pack)) (mesg "<1func") temp))) ; use tail-recursion instead of `while'
(t (error "foo bar"))))
(defun* some ()
(mesg "some->" 1)
(return-from some (progn (mesg "<-some") (list 2 3 4))))
(base)
The pack variable is my value-list as data structure. I also use func to reiterate itself (in tail-recursive call) with a special accumulating-parameter so that I avoid "imperative" while.
So instead of what I would expect (each > is paired by <)
base->
init->
func->
init->
func->
some->
<-some
<-func
<-init
func-> ; tail-recursion
<+func
<1func
<-init
<-base
my program behaves as follows.
base
-> init
-> func
-> init
-> func
-> some
|
__________________________+
|
v
; control yielded here (to `base`)
[not anymore]
Why is the control yielded too soon back to the start of the program, and not continue in the first call to func, after return from the second call via init?
Appreciate any help,
Sebastian
Looking at your code, it is not clear to me what's the extent of the block in func. If the block includes the whole func definition, then yes, the control reaches func when returning, but the block is skipped completely, hence the function completely, and comes back all the way up where it was called (eventually base). May be that the case?
If that's so, you have to put the code that you want to execute after a return after the block.
EDIT: Looking again at your code, I think you're not using the return as it should be used. For instance in init you have
(block nil
...
(return (func ...)))
This return "cancels" the block, and takes the same effect as not having the block at all, unless some function called in "..." does have a return without a block. So the return here cancels the possible return points of func.
Thanks both for your answer: inserting into my program those messages I tried as with the code I added for explanations revealed there are no defun* problems with elisp, but some things I mistook in design.

Resources