@JavaScriptclass AES(val key: Array[Int]) { // here goes Scala implementation}
def main(args: Array[String]) { val data = "Kill all humans" val key = "secret key" val aes = new Aes(key) val encrypted = aes.encrypt(data)
val aesJs = AES.javaScript val js = javascript { AES.javaScript val aes = new AES(inject(key)) aes.decrypt(inject(encrypted)) } decryptedInJs = js.eval() assert(decryptedInJs == data)}
@JavaScriptcase class User(id: Int, name: String, birthdat: Date)
def getUser = { val newborn = new User(1, "Alex", new Date()) newborn.asJson}def updateUser(json: String) { val user = User.fromJson(json) ...}
javascript { val newborn = new User(1, "Alex", new Date()) $.getJSON('ajax/getUser', (user: User) => $("#user").text(user.name)); user.birthday = new Date(); $.ajax(url = "ajax/updateUser", data = user.asJson(), dataType = "json")}
Hi Sebastian,Glad to hear about the meetup, I'm very interested in all the feedback. Is the meetup going to be a video?
Well, the basic idea would be that you write Scala code that could be run as Scala code and as a JavaScript.
@JavaScriptclass AES(val key: Array[Int]) {// here goes Scala implementation}
def main(args: Array[String]) {val data = "Kill all humans"val key = "secret key"val aes = new Aes(key)val encrypted = aes.encrypt(data)
val aesJs = AES.javaScript // forgotten?val js = javascript {AES.javaScript // why is this line needed?
val aes = new AES(inject(key))aes.decrypt(inject(encrypted))}
decryptedInJs = js.eval() // what happens here exactly?assert(decryptedInJs == data)}
Also, you'll be able to share data and serialize/deserialize it to JSON automatically:
@JavaScriptcase class User(id: Int, name: String, birthdate: Date)
def getUser = {val newborn = new User(1, "Alex", new Date())newborn.asJson}def updateUser(json: String) {val user = User.fromJson(json)...}javascript {val newborn = new User(1, "Alex", new Date())$.getJSON('ajax/getUser', (user: User) => $("#user").text(user.name));user.birthday = new Date();$.ajax(url = "ajax/updateUser", data = user.asJson(), dataType = "json")}
You'll be able to write your both client-side and server-side code in Scala with its type safety, trait decomposition, IDE support (refactoring, navigation).
So, summary would be "Write once in Scala, run everywhere" :)
2013/9/13 Alexander Nemish <ane...@gmail.com>Hi Sebastian,Glad to hear about the meetup, I'm very interested in all the feedback. Is the meetup going to be a video?Normally we don't record all of our talks. But I'll ask and arrange something.
Well, the basic idea would be that you write Scala code that could be run as Scala code and as a JavaScript.I am missing something in the code snippet below...* What do you do with aesJs? (it was forgotten, right?)
* What do you do with the lone "AES.javaScript" line?
val aesJsAst = () => AES.javaScript
javascript {
inject(aesJsAst)
val aes = new AES(...)
}
* What happens with js.eval()? The JS is executed by a JS engine on the Scala process? If yes, which one?
@JavaScriptclass AES(val key: String) {
// here goes Scala implementation}
def main(args: Array[String]) { val data = "Kill all humans" val key = "secret key" val aes = new Aes(key) val encrypted = aes.encrypt(data)
val aesJsAst = () => AES.javaScript val js = javascript { inject(aesJsAst) /*include AES implementation into generated JavaScript*/
val aes = new AES(inject(key)) aes.decrypt(inject(encrypted)) }
decryptedInJs = js.eval() /* generated JavaScript is executed using Java ScriptEngine, just as an example */ assert(decryptedInJs == data) /* validate we got the same data we encripted */}
Thanks for sharing the example! When will we be able to enjoy this? ;-)
--
Yes, the JS will be executed using standard Java ScriptEngine JavaScript implementation, Rhino. That was just an example, think as this code is passed to a browser and is executed there.
Thanks for sharing the example! When will we be able to enjoy this? ;-)Heh, good question. I'm working on this, though it's an "evening" project and I've got busy evenings recently :-/Also, there are several differences working with def macros and annotation macros. Basically, macro annotation AST is not typechecked, so I don't have types for all the subtrees I need to generate valid JavaScript AST. I'll discuss these issues with Eugene Burmako, hopefully we'll be able to fix them eventually.
--
On Sep 14, 2013 3:14 PM, "Eugene Burmako" <eugene....@epfl.ch> wrote:
>
> Looking forward to our discussion! I'll be travelling next week, but we could chat the week after next (if this works for you, of course).
>
> By the way, why not auto-inject all companions of all @JavaScript classes used in the javascript block?
>
Wouldn't that potentially result in duplicate definitions if it's used in multiple javascript blocks?
I was thinking of an analogue to inject, so you'd manually output in one place
javascript {
define[AES]
}
Also I would rather that the method added to the companion have a more private, less collidable name, like __jscala_definition_ast. It would not be referenced by user source code, only be inserted to replace the call to define.
I'm hoping, G-d willing, to add at some point to reactive a javascript component dependency management capability, which might be in a better position to automate such things.
Anyway it really looks great and exciting!