Xtend

476 views

Published on

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

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

No Downloads
Views
Total views
476
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
5
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Xtend

  1. 1. Язык программирования
  2. 2. Xtend • Язык общего назначения
  3. 3. Xtend • Язык общего назначения • Транслируется в Java 5
  4. 4. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП
  5. 5. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП • Простота изучения (намного проще Scala), схожесть с Java
  6. 6. Xtend • Язык общего назначения • Транслируется в Java 5 • ООП + немного ФП • Простота изучения (намного проще Scala), схожесть с Java • Библиотека – тонкая прослойка над Java (≈100 классов) + Guava
  7. 7. Языки JVM Yeti Erjang Frege
  8. 8. Языки JVM Yeti Erjang Frege
  9. 9. Языки JVM Yeti Frege
  10. 10. Языки JVM
  11. 11. Языки JVM
  12. 12. Языки JVM
  13. 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. 14. Опрос
  15. 15. No ; and () class Main { def static void main(String[] args) { println(5.toString) } }
  16. 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. 17. val, var and type inference val n = 5 for (i : 1..n) { var str = i.toString println(str) str = ... }
  18. 18. val, var and type inference val int n = 5 for (int i : 1..n) { var String str = i.toString println(str) str = ... }
  19. 19. Type inference val list = new ArrayList list.add(1) list.add("text") list.add(true) println(list)
  20. 20. Type inference val list = new ArrayList list.add(1) list.add("text") list.add(true) println(list) Какой тип у ArrayList?
  21. 21. Type inference val list = new ArrayList<Serializable> list.add(1) list.add("text") list.add(true) println(list)
  22. 22. Type inference val list = new ArrayList<Comparable<?>> list.add(1) list.add("text") list.add(true) println(list)
  23. 23. Everything is an expression def static readData() { val data = try { fileContentsToString('data.txt') } catch (IOException e) { "dummy data" } println(data) data }
  24. 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. 25. Классы @Data class Person { val String firstName val String lastName val int age def void sayHello() { println('''Hello, my name is «firstName» «lastName»''') } }
  26. 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. 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. 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. 29. extension-методы "text".toFirstUpper
  30. 30. extension-методы "text".toFirstUpper import org.eclipse.xtext.xbase.lib.StringExtensions; … StringExtensions.toFirstUpper("text");
  31. 31. Стандартные extension-методы ObjectExtensions ByteExtensions ShortExtensions IntegerExtensions LongExtensions FloatExtensions BooleanExtensions DoubleExtensions CharacterExtensions BigIntegerExtensions BigDecimalExtensions IterableExtensions MapExtensions ListExtensions CollectionExtensions FunctionExtensions ProcedureExtensions ComparableExtensions
  32. 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. 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. 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. 35. Extension providers class EntityRepository { var extension EntityManager entityManager def void doSmth() { val person = new Person("John", "Doe") person.persist } }
  36. 36. Lambdas val Comparator<String> c = [a,b | Integer::compare(a.length, b.length)]
  37. 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. 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. 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. 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. 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. 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. 43. Задача Найти человека с самой длинной фамилией
  44. 44. Решение #0 var Person person = null; for (p : persons) { if (person == null || p.lastName.length > person.lastName.length) { person = p } }
  45. 45. Решение #0 var Person person = null; for (p : persons) { if (person == null || p.lastName.length > person.lastName.length) { person = p } }
  46. 46. Решение #1 val person = persons.sortBy[lastName.length].last
  47. 47. Решение #2 import static extension java.util.Collections.* val person = persons.max[ p1, p2 | p1.lastName.length - p2.lastName.length ]
  48. 48. Решение #3 val person = persons.reduce[ pWithLongestLastName, p | if (pWithLongestLastName.lastName.length > p.lastName.length) pWithLongestLastName else p ]
  49. 49. Решение #4 val person = persons.maxBy[lastName.length]
  50. 50. Multiple dispatch GameObject Spaceship Asteroid
  51. 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. 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. 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. 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. 55. Template expressions val name = "James" println("Hello " + name + "!")
  56. 56. Template expressions val name = "James" println('''Hello «name»!''')
  57. 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. 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. 59. Active annotations class Tweets { List<String> allTweets = TweetReader::allTweets ... }
  60. 60. Active annotations class Tweets { @Lazy List<String> allTweets = TweetReader::allTweets ... }
  61. 61. Active annotations @Target(ElementType::FIELD) annotation Lazy { }
  62. 62. Active annotations @Target(ElementType::FIELD) @Active(typeof(LazyProcessor)) annotation Lazy { }
  63. 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. 64. Заключение • Xtend – довольно сырой язык
  65. 65. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество
  66. 66. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество • Неплохая поддержка IDE
  67. 67. Заключение • Xtend – довольно сырой язык – Есть баги – Проблемы с производительностью – Очень маленькое сообщество • Неплохая поддержка IDE • Язык не является убийцей Java, он является убийцей её синтаксиса 

×