A Javascript DSL?

41 views
Skip to first unread message

Peter Robinett

unread,
Jul 7, 2010, 8:07:06 AM7/7/10
to Lift
Hi all,

AsI was biking to the office today I started thinking about returning
the the Javascript dependency management system I'd like to add to
Lift for things like lift-flot and that got me thinking more generally
about how Lift handles Javascript. I know some other Lifters has been
thinking about better ways to deal with client-side code, as I've
heard one or two people mention using things like HaXe to write
Javascript. Because of all the Javascript representations in Lift, you
can actually construct lots of valid Javascript code in Lift using the
various object in net.liftweb.http.js. That got me thinking, why
couldn't we just use Scala across the board to write Javascript?

For instance, right now to write a simple Javascript for loop in Lift
you'd do something like this:

scala> import
net.liftweb.http.js.JsCmds._
import net.liftweb.http.js.JsCmds._

scala> import net.liftweb.http.js.JE._
import net.liftweb.http.js.JE._

scala> JsFor(JsEq(JsVar("k"), Num(0)), JsLt(JsVar("k"), Num(10)),
JsVar("k") === (JsVar("k") + Num(1)), Call("console.log", JsVar("k")))
res0: net.liftweb.http.js.JsCmds.JsFor = JsFor(k == 0,k < 10,k = k
+ 1,console.log(k))

(Incidentally, shouldn't the first argument of JsFor be a JsExp, not a
JsEq?) It would be very cool if you could write something like:

For (var k = 0, k < 10, k++) {
console.log(k);
}

We can start to get there:

def For(start: JsEq, condition: JsExp, increment: JsExp)(body: JsExp)
= JsFor(start, condition, increment, body)

class jsOps(exp: JsExp) {
def < (right: JsExp) = JsLt(exp, right)
}

implicit def toJsOps(exp: JsExp) = new jsOps(exp)

For(JsEq(JsVar("k"), Num(1)), JsVar("k") < Num(10), JsVar("k") ++) {
Call("console.log", JsVar("k"))
}

I used an implicit def because I was just playing around in my REPL.
Also, I cheated on the ++. In theory you'd have something where JsVars
might know their values and so you could manipulate them.

class jsVarWithValue(jsVar: JsExp, value: Box[JsExp]) {
def ++ = value.map(v => new jsVarWithValue(jsVar === jsVar + Num(1),
Full(v + 1))) openOr (jsVar === jsVar + Num(1))
}

implicit def jsVarValued(jsVar: JsVar) = new jsVarWithValue(jsVar,
Empty)

Actually, I guess that might work...

JsVarWithValue hints at a larger potential feature: not only being
about to generate a final JsExp that can be converted to a String
which will evaluate correctly in a Javascript interpreter but actually
being able to know something about the state of the Javascript script
from within Scala while you're assembling the final JsExp. The hope is
that you'd be able to have the super-simple syntax I showed at the
beginning of this message and actually run the loop as valid Scala and
have 0 through 9 printed to the console. Not being a Scala Jedi, I
don't know if this is do-able but I suspect that with some crazy type
and closure magic it might be possible.

Thanks for reading! Please let me know what you think!

Peter

Marius

unread,
Jul 7, 2010, 8:29:34 AM7/7/10
to Lift
please see this:
http://groups.google.com/group/liftweb/browse_thread/thread/b63e760457096265/c32aaa86e10d66c6?lnk=gst&q=JavaScript#c32aaa86e10d66c6

I suggested a while ago a JS DSL that would require more polishing but
you'll get the idea. This didn't get anywhere because there was not
much interest I guess. This is more like a fine-grained approach as
opposed of current coarse-grained approach. IMHO both suitable in
certain circumstances.


Br's,
Marius

Timothy Perrett

unread,
Jul 7, 2010, 8:46:47 AM7/7/10
to lif...@googlegroups.com
I think the JS stuff in Lift can be confusing, so anything that would help with that (by way of a DSL etc) would be a good thing. That being said, we need to be careful about what we are doing, as peter, I cant help but feel what you are proposing is not too far from writing JS as first-class code in Scala (similar to what has been done with SQL by way of compiler plugin) and im really not sure that would be the way to go.

Cheers, Tim

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

Peter Robinett

unread,
Jul 7, 2010, 9:03:48 AM7/7/10
to Lift
Hey Marius,

Thanks for the link, I missed that discussion. What you've developed
looks nice. I think it could be even more similar to standard
Javascript with some nice implicits, so this:

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) `;`
}

Becomes this:

val js = Function 'myFunc ('param1, 'param2) {
If ('param1 < 30) {
Var 'home := Number(234) + 3 / 3
Var 'someArray := Array(1, 2, 3, 4, 5)
'myFunc(1, 2, "do it", 'home)
$("#myID") >> 'attr("value", "123")
} ~
Foreach(Var 'i in 'someArray) {
'console >> 'log("Hi there " + 'i)
} ~
Function ('arg1, 'arg2) {
'alert("Anonymous function " + 'arg1 + 'arg2)
}(1, 2)
}

I see from the thread that you chose things like the `;` with care, so
just take changes as my two cents on how I like to write Javascript. I
guess the syntax is very similar to what Naftoli developed...

Peter

On Jul 7, 2:29 pm, Marius <marius.dan...@gmail.com> wrote:
> please see this:http://groups.google.com/group/liftweb/browse_thread/thread/b63e76045...

Peter Robinett

unread,
Jul 7, 2010, 9:29:31 AM7/7/10
to Lift
On Jul 7, 2:46 pm, Timothy Perrett <timo...@getintheloop.eu> wrote:
> That being said, we need to be careful about what we are doing, as peter, I cant help but feel what you are proposing is not too far from writing JS as first-class code in Scala (similar to what has been done with SQL by way of compiler plugin) and im really not sure that would be the way to go.

You're right Tim, that is essentially what I'm proposing. Why are you
opposed to it? Too many implicits? Losing the fact that you're writing
Scala? Perhaps putting it in dedicated block like Kevin discussed on
the Scala mailing list (http://comments.gmane.org/
gmane.comp.lang.scala/20605) would help?

Peter

On Jul 7, 2:46 pm, Timothy Perrett <timo...@getintheloop.eu> wrote:
> I think the JS stuff in Lift can be confusing, so anything that would help with that (by way of a DSL etc) would be a good thing. That being said, we need to be careful about what we are doing, as peter, I cant help but feel what you are proposing is not too far from writing JS as first-class code in Scala (similar to what has been done with SQL by way of compiler plugin) and im really not sure that would be the way to go.
>
> Cheers, Tim
>
> On 7 Jul 2010, at 13:29, Marius wrote:
>
>
>
> > please see this:
> >http://groups.google.com/group/liftweb/browse_thread/thread/b63e76045...

Kevin Wright

unread,
Jul 7, 2010, 9:31:47 AM7/7/10
to lif...@googlegroups.com
Blast! You've rumbled me...

I was indeed thinking about Javascript when I started that thread :)
--
Kevin Wright

mail/google talk: kev.lee...@gmail.com
wave: kev.lee...@googlewave.com
skype: kev.lee.wright
twitter: @thecoda

Timothy Perrett

unread,
Jul 7, 2010, 10:07:50 AM7/7/10
to lif...@googlegroups.com
Peter,

It was more a case of "we've discussed that before at length, and the feeling was it was the wrong solution for lift". Search the archives, im sure its been debated numerous times.

Im not saying we dont need something better or different than what we have now, rather, this was what was discussed before :-)

Cheers, Tim

David Pollak

unread,
Jul 7, 2010, 11:53:51 AM7/7/10
to lif...@googlegroups.com
I'd love to see a better JavaScript DSL... but I'd also like to see it be type-safe.

I think the best bet is a subset of the Scala syntax that is turned in JavaScript by a compiler plugin.  That way you get the goodness of type checking and the benefits of a unified syntax.

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




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

TylerWeir

unread,
Jul 7, 2010, 12:07:50 PM7/7/10
to Lift
On Jul 7, 11:53 am, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> I'd love to see a better JavaScript DSL... but I'd also like to see it be
> type-safe.
>
> I think the best bet is a subset of the Scala syntax that is turned in
> JavaScript by a compiler plugin.  That way you get the goodness of type
> checking and the benefits of a unified syntax.

Hooba jooba, this would be nice.
+1 to this idea.
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/liftweb?hl=en.
>
> --
> Lift, the simply functional web frameworkhttp://liftweb.net
> Beginning Scalahttp://www.apress.com/book/view/1430219890

Peter Robinett

unread,
Jul 7, 2010, 12:09:02 PM7/7/10
to Lift
I would love that also!

Peter

Maxime Lévesque

unread,
Jul 7, 2010, 12:53:04 PM7/7/10
to Lift

I'd love to see a JavaScript DSL, it would be even cooler if there
was
an RPC mechanism to exchange object with a backend in a type safe
maner,
like GWT.

There is an effort going on to bring GWT to Scala :

http://github.com/lexspoon/scalagwt-gwt

The only thing that sucks about GWT is that it brings the verbosity of
Java,
if they do the Scala GWT right, it will be quite awesome, if not....
then
someone might have written a JavaScript DSL by then ! ;-)

David Pollak

unread,
Jul 7, 2010, 12:56:43 PM7/7/10
to lif...@googlegroups.com


2010/7/7 Maxime Lévesque <maxime....@gmail.com>


 I'd love to see a JavaScript DSL, it would be even cooler if there
was
an RPC mechanism to exchange object with a backend in a type safe
maner,

There's already some of those pieces working already with the Lift JSON support and JSON calls.  I'd like to see JSON deltas so that we can just send the deltas to the client (and back again).
 
--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890

Kevin Wright

unread,
Jul 7, 2010, 4:20:56 PM7/7/10
to lif...@googlegroups.com
I suspect that it'll be an 80:20 problem.

Most of the heavy lifting can be done with a vanilla DSL, but a compiler plugin might be needed for the fiddly bits.  So long as any plugin logic can occur between the parser and namer phases then this should actually be fairly easy to do.

Right now, my thinking is that we want a way to inject context into named blocks; an approach that meets my above-defined criteria (just a bit too co-incidental eh?)

I'm up to the challenge if the demand is there :)


Timothy Perrett

unread,
Jul 7, 2010, 4:25:46 PM7/7/10
to lif...@googlegroups.com
Ok, im remembering something... Didn't we want to avoid compiler plugins because of the extra hassle of bundling them or something? There was a specific reason DPP wanted to avoid them if I recall... exactly what that was, i forget, but there was certainly some complication in doing a plugin.

Does anyone else remember this or is it just me? Personally, i've not written a compiler plugin, nor ever used one so I don't know whats involved to say either way.

Cheers, Tim

David Pollak

unread,
Jul 7, 2010, 4:32:55 PM7/7/10
to lif...@googlegroups.com
On Wed, Jul 7, 2010 at 1:25 PM, Timothy Perrett <tim...@getintheloop.eu> wrote:
Ok, im remembering something... Didn't we want to avoid compiler plugins because of the extra hassle of bundling them or something? There was a specific reason DPP wanted to avoid them if I recall... exactly what that was, i forget, but there was certainly some complication in doing a plugin.

Does anyone else remember this or is it just me?

It's just you. ;-)

The Scala compiler plugin API is pretty stable now and Maven and sbt support plugins.
 

Timothy Perrett

unread,
Jul 7, 2010, 5:09:48 PM7/7/10
to lif...@googlegroups.com
haha! well, thats no surprise! I'll get back into my cave then...

David Pollak

unread,
Jul 7, 2010, 5:15:57 PM7/7/10
to lif...@googlegroups.com
On Wed, Jul 7, 2010 at 2:09 PM, Timothy Perrett <tim...@getintheloop.eu> wrote:
haha! well, thats no surprise! I'll get back into my cave then...

Do you have beer in your cave or do you come out to go to the pub? ;-)
 

On 7 Jul 2010, at 21:32, David Pollak wrote:

> It's just you. ;-)
>
> The Scala compiler plugin API is pretty stable now and Maven and sbt support plugins.

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

Timothy Perrett

unread,
Jul 7, 2010, 5:25:42 PM7/7/10
to lif...@googlegroups.com
I brew my own thankfully, this allows me to stay within the cave most of the time writing Lift in Action ;-)

Naftoli Gugenheim

unread,
Jul 7, 2010, 5:59:15 PM7/7/10
to liftweb
I'm not sure why it didn't get anywhere. We had two approaches and had begun discussing the pros and cons of each. No one responded to my last message, so I'm unclear what the disadvantages of my approach are.
I'm okay with whichever DSL is chosen but shouldn't we discuss the differences thoroughly first?


Naftoli Gugenheim

unread,
Jul 7, 2010, 6:00:09 PM7/7/10
to liftweb
As long as you don't have a 'bear' in the cave...


Peter Robinett

unread,
Jul 8, 2010, 3:11:07 AM7/8/10
to Lift
Ok, good to know. And yes, I think we should discuss the DSL syntax,
though I imagine deciding how it will be implemented (compiler plugin,
etc) will also place some constraints on the DSL. As you may have
noticed, I'd like to get as close to javascript as possible.

Peter

On Jul 7, 11:59 pm, Naftoli Gugenheim <naftoli...@gmail.com> wrote:
> I'm not sure why it didn't get anywhere. We had two approaches and had begun
> discussing the pros and cons of each. No one responded to my last message,
> so I'm unclear what the disadvantages of my approach are.
> I'm okay with whichever DSL is chosen but shouldn't we discuss the
> differences thoroughly first?
>
>
>
> On Wed, Jul 7, 2010 at 8:29 AM, Marius <marius.dan...@gmail.com> wrote:
> > please see this:
>
> >http://groups.google.com/group/liftweb/browse_thread/thread/b63e76045...
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com >
> > .

Naftoli Gugenheim

unread,
Jul 8, 2010, 3:02:19 PM7/8/10
to liftweb
Okay, so would you like to start the discussion with an example of how my DSL could be made closer to javascript?



To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages