****December 25, 2021

<aside> 🚧 Just found the idea illustrated in this article is very similar to Chapter 2 in EOPL 🤔

</aside>

Old Memory

About a year ago, I tried to teach Scheme to my childhood playmate who's a 2nd cs student, and once claimed that "what programming languages do is just to offer programmers different ways to abstract data and abstract opeartion on such data."

I still believe so, but with different understandings.

At that time, without dipping into the world of types, I just opened a DrRacket, and told "In functional programming language like Scheme, keyword define is the only way to abstract data and give it a name; keyword lambda is the only way to abstract function that just accepts an input and gives you the output". I convinced myself with these words too, and further said: "of course you can also use define to assign a name to lambda function and manipulate function just like data, and this idea is called first-class function."

"Genius explanation!", I was satisfied, but didn't expect the fact that I would have been being confused by "what the heck is data abstraction" for about half a year after being exposed to typed FP languages like Haskell and Coq.

In this article, I'm going to conclude different ways and styles of abstracting data and try to find some similarities and differences in those languages.

Scheme/Racket

In Racket Guide, data abstraction has been classified into two sections: "Built-In Datatypes" and "Programmer-Defined Datatypes". The former talks about booleans, symbols, lists and hash tables etc. and their respective syntax: anywhere #t and #f will always be recognized as boolean and 'anything will always be recognized as symbol. There will be never ambiguous in those syntax.

It's rather weird that people would like to call it literals (string literals and list literals) in order to distinguish it from mutable data when I just started learning programming, and that complicates things to some extent. So we can assume all data is immutable temporarily.

Now we can look at struct, which lets you define a datatype dynamically. Before looking at how struct will be used, we can try to brainstorm on what needs to be done in order to abstract data.

There are some points I can name:

  1. we should provide a way to build abstraction pattern (struct, datatype).
  2. we should provide a way to create data from abstraction (constructor).
  3. we should provide a way to retrieve data from abstraction (eliminators, accessors).
  4. we should provide a way to differentiate between those abstractions (types).

Racket designers then answer these points one by one, for (1) you can use struct keyword to name an abstraction:

(struct position (x y z))

For (2) you can use position operator to create a position