Is it ok to use closures?

I would like to learn how Java closures work, is it ok to use them in core? It requires Java8 that’s why I’m asking.

One of the reasons we upgraded to Java 8 (besides Java 6 being EOL) was to support new language features.

So yes, it is okay to use closures in openmrs-core (but not in any code that would have to be backported, e.g. bugfixes).

That said, don’t use them pointlessly in a way that impedes code readability. :slight_smile:

For instance, this fragment:

VisitService visitService = Context.getVisitService();
List<Visit> visits = Context.getVisitService().getVisitsByPatient(patient);
for (Visit visit : visits) {
    visitService.voidVisit(visit, "Patient deleted");
}

Can be rewritten as:

final VisitService visitService = Context.getVisitService();
List<Visit> visits = Context.getVisitService().getVisitsByPatient(patient);
visits.forEach(visit -> visitService.voidVisit(visit, "Patient deleted"));

Not much gain, and probably not more readable.

I think closures improve readability when you’re doing things like filtering collections.

E.g. the following, from Person.java, could be a one-liner using closures. (At least it could be a one-liner in Groovy. I don’t know if Java 8 is as expressive for functional idioms.)

public List<PersonAttribute> getActiveAttributes() {
	List<PersonAttribute> attrs = new Vector<PersonAttribute>();
	for (PersonAttribute attr : getAttributes()) {
		if (!attr.isVoided()) {
			attrs.add(attr);
		}
	}
	return attrs;
}

Here’s the one liner, a bit verbose though.

public List<PersonAttribute> getActiveAttributes() {
	return getAttributes().stream().filter(attr -> !attr.isVoided()).collect(Collectors.toList());
}

I wish it was possible to just do:

public List<PersonAttribute> getActiveAttributes() {
    return getAttributes().filter(attr -> !attr.isVoided());
}

I am looking forward to being able to use the new java 8 features (especially closures) but I’m curious if a decision has been made about which OpenMRS platform version will be the first to require java 8.

The decision was made for it to be the OpenMRS Platform 2.0!

1 Like