Ceylon idioms by Gavin King

71 %
29 %
Information about Ceylon idioms by Gavin King
Technology

Published on February 5, 2014

Author: UnFroMage

Source: slideshare.net

Description

Discover Ceylon idioms that will make you run to try Ceylon.

Ten Ceylon Idioms Gavin King - Red Hat profiles.google.com/gavin.king ceylon-lang.org !

“Powerful” • Languages with static typing are less expressive, in a certain narrow sense, than dynamic languages • Ceylon has a very strict type system, fussier even than Java or C# • So to counterbalance that, we need additional power, within the type system, to abstract over things, thus regaining expressivity • Let’s explore the type system via some idioms

Idiom #1 Idiom: functions with multiple outcomes For example, an operation might return a Person, an Org, or nothing. //Java ! Object findByName(String name) throws NotFoundException { ... } ! We can handle the different outcomes using instanceof, type casts, and catch: try { Object result = findByName(name); if (result instanceof Org) { Org org = (Org) result; ... } if (result instanceof Person) { Person person = (Person) result; ... } } catch (NotFoundException nfe) { ... }

Idiom #1 Idiom: functions with multiple outcomes A function with more than one “outcome” can be defined using a union type. ! Org|Person|NotFound findByName(String name) => ... ; ! We can handle the various outcomes using switch: value result = findByName(name); switch (result) case (is Org|Person) { ... } case (is NotFound) { ... }

Item? get(Key key) Idiom #2 Idiom: functions returning null Example: retrieving an element from a map. (Special case of multiple outcomes!) ! Item? get(Key key) => ... ; ! For a union type of form Null|Item, we have some special syntax sugar: value map = HashMap { “enrique”->cst, “tom”->gmt, “ross”->pst }; Timezone tz = map[name] else cet;

Item? get(Key key) Idiom #2 Idiom: functions returning null What if we know that get() can’t return null, because of some constraint upon the given key? We can make use of an assertion. ! if (name in map) { assert (exists tz = map[name]); ! return ZonedTime(time, tz); } ! A different way to write this code: ! if (exists tz = map[name]) { return ZonedTime(time, tz); }

Idiom #3 Idiom: overloading For example, an operation might apply to an Integer, or to a Float. ! //Java Float sqrt(Float ! number) { ... } Float sqrt(Integer number) { ... } ! Actually two different, unrelated operations. !

Idiom #3 Idiom: overloading A function parameter can be defined using a union type. ! Float sqrt(Float|Integer number) { switch (number) ! case (is Float) { ... } case (is Integer) { ... } ! } ! Now we have a single operation: Float fourthRoot(Float|Integer number) => sqrt(sqrt(number)); ! And we can obtain a reference to it: Float(Float|Integer) sqrtFun = sqrt;

Idiom #4 Idiom: multiple return values For example, an operation might return a Name //Java class NameAndAddress { ... } ! and an Address. ! ! NameAndAddress getNameAndAddress(Person person) { ! return new NameAndAddress(new Name(person.getFirst(), person.getLast()), person.getHome().getAddress()); ! } ! We have to define a class. !

Idiom #4 Idiom: multiple return values A function can be defined to return a tuple type. [Name,Address] getNameAndAddress(Person person) ! => [Name(person.first, person.last), person.home.address]; ! Now a caller can extract the individual return values: value nameAndAddress = ! getNameAndAddress(person); Name name = nameAndAddress[0]; ! Address address = nameAndAddress[1]; ! What about other indexes? Null missing = nameAndAddress[3]; Name|Address|Null val = nameAndAddress[index];

Idiom #5 Idiom: spreading tuple return values Imagine we want to pass the result of getNameAndAddress() to another function or class initializer. ! class SnailMail(Name name, Address address) { ... } ! We can use the spread operator, *, like in Groovy: ! value snail = SnailMail(*getNameAndAddress(person)); ! Or we can work at the function level, using unflatten() SnailMail(Person) newSnail = compose(unflatten(SnailMail), getNameAndAddress); SnailMail snail = newSnail(person);

Idiom #6 Idiom: unions of values Imagine we want to write down the signature of Set.union() in Java: ! //Java interface Set<T> { ! public <U super T> Set<U> union(Set<? extends U> set); } ! This doesn’t actually compile since Java doesn’t have lower bounded type parameters. (The equivalent thing would work in Scala though.) Set<Foo> setOfFoo = ... ; Set<Bar> setOfBar = ... ; ! Set<Object> setOfFoosAndBars = setOfFoo.union(setOfBar);

Idiom #6 Idiom: unions of values Unions of values correspond to unions of types! ! interface Set<These> { shared formal Set<These|Those> union<Those>(Set<Those> set); ! } ! Exactly the right type pops out automatically. Set<Foo> setOfFoo = ... ; Set<Bar> setOfBar = ... ; ! Set<Foo|Bar> setOfFoosAndBars = setOfFoo | setOfBar;

Idiom #7 Idiom: intersections of values Now let’s consider the case of Set.intersection() in Java. //exercise for the audience I tried a bunch of things and didn’t come close to anything like the right thing.

Idiom #7 Idiom: intersections of values Intersections of values correspond to intersections of types! ! interface Set<These> { shared formal Set<These&Those> intersection<Those>(Set<Those> set); ! } ! Again, exactly the right type pops out automatically. Set<Foo> setOfFoo = ... ; Set<Bar> setOfBar = ... ; ! Set<Foo&Bar> setOfFooBars = setOfFoo & setOfBar;

Idiom #7 Idiom: intersections of values Example: the coalesce() function eliminates null elements from an Iterable object. ! {Element&Object*} coalesce<Element>({Element*} elements) => { for (e in elements) if (exists e) e }; ! Exactly the right type pops out automatically. ! {String?*} words = { “hello”, null, “world” }; {String*} strings = coalesce(words); ! ! (Even though I’m explicitly writing in the types, I could have let them be inferred.)

Idiom #8 Idiom: empty vs nonempty Problem: the max() function can return null, but only when the Iterable object might be empty. ! shared Value? max<Value>({Value*} values) ! given Value satisfies Comparable<Value> { ... } ! What if we know it’s nonempty? A separate function? ! shared Value maxNonempty<Value>({Value+} values) ! given Value satisfies Comparable<Value> { ... } ! This doesn’t let us abstract.

Idiom #8 Idiom: empty vs nonempty Solution: the Iterable object has an extra type parameter. ! shared Absent|Value max<Value,Absent>(Iterable<Value,Absent> values) ! given Value satisfies Comparable<Value> given Absent satisfies Null { ... } ! Exactly the right type pops out automatically. Null maxOfNone = max {}; String maxOfSome = max { “hello”, “world” }; ! {String*} noneOrSome = ... ; String? max = max(noneOrSome);

Idiom #9 Idiom: abstract over function types Example: the compose() function composes functions. ! X compose<X,Y,A>(X(Y) x, Y(A) y)(A a) ! => x(y(a)); ! But this is not quite as general as it could be! ! value printSqrt = compose(print,sqrt); ! What about functions with multiple parameters? value printSum = compose(print,plus<Float>);

Idiom #9 Idiom: abstract over function types Solution: abstract over unknown tuple type. ! Callable<X,Args> compose<X,Y,Args>(X(Y) x, Callable<Y,Args> y) ! given Args satisfies Anything[] => flatten((Args args) => x(unflatten(y)(args))); ! ! A little uglier, but does the job! Anything(Float,Float) printSum = compose(print,plus<Float>);

Idiom #10 Idiom: discovery Example: auto-discover classes annotated test. shared test class IdiomTests() { ... } ! We use the Ceylon metamodel: void metamodel() { value declarations = `package org.jboss.example.tests` .annotatedMembers<ClassDeclaration,TestAnnotation>(); for (decl in declarations) { if (decl.parameterDeclarations.empty) { value model = decl.classApply<Anything,[]>(); // instantiate the class print(model()); } } }

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Eight Ceylon Idioms - ceylon-lang.org

Eight Ceylon Idioms Gavin King - Red Hat profiles.google.com/gavin.king ceylon-lang.org! Ceylon is:! ... We use the Ceylon metamodel:
Read more

Ceylon: Team blog

Ceylon idioms by Gavin King. ... Cayla and Vert.x in Ceylon, by Gavin King. Ceylon SDK. Ceylon SDK by Stéphane Épardaud. ceylon.build. Ceylon.build by ...
Read more

NHV-0469 Ceylon Idioms ∞ Devoxx

Ceylon Idioms Toutes les conférences ... Gavin King; Gavin King leads the Ceylon project at Red Hat. Gavin is the creator of Hibernate, a popular object ...
Read more

First Ceylon Tour in Paris | Planet JBoss Developer

Ceylon idioms by Gavin King. Cayla and Vert.x in ... the turnout and to answer the questions we got when we announced the first Ceylon Tour in ...
Read more

Gavin King: Ceylon at DevNation 2014 - Miles to go 3.0 ...

What sessions are you giving at DevNation ? “Eleven Ceylon Idioms”, a talk that aims to quickly introduce some distinctive features of Ceylon’s type ...
Read more

Gavin King: Ceylon at DevNation 2014 | Planet JBoss Developer

What sessions are you giving at DevNation ? “Eleven Ceylon Idioms”, a talk that aims to quickly introduce some distinctive features of Ceylon’s type ...
Read more

Gavin King - Ceylon Introduction! - YouTube

Gavin King leads the Ceylon project at Red Hat. Gavin is the creator of Hibernate, a popular object/relational persistence solution for Java ...
Read more

Gavin King ∞ Devoxx

Gavin King leads the Ceylon project at Red Hat. Gavin is the creator of Hibernate, a popular object/relational persistence solution for Java, and the Seam ...
Read more