In this video by Rich Hickey, the Clojure creator, he advises to use map to represent data instead of using a class to represent it, as done in Java. I don’t understand how it can be better, since how can the API user know what the input keys are if they are simply represented as maps.

Example:

PersonAPI {
    Person addPerson(Person obj);
    Map<String, Object> addPerson(Map<String, Object> personMap);
}

In the second function, how does the API user know what the needed inputs are for creating a person?

4

Exagg’itive Summary (TM)

You get a few things.

  • Prototypal inheritance and cloning
  • Dynamic addition of new properties
  • Co-existence of objects of different versions (specification levels) of the same class.
    • Objects belonging to the more recent versions (specification levels) will have extra “optional” properties.
  • Introspection of properties, old and new
  • Introspection of validation rules (discussed below)

There’s one fatal drawback.

  • Compiler doesn’t check for misspelled strings for you.
  • Automatic refactoring tools won’t rename property key names for you – unless you pay for the fancy ones.

The thing is, you can get introspection by using, um, introspection. This is what usually happens:

  • Enable reflection.
  • Add a large introspection library into your project.
  • Mark off various object methods and properties with attributes or annotations.
  • Let the introspection library do the magic.

In other words, if you don’t ever need to interface with FP, you don’t have to take Rich Hickey’s advice.

Last, but not the least (nor the prettiest), although using String as property key makes the most straightforward sense, you don’t have to use Strings. Many legacy systems, including Android™, uses integer IDs extensively through the entire framework to refer to classes, properties, resources, etc.

Android is a trademark of Google Inc.


You can also make both worlds happy.

For the Java world, implement the getters and setters as usual.

For the FP world, implement the

  • Object getPropertyByName(String name)
  • void setPropertyByName(String name, Object value) throws IllegalPropertyChangeException
  • List<String> getPropertyNames()
  • Class<?> getPropertyValueClass(String name)

Inside these function, yes, ugly code, but there are IDE plugins that will fill that up for you, using… uh, a smart plugin that reads your code.

The Java side of things will be just as performant as usual. They’ll never use that ugly part of the code. You might even want to hide it from Javadoc.

The FP side of the world can write whatever “leet” code they want, and they typically don’t yell at you about the code being slow.


In general, using a map (property bag) in place of object is commonplace in software development. It is not unique to functional programming or any particular types of languages. It may not be an idiomatic approach for any given language, but there are situations which calls for it.

In particular, serialization/deserialization often requires a similar technique.

Just some general thoughts regarding “map as object”.

  1. You still have to provide a function for validating such a “map as object”. The difference is that “map as object” allows for more flexible (less restrictive) validation criteria.
  2. You can easily add addition fields to the “map as object”.
  3. To provide a specification of the minimum requirement of a valid object, you will need to:
    • List the “minimally required” set of keys expected in the map
    • For each key whose value needs to be validated, provide a value validation function
    • If there are validation rules that need to check multiple key values, provide that as well.
    • What’s the benefit? Providing the specification this way is introspective: you can write a program to query the minimally required set of keys, and to obtain the validation function for each key.
    • In OOP, all of these are rolled up into a black box, in the name of “encapsulation”. In place of machine-readable validation logic, the caller can only read human-readable “API documentation” (if fortunately it exists).

5

That’s an excellent talk by someone who really knows what he’s talking about. I recommend readers watch the entire thing. It’s only 36 minutes long.

One of his main points is that simplicity opens opportunities for change later on. Choosing a class to represent a Person provides the immediate benefit of creating a statically-verifiable API, as you pointed out, but that comes with the cost of limiting opportunities or increasing costs for change and reuse later on.

His point is that using the class might be a reasonable choice, but it should be a conscious choice that comes with full awareness of its cost, and programmers traditionally do a very poor job of noticing those costs, let alone taking them into consideration. That choice should be reevaluated as your requirements grow.

The following are some code changes (one or two of which were mentioned in the talk) that are potentially simpler using a list of maps compared to using a list of Person objects:

  • Sending a person to a REST server. (A function created to put a Map of primitives into a transmittable format is highly reusable and might even be provided in a library. A Person object is likely to need custom code to accomplish the same job).
  • Automatically construct a list of people from a relational database query. (Again, one generic and highly-reusable function).
  • Automatically generate a form to display and edit a person.
  • Use common functions to work with person data that is highly non-homogeneous, like a student versus an employee.
  • Get a list of all persons who reside in a certain zip code.
  • Reuse that code to get a list of all businesses in a certain zip code.
  • Add a customer-specific field to a person without affecting other clients.

We solve these kinds of problems all the time, and have patterns and tools for them, but rarely stop to think about if choosing a simpler, more flexible data representation in the beginning would have made our job easier.

8

  • If the data has little or no behavior, with flexible content that is likely to change, use a Map. IMO, a typical “javabean” or “Data Object” that consists of an Anemic Domain Model with N fields, N setters and N getters, is a waste of time. Don’t try to impress others with your glorified struct by wrapping it in a fancy smancy class. Be honest, make your intentions clear, and use a Map. (Or, if it makes any sense to your domain, a JSON or XML object)

  • If the data has significant actual behavior, a.k.a methods (Tell, Don’t Ask), then use a class. And pat yourself on the back for using real Object Oriented programming :-).

  • If the data has a lot of essential validation behavior and required fields, use a class.

  • If the data has a moderate amount of validation behavior, that’s borderline.

  • If the data fires property change events, that is actually easier and far less tedious with a Map. Just write a little subclass.

  • One main drawback of using a Map is that the user has to cast the values to Strings, ints, Foos, etc. If this is highly annoying and error-prone, consider a class. Or consider a helper class that wraps the Map with the relevant getters.

1

The API for a map has two levels.

  1. The API for maps.
  2. The conventions of the application.

The API can be described in the map by convention. For example the pair :api api-validate can be placed in the map or :api-foo validate-foo could be the convention. The map can even store api api-documentation-link.

Using conventions lets the programmer create a domain specific language that standardizes access across “types” implemented as maps. Using (keys map) allows for determining properties at runtime.

There’s nothing magical about maps and there’s nothing magical about objects. It’s all dispatch.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật