fantom and tales
DESCRIPTION
Presentation at JUG-chennai on Fantom and TalesTRANSCRIPT
Fantom
Fantom is boring - Brian frank
BY DESIGNcreator of
fantom(along with andy frank)
It’s about damn timeWe had a boring language
JavaLet’s start with
Another language?Why do we need
Java was looking great in 1995
In 2011, still beautiful just a little old
Java Better?
What would you change to make
Lets keep the compiler
THE LITTLE CHANGES
Remove semi-colens
int a = 0 ; int b = 2 ;
int a = 0
int b = 2
String interpolationString event = “jug”;String host = “Raj”;
Sop(“Welcome to ‘“ + event + “’ by “ + host)
Sop(“Welcome to ‘$event’ by $host “)
Type inference
String event = “Jug Meeting”
event = “Jug Meeting”
Multiline strings
String query = """ select * from users where company=‘microsoft’ and userid
in(select id from usersalary where sal > 200000000)
"""
String query = “select * from users where” + “company=‘microsoft’ and ” + “ userid in(select id from usersalary” +
“where sal > 200000000)”
echo
System.out.println(“hi”)
echo(“hi”)
Everything’s an object
3.toString()
3.times{ echo(“hi”)}
Non null-able fields
Int a = 3 Int? b = 3
a = null //compiler error
Less noisy ‘list’ syntax
User[] users = new User[]
//Array style index accessusers[0] = new User();
//List style auto grow and stuffusers.add(new User());
Less noisy ‘Map’ syntax
String:User map = String:User[:]map[“steve”] = new User();map[“woz”] = new User();
Map<String, User> map = new HashMap<String, User>();map.put(“steve”, new User());map.put(“woz”, new User());
Accessor methods
class Person{ String name; Int age { set { … } get{…} }}
Person p = new Person();p.name = “Kaushik”;p.age = 20;
default param values
Void printMyLang(Str lang = “java”){ System.out.println(lang);}
printMyLang(); //prints “java”printMyLang(“fantom”); //prints “fantom”
THE NOT-SO-LITTLE CHANGES
BETTER MODULARIZATION
android-1.1.jar guava.jar
com.google.utils.Activity
Which jar?
jscomp.jar tales.jar
tales.pod email.pod
tales::Activity
Which pod?
web.pod sys.pod
What are we giving up?Unique classes in pod - No two “Utilities” class in a pod
Unique method name in a class - No method overloading
easy reflectionclass Article{ public String test(Str name){ …. }}
Obj obj := Article()Str title := Atricle#.method(“test”).invoke(obj)
Readable serializationString str = “““acme::Article { title = "Something" viewCount = 123 }”””
Article a = str.in.readObj
STATIC AND DYNAMIC TYPING
Always compile Never compile
Sometimes compile, Sometimes Don’t
Static and dynamicuser := new User()user.doSomething(“”); //Checked by compileruser->doSomething(“”); //Checked by runtime
if dynamic method not present, a trap() implementation is called to do “meta” programming
MIXINS
interface with implementationmixin Audio{ abstract Int getVolume(); Void incrementVolume() { volume += 1 } Void decrementVolume() { volume -= 1 }}
class Television : Audio{ override Int getVolume(){return 0;}}
Pass around methodsprefix := |Str name->Str| { return “Hi $name” }suffix := |Str name->Str| { return “$name, Hello”}
sayWelcome(prefix)sayWelcome(suffix)
Void sayWelcome(|Str->Str| code){ log(“going to say welcome”) code(“Kaushik”) log(“Said welcome”)}
3.times{ echo(“hi”)}
ACTORSJust like threads.
but no shared state
BETTER APIS
DATE AND IOCalendar - Weird c like constants - Months are zero based, Weekdays are 1 based
IO - Over 60 classes - In fantom most functionalities in 4 classes
File, Buf, Instream, OutStream
BORING?
TALES
What’s a framework?
Current state of Tales
Tales is BoringWithout tales you will need to know atleast
-HTML, css-JavaScript-Fantom-SQL
With tales you will need to know only
-HTML, css-JavaScript-Fantom-SQL
Embrace HTML
What we will not have// Create a 4 by 4 grid layout.GridLayout grid = new GridLayout(4, 4);grid.addStyleName("example-gridlayout");// Fill out the first row using the cursor.grid.addComponent(new Button("R/C 1"));for (int i = 0; i < 3; i++) { grid.addComponent(new Button("Col " + (grid.getCursorX() + 1)));}// Fill out the first column using coordinates.for (int i = 1; i < 4; i++) { grid.addComponent(new Button("Row " + i), 0, i);}// Add some components of various shapes.grid.addComponent(new Button("3x1 button"), 1, 1, 3, 1);grid.addComponent(new Label("1x2 cell"), 1, 2, 1, 3);InlineDateField date = new InlineDateField("A 2x2 date field");date.setResolution(DateField.RESOLUTION_DAY);grid.addComponent(date, 2, 2, 3, 3);
What we will Definitely not have
<%for(int i=0;i<20; i++){%>hello <%=name%>
<%}%>
What we will not even have
<c:forEach var="i" begin="1" end="20" step="1" varStatus="status"><c:out value="${i}" />
</c:forEach>
What we will have//templateHello <div talesId=”name” />
//fantomadd(label->name(“kaushik”))
//outputHello <div>kaushik</div>
What we will have(2)//template<div talesId=”name” />
//fantomUser[] users := User{}.listadd(repeater->name(users)|User user|{ text->value(user.name)})
//output<div>name1</div><div>name2</div><div>name3</div><div>name4</div>
EMBRACE JAVASCRIPT
What we will not have TextBox box = new TextBox(""); Link l = new Link("click me"); Label a = new Label(""); add(box); add(l); add(a); link.addActionListener(new ActionListener(){
public void actionPerformed(ActionEven e){a.setText(box.getVal());
} });
//because this is easy too..
$("#link").click(function(){$("#label").text($
("#box").val()); });
Encapsulate & compileclass Alerter{ Void sayHi(Str? taskName){ client<| alert(taskName); |> }}
..a. sayHi(2); //Will not compile
Simpler than DWR Ajaxclass TaskPage : Page{ Void addTask(Str? taskName){ client<| if(!taskName){alert(“No task name”); return;} params[“name”] = taskName; |> server{ taskService.addTask(params[“name”]); } client<|
alert(“Task added”); |> }}
Embrace Fantom
FIX AND GO
Dependency injection & AOPBind{type=UserService#; toType=”UserServiceImpl”},Bind{name = “noOfRows”; toValue=5}
class UserPage{ @inject UserService userService; @inject noOfRows}
Embrace HTTP
REST
Stateful and Scalable
//During a Page Load
//Set values per pagepage[“captcha-val”] = “dixleo”
//During another request from that pageStr captchaVal = page[“captcha-val”]
Embrace SQL
Part ORM Part Data-mapping//This is validUser u := User{id = 1}.oneUser[] users := User{company = “oracle”}.list
//This is too..User[] users := User{}.queryList(“select id, name from users”)
//you can even externalize your queriesClass BlogSql{ Str userSql := “select id, name from users”}
//And get it injected@inject Sql blogSqlUser[] users := User{}.queryList(blogSql->userSql)