Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-21 Thread Naftoli Gugenheim
Inlined

2009/12/19 Marius marius.dan...@gmail.com

 If I may a few notes:

 Syntactically it doesn't seem to me that there are much differences
 between this and the initial proposal. Probably the most noticeable
 diffs are in algebraic expressions like

 Var(y) := (2:Expr) * x * 2

 which probably looks more appealing than

 Var(y) := 2 __* x __* 2


First, I should confess that I didn't look at your source code before I
wrote my approach, although I saw it now. That said, I agree that there is
plenty in common between the two approaches, and also a couple of
differences. Feel free to use whatever blend you like!


 The other thing is that you don't end JS statements with ;  ... I
 don't think this is a good JS practice. I added `;` function to allow
 user to specify this terminator when needed.


It would be trivial to have my implementation add semicolons in the
generated code without requiring any change in the DSL's usage.




I'm also not at all in favor of function names starting with capital
 letter.


Please rename them to whatever you like!



 I was also running into a Scala compiler crash when using constructs
 like: case class Fnc(name: String)(params: String*)(body : = String)
 {} :D


Then possibly functions are better suited than case classes for providing
the names of the DSL syntax. If that means you prefer lowercase names please
change them!



I'm not sure why in things like: def Function()(argNames: String*)
 (body: PartialFunction[List[JSIdent], Unit]): JSAnonFunc you used
 PartialFunctions ... you are callin gthe PF without checking if the
 function is defined for its parameter which could lead to MachError.


What would it help to intercept such a situation--to provide a more
descriptive error message? It's an error either way.
In any case, I realized after I wrote it (as I mentioned) that the signature
could be changed to
def Function(numParams: Int)(body: PartialFunction[List[JSIdent], Unit])
that is, there is no reason to specify names for the parameters. Since the
PF format binds scala identifiers to represent the arguments, names could be
autogenerated. Similarly,
val x = Var(x)
could be changed to
val x = Var()
and x would represent a JS var whose name is autogenerated.
I could be totally wrong but it seems to me that the ability to have Scala
identifiers and not just implicitly converted symbols provides more
scalability. For instance you could have utility functions in Scala that
help build the javascript but don't need the implicits in scope.




 I see you took a different approach of building JS code in a more
 imperative manner where generated code is kept in the ThreadGlobal
 state. My initial approach and actually my design intent was to use
 functional composition to write the code which tremendously simplifies
 the library code.


Could you elaborate? What makes your code more functional?

With your approach,
 JsIf('param1  30) {
   Var ('home) :=  (234: Js) + 3 / 3 `;`
   println(Hi there)
   Var ('someArray) := JsArray(1, 2, 3, 4, 5) `;`
   'myFunc(1, 2, do it, 'home) `;`
   $(#myID)  'attr(value, 123) `;`
 } ~
would not work, because JsIf's second parameter list takes a =Js, that is,
it only uses on the expression returned. In the above example, the
Var('home) ... line goes into a black hole.
In my case you have much more flexibility because the entire code block does
not have to be one long expression. All DSL invocations are captured.
This is also the reason my approach does not require using semicolons.
Also, it would be advantageous if the result of executing the DSL was the
regular Lift JavaScript AST. This would avoid code duplication in terms of
the algorithm that generates the output javascript text (which if it does
not already could have shared features like whitespace compression or pretty
printing), while at the same time allowing the generated AST to be processed
by code that can also work with plain Lift JavaScript AST objects. I'm not
clear how that would work with your approach, but with mine it's trivial.

I should mention that much of the inspiration for this builder approach came
from the SWT DSL, by Rodant.


 I made some adjustments to my initial approach and something like:

val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1  30) {
 Var ('home) :=  (234: Js) + 3 / 3 `;`
 Var ('someArray) := JsArray(1, 2, 3, 4, 5) `;`
'myFunc(1, 2, do it, 'home) `;`
$(#myID)  'attr(value, 123) `;`
  } ~
  JsForEach(Var('i) in 'someArray) {
'console  'log(Hi there  + 'i) `;`
  } ~
  JsAnonFunc('arg1, 'arg2) {
   'alert(Anonymous function  + 'arg1 + 'arg2)
  }(1, 2) `;`
}
println(js.toJs)

 generates

 function myFunc( param1, param2 ) {
 if (param1  30) {
 var home = 234 + 3 / 3;
 var someArray = [ 1, 2, 3, 4, 5 ];
 myFunc(1, 2, do it, home);
 $(#myID).attr(value, 123);
 }
 for (var i in someArray) {
 console.log(Hi there 'i);
 }
 function ( 

[Lift] Re: Scala to JavaScript DSL ...

2009-12-19 Thread Marius
If I may a few notes:

Syntactically it doesn't seem to me that there are much differences
between this and the initial proposal. Probably the most noticeable
diffs are in algebraic expressions like

Var(y) := (2:Expr) * x * 2

which probably looks more appealing than

Var(y) := 2 __* x __* 2

The other thing is that you don't end JS statements with ;  ... I
don't think this is a good JS practice. I added `;` function to allow
user to specify this terminator when needed.

I'm also not at all in favor of function names starting with capital
letter.

I was also running into a Scala compiler crash when using constructs
like: case class Fnc(name: String)(params: String*)(body : = String)
{} :D

I'm not sure why in things like: def Function()(argNames: String*)
(body: PartialFunction[List[JSIdent], Unit]): JSAnonFunc you used
PartialFunctions ... you are callin gthe PF without checking if the
function is defined for its parameter which could lead to MachError.

I see you took a different approach of building JS code in a more
imperative manner where generated code is kept in the ThreadGlobal
state. My initial approach and actually my design intent was to use
functional composition to write the code which tremendously simplifies
the library code.

I made some adjustments to my initial approach and something like:

val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1  30) {
Var ('home) :=  (234: Js) + 3 / 3 `;`
Var ('someArray) := JsArray(1, 2, 3, 4, 5) `;`
'myFunc(1, 2, do it, 'home) `;`
$(#myID)  'attr(value, 123) `;`
  } ~
  JsForEach(Var('i) in 'someArray) {
'console  'log(Hi there  + 'i) `;`
  } ~
  JsAnonFunc('arg1, 'arg2) {
   'alert(Anonymous function  + 'arg1 + 'arg2)
  }(1, 2) `;`
}
println(js.toJs)

generates

function myFunc( param1, param2 ) {
if (param1  30) {
var home = 234 + 3 / 3;
var someArray = [ 1, 2, 3, 4, 5 ];
myFunc(1, 2, do it, home);
$(#myID).attr(value, 123);
}
for (var i in someArray) {
console.log(Hi there 'i);
}
function ( arg1, arg2 ) {
alert(Anonymous function 'arg1'arg2)
}(1, 2);
}

I guess in many respects these things are subjective. Personally so
far I am linking better my approach with the changes for expression
building (no more __ prefixed functions).

Br's,
Marius

On Dec 18, 4:34 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
 Okay!
 The following code:

      val jsFunc: JSFunc = Function(myFunc)(param1, param2) {case
  param1 :: param2 :: Nil =

         Var(someArray) := Array(1, 2, 3, 4, 5)

         If(param1  30) {

           val x = Var(x)               // now we can use either x or 'x

           x := (234 - 3) / 2             // calculation happens in scala

           Var(y) := (2:Expr) * x * 2   // calculation happens in

  javascript

           'jsFunc(1, 2, do it, 'y)

           val $ = JSIdent($)

           $(#myID)  'attr(value, 123)

         } Else {

           'console  'log(=30)

         }

         ForEach(Var(i) In 'someArray) {

           'console  'log(Hi there   'i)

         }

         Function()(arg1, arg2) { case arg1 :: arg2 :: Nil =

           'alert(Anonymous function (  arg1  ,   arg2  ))

         }(1,2)

     }

     println(jsFunc.toCode)

 Produces:

 function myFunc(param1, param2) {

 var someArray

 someArray = [1.0, 2.0, 3.0, 4.0, 5.0]

 if((param1  30.0)) {

 var x

 x = 115.0

 var y

 y = ((2.0 * x) * 2.0)

 jsFunc(1.0, 2.0, do it, y)

 ($(#myID)).attr(value, 123)

 } else {

 (console).log(=30)

 }

 var i

 for(i in someArray) {

 (console).log((Hi there  + i))

 }

 function (arg1, arg2) {

 alert(Anonymous function ( + arg1) + , )  arg2) + )))

 }(1.0, 2.0)
 }

 It may be desirable that instead of defining your own names for Vars and
 function parameters, names are auto-generated, since you can anyway use
 typesafe scala identifiers. This would save boilerplate and produce more
 obfuscated code, and other than the name generating algorithm is a trivial
 change to make.
 Note that since I am not familiar with Lift's JavaScript APIs I just wrote
 my own AST, which consists of case classes that contain their data
 parameters and a toCode method. Feel free to delete them and plug Lift's
 classes instead--there is no dependency on anything unique about them.
 Also note that to prevent string + ident from compiling as a string to be
 outputted and instead output a + operation, you have two choices: use the 
 operator instead, which is replaced with + when either operand is a string,
 or write (string:Expr) + ident.

 2009/12/17 Naftoli Gugenheim naftoli...@gmail.com

  Current state attached.

  2009/12/17 Marius marius.dan...@gmail.com

  Let me know when you have something.

  Br's,
  Marius

  On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
   I'm thinking of an approach to writing a DSL with a much cleaner syntax.
  I'll try to put something together.

   -

   Marius 

Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-17 Thread Naftoli Gugenheim
I think I'm nearly there (that is a working equivalent of your sample) with 
G-d's help...

-
Mariusmarius.dan...@gmail.com wrote:

Let me know when you have something.

Br's,
Marius

On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
 I'm thinking of an approach to writing a DSL with a much cleaner syntax. I'll 
 try to put something together.

 -

 Marius Danciumarius.dan...@gmail.com wrote:

 All,

 I just want to see if there is any interest in the approach discussed here.
 As you know Lift has some interesting support for building JavaScript
 constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a lot
 this support and it's great but if your JS code that you want to send down
 to the browser (say as an Ajax or Comet partial update response) gets a bit
 more complicated then constructing the JS fragment leads IMO to some
 cumbersome Scala code. I found myselft in quite a few situation to use JsRaw
 to write the JavaScript fragment in order for the code reader to understand
 what JavaScript code will be generated. But of course with JsRaw we put
 everything into a String so I'm not a big fan of this approach. So I started
 to define a JavaScript like DSL that IMO is closer to JavaScript form.
 Attached is a source code smaple of how this looks like, so for instance we
 can have something like:

 val js = JsFunc('myFunc, 'param1, 'param2) {
     JsIf('param1 __ 30) {
         Var('home) := Wrap(234 __- 3) __/ 2 `;`
         Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
         'myFunc(1, 2, do it, 'home) `;`
         $(#myID)  'attr(value, 123) `;`
       } ~
       JsForEach(Var('i) in 'someArray) {
         'console  'log(Hi there  __+ 'i) `;`
       } ~
       JsAnonFunc('arg1, 'arg2) {
        'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
       }(1, 2) `;`
     }

     println(js.toJs)

 this yields the following JavaScript code:

 function myFunc( param1, param2 ) {
 if (param1  30) {
 var home = ( 234 - 3 ) / 2;
 var someArray = [ 1, 2, 3, 4, 5 ];
 myFunc(1, 2, do it, home);
 $(#myID).attr(value, 123);}

 for (var i in someArray) {
 console.log(Hi there  + i);}

 function ( arg1, arg2 ) {
 alert(Anonymous function  + arg1 + arg2)

 }(1, 2);
 }

 ... ok I just droped nonsense code in there for exemplification. A few
 words:

 1. JsIf, JsForEach describe JavaScript if and for(each) statements
 2. Functions like __, __, ... __+, __- are function that alows definition
 of boolean and/or algebraic expressions.
 3. Wrap just wraps an expression into ()
 4. Var defined a variable
 5 := defines an assignment
 6. JsFunc declares a JS function
 7. JsAnonFunc declares an anonymous function
 8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function invocation
 by providing 4 parameter.
 9. ~ is just a function that chains statements that don;t necessarily end in
 ;

 Do you think that something like this would be usable in Lift?

 Br's,
 Marius

 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group 
 athttp://groups.google.com/group/liftweb?hl=en.

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.


--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-17 Thread Naftoli Gugenheim
Current state attached.


2009/12/17 Marius marius.dan...@gmail.com

 Let me know when you have something.

 Br's,
 Marius

 On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
  I'm thinking of an approach to writing a DSL with a much cleaner syntax.
 I'll try to put something together.
 
  -
 
  Marius Danciumarius.dan...@gmail.com wrote:
 
  All,
 
  I just want to see if there is any interest in the approach discussed
 here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a
 lot
  this support and it's great but if your JS code that you want to send
 down
  to the browser (say as an Ajax or Comet partial update response) gets a
 bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use
 JsRaw
  to write the JavaScript fragment in order for the code reader to
 understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I
 started
  to define a JavaScript like DSL that IMO is closer to JavaScript form.
  Attached is a source code smaple of how this looks like, so for instance
 we
  can have something like:
 
  val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1 __ 30) {
  Var('home) := Wrap(234 __- 3) __/ 2 `;`
  Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
  'myFunc(1, 2, do it, 'home) `;`
  $(#myID)  'attr(value, 123) `;`
} ~
JsForEach(Var('i) in 'someArray) {
  'console  'log(Hi there  __+ 'i) `;`
} ~
JsAnonFunc('arg1, 'arg2) {
 'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
}(1, 2) `;`
  }
 
  println(js.toJs)
 
  this yields the following JavaScript code:
 
  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);}
 
  for (var i in someArray) {
  console.log(Hi there  + i);}
 
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
 
  }(1, 2);
  }
 
  ... ok I just droped nonsense code in there for exemplification. A few
  words:
 
  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows
 definition
  of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
 invocation
  by providing 4 parameter.
  9. ~ is just a function that chains statements that don;t necessarily end
 in
  ;
 
  Do you think that something like this would be usable in Lift?
 
  Br's,
  Marius
 
  --
 
  You received this message because you are subscribed to the Google Groups
 Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
 .
  For more options, visit this group athttp://
 groups.google.com/group/liftweb?hl=en.

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.




--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




DSL.scala
Description: Binary data


Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-17 Thread Naftoli Gugenheim
Okay!
The following code:

 val jsFunc: JSFunc = Function(myFunc)(param1, param2) {case
 param1 :: param2 :: Nil =

Var(someArray) := Array(1, 2, 3, 4, 5)

If(param1  30) {

  val x = Var(x)   // now we can use either x or 'x

  x := (234 - 3) / 2 // calculation happens in scala

  Var(y) := (2:Expr) * x * 2   // calculation happens in
 javascript

  'jsFunc(1, 2, do it, 'y)

  val $ = JSIdent($)

  $(#myID)  'attr(value, 123)

} Else {

  'console  'log(=30)

}

ForEach(Var(i) In 'someArray) {

  'console  'log(Hi there   'i)

}

Function()(arg1, arg2) { case arg1 :: arg2 :: Nil =

  'alert(Anonymous function (  arg1  ,   arg2  ))

}(1,2)

}

println(jsFunc.toCode)


Produces:

function myFunc(param1, param2) {

var someArray

someArray = [1.0, 2.0, 3.0, 4.0, 5.0]

if((param1  30.0)) {

var x

x = 115.0

var y

y = ((2.0 * x) * 2.0)

jsFunc(1.0, 2.0, do it, y)

($(#myID)).attr(value, 123)

} else {

(console).log(=30)

}

var i

for(i in someArray) {

(console).log((Hi there  + i))

}

function (arg1, arg2) {

alert(Anonymous function ( + arg1) + , )  arg2) + )))

}(1.0, 2.0)

}


It may be desirable that instead of defining your own names for Vars and
function parameters, names are auto-generated, since you can anyway use
typesafe scala identifiers. This would save boilerplate and produce more
obfuscated code, and other than the name generating algorithm is a trivial
change to make.
Note that since I am not familiar with Lift's JavaScript APIs I just wrote
my own AST, which consists of case classes that contain their data
parameters and a toCode method. Feel free to delete them and plug Lift's
classes instead--there is no dependency on anything unique about them.
Also note that to prevent string + ident from compiling as a string to be
outputted and instead output a + operation, you have two choices: use the 
operator instead, which is replaced with + when either operand is a string,
or write (string:Expr) + ident.


2009/12/17 Naftoli Gugenheim naftoli...@gmail.com

 Current state attached.


 2009/12/17 Marius marius.dan...@gmail.com

 Let me know when you have something.

 Br's,
 Marius

 On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
  I'm thinking of an approach to writing a DSL with a much cleaner syntax.
 I'll try to put something together.
 
  -
 
  Marius Danciumarius.dan...@gmail.com wrote:
 
  All,
 
  I just want to see if there is any interest in the approach discussed
 here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a
 lot
  this support and it's great but if your JS code that you want to send
 down
  to the browser (say as an Ajax or Comet partial update response) gets a
 bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use
 JsRaw
  to write the JavaScript fragment in order for the code reader to
 understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I
 started
  to define a JavaScript like DSL that IMO is closer to JavaScript form.
  Attached is a source code smaple of how this looks like, so for instance
 we
  can have something like:
 
  val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1 __ 30) {
  Var('home) := Wrap(234 __- 3) __/ 2 `;`
  Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
  'myFunc(1, 2, do it, 'home) `;`
  $(#myID)  'attr(value, 123) `;`
} ~
JsForEach(Var('i) in 'someArray) {
  'console  'log(Hi there  __+ 'i) `;`
} ~
JsAnonFunc('arg1, 'arg2) {
 'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
}(1, 2) `;`
  }
 
  println(js.toJs)
 
  this yields the following JavaScript code:
 
  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);}
 
  for (var i in someArray) {
  console.log(Hi there  + i);}
 
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
 
  }(1, 2);
  }
 
  ... ok I just droped nonsense code in there for exemplification. A few
  words:
 
  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows
 definition
  of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
 invocation
  by providing 

Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-17 Thread Ross Mellgren
I like the source for the DSL very much, I think it's very well written. Thanks 
for sharing it.

-Ross

On Dec 17, 2009, at 9:34 PM, Naftoli Gugenheim wrote:

 Okay!
 The following code:
 val jsFunc: JSFunc = Function(myFunc)(param1, param2) {case param1 
 :: param2 :: Nil =
 Var(someArray) := Array(1, 2, 3, 4, 5)
 If(param1  30) {
   val x = Var(x)   // now we can use either x or 'x
   x := (234 - 3) / 2 // calculation happens in scala
   Var(y) := (2:Expr) * x * 2   // calculation happens in javascript
   'jsFunc(1, 2, do it, 'y)
   val $ = JSIdent($)
   $(#myID)  'attr(value, 123)
 } Else {
   'console  'log(=30)
 }
 ForEach(Var(i) In 'someArray) {
   'console  'log(Hi there   'i)
 }
 Function()(arg1, arg2) { case arg1 :: arg2 :: Nil =
   'alert(Anonymous function (  arg1  ,   arg2  ))
 }(1,2)
 }
 println(jsFunc.toCode)
 
 Produces:
 
 function myFunc(param1, param2) {
 var someArray
 someArray = [1.0, 2.0, 3.0, 4.0, 5.0]
 if((param1  30.0)) {
 var x
 x = 115.0
 var y
 y = ((2.0 * x) * 2.0)
 jsFunc(1.0, 2.0, do it, y)
 ($(#myID)).attr(value, 123)
 } else {
 (console).log(=30)
 }
 var i
 for(i in someArray) {
 (console).log((Hi there  + i))
 }
 function (arg1, arg2) {
 alert(Anonymous function ( + arg1) + , )  arg2) + )))
 }(1.0, 2.0)
 }
 
 It may be desirable that instead of defining your own names for Vars and 
 function parameters, names are auto-generated, since you can anyway use 
 typesafe scala identifiers. This would save boilerplate and produce more 
 obfuscated code, and other than the name generating algorithm is a trivial 
 change to make.
 Note that since I am not familiar with Lift's JavaScript APIs I just wrote my 
 own AST, which consists of case classes that contain their data parameters 
 and a toCode method. Feel free to delete them and plug Lift's classes 
 instead--there is no dependency on anything unique about them.
 Also note that to prevent string + ident from compiling as a string to be 
 outputted and instead output a + operation, you have two choices: use the  
 operator instead, which is replaced with + when either operand is a string, 
 or write (string:Expr) + ident.
 
 
 2009/12/17 Naftoli Gugenheim naftoli...@gmail.com
 Current state attached.
 
 
 2009/12/17 Marius marius.dan...@gmail.com
 
 Let me know when you have something.
 
 Br's,
 Marius
 
 On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
  I'm thinking of an approach to writing a DSL with a much cleaner syntax. 
  I'll try to put something together.
 
  -
 
  Marius Danciumarius.dan...@gmail.com wrote:
 
  All,
 
  I just want to see if there is any interest in the approach discussed here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a lot
  this support and it's great but if your JS code that you want to send down
  to the browser (say as an Ajax or Comet partial update response) gets a bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use JsRaw
  to write the JavaScript fragment in order for the code reader to understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I started
  to define a JavaScript like DSL that IMO is closer to JavaScript form.
  Attached is a source code smaple of how this looks like, so for instance we
  can have something like:
 
  val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1 __ 30) {
  Var('home) := Wrap(234 __- 3) __/ 2 `;`
  Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
  'myFunc(1, 2, do it, 'home) `;`
  $(#myID)  'attr(value, 123) `;`
} ~
JsForEach(Var('i) in 'someArray) {
  'console  'log(Hi there  __+ 'i) `;`
} ~
JsAnonFunc('arg1, 'arg2) {
 'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
}(1, 2) `;`
  }
 
  println(js.toJs)
 
  this yields the following JavaScript code:
 
  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);}
 
  for (var i in someArray) {
  console.log(Hi there  + i);}
 
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
 
  }(1, 2);
  }
 
  ... ok I just droped nonsense code in there for exemplification. A few
  words:
 
  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows definition
  of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an 

Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-17 Thread Naftoli Gugenheim
You're welcome. There's still some work to do; I would call it a proof of
concept. But I'll let Marius finish it up. :)


On Thu, Dec 17, 2009 at 10:18 PM, Ross Mellgren dri...@gmail.com wrote:

 I like the source for the DSL very much, I think it's very well written.
 Thanks for sharing it.

 -Ross

 On Dec 17, 2009, at 9:34 PM, Naftoli Gugenheim wrote:

 Okay!
 The following code:

 val jsFunc: JSFunc = Function(myFunc)(param1, param2) {case
 param1 :: param2 :: Nil =

 Var(someArray) := Array(1, 2, 3, 4, 5)

 If(param1  30) {

   val x = Var(x)   // now we can use either x or 'x

   x := (234 - 3) / 2 // calculation happens in scala

   Var(y) := (2:Expr) * x * 2   // calculation happens in
 javascript

   'jsFunc(1, 2, do it, 'y)

   val $ = JSIdent($)

   $(#myID)  'attr(value, 123)

 } Else {

   'console  'log(=30)

 }

 ForEach(Var(i) In 'someArray) {

   'console  'log(Hi there   'i)

 }

 Function()(arg1, arg2) { case arg1 :: arg2 :: Nil =

   'alert(Anonymous function (  arg1  ,   arg2  ))

 }(1,2)

 }

 println(jsFunc.toCode)


 Produces:

 function myFunc(param1, param2) {

 var someArray

 someArray = [1.0, 2.0, 3.0, 4.0, 5.0]

 if((param1  30.0)) {

 var x

 x = 115.0

 var y

 y = ((2.0 * x) * 2.0)

 jsFunc(1.0, 2.0, do it, y)

 ($(#myID)).attr(value, 123)

 } else {

 (console).log(=30)

 }

 var i

 for(i in someArray) {

 (console).log((Hi there  + i))

 }

 function (arg1, arg2) {

 alert(Anonymous function ( + arg1) + , )  arg2) + )))

 }(1.0, 2.0)

 }


 It may be desirable that instead of defining your own names for Vars and
 function parameters, names are auto-generated, since you can anyway use
 typesafe scala identifiers. This would save boilerplate and produce more
 obfuscated code, and other than the name generating algorithm is a trivial
 change to make.
 Note that since I am not familiar with Lift's JavaScript APIs I just wrote
 my own AST, which consists of case classes that contain their data
 parameters and a toCode method. Feel free to delete them and plug Lift's
 classes instead--there is no dependency on anything unique about them.
 Also note that to prevent string + ident from compiling as a string to be
 outputted and instead output a + operation, you have two choices: use the 
 operator instead, which is replaced with + when either operand is a string,
 or write (string:Expr) + ident.


 2009/12/17 Naftoli Gugenheim naftoli...@gmail.com

 Current state attached.


 2009/12/17 Marius marius.dan...@gmail.com

 Let me know when you have something.

 Br's,
 Marius

 On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
  I'm thinking of an approach to writing a DSL with a much cleaner
 syntax. I'll try to put something together.
 
  -
 
  Marius Danciumarius.dan...@gmail.com wrote:
 
  All,
 
  I just want to see if there is any interest in the approach discussed
 here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite
 a lot
  this support and it's great but if your JS code that you want to send
 down
  to the browser (say as an Ajax or Comet partial update response) gets a
 bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use
 JsRaw
  to write the JavaScript fragment in order for the code reader to
 understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I
 started
  to define a JavaScript like DSL that IMO is closer to JavaScript
 form.
  Attached is a source code smaple of how this looks like, so for
 instance we
  can have something like:
 
  val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1 __ 30) {
  Var('home) := Wrap(234 __- 3) __/ 2 `;`
  Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
  'myFunc(1, 2, do it, 'home) `;`
  $(#myID)  'attr(value, 123) `;`
} ~
JsForEach(Var('i) in 'someArray) {
  'console  'log(Hi there  __+ 'i) `;`
} ~
JsAnonFunc('arg1, 'arg2) {
 'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
}(1, 2) `;`
  }
 
  println(js.toJs)
 
  this yields the following JavaScript code:
 
  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);}
 
  for (var i in someArray) {
  console.log(Hi there  + i);}
 
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
 
  }(1, 2);
  }
 
  ... ok I just droped nonsense code in there for exemplification. A few
  words:
 
  1. JsIf, JsForEach describe JavaScript if and 

[Lift] Re: Scala to JavaScript DSL ...

2009-12-16 Thread Marius
Let me know when you have something.

Br's,
Marius

On Dec 17, 8:58 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
 I'm thinking of an approach to writing a DSL with a much cleaner syntax. I'll 
 try to put something together.

 -

 Marius Danciumarius.dan...@gmail.com wrote:

 All,

 I just want to see if there is any interest in the approach discussed here.
 As you know Lift has some interesting support for building JavaScript
 constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a lot
 this support and it's great but if your JS code that you want to send down
 to the browser (say as an Ajax or Comet partial update response) gets a bit
 more complicated then constructing the JS fragment leads IMO to some
 cumbersome Scala code. I found myselft in quite a few situation to use JsRaw
 to write the JavaScript fragment in order for the code reader to understand
 what JavaScript code will be generated. But of course with JsRaw we put
 everything into a String so I'm not a big fan of this approach. So I started
 to define a JavaScript like DSL that IMO is closer to JavaScript form.
 Attached is a source code smaple of how this looks like, so for instance we
 can have something like:

 val js = JsFunc('myFunc, 'param1, 'param2) {
     JsIf('param1 __ 30) {
         Var('home) := Wrap(234 __- 3) __/ 2 `;`
         Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
         'myFunc(1, 2, do it, 'home) `;`
         $(#myID)  'attr(value, 123) `;`
       } ~
       JsForEach(Var('i) in 'someArray) {
         'console  'log(Hi there  __+ 'i) `;`
       } ~
       JsAnonFunc('arg1, 'arg2) {
        'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
       }(1, 2) `;`
     }

     println(js.toJs)

 this yields the following JavaScript code:

 function myFunc( param1, param2 ) {
 if (param1  30) {
 var home = ( 234 - 3 ) / 2;
 var someArray = [ 1, 2, 3, 4, 5 ];
 myFunc(1, 2, do it, home);
 $(#myID).attr(value, 123);}

 for (var i in someArray) {
 console.log(Hi there  + i);}

 function ( arg1, arg2 ) {
 alert(Anonymous function  + arg1 + arg2)

 }(1, 2);
 }

 ... ok I just droped nonsense code in there for exemplification. A few
 words:

 1. JsIf, JsForEach describe JavaScript if and for(each) statements
 2. Functions like __, __, ... __+, __- are function that alows definition
 of boolean and/or algebraic expressions.
 3. Wrap just wraps an expression into ()
 4. Var defined a variable
 5 := defines an assignment
 6. JsFunc declares a JS function
 7. JsAnonFunc declares an anonymous function
 8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function invocation
 by providing 4 parameter.
 9. ~ is just a function that chains statements that don;t necessarily end in
 ;

 Do you think that something like this would be usable in Lift?

 Br's,
 Marius

 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group 
 athttp://groups.google.com/group/liftweb?hl=en.

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-13 Thread Naftoli Gugenheim
Other advantages of a DSL include type safety and typo safety. :)

-
Mariusmarius.dan...@gmail.com wrote:

That is certainly one way to go but personally I'm not at all a fan of
this string literals approach,. For instance if Scala would not have
had built in XML support using XML as string literals Lift would
probably loose some of its attractions... but that's my opinion.
Furthermore a DSL like language allows better compositionality than
concatenating strings when we want to iteratively add JS code ... for
instance calling the same function multiple times with different
arguments, or collecting code fragments generated by different
application components etc.

Also it seems to me that your approach (somehow similar with
Velocity's) is more expensive but I admit that this is not at all a
strong argument because we're talking about small javascript fragments
so the delta is negligible.

Br's,
Marius

On Dec 12, 8:42 pm, Alex Boisvert alex.boisv...@gmail.com wrote:
 Personally, I would rather go with a JavaScript literal and a simple
 templating mechanism for substitution/binding of Javascript literals + Json
 objects that would drive dynamic code (if conditionals, for-loops, ...).

 Taking your example,

 def myFunc = {
   function myFunc( param1, param2 ) {
     if (param1  ${limit}) {
       var home = ( ${max} - 3 ) / 2;
       var someArray = ${array};
       myFunc(1, 2, do it, home);
       $(#myID).attr(value, 123);
     }
     for (var i in ${someArray}) {
       console.log(Hi there  + i);
     }
     function ( arg1, arg2 ) {
       alert(Anonymous function  + arg1 + arg2)
     }(1, 2);
   }.jsBind(
     max - max,
     array - array,
     someArray - someArray,
     ...
   )

 Not a fully fleshed out example but you get the idea.  You'd still be able
 to bind existing JsExp/JsCmds  so some parts could still be abstracted and
 typed checked.

 I would find this more readable and simpler that learning a quirky DSL
 syntax.  And I could still copy/paste Javascript code to/from the browser
 and test it easily.

 alex

 On Sat, Dec 12, 2009 at 2:07 AM, Marius Danciu marius.dan...@gmail.comwrote:

  All,

  I just want to see if there is any interest in the approach discussed here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a lot
  this support and it's great but if your JS code that you want to send down
  to the browser (say as an Ajax or Comet partial update response) gets a bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use JsRaw
  to write the JavaScript fragment in order for the code reader to understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I started
  to define a JavaScript like DSL that IMO is closer to JavaScript form.
  Attached is a source code smaple of how this looks like, so for instance we
  can have something like:

  val js = JsFunc('myFunc, 'param1, 'param2) {
      JsIf('param1 __ 30) {
          Var('home) := Wrap(234 __- 3) __/ 2 `;`
          Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
          'myFunc(1, 2, do it, 'home) `;`
          $(#myID)  'attr(value, 123) `;`
        } ~
        JsForEach(Var('i) in 'someArray) {
          'console  'log(Hi there  __+ 'i) `;`
        } ~
        JsAnonFunc('arg1, 'arg2) {
         'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
        }(1, 2) `;`
      }

      println(js.toJs)

  this yields the following JavaScript code:

  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);
  }
  for (var i in someArray) {
  console.log(Hi there  + i);
  }
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
  }(1, 2);
  }

  ... ok I just droped nonsense code in there for exemplification. A few
  words:

  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows definition
  of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
  invocation by providing 4 parameter.
  9. ~ is just a function that chains statements that don;t necessarily end
  in ;

  Do you think that something like this would be usable in Lift?

  Br's,
  Marius

  --
  You received this message because you are subscribed to the Google Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  

Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-13 Thread Alex Boisvert
On Sat, Dec 12, 2009 at 11:06 AM, Marius marius.dan...@gmail.com wrote:

 That is certainly one way to go but personally I'm not at all a fan of
 this string literals approach,. For instance if Scala would not have
 had built in XML support using XML as string literals Lift would
 probably loose some of its attractions... but that's my opinion.


Agreed, XML is baked-in.  It's not a DSL built on top of other features.


 Furthermore a DSL like language allows better compositionality than
 concatenating strings when we want to iteratively add JS code ... for
 instance calling the same function multiple times with different
 arguments, or collecting code fragments generated by different
 application components etc.


There's no guarantee of compositionality for DSLs.   You have to design it
to be, and it's quite difficult to get right.   And then you pretty much
reinvent another language.  First you have Scala, then you have Javascript,
then you have something in between which is FrankenScalaScript.Just my
opinion :)



 Also it seems to me that your approach (somehow similar with
 Velocity's) is more expensive but I admit that this is not at all a
 strong argument because we're talking about small javascript fragments
 so the delta is negligible.


I would beg to differ but we're so far from any implementation of either to
judge performance at this stage.

alex

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: Scala to JavaScript DSL ...

2009-12-13 Thread Marius


On Dec 14, 4:54 am, Alex Boisvert alex.boisv...@gmail.com wrote:
 On Sat, Dec 12, 2009 at 11:06 AM, Marius marius.dan...@gmail.com wrote:
  That is certainly one way to go but personally I'm not at all a fan of
  this string literals approach,. For instance if Scala would not have
  had built in XML support using XML as string literals Lift would
  probably loose some of its attractions... but that's my opinion.

 Agreed, XML is baked-in.  It's not a DSL built on top of other features.

  Furthermore a DSL like language allows better compositionality than
  concatenating strings when we want to iteratively add JS code ... for
  instance calling the same function multiple times with different
  arguments, or collecting code fragments generated by different
  application components etc.

 There's no guarantee of compositionality for DSLs.   You have to design it
 to be, and it's quite difficult to get right.   And then you pretty much
 reinvent another language.  First you have Scala, then you have Javascript,
 then you have something in between which is FrankenScalaScript.    Just my
 opinion :)

Yeah ... I'm also a little concerned about the new syntax but I
don't think that's such a big impediment. What I meant by
compositionality is that you can easily put together code fragments by
naturally using  ~ or `;` functions and that's supported by the above
code. Similar with JsCmd  function. Also most function are taking JS
parameters which allows us to pass JS code (calls to other JS
functions or even pass functions and have higher order javascript
functions) as arguments to JS functions.

I know it's your opinion and I do respect it. To be honest I'm not a
huge DSL fun but in this context I really think it can help writing
JavaScript fragments from Scala code.


  Also it seems to me that your approach (somehow similar with
  Velocity's) is more expensive but I admit that this is not at all a
  strong argument because we're talking about small javascript fragments
  so the delta is negligible.

 I would beg to differ but we're so far from any implementation of either to
 judge performance at this stage.

Not judging ... just that the style you mentioned inherently implies
string parsing that is not necessary in the DSL approach.


Are there any other opinions out there?


 alex

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: Scala to JavaScript DSL ...

2009-12-12 Thread Marius
My notes inline.

On Dec 12, 12:34 pm, Timothy Perrett timo...@getintheloop.eu wrote:
 Hey Marius,

 Within this DSL will you be using JsObj under the hood or lift-json?

I was thinking to use lift-json in this case ... but I'd also of
prefer having a lift-js project.


 I would be very reluctant about adding new things to lift that don't  
 unify our Js and JSON libs.

Depends what you mean by unify. lift-json is not the same with js
support, js should utilize lift-json to build json constructs being
part of the javascript generated but lift-json has nothing to to with
a potential lift-js project. Therefore I would keep lift-json and lift-
js separated and have lift-js utilize lift-json whenever possible.


 On this note, will this unification take place before 2.0?

Too soon to tell. I'm not sure yet if people like this proposal so we
first need acceptance and then talk schedules.


 Cheers, Tim

 Sent from my iPhone

 On 12 Dec 2009, at 10:07, Marius Danciu marius.dan...@gmail.com wrote:

  All,

  I just want to see if there is any interest in the approach  
  discussed here. As you know Lift has some interesting support for  
  building JavaScript constructs from Scala code usig JsExp, JsCmd etc  
  classes. I used quite a lot this support and it's great but if your  
  JS code that you want to send down to the browser (say as an Ajax or  
  Comet partial update response) gets a bit more complicated then  
  constructing the JS fragment leads IMO to some cumbersome Scala  
  code. I found myselft in quite a few situation to use JsRaw to write  
  the JavaScript fragment in order for the code reader to understand  
  what JavaScript code will be generated. But of course with JsRaw we  
  put everything into a String so I'm not a big fan of this approach.  
  So I started to define a JavaScript like DSL that IMO is closer to  
  JavaScript form. Attached is a source code smaple of how this looks  
  like, so for instance we can have something like:

  val js = JsFunc('myFunc, 'param1, 'param2) {
      JsIf('param1 __ 30) {
          Var('home) := Wrap(234 __- 3) __/ 2 `;`
          Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
          'myFunc(1, 2, do it, 'home) `;`
          $(#myID)  'attr(value, 123) `;`
        } ~
        JsForEach(Var('i) in 'someArray) {
          'console  'log(Hi there  __+ 'i) `;`
        } ~
        JsAnonFunc('arg1, 'arg2) {
         'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
        }(1, 2) `;`
      }

      println(js.toJs)

  this yields the following JavaScript code:

  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);
  }
  for (var i in someArray) {
  console.log(Hi there  + i);
  }
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
  }(1, 2);
  }

  ... ok I just droped nonsense code in there for exemplification. A  
  few words:

  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows  
  definition of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function  
  invocation by providing 4 parameter.
  9. ~ is just a function that chains statements that don;t  
  necessarily end in ;

  Do you think that something like this would be usable in Lift?

  Br's,
  Marius
  --

  You received this message because you are subscribed to the Google  
  Groups Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to 
  liftweb+unsubscr...@googlegroups.com
  .
  For more options, visit this group 
  athttp://groups.google.com/group/liftweb?hl=en
  .
  App.scala

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: Scala to JavaScript DSL ...

2009-12-12 Thread Indrajit Raychaudhuri

On 12/12/09 4:39 PM, Marius wrote:
 My notes inline.

 On Dec 12, 12:34 pm, Timothy Perretttimo...@getintheloop.eu  wrote:
 Hey Marius,

 Within this DSL will you be using JsObj under the hood or lift-json?

 I was thinking to use lift-json in this case ... but I'd also of
 prefer having a lift-js project.


 I would be very reluctant about adding new things to lift that don't
 unify our Js and JSON libs.

 Depends what you mean by unify. lift-json is not the same with js
 support, js should utilize lift-json to build json constructs being
 part of the javascript generated but lift-json has nothing to to with
 a potential lift-js project. Therefore I would keep lift-json and lift-
 js separated and have lift-js utilize lift-json whenever possible.

I would be hugely in favor of lift-js. I see lift-json deal with the 
data container related functionality. This would be clearly demarcated 
from lift-js (the scripting, method calls etc.) that is primarily used 
for deeper framework level integration for building (mostly web) 
applications.

In that sense, lift-webkit could also shed some weight in favor of 
lift-js (parts of net.liftweb.http.js, for example). On one hand we 
would have a neatly composed package with focused purpose and on the 
other hand lift-webkit would feel 'lighter' to projects that don't need 
any of the js functionality at all.

The dependency tree could look like (lower components depend on one or 
more above them):

lift-common
lift-actor [1]
lift-json [1]
lift-util [2]
lift-js [2]
lift-webkit [3]

[1] Independent of each other currently.
[2] Can interchange depending on how things go.
[3] In some sense lift-webkit still ends up depending on lift-js 
transitively. But that's better than 2.7M monolith :) It can even create 
opportunity for marking lift-js as 'optional dependency' for lift-webkit.

In any case, this is a derived profit and doesn't have to be the primary 
goal.



 On this note, will this unification take place before 2.0?

 Too soon to tell. I'm not sure yet if people like this proposal so we
 first need acceptance and then talk schedules.


 Cheers, Tim

 Sent from my iPhone

 On 12 Dec 2009, at 10:07, Marius Danciumarius.dan...@gmail.com  wrote:

 All,

 I just want to see if there is any interest in the approach
 discussed here. As you know Lift has some interesting support for
 building JavaScript constructs from Scala code usig JsExp, JsCmd etc
 classes. I used quite a lot this support and it's great but if your
 JS code that you want to send down to the browser (say as an Ajax or
 Comet partial update response) gets a bit more complicated then
 constructing the JS fragment leads IMO to some cumbersome Scala
 code. I found myselft in quite a few situation to use JsRaw to write
 the JavaScript fragment in order for the code reader to understand
 what JavaScript code will be generated. But of course with JsRaw we
 put everything into a String so I'm not a big fan of this approach.
 So I started to define a JavaScript like DSL that IMO is closer to
 JavaScript form. Attached is a source code smaple of how this looks
 like, so for instance we can have something like:

 val js = JsFunc('myFunc, 'param1, 'param2) {
  JsIf('param1 __  30) {
  Var('home) := Wrap(234 __- 3) __/ 2 `;`
  Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
  'myFunc(1, 2, do it, 'home) `;`
  $(#myID)  'attr(value, 123) `;`
} ~
JsForEach(Var('i) in 'someArray) {
  'console  'log(Hi there  __+ 'i) `;`
} ~
JsAnonFunc('arg1, 'arg2) {
 'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
}(1, 2) `;`
  }

  println(js.toJs)

 this yields the following JavaScript code:

 function myFunc( param1, param2 ) {
 if (param1  30) {
 var home = ( 234 - 3 ) / 2;
 var someArray = [ 1, 2, 3, 4, 5 ];
 myFunc(1, 2, do it, home);
 $(#myID).attr(value, 123);
 }
 for (var i in someArray) {
 console.log(Hi there  + i);
 }
 function ( arg1, arg2 ) {
 alert(Anonymous function  + arg1 + arg2)
 }(1, 2);
 }

 ... ok I just droped nonsense code in there for exemplification. A
 few words:

 1. JsIf, JsForEach describe JavaScript if and for(each) statements
 2. Functions like __, __, ... __+, __- are function that alows
 definition of boolean and/or algebraic expressions.
 3. Wrap just wraps an expression into ()
 4. Var defined a variable
 5 := defines an assignment
 6. JsFunc declares a JS function
 7. JsAnonFunc declares an anonymous function
 8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
 invocation by providing 4 parameter.
 9. ~ is just a function that chains statements that don;t
 necessarily end in ;

 Do you think that something like this would be usable in Lift?

 Br's,
 Marius
 --

 You received this message because you are subscribed to the Google
 Groups Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 

[Lift] Re: Scala to JavaScript DSL ...

2009-12-12 Thread Marius
I agree. Although to be more specific I guess my proposal can be split
in 2:

1. The syntax style proposed that would probably evolve depending on
the feedback.
2. The existence of lift-js project.

Br's,
Marius

On Dec 12, 6:44 pm, Indrajit Raychaudhuri indraj...@gmail.com wrote:
 On 12/12/09 4:39 PM, Marius wrote:



  My notes inline.

  On Dec 12, 12:34 pm, Timothy Perretttimo...@getintheloop.eu  wrote:
  Hey Marius,

  Within this DSL will you be using JsObj under the hood or lift-json?

  I was thinking to use lift-json in this case ... but I'd also of
  prefer having a lift-js project.

  I would be very reluctant about adding new things to lift that don't
  unify our Js and JSON libs.

  Depends what you mean by unify. lift-json is not the same with js
  support, js should utilize lift-json to build json constructs being
  part of the javascript generated but lift-json has nothing to to with
  a potential lift-js project. Therefore I would keep lift-json and lift-
  js separated and have lift-js utilize lift-json whenever possible.

 I would be hugely in favor of lift-js. I see lift-json deal with the
 data container related functionality. This would be clearly demarcated
 from lift-js (the scripting, method calls etc.) that is primarily used
 for deeper framework level integration for building (mostly web)
 applications.

 In that sense, lift-webkit could also shed some weight in favor of
 lift-js (parts of net.liftweb.http.js, for example). On one hand we
 would have a neatly composed package with focused purpose and on the
 other hand lift-webkit would feel 'lighter' to projects that don't need
 any of the js functionality at all.

 The dependency tree could look like (lower components depend on one or
 more above them):

 lift-common
 lift-actor [1]
 lift-json [1]
 lift-util [2]
 lift-js [2]
 lift-webkit [3]

 [1] Independent of each other currently.
 [2] Can interchange depending on how things go.
 [3] In some sense lift-webkit still ends up depending on lift-js
 transitively. But that's better than 2.7M monolith :) It can even create
 opportunity for marking lift-js as 'optional dependency' for lift-webkit.

 In any case, this is a derived profit and doesn't have to be the primary
 goal.



  On this note, will this unification take place before 2.0?

  Too soon to tell. I'm not sure yet if people like this proposal so we
  first need acceptance and then talk schedules.

  Cheers, Tim

  Sent from my iPhone

  On 12 Dec 2009, at 10:07, Marius Danciumarius.dan...@gmail.com  wrote:

  All,

  I just want to see if there is any interest in the approach
  discussed here. As you know Lift has some interesting support for
  building JavaScript constructs from Scala code usig JsExp, JsCmd etc
  classes. I used quite a lot this support and it's great but if your
  JS code that you want to send down to the browser (say as an Ajax or
  Comet partial update response) gets a bit more complicated then
  constructing the JS fragment leads IMO to some cumbersome Scala
  code. I found myselft in quite a few situation to use JsRaw to write
  the JavaScript fragment in order for the code reader to understand
  what JavaScript code will be generated. But of course with JsRaw we
  put everything into a String so I'm not a big fan of this approach.
  So I started to define a JavaScript like DSL that IMO is closer to
  JavaScript form. Attached is a source code smaple of how this looks
  like, so for instance we can have something like:

  val js = JsFunc('myFunc, 'param1, 'param2) {
       JsIf('param1 __  30) {
           Var('home) := Wrap(234 __- 3) __/ 2 `;`
           Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
           'myFunc(1, 2, do it, 'home) `;`
           $(#myID)  'attr(value, 123) `;`
         } ~
         JsForEach(Var('i) in 'someArray) {
           'console  'log(Hi there  __+ 'i) `;`
         } ~
         JsAnonFunc('arg1, 'arg2) {
          'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
         }(1, 2) `;`
       }

       println(js.toJs)

  this yields the following JavaScript code:

  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);
  }
  for (var i in someArray) {
  console.log(Hi there  + i);
  }
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
  }(1, 2);
  }

  ... ok I just droped nonsense code in there for exemplification. A
  few words:

  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows
  definition of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
  invocation by providing 4 parameter.
  9. ~ is just a 

[Lift] Re: Scala to JavaScript DSL ...

2009-12-12 Thread Marius
That is certainly one way to go but personally I'm not at all a fan of
this string literals approach,. For instance if Scala would not have
had built in XML support using XML as string literals Lift would
probably loose some of its attractions... but that's my opinion.
Furthermore a DSL like language allows better compositionality than
concatenating strings when we want to iteratively add JS code ... for
instance calling the same function multiple times with different
arguments, or collecting code fragments generated by different
application components etc.

Also it seems to me that your approach (somehow similar with
Velocity's) is more expensive but I admit that this is not at all a
strong argument because we're talking about small javascript fragments
so the delta is negligible.

Br's,
Marius

On Dec 12, 8:42 pm, Alex Boisvert alex.boisv...@gmail.com wrote:
 Personally, I would rather go with a JavaScript literal and a simple
 templating mechanism for substitution/binding of Javascript literals + Json
 objects that would drive dynamic code (if conditionals, for-loops, ...).

 Taking your example,

 def myFunc = {
   function myFunc( param1, param2 ) {
     if (param1  ${limit}) {
       var home = ( ${max} - 3 ) / 2;
       var someArray = ${array};
       myFunc(1, 2, do it, home);
       $(#myID).attr(value, 123);
     }
     for (var i in ${someArray}) {
       console.log(Hi there  + i);
     }
     function ( arg1, arg2 ) {
       alert(Anonymous function  + arg1 + arg2)
     }(1, 2);
   }.jsBind(
     max - max,
     array - array,
     someArray - someArray,
     ...
   )

 Not a fully fleshed out example but you get the idea.  You'd still be able
 to bind existing JsExp/JsCmds  so some parts could still be abstracted and
 typed checked.

 I would find this more readable and simpler that learning a quirky DSL
 syntax.  And I could still copy/paste Javascript code to/from the browser
 and test it easily.

 alex

 On Sat, Dec 12, 2009 at 2:07 AM, Marius Danciu marius.dan...@gmail.comwrote:

  All,

  I just want to see if there is any interest in the approach discussed here.
  As you know Lift has some interesting support for building JavaScript
  constructs from Scala code usig JsExp, JsCmd etc classes. I used quite a lot
  this support and it's great but if your JS code that you want to send down
  to the browser (say as an Ajax or Comet partial update response) gets a bit
  more complicated then constructing the JS fragment leads IMO to some
  cumbersome Scala code. I found myselft in quite a few situation to use JsRaw
  to write the JavaScript fragment in order for the code reader to understand
  what JavaScript code will be generated. But of course with JsRaw we put
  everything into a String so I'm not a big fan of this approach. So I started
  to define a JavaScript like DSL that IMO is closer to JavaScript form.
  Attached is a source code smaple of how this looks like, so for instance we
  can have something like:

  val js = JsFunc('myFunc, 'param1, 'param2) {
      JsIf('param1 __ 30) {
          Var('home) := Wrap(234 __- 3) __/ 2 `;`
          Var('someArray) := JsArray(1, 2, 3, 4, 5) `;`
          'myFunc(1, 2, do it, 'home) `;`
          $(#myID)  'attr(value, 123) `;`
        } ~
        JsForEach(Var('i) in 'someArray) {
          'console  'log(Hi there  __+ 'i) `;`
        } ~
        JsAnonFunc('arg1, 'arg2) {
         'alert(Anonymous function  __+ 'arg1 __+ 'arg2)
        }(1, 2) `;`
      }

      println(js.toJs)

  this yields the following JavaScript code:

  function myFunc( param1, param2 ) {
  if (param1  30) {
  var home = ( 234 - 3 ) / 2;
  var someArray = [ 1, 2, 3, 4, 5 ];
  myFunc(1, 2, do it, home);
  $(#myID).attr(value, 123);
  }
  for (var i in someArray) {
  console.log(Hi there  + i);
  }
  function ( arg1, arg2 ) {
  alert(Anonymous function  + arg1 + arg2)
  }(1, 2);
  }

  ... ok I just droped nonsense code in there for exemplification. A few
  words:

  1. JsIf, JsForEach describe JavaScript if and for(each) statements
  2. Functions like __, __, ... __+, __- are function that alows definition
  of boolean and/or algebraic expressions.
  3. Wrap just wraps an expression into ()
  4. Var defined a variable
  5 := defines an assignment
  6. JsFunc declares a JS function
  7. JsAnonFunc declares an anonymous function
  8. 'myFunc(1, 2, do it, 'home)  is simply a javascript function
  invocation by providing 4 parameter.
  9. ~ is just a function that chains statements that don;t necessarily end
  in ;

  Do you think that something like this would be usable in Lift?

  Br's,
  Marius

  --
  You received this message because you are subscribed to the Google Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
  .
  For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.

--