Mathematica like eval

2014-06-13 Thread Dilvan
   Hi all,

   I'm a novice to Clojure (but not to programming). 
   I'm looking for an implementation of an eval function to eval expression 
like Mathematica does.
   For instance, in Mathematica the expression:

   8 + a + 9 (2 + b) + 2

   if a and b are not bound, translates to

Plus[10, a, Times[9, Plus[2, b]]]

   if a and b become bounded later (let say to 1 and 2) and the expression 
is evaluated again, it returns 47.

   I would like to be able to run:
 (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
   and get, if a and b are unbound:
 (fn [x y] (+ 10 x (* 9 (+ 2 y
   or (better still)
 ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y]
   Notice that, whenever possible, the eval takes place and parts of the 
expression are evaluated (in the example above, the expression (+ 8 2) is 
evaluated to 10).  

   If you know of any implementation or have any ideas on the subject, 
please let me know.

   Cheers,
Dilvan.
 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Mathematica like eval

2014-06-13 Thread Christopher Small
There is a nice example of something similar to this in Joy of Clojure (2nd 
edition anyway; not sure about first). It only shows you how to do 
contextual-evaluation, and doesn't return a function if some set of the 
symbols are not mapped in the context, but I'll bet you could modify the 
example to infer when one of the variables is missing in the context 
specification, and return a function in that case. It is right at the 
beginning of the section on macros. Good book, BTW.

Can maybe share more later if you aren't interested in getting the book or 
need more guidance on this.

Chris


On Friday, June 13, 2014 2:46:56 PM UTC-7, Dilvan wrote:
>
>Hi all,
>
>I'm a novice to Clojure (but not to programming). 
>I'm looking for an implementation of an eval function to eval 
> expression like Mathematica does.
>For instance, in Mathematica the expression:
>
>8 + a + 9 (2 + b) + 2
>
>if a and b are not bound, translates to
>
> Plus[10, a, Times[9, Plus[2, b]]]
>
>if a and b become bounded later (let say to 1 and 2) and the expression 
> is evaluated again, it returns 47.
>
>I would like to be able to run:
>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
>and get, if a and b are unbound:
>  (fn [x y] (+ 10 x (* 9 (+ 2 y
>or (better still)
>  ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y]
>Notice that, whenever possible, the eval takes place and parts of the 
> expression are evaluated (in the example above, the expression (+ 8 2) is 
> evaluated to 10).  
>
>If you know of any implementation or have any ideas on the subject, 
> please let me know.
>
>Cheers,
> Dilvan.
>  
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Mathematica like eval

2014-06-14 Thread Maik Schünemann
Hi,
You can use expresso  for
this:
(use 'numeric.expresso.core)
(def e (ex (+ 8 a (* 9 (+ 2 b)) 2)))
;=> (+ 8 a (* 9 (+ 2 b)) 2)
This expression can now be manipulated by expresso to
simplify it, solve it, etc.
you can substitute a and b for its values when you know them and then
evaluate
(evaluate (substitute e '{a 1 b 2})) (or (evaluate e '{a 1 b 2}) which is
equivalent)
;=> 47
But I think you are searching for compile-expr which turns the expression
to a efficient clojure function taking the arguments
((compile-expr [a b] (+ a b)) 1 2) ;=> 3
In your example, you can get the partial evaluate behaviour by using
optimize on the expression beforehand. optimize will do several
transformations one of them is constant merging:
(optimize e) ;=> (+ 10 a (* 9 (+ 2 b)))
which can the compiled by compile-expr* (the function equivalent)
(def partial-evaluated (compile-expr* '[a b] (optimize e)))
(partial-evaluated 1 2) ;=> 47

Hope this helps
M*aik*




On Sat, Jun 14, 2014 at 1:43 AM, Christopher Small 
wrote:

> There is a nice example of something similar to this in Joy of Clojure
> (2nd edition anyway; not sure about first). It only shows you how to do
> contextual-evaluation, and doesn't return a function if some set of the
> symbols are not mapped in the context, but I'll bet you could modify the
> example to infer when one of the variables is missing in the context
> specification, and return a function in that case. It is right at the
> beginning of the section on macros. Good book, BTW.
>
> Can maybe share more later if you aren't interested in getting the book or
> need more guidance on this.
>
> Chris
>
>
>
> On Friday, June 13, 2014 2:46:56 PM UTC-7, Dilvan wrote:
>>
>>Hi all,
>>
>>I'm a novice to Clojure (but not to programming).
>>I'm looking for an implementation of an eval function to eval
>> expression like Mathematica does.
>>For instance, in Mathematica the expression:
>>
>>8 + a + 9 (2 + b) + 2
>>
>>if a and b are not bound, translates to
>>
>> Plus[10, a, Times[9, Plus[2, b]]]
>>
>>if a and b become bounded later (let say to 1 and 2) and the
>> expression is evaluated again, it returns 47.
>>
>>I would like to be able to run:
>>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
>>and get, if a and b are unbound:
>>  (fn [x y] (+ 10 x (* 9 (+ 2 y
>>or (better still)
>>  ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y]
>>Notice that, whenever possible, the eval takes place and parts of the
>> expression are evaluated (in the example above, the expression (+ 8 2) is
>> evaluated to 10).
>>
>>If you know of any implementation or have any ideas on the subject,
>> please let me know.
>>
>>Cheers,
>> Dilvan.
>>
>>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Mathematica like eval

2014-06-16 Thread Dilvan
   Hi,

   Thanks for both answers. I will try to find the relevant text in Joy of 
Clojure (I have access to the first edition).
   I followed the expresso  
link, but I am not interested in mathematical expressions.
   Refining my question: I am more interested in the programming aspects of 
Mathematica (or to its descendant Wolfram Language). In the eval case, a 
better example would be (a is unbound):

 (def b 1)
 (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
 --> '(+ 37 a)
  
   Eval-partial would return a Lisp expression with unbound symbols. 
   The expression being evaluated could be quite complex.
   With eval-partial, I would like to be able to have complex functions 
that depend on results that aren't ready yet. They would evaluate 
(partially) to expressions that could be re-evaluated later, to see if all 
the symbols they depend upon are ready (bound). I intend to use this 
technique to write more flexible DSLs.

   BTW, if expresso can do some similar to this, I am willing to give it a 
second look.

   Any ideas?

   Cheers,

Dilvan.

On Friday, June 13, 2014 6:46:56 PM UTC-3, Dilvan wrote:
>
>Hi all,
>
>I'm a novice to Clojure (but not to programming). 
>I'm looking for an implementation of an eval function to eval 
> expression like Mathematica does.
>For instance, in Mathematica the expression:
>
>8 + a + 9 (2 + b) + 2
>
>if a and b are not bound, translates to
>
> Plus[10, a, Times[9, Plus[2, b]]]
>
>if a and b become bounded later (let say to 1 and 2) and the expression 
> is evaluated again, it returns 47.
>
>I would like to be able to run:
>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
>and get, if a and b are unbound:
>  (fn [x y] (+ 10 x (* 9 (+ 2 y
>or (better still)
>  ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y]
>Notice that, whenever possible, the eval takes place and parts of the 
> expression are evaluated (in the example above, the expression (+ 8 2) is 
> evaluated to 10).  
>
>If you know of any implementation or have any ideas on the subject, 
> please let me know.
>
>Cheers,
> Dilvan.
>  
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Mathematica like eval

2014-06-16 Thread kovas boguta
So I've thought about this quite a bit (as have some other people,
like Brandon Bloom), and started working on a library a while back
exploring some ideas https://github.com/kovasb/term

The main idea of term is to take any expression and turn unbound
symbols into datatypes that satisfy mathematica-like properties.

for instance

(head (term (a 1 2 3))) -> a
(let [x (term a)] (head (x 1 2 3))) -> a
(term (map a [1 2 3])) -> ((a 1) (a 2) (a 3))


This works pretty well, but to be truly useful you also need a
standard library of transformation rules that will for instance
implement + with combinations of symbols and concrete values, and of
course an evaluator.

Based on my experiments it is quite possible to create a term
rewriting evaluator that matches Mathematica's speed (see
https://github.com/kovasb/combinator)

The main question is how such a system deals with clojure
interoperability. Ultimately the transformation rules must bottom out
in clojure, and their results will eventually be consumed by clojure,
so getting that right will largely determine the usability of the
system.











On Mon, Jun 16, 2014 at 7:57 AM, Dilvan  wrote:
>Hi,
>
>Thanks for both answers. I will try to find the relevant text in Joy of
> Clojure (I have access to the first edition).
>I followed the expresso link, but I am not interested in mathematical
> expressions.
>Refining my question: I am more interested in the programming aspects of
> Mathematica (or to its descendant Wolfram Language). In the eval case, a
> better example would be (a is unbound):
>
>  (def b 1)
>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
>  --> '(+ 37 a)
>
>Eval-partial would return a Lisp expression with unbound symbols.
>The expression being evaluated could be quite complex.
>With eval-partial, I would like to be able to have complex functions that
> depend on results that aren't ready yet. They would evaluate (partially) to
> expressions that could be re-evaluated later, to see if all the symbols they
> depend upon are ready (bound). I intend to use this technique to write more
> flexible DSLs.
>
>BTW, if expresso can do some similar to this, I am willing to give it a
> second look.
>
>Any ideas?
>
>Cheers,
>
> Dilvan.
>
>
> On Friday, June 13, 2014 6:46:56 PM UTC-3, Dilvan wrote:
>>
>>Hi all,
>>
>>I'm a novice to Clojure (but not to programming).
>>I'm looking for an implementation of an eval function to eval
>> expression like Mathematica does.
>>For instance, in Mathematica the expression:
>>
>>8 + a + 9 (2 + b) + 2
>>
>>if a and b are not bound, translates to
>>
>> Plus[10, a, Times[9, Plus[2, b]]]
>>
>>if a and b become bounded later (let say to 1 and 2) and the expression
>> is evaluated again, it returns 47.
>>
>>I would like to be able to run:
>>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b
>>and get, if a and b are unbound:
>>  (fn [x y] (+ 10 x (* 9 (+ 2 y
>>or (better still)
>>  ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y]
>>Notice that, whenever possible, the eval takes place and parts of the
>> expression are evaluated (in the example above, the expression (+ 8 2) is
>> evaluated to 10).
>>
>>If you know of any implementation or have any ideas on the subject,
>> please let me know.
>>
>>Cheers,
>> Dilvan.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Mathematica like eval

2014-06-16 Thread Brandon Bloom
Since my ears are ringing, I'll chime in.

There's a few things to separate out here:

1) Symbolic math
2) Term rewriting
3) Staged computation

Mathematica can provide all three to varying degrees. Espresso targets 
symbolic mathematics. Kovas' work is about term rewriting as a 
computational paradigm. Clojure offers limited, but practically proven 
facilities for staged computation in the form of eval, macros, etc.

My guess is that you can accomplish whatever specific DSL task you're after 
with traditional functional approaches and get acceptable performance. 
Seeing as you're new to Clojure, I suggest you try to go down that road 
first. When you have a particular use case to discuss and some experience 
solving the problem with traditional techniques, we can discuss 
opportunities for more sophisticated approaches.

However, if you're really after #3, you're probably out of luck in the 
short term. Longer term, I indent to experiment with this stuff in the 
context of https://github.com/brandonbloom/eclj

Cheers,
Brandon

On Monday, June 16, 2014 1:25:40 PM UTC-4, kovasb wrote:
>
> So I've thought about this quite a bit (as have some other people, 
> like Brandon Bloom), and started working on a library a while back 
> exploring some ideas https://github.com/kovasb/term 
>
> The main idea of term is to take any expression and turn unbound 
> symbols into datatypes that satisfy mathematica-like properties. 
>
> for instance 
>
> (head (term (a 1 2 3))) -> a 
> (let [x (term a)] (head (x 1 2 3))) -> a 
> (term (map a [1 2 3])) -> ((a 1) (a 2) (a 3)) 
>
>
> This works pretty well, but to be truly useful you also need a 
> standard library of transformation rules that will for instance 
> implement + with combinations of symbols and concrete values, and of 
> course an evaluator. 
>
> Based on my experiments it is quite possible to create a term 
> rewriting evaluator that matches Mathematica's speed (see 
> https://github.com/kovasb/combinator) 
>
> The main question is how such a system deals with clojure 
> interoperability. Ultimately the transformation rules must bottom out 
> in clojure, and their results will eventually be consumed by clojure, 
> so getting that right will largely determine the usability of the 
> system. 
>
>
>
>
>
>
>
>
>
>
>
> On Mon, Jun 16, 2014 at 7:57 AM, Dilvan > 
> wrote: 
> >Hi, 
> > 
> >Thanks for both answers. I will try to find the relevant text in Joy 
> of 
> > Clojure (I have access to the first edition). 
> >I followed the expresso link, but I am not interested in mathematical 
> > expressions. 
> >Refining my question: I am more interested in the programming aspects 
> of 
> > Mathematica (or to its descendant Wolfram Language). In the eval case, a 
> > better example would be (a is unbound): 
> > 
> >  (def b 1) 
> >  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b 
> >  --> '(+ 37 a) 
> > 
> >Eval-partial would return a Lisp expression with unbound symbols. 
> >The expression being evaluated could be quite complex. 
> >With eval-partial, I would like to be able to have complex functions 
> that 
> > depend on results that aren't ready yet. They would evaluate (partially) 
> to 
> > expressions that could be re-evaluated later, to see if all the symbols 
> they 
> > depend upon are ready (bound). I intend to use this technique to write 
> more 
> > flexible DSLs. 
> > 
> >BTW, if expresso can do some similar to this, I am willing to give it 
> a 
> > second look. 
> > 
> >Any ideas? 
> > 
> >Cheers, 
> > 
> > Dilvan. 
> > 
> > 
> > On Friday, June 13, 2014 6:46:56 PM UTC-3, Dilvan wrote: 
> >> 
> >>Hi all, 
> >> 
> >>I'm a novice to Clojure (but not to programming). 
> >>I'm looking for an implementation of an eval function to eval 
> >> expression like Mathematica does. 
> >>For instance, in Mathematica the expression: 
> >> 
> >>8 + a + 9 (2 + b) + 2 
> >> 
> >>if a and b are not bound, translates to 
> >> 
> >> Plus[10, a, Times[9, Plus[2, b]]] 
> >> 
> >>if a and b become bounded later (let say to 1 and 2) and the 
> expression 
> >> is evaluated again, it returns 47. 
> >> 
> >>I would like to be able to run: 
> >>  (eval-partial '(+ (+ 8 2) a (* 9 (+ 2 b 
> >>and get, if a and b are unbound: 
> >>  (fn [x y] (+ 10 x (* 9 (+ 2 y 
> >>or (better still) 
> >>  ['(a b) (fn [x y] (+ 10 x (* 9 (+ 2 y] 
> >>Notice that, whenever possible, the eval takes place and parts of 
> the 
> >> expression are evaluated (in the example above, the expression (+ 8 2) 
> is 
> >> evaluated to 10). 
> >> 
> >>If you know of any implementation or have any ideas on the subject, 
> >> please let me know. 
> >> 
> >>Cheers, 
> >> Dilvan. 
> >> 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clo...@googlegroups.com 
>  
> > Note that posts from new me