Skip to main content

Explaining Java's Optional

· 3 min read
TLDR: You should watch this video by Stuart Marks if you wish to learn more about the considerations behind Java's Optional feature and its practical usage.

Motivation

I was introduced to Java's Optional as a response to the billion-dollar mistake made by Tony Hoare, the little monster called "null".

Tony Hoare introduced Null references in ALGOL W back in 1965 "simply because it was so easy to implement", says Mr. Hoare. He talks about that decision considering it "my billion-dollar mistake".

Honestly, I had never considered null as the problematic kid on the block. If there were any thoughts as a Java beginner, I felt that null was extremely helpful in dealing with return types. No suitable object for a method to return? Just return null.

When I learned about Optional, I thought that it is an unnecessary abstraction. Why go through the trouble of boxing up an object and then pass the instructions to the box in order to interact with the value contained in the Optional? This is actually because of the problem of null reference and also issues with having null as a return value.

Problem with null reference

When methods calls are chained together, a method within the chain will cause the following method to throw an exception if it returns null.

methodA().methodB().methodC();
// if methodB returns null, it results in
// null.methodC()
// Not a good idea

The issue with this is that although we can proactively check for null references before invoking a method call, that solution will result in messy and necessarily long code just to ensure a method call is legitimate.

Foo foo = methodA();
if (foo != null) {
Bar bar = foo.methodB();
if (bar != null) {
Coo coo = bar.methodC();
}
}

Problem with the meaning of null

There might be cases where null is returned to signify an empty value. And there might be cases that null is returned to mean invalid. Therefore, it might be confusing to use it as a return type. This often means that the developer has to put in an extra effort to express his intent in the comment or in the documentation. The callers to such code also suffer from having to deal with such functions with care.

Solution provided by Optional

I choose to leave out the details of Optional API and its usage for now as I intend to cover it together with Java's Stream and CompletableFuture, drawing on their similarity of providing a context/abstraction. The details of the Optional API could be found at the official Java API website

Conclusion

Optional is simply a language feature but it is worth learning the concept and reasoning behind its existence. This is because most languages face the same issue and while individual implementations might have different names, they all operate on similar logic and resolution technique.

Recommended guidelines

  • Optional intended to provide is a limited mechanism for method return types where there is a clear need to represent "no result", and where using null for that is overwhelmingly likely to cause errors.
  • Avoid using Optional.get()
  • Avoid using Optional in fields, method parameters, and collections.

Thoughts on teaching

· 8 min read

Motivation

When I completed my first module in NUS, I winced at the thought of applying to be a teaching assistant(TA). I could not understand why one would put himself through reading messy and error-ridden code from students who just started programming. While comments from my TA of that time were helpful, they did not significantly impact my learning.

I changed my impression of TA after my first semester at NUS.

Two things happened

I had a TA who told us "free feel to contact me for any queries and I will respond ASAP". Given that the class size was small(less than 10 students), I made full use of the opportunity to shoot many questions at my TA via the class Discord server. I received responses that were timely and thoughtful. This was great even though I did not require help that often. I had a sense of confidence that no matter what questions that I had in mind, I would have someone who could address them immediately. When I did require help for concepts that were difficult to understand, my TA was able to communicate with me via a Discord voice chat or a screen share. In summary, I had a great "user experience" provided by an excellent teaching staff.

I was also actively involved in a class discussion forum. While I didn't really ask questions, I read through many interesting ones that provoked my thinking. At times I would be drafting an answer to a question raised by another student and I would find loopholes in my justification. Or, when I thought things were supposed to work in a certain way, I would find compilation errors in the example code that I was going to use to illustrate my point. There were many late nights in which I researched and refined my answer to someone's question in the forum. That's when I knew peer learning or learning from what others have to say could be extremely valuable.

I realized that TA could greatly supplement learning and made an impact on how students perceive a module. The second realization is that the students who are taking a module have questions that challenge and poke the module material further. Utilizing that source of learning can make one acquire a deeper understanding of a module, even after taking it. Becoming a TA is a great way to tap on that resource.

My Turn

The application

I am grateful for such TA opportunities available for undergraduate students in NUS. I applied for a TA position in CS2030 Programming Methodology II with the following note to the prof, in case anyone who's interested to see a sample of how I broached the subject:

Hi Prof,

This is Yongliang, a CS student from your module CS2030S. I would like to indicate my interest to be a TA for the next semester.

Coming from background in Python(CS1010X), I was totally not “type aware” and had some difficulties with more complicated languages such as C and Java.

Before the current semester, I took CS2040 with Java and even after that, I had no idea why things were coded in a certain way. For example, why do people

write List<Integer> m = new ArrayList<>(); instead of ArrayList<Integer> m = new ArrayList<>();. So I looked forward to CS2030S very much

before the semester and I would say that this module really make it clear to me three aspects of programming: Java itself, OOP & Functional Programming.

Besides the module content, I also particularly enjoyed meaningful discussions I had with other classmates in our Github issues, where I learned more about type inference

and even things like “target type” and “type witness”. I personally enjoyed this module very much and would love to contribute if possible.

Also taking this opportunity to thank you for your care and support for the students, I appreciate it 😊

The experience

Given that this was my first run as a TA, I would just summarize that the experience was fruitful and humbling. I shall write about it in detail in another blog post.

Reflecting on Teaching Tactics

The whole teaching experience made me realize that teaching is difficult. Like most of the things I do, I then look for ways to improve. I chanced upon the essay "Teaching Tactics" by Eric Hehner near the end of the semester. Eric, who is a computer scientist and a professor at the University of Toronto, wrote about his thoughts and observations on teaching computer science courses. I find the insights expressed by him interesting and would like to discuss those that were surprising to me and gather some actionable items to incorporate into my teaching in the future.

The first point is on "acting stupid". In his essay, Eric described an experiment he conducted. In one of the semesters, he was tasked to teach two sections of the same course. He took on an authoritative attitude with the first class, where he solved all problems and demonstrated his excellent grasp of the material delivered. However, he acted unsure of himself in the second class. He appeared "stupid" and confused when presenting some problems. At the end of the semester, there were two comparisons made by Eric. The first comparison being teaching evaluations. The first class evaluated him to be an excellent professor who knew his stuff. The second class deemed him terrible and incapable to teach the topic. The second comparison being student performance. The first class did not do as well as the second class. While acknowledged by Eric that the standalone experiment would not be able to produce any significant conclusion, I thought it was a creative approach in understanding the best learning environment for students. I felt like I would have acted the same way as students in the two classes.

The second point is on "assignment vs assessment". Briefly speaking, Eric talked about his view that assignments should allow collaborative peer learning and answers should be freely available; Assessments, on the other hand, follow the more traditional examination approach. I thought that the separation is beneficial. As a student, I know that we can't solve all problems and there might be times where we would look for hints online or from our friends. Discussing a particular problem with others would also help us consolidate our learning much better than doing it alone. There is also the issue where we might have given up on attempting a difficult problem after hours of clueless efforts. A nudge from a friend could help tremendously, without revealing the solution itself.

The last point is on "online teaching". Learning has shifted online due to unforeseen circumstances that no one has expected. In his essay, Eric cautioned that simply recording a teacher teaching a class as per offline setting is letting go of the opportunity to harness the prowess of technology. He talked about bite-size videos and making the online sessions interactive by solving problems instead, given that students can view the lecture content beforehand. This got me thinking because I was teaching lab sessions where a problem set will be released and attempted by students in the session. As a TA, I can either do some more sharing of the lecture content that might be useful for students to tackle the problem set, or I can walk around to answer questions when students start to step through the problems. If I spend much time on the former portion, I would unavoidably eat into the time for students to ask me questions during the lab session. This balance is hard to achieve because I realized that explaining the concepts often takes up a lot of time in front of the class.

One possible tweaking, should I be given another chance to TA a programming module, will be that I might look into recording bite-size content to walk through some example code that explains the concepts related. I will then release them before the lab sessions for students to watch. If students are unable to watch it in their own time, they can choose to watch it during the lab session. If they know that they understand certain topics well enough, they can go ahead and attempt questions in the lab and ask me questions if any. This way students have control in deciding what kind of lab setting is most optimum for them. If they find my teaching style and explaining video to be ineffective, they could spare themselves the time and focus on the problem set and the guidance I could provide when they are tackling the questions.

Conclusion

I expect my belief and thinking around the topic of teaching to evolve and therefore will continue to post related content on this area.

Reference:

React Hooks Notes

· 2 min read

Motivation

Building a simple table of reference for the forgetful😂

Based on:



| Hook | Usage |
|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| useState | const [count, setCount] = useState(0); |
| useEffect | useEffect(() => {<br/> console.log("run when mounted & when state changes")<br/>})<br/><br/>useEffect(() => {<br/> console.log("run once when mounted")<br/>},[])<br/><br/>useEffect(() => {<br/> console.log("run when state changes")<br/>},[state])<br/><br/>useEffect(() => {<br/> console.log("set tear down function");<br/> return () => console.log("run when tear down");<br/>}) |
| useContext | // share data without passing props<br/>// create<br/>const data = {state:'happy'}<br/>const DataContext = createContext(data);<br/><br/>// wrap<br/>const App = () => {<br/> \<DataContext.Provider value={data.state}><br/> \<ChildComponent /><br/> \</DataContext.Provider><br/>}<br/><br/>// use<br/>const ChildComponent = () => {<br/> const data = useContext(DataContext);<br/> return \<p>{state}\</p>;<br/>} |
| useRef | // for mutable state that does not re-render UI<br/>const count = useRef(0);<br/>count.current++; <br/><br/>// for element from the DOM<br/>const myBtn = useRef(null);<br/>const click = () => myBtn.current.click();<br/>return (\<button ref={myBtn}>\</button>); |
| useReducer | // dispatch actions to reducer function<br/>const reducer = (state, action) => {<br/> if (action.type === 'increment') { // or switch<br/> return state + 1;}<br/>}<br/><br/>const [state, dispatch] = useReducer(reducer, 0);<br/><br/>return (<br/> \<button onClick={() => dispatch({type: 'increment'})}>+\</button><br/>); |
| useMemo | // for expensive computation to get return values<br/>useMemo(() => {<br/> return count \*\* 2; // expensive<br/>}, [count]) // recompute when count changes |
| useCallback | // for functions<br/>const showCount = useCallback(() => {<br/> console.log(\`change only when \${count} changes\`);<br/>}, [count])<br/><br/>return (<br/> \<div handler = {showCount}>\</div>;<br/>) |