Your SlideShare is downloading. ×

Xtend

230

Published on

Язык программирования Xtend

Язык программирования Xtend

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
230
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
3
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Язык программирования
  • 2. Xtend • Язык общего назначения
  • 3. Xtend • Язык общего назначения • Транслируется в Java 5
  • 4. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП
  • 5. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП • Простота изучения (намного проще Scala), схожесть с Java
  • 6. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП • Простота изучения (намного проще Scala), схожесть с Java • Библиотека – тонкая прослойка над Java (≈100 классов) + Guava
  • 7. Языки JVM Yeti Erjang Frege
  • 8. Языки JVM Yeti Erjang Frege
  • 9. Языки JVM Yeti Frege
  • 10. Языки JVM
  • 11. Языки JVM
  • 12. Языки JVM
  • 13. Кол-во вопросов на SO 457101 17592 6564 5612 1748 1143 82 23 14 9 8 7 6 3 1 10 100 1000 10000 100000 1000000 Java Scala Groovy Clojure JRuby Jython Xtend Kotlin Mirah Gosu Fantom Ceylon Yeti X10
  • 14. Опрос
  • 15. No ; and () class Main { def static void main(String[] args) { println(5.toString) } }
  • 16. Translation to Java import org.eclipse.xtext.xbase.lib.InputOutput; @SuppressWarnings("all") public class Main { public static void main(final String[] args) { String _string = Integer.valueOf(5).toString(); InputOutput.<String>println(_string); } }
  • 17. val, var and type inference val n = 5 for (i : 1..n) { var str = i.toString println(str) str = ... }
  • 18. val, var and type inference val int n = 5 for (int i : 1..n) { var String str = i.toString println(str) str = ... }
  • 19. Type inference val list = new ArrayList list.add(1) list.add("text") list.add(true) println(list)
  • 20. Type inference val list = new ArrayList list.add(1) list.add("text") list.add(true) println(list) Какой тип у ArrayList?
  • 21. Type inference val list = new ArrayList<Serializable> list.add(1) list.add("text") list.add(true) println(list)
  • 22. Type inference val list = new ArrayList<Comparable<?>> list.add(1) list.add("text") list.add(true) println(list)
  • 23. Everything is an expression def static readData() { val data = try { fileContentsToString('data.txt') } catch (IOException e) { "dummy data" } println(data) data }
  • 24. switch def String describe(Object x) { switch x { Integer case x > 0 : "Positive integer" String : "String" List<?> case x.empty : "Empty list" List<?> : "Non-empty list" default : x.class.simpleName } }
  • 25. Классы @Data class Person { val String firstName val String lastName val int age def void sayHello() { println('''Hello, my name is «firstName» «lastName»''') } }
  • 26. Классы @Data @SuppressWarnings("all") public class Person { private final String _firstName; public String getFirstName() { this._firstName; } private final String _lastName; public String getLastName() { return this._lastName; } private final int _age; public int getAge() { return this._age; } public void sayHello() { ... } public Person(final String firstName, final String lastName, final int age) { ... } @Override public int hashCode() { ... } @Override public boolean equals(final Object obj) { ... } @Override public String toString() { ... } }
  • 27. Классы class Task implements Runnable { @Property val String name @Property var int timeout new(String name, int timeout) { this._name = name this._timeout = timeout } new(String name) { this(name, 600) } override run() { println('''Running task "«name»"''') ... } }
  • 28. Операторы Xtend Java a == b Objects.equals(a, b) a === b a == b a -> b Pair.of(a, b) a ** b Math.pow(a, b) a .. b new IntegerRange(a, b) a ..< b new ExclusiveRange(a, b, true) a >.. b new ExclusiveRange(a, b, false) a ?: b if (a != null) a else b a?.doStuff if (a != null) a.doStuff()
  • 29. extension-методы "text".toFirstUpper
  • 30. extension-методы "text".toFirstUpper import org.eclipse.xtext.xbase.lib.StringExtensions; … StringExtensions.toFirstUpper("text");
  • 31. Стандартные extension-методы ObjectExtensions ByteExtensions ShortExtensions IntegerExtensions LongExtensions FloatExtensions BooleanExtensions DoubleExtensions CharacterExtensions BigIntegerExtensions BigDecimalExtensions IterableExtensions MapExtensions ListExtensions CollectionExtensions FunctionExtensions ProcedureExtensions ComparableExtensions
  • 32. Внешние extension-методы import java.io.File import com.google.common.io.Files; class Main { def static void main(String[] args) { val file = new File('''C:jdk1.7.0_25README.html''') val bytes = Files::toByteArray(file) ... } }
  • 33. Внешние extension-методы import java.io.File import static extension com.google.common.io.Files.*; class Main { def static void main(String[] args) { val file = new File('''C:jdk1.7.0_25README.html''') val bytes = file.toByteArray ... } }
  • 34. Локальные extension-методы class Main { def static void main(String[] args) { val f = 5.factorial println(f) } def static int factorial(int n) { if (n == 1) 1 else n * factorial(n - 1) } }
  • 35. Extension providers class EntityRepository { var extension EntityManager entityManager def void doSmth() { val person = new Person("John", "Doe") person.persist } }
  • 36. Lambdas val Comparator<String> c = [a,b | Integer::compare(a.length, b.length)]
  • 37. Lambdas val Comparator<String> c = [a,b | Integer::compare(a.length, b.length)] final Comparator<String> _function = new Comparator<String>() { public int compare(final String a, final String b) { int _length = a.length(); int _length_1 = b.length(); int _compare = Integer.compare(_length, _length_1); return _compare; } }; final Comparator<String> c = _function;
  • 38. Lambdas val persons = #[ new Person("John", "Doe"), new Person("Jane", "Roe"), new Person("David", "McFly") ] val names = persons.map([p | p.firstName]) // John, Jane, David
  • 39. Lambdas val persons = #[ new Person("John", "Doe"), new Person("Jane", "Roe"), new Person("David", "McFly") ] val names = persons.map([it.firstName]) // John, Jane, David
  • 40. Lambdas val persons = #[ new Person("John", "Doe"), new Person("Jane", "Roe"), new Person("David", "McFly") ] val names = persons.map([firstName]) // John, Jane, David
  • 41. Lambdas val persons = #[ new Person("John", "Doe"), new Person("Jane", "Roe"), new Person("David", "McFly") ] val names = persons.map[firstName] // John, Jane, David
  • 42. Lambdas val persons = #[ new Person("John", "Doe", true), new Person("Jane", "Roe", false), new Person("David", "McFly", true) ] val women = persons.filter[female] // Jane Roe
  • 43. Задача Найти человека с самой длинной фамилией
  • 44. Решение #0 var Person person = null; for (p : persons) { if (person == null || p.lastName.length > person.lastName.length) { person = p } }
  • 45. Решение #0 var Person person = null; for (p : persons) { if (person == null || p.lastName.length > person.lastName.length) { person = p } }
  • 46. Решение #1 val person = persons.sortBy[lastName.length].last
  • 47. Решение #2 import static extension java.util.Collections.* val person = persons.max[ p1, p2 | p1.lastName.length - p2.lastName.length ]
  • 48. Решение #3 val person = persons.reduce[ pWithLongestLastName, p | if (pWithLongestLastName.lastName.length > p.lastName.length) pWithLongestLastName else p ]
  • 49. Решение #4 val person = persons.maxBy[lastName.length]
  • 50. Multiple dispatch GameObject Spaceship Asteroid
  • 51. Multiple dispatch def static void main(String[] args) { val GameObject asteroid = new Asteroid val GameObject spaceship = new Spaceship collide(asteroid, spaceship) } def static void collide(Asteroid x, Asteroid y) { println('астероид сталкивается с астероидом') } def static void collide(Asteroid x, Spaceship y) { println('астероид сталкивается с космическим кораблем') } def static void collide(Spaceship x, Asteroid y) { println('космический корабль сталкивается с астероидом') } def static void collide(Spaceship x, Spaceship y) { println('космический корабль сталкивается с космическим кораблем') }
  • 52. Multiple dispatch def static void main(String[] args) { val GameObject asteroid = new Asteroid val GameObject spaceship = new Spaceship collide(asteroid, spaceship) // Ошибка компиляции } def static void collide(Asteroid x, Asteroid y) { println('астероид сталкивается с астероидом') } def static void collide(Asteroid x, Spaceship y) { println('астероид сталкивается с космическим кораблем') } def static void collide(Spaceship x, Asteroid y) { println('космический корабль сталкивается с астероидом') } def static void collide(Spaceship x, Spaceship y) { println('космический корабль сталкивается с космическим кораблем') }
  • 53. Multiple dispatch def static void main(String[] args) { val GameObject asteroid = new Asteroid val GameObject spaceship = new Spaceship collide(asteroid, spaceship) // OK } def static dispatch void collide(Asteroid x, Asteroid y) { println('астероид сталкивается с астероидом') } def static dispatch void collide(Asteroid x, Spaceship y) { println('астероид сталкивается с космическим кораблем') } def static dispatch void collide(Spaceship x, Asteroid y) { println('космический корабль сталкивается с астероидом') } def static dispatch void collide(Spaceship x, Spaceship y) { println('космический корабль сталкивается с космическим кораблем') }
  • 54. Multiple dispatch protected static void _collide(final Asteroid x, final Asteroid y) { InputOutput.<String>println("астероид сталкивается с астероидом"); } protected static void _collide(final Asteroid x, final Spaceship y) { InputOutput.<String>println("астероид сталкивается с космическим кораблем"); } protected static void _collide(final Spaceship x, final Asteroid y) { InputOutput.<String>println("космический корабль сталкивается с астероидом"); } protected static void _collide(final Spaceship x, final Spaceship y) { InputOutput.<String>println("космический корабль сталкивается с космическим кораблем"); } public static void collide(final GameObject x, final GameObject y) { if (x instanceof Asteroid && y instanceof Asteroid) { _collide((Asteroid)x, (Asteroid)y); return; } else if (x instanceof Asteroid && y instanceof Spaceship) { _collide((Asteroid)x, (Spaceship)y); return; } else if (x instanceof Spaceship && y instanceof Asteroid) { _collide((Spaceship)x, (Asteroid)y); return; } else if (x instanceof Spaceship && y instanceof Spaceship) { _collide((Spaceship)x, (Spaceship)y); return; } else { throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object>asList(x, y).toString()); } }
  • 55. Template expressions val name = "James" println("Hello " + name + "!")
  • 56. Template expressions val name = "James" println('''Hello «name»!''')
  • 57. Template expressions val name = "James" println('''Hello «name»!''') final String name = "James"; StringConcatenation _builder = new StringConcatenation(); _builder.append("Hello "); _builder.append(name, ""); _builder.append("!"); InputOutput.<String>println(_builder.toString());
  • 58. Template expressions def static html(String text, String image) { ''' <!DOCTYPE html> <html> <body> <p>«text»</p> <img src='«image»' width='«getWidth(image)»' height='«getHeight(image)»'/> </body> </html> ''' }
  • 59. Active annotations class Tweets { List<String> allTweets = TweetReader::allTweets ... }
  • 60. Active annotations class Tweets { @Lazy List<String> allTweets = TweetReader::allTweets ... }
  • 61. Active annotations @Target(ElementType::FIELD) annotation Lazy { }
  • 62. Active annotations @Target(ElementType::FIELD) @Active(typeof(LazyProcessor)) annotation Lazy { }
  • 63. Active annotations @Target(ElementType::FIELD) @Active(typeof(LazyProcessor)) annotation Lazy { } class LazyProcessor extends AbstractFieldProcessor { override doTransform(MutableFieldDeclaration field, extension TransformationContext context) { if (field.type.primitive) field.addError("Fields with primitives are not supported by @Lazy") if (field.initializer == null) field.addError("A lazy field must have an initializer.") field.declaringType.addMethod('_init' + field.simpleName) [ visibility = Visibility::PRIVATE returnType = field.type body = field.initializer ] field.declaringType.addMethod('get' + field.simpleName.toFirstUpper) [ returnType = field.type body = [''' if («field.simpleName»==null) «field.simpleName» = _init«field.simpleName»(); return «field.simpleName»; '''] ] } }
  • 64. Заключение • Xtend – довольно сырой язык
  • 65. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество
  • 66. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество • Неплохая поддержка IDE
  • 67. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество • Неплохая поддержка IDE • Язык не является убийцей Java, он является убийцей её синтаксиса 

×