Katie Miller (@codemiller) & Steve Dalton (@spidie)
Learning Haskell will make you a better Java programmer ... it will rewire your brain in a way that will make you write better Java programs.— Simon Peyton Jones (Haskell Creator), YOW! 2011
class Dog(object):
def __setattr__(self, *args):
raise TypeError("can't modify immutable instance")
__delattr__ = __setattr__
def __init__(self, name):
super(Dog, self).__setattr__('name', name)
billy = Dog('Billy')
billy.name = 'Buster' # no can do!
class Dog
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function __get($key)
{
if (property_exists($this, $key)) {
return $this->{$key};
} else {
throw new \RuntimeException("Property doesn't exist");
}
}
public function __set($key, $value)
{
throw new \RuntimeException("This object is immutable");
}
}
$billy = new Dog("Billy");
$billy->name = "Buster"; // no dice!
class ImmutableDateTime
{
private $_dt;
public function __construct($time = 'now', DateTimeZone $timezone = NULL) {
$this->_dt = new DateTime($time, $timezone);
}
...
public function add(DateInterval $interval) {
$clone = clone($this->_dt);
$clone->add($interval);
return $clone;
}
public function setDate($year, $month, $day) {
throw new ImmutableException();
}
}
class ImmutableException extends \Exception {
public function __construct() {
parent::__construct("Can't modify immutable DateTime!");
}
}
void saveCat(final AnimalCallback<Cat> cb, final Cat cat) {
try {
cb.begin();
createRestClient(cb).updateCat(cat);
} catch (final Exception ex) {
cb.generalException(ex);
}
}
void getCow(final AnimalCallback<Cow> cb, final int id) {
final String exp = "{\"tail\":{\"type\": \"" + TAIL + "\"}}";
try {
cb.begin();
createRestClient(cb).getCow(id, exp);
} catch (final Exception ex) {
cb.generalException(ex);
}
}
void saveDog(final AnimalCallback<Dog> cb, final Dog dog) {
try {
cb.begin();
createRestClient(cb).updateDog(dog, BARK);
} catch (final Exception ex) {
cb.generalException(ex);
}
}
interface Caller {
public void call() throws Exception;
}
<T> void doCall(AnimalCallback<T> cb, Caller restCaller) {
try {
cb.begin();
restCaller.call();
} catch (final Exception e) {
cb.generalException(e);
}
}
void saveCat(final AnimalCallback<Cat> cb, final Cat cat) {
doCall(cb, new Caller() {
@Override
public void call() throws Exception {
createRestClient(cb).updateCat(cat);
}
});
}
void getCow(final AnimalCallback<Cow> cb, final int id) {
final String exp = "{\"tail\":{\"type\": \"" + TAIL + "\"}}";
doCall(cb, new Caller() {
@Override
public void call() throws Exception {
createRestClient(cb).getCow(id, expand);
}
});
}
void saveDog(final AnimalCallback<Dog> cb, final Dog dog) {
doCall(cb, new Caller() {
@Override
public void call() throws Exception {
createRestClient(cb).updateDog(dog, BARK);
}
});
}
interface Caller {
public void call() throws Exception;
}
<T> void doCall(AnimalCallback<T> cb, Caller restCaller) {
try {
cb.begin();
restCaller.call();
} catch (final Exception e) {
cb.generalException(e);
}
}
void saveCat(AnimalCallback<Cat> cb, Cat cat) {
doCall(cb, () -> createRestClient(cb).updateCat(cat));
}
void getCow(AnimalCallback<Cow> cb, int id) {
String exp = "{\"tail\":{\"type\": \"" + TAIL + "\"}}";
doCall(cb, () -> createRestClient(cb).getCow(id, exp));
}
void saveDog(AnimalCallback<Dog> cb, Dog dog) {
doCall(cb, () -> createRestClient(cb).updateDog(dog, BARK));
}
my @list = (1 .. 4);
my @mult = map { $_ * 2 } @list;
my @numbers = (8, 2, 5, 3, 1, 7);
my @big_numbers = grep { $_ > 4 } @numbers;
fold(+, 0, [3,5,2,1])
| | |
func start list
reduce { $a < $b ? $a : $b } 1..10
reduce { $a lt $b ? $a : $b } 'aa'..'zz'
reduce { $a + $b } 0, 1..10
reduce { $a . $b } 'a'..'z'
squares = []
for x in range(10):
squares.append(x**2)
squares = [x**2 for x in range(10)]
I call it my billion-dollar mistake.— QuickSort inventor Sir Tony Hoare on his invention of the null reference
It's not always obvious that null means 'no value for this parameter' — heck, as a return value, sometimes it means 'error', or even 'success' (!!), or simply 'the correct answer is nothing'.— Louis Wasserman of the Google Guava team
public static void main(String[] args) {
Map<Integer, String> petEnclosures = newHashMap();
petEnclosures.put(101, "Spot");
petEnclosures.put(102, "Fluffy");
petEnclosures.put(103, null);
petEnclosures.put(104, "Felix");
int enclosure = getEnclosureArg(args);
String petName = petEnclosures.get(enclosure);
System.out.println("Enclosure contains " + petName);
// What does a null petName mean here?
}
static <K, V> Optional<Optional<V>> lookup(Map<K, V> map, K key) {
if (! map.containsKey(key)) {
return Optional.absent();
}
return Optional.of(Optional.fromNullable(map.get(key)));
}
public static void main(String[] args) {
Map<Integer, String> petEnclosures = newHashMap();
petEnclosures.put(101, "Spot");
petEnclosures.put(102, "Fluffy");
petEnclosures.put(103, null);
petEnclosures.put(104, "Felix");
Optional<Optional<String>> enclosureValue = lookup(petEnclosures, enclosure);
if (! enclosureValue.isPresent()) {
printErrorAndExit("Enclosure number invalid");
}
petName = enclosureValue.get().or("nothing");
System.out.println("Enclosure contains " + petName);
}
// Author: Mario Fusco
int readPosInt(Map<String, String> map, String name) {
String value = map.get(name);
if (value == null) return 0;
int i = 0;
try {
i = Integer.parseInt(value);
} catch (NumberFormatException nfe) { }
if (i < 0) return 0;
return i;
}
int readPosIntWithOption(Map<String, String> map, String name) {
return asOption(map.get(name))
.flatMap(FunctionUtils::stringToInt)
.filter(i -> i > 0)
.getOrElse(0);
}
# Author: Fraser Tweedale
class Maybe(object):
@classmethod
def ret(cls, x): return Just(x)
class Nothing(Maybe):
def __init__(self): pass
def __rshift__(self, f): return self
def __repr__(self): return 'Nothing()'
class Just(Maybe):
def __init__(self, x): self._x = x
def __rshift__(self, f):
return f(self._x)
def __repr__(self): return 'Just({!r})'.format(self._x)
def mdiv(n, d):
return Nothing() if not d else Just(n / d)
def divby(d):
return lambda n: mdiv(n, d)
print Just(10) >> divby(2) // Just(5)
print Just(10) >> divby(0) // Nothing()
print Just(10) >> divby(0) >> divby(2) // Nothing()
print Just(16) >> divby(2) >> divby(2) // Just(4)