#+title: Java CheatSheet
#+macro: blurb Quick reference for an old-school-cool high-level language ^_^
#+author: Musa Al-hassy
#+email: alhassy@gmail.com
#+property: header-args :results none :exports code :eval never-export
#+filetags: java cheat-sheet
#+fileimage: modern-java.png 88% 88%
#+description: Quick reference for an old-school-cool high-level language ^_^
#+macro: src @@latex: \mintinline{java}{$1}@@ @@html: <code class="src src-java"><span style="color: #98971a; font-weight: bold;">$1</span></code>@@
* COMMENT Stuff to relocate to AlBasmal.org :noexport:
#+macro: begin-ignore-html #+html: <!--
#+macro: end-ignore-html #+html: -->
:details: makes a <details> block in HTML, and produces no contents in LaTeX.
#+begin_src emacs-lisp
(org-deftag details (anchor color)
"HTML export a heading as if it were a <details> block; ANCHOR & COLOR are optional
arguments indicating the anchor for this block as well as the background colour of the resulting block.
For example, in my blog, I would use :details_rememberthis_#F47174: to mark a section as
friendly-soft-red to denote it as an “advanced” content that could be ignored
on a first reading of my article.
Incidentally, `orange' and `#f2b195' are also nice ‘warning’ colours.
Sections with this tag are simply hidden for LaTeX exports.
"
(insert "\n#+latex: \\iffalse \n#+html:"
(format "<div>%s <details class=\"float-child\" style=\"background-color: %s\">"
(if anchor (format "<a style=\"width: 1%%;float: left; padding: 0px\" id=\"%s\" href=\"#%s\">🔗</a>" anchor anchor) "")
color)
"<summary> <strong> <font face=\"Courier\" size=\"3\" color=\"green\">"
(s-replace-regexp "^\** " "" o-heading)
"</font> </strong> </summary>")
(org-next-visible-heading 1)
(insert "#+html: </details> </div> \n#+latex: \\fi\n"))
#+end_src
:centerline: Centerlines a section's title (LaTeX only)
#+begin_src emacs-lisp
(org-deftag centerline (NO_ARGS) TODOFIXME "Centerlines a section's title (LaTeX only); otherwise the title is left alone for non-LaTeX backends."
(insert (format "\n#+latex: \\textbf{\\centerline{%s}} \\iffalse \n%s \n#+latex: \\fi \n"
(s-replace-regexp "^\** " "" o-heading)
o-heading)))
#+end_src
:noexport_BACKEND: noexport's a section's title for a given backend
#+begin_src emacs-lisp
(org-deftag noexport (backend)
"noexports a section's title for a given backend (defaulting to HTML)."
(unless backend (setq backend "html"))
(let (begin-ignore end-ignore)
(if (equal backend "pdf")
(setq begin-ignore "\\iffalse" end-ignore "\\fi"))
(if (equal backend "html")
(setq begin-ignore "<!--" end-ignore "-->"))
(insert (format "\n#+%s: %s\n" backend begin-ignore))
(insert o-heading)
(org-next-visible-heading 1)
(insert (format "\n#+%s: %s\n" backend end-ignore))))
#+end_src
* COMMENT Additions to AlBasmala
:Add_to_AlBasmala:
Speaking of local variables, let's always load ones we've already marked as safe
---see the bottom of the source of this file for an example of local variables.
( At one point, all my files had locals! )
#+BEGIN_SRC emacs-lisp :tangle no
(setq enable-local-variables :safe)
#+END_SRC
:End:
* COMMENT Colourful Source Blocks :update_init_with_new_info_if_need_be:
brew install pygments
export PATH="/opt/homebrew/opt/python@3.11/bin/python3.11:$PATH"
--------------------------------------------------------------------------------
Invoke the following with C-c C-c, or better yet place it in your Emacs configuration,
to ensure references are picked up and source code highlighting is turned on
using the Minted package ---which in turn requires the pygmentize system tool.
#+BEGIN_SRC emacs-lisp
(setq org-latex-listings 'minted
org-latex-packages-alist '(("" "minted"))
org-latex-pdf-process
'("pdflatex -shell-escape -output-directory %o %f"
"biber %b"
"pdflatex -shell-escape -output-directory %o %f"
"pdflatex -shell-escape -output-directory %o %f"))
#+END_SRC
For faster pdf generation, consider invoking:
#+BEGIN_SRC emacs-lisp
(setq org-latex-pdf-process
'("pdflatex -interaction nonstopmode -output-directory %o %f"))
#+END_SRC
By default, Org exports LaTeX using the nonstopmode option,
which tries its best to produce a PDF
---which ignores typesetting errors altogether,
and therefore is not necessarily ideal when using LaTeX.
* LaTeX Extra, Local, Setup :ignore:
#+LATEX_HEADER: \def\cheatsheeturl{http://alhassy.com/java-cheat-sheet}
#+LATEX_HEADER: \def\cheatsheetcols{2}
#+LATEX_HEADER: \landscapetrue
#+LATEX_HEADER: \def\cheatsheetitemsep{-0.5em}
#+LATEX_HEADER: \newunicodechar{𝑻}{\ensuremath{T}}
#+LATEX_HEADER: \newunicodechar{⊕}{\ensuremath{\oplus}}
#+LATEX_HEADER: \newunicodechar{≈}{\ensuremath{\approx}}
#+LATEX_HEADER: \newunicodechar{𝒪}{\ensuremath{\mathcal{O}}}
#+LATEX_HEADER: \newunicodechar{𝓈}{\ensuremath{\mathcal{s}}}
#+LATEX_HEADER: \newunicodechar{𝓍}{\ensuremath{x}}
#+LATEX_HEADER: \newunicodechar{𝓎}{\ensuremath{y}}
#+LATEX_HEADER: \newunicodechar{ʸ}{\ensuremath{^y}}
#+LATEX_HEADER: \newunicodechar{⟦}{\ensuremath{\llbracket}}
#+LATEX_HEADER: \newunicodechar{⟧}{\ensuremath{\rrbracket}}
#+LATEX_HEADER: \newunicodechar{ⁿ}{\ensuremath{^n}}
#+LATEX_HEADER: \newunicodechar{¹}{\ensuremath{^1}}
#+LATEX_HEADER: \newunicodechar{⁰}{\ensuremath{^0}}
#+LATEX_HEADER: \newunicodechar{₌}{\ensuremath{_=}}
#+latex_header: \usepackage{tcolorbox}
* COMMENT Contents :TOC:QUOTE:myIgnore:
#+BEGIN_QUOTE
- Extra, Local, Setup
- Project Goal
- CheatSheet Examples
- Why Learn & Relearn?
- Getting Started
- What if it's not good enough?
- What if I want N columns? Or non-landscape? Or multiple formats?
- Colourful Source Blocks
- break
- Basic Equational Support
- Unicode
- Parallel Environment
- break
- Subsection Support
- A new child tree
- Another child tree
- Making ~README.org~
#+END_QUOTE
* COMMENT OG CheatSheet notes
** LaTeX commands ↦ #+latex: \LaTeX
Execute the following block, with C-c C-c anywhere inside it,
to hide all LaTeX specific items away so that, for example, the generated HTML
does not show them.
#+BEGIN_SRC emacs-lisp :results no
(defun my/replace-in-buffer (this that)
"Replace every occurance of regexp ‘this’ with ‘that’
in the current buffer."
(interactive)
(save-excursion
(beginning-of-buffer)
(while (re-search-forward this nil t)
(replace-match that)
))
)
(let (this that)
(dolist (kp '( ( "^[ ]*\\\\room" . "#+latex: \\\\room")
( "^[ ]*\\\\vspace" . "#+latex: \\\\vspace")
( "^[ ]*\\\\newpage" . "#+latex: \\\\newpage")
( "^[ ]*\\\\columnbreak" . "#+latex: \\\\columnbreak")
))
(setq this (car kp))
(setq that (cdr kp))
(my/replace-in-buffer this that)
)
)
#+END_SRC
#+RESULTS:
** Project Goal
#+latex: \hspace{-12pt}
Use the elegant & intuitive Org-mode syntax to produce exquisite reference sheets.
- For example, the boxed section headers here are produced from usual Org headers,
as in * my section; and one may use org-ref for citations, as in nameref:name
#+latex: \vspace{-1em}
Read Org-mode for beginners for a refresher!
- For more see The Compact Org-mode Guide.
Execute C-c C-e l o or M-x compile to produce a nice looking PDF of your reference sheet.
#+latex: \vspace{-0em}
#+begin_center
To learn more, manipulating this source is the way to go!
#+end_center
:myIgnore:
#+latex: \vspace{1em}
Also, opening this file produces a README.md ;-)
Which can then be regenerated on-demand with f11.
:End:
*** COMMENT Org-mode Basics
Read Org-mode for beginners for a refresher!
- For more see The Compact Org-mode Guide.
#+latex: \vspace{1em}
+ Reloading :: To reload a file with updated org settings, press
C-c C-c on a settings line --i.e., one beginning with a #+, to reset the
temporary file cache.
+ Inclusion :: During export, you can include the content of another file.
- Syntax: #+INCLUDE: "⟨fileName⟩" [⟨markup⟩ [⟨language⟩]]
* markup ::= src | example
* language ::= C | haskell | emacs-lisp | ⋯
* If the markup is not given, the text will be assumed to be in
Org mode format and will be processed normally; c.f., Setup files.
- To visit the file, C-c ' while the cursor is on the line with the file name.
- Include only portions of a file by appending with :lines "x-y" where x is the first
line and y is the second-to-last line. Also "-y" for upto but not including line y,
and "x-" for taking line x until the end of the file.
** What if I want N columns? Or non-landscape? Or multiple formats?
At the top, say after the #+INCLUDE: CheatSheet/CheatSheetSetup.org line, add
the following.
#+BEGIN_EXAMPLE org :tangle no
,#+LATEX_HEADER: \def\cheatsheetcols{N}
,#+LATEX_HEADER: \landscapefalse
#+END_EXAMPLE
For example, having three narrow columns is useful for term-heavy or formula heavy sheets.
In contrast, dense sheets may appear less daunting when rendered as single-column in portrait.
Sometimes a double-column portrait is more appropriate.
Press C-c C-c on the following incantation to produce a single column portrait of the cheat sheet.
#+name: make-portrait
#+BEGIN_SRC emacs-lisp :results none
(with-temp-buffer
(insert
"#+EXPORT_FILE_NAME: CheatSheet_Portrait.pdf
,#+LATEX_HEADER_EXTRA: \\landscapefalse \\def\\cheatsheetcols{1}
,#+INCLUDE: CheatSheet.org
")
(let ((org-export-use-babel nil))
(org-mode)
(org-latex-export-to-pdf)
)
)
#+END_SRC
** spacing break :myIgnore:
#+latex: \columnbreak
** spacing break :accomodating_multiple_formats:myIgnore:
#+LATEX: \ifnum\cheatsheetcols=1 \newpage \else \columnbreak \fi
** Unicode
I tend to use a lot of unicode and so this project comes with a unicode
style file. We may add additional support for unicode characters as follows.
#+BEGIN_EXAMPLE org
,#+LATEX_HEADER: \newunicodechar{⊕}{\ensuremath{\oplus}}
#+END_EXAMPLE
Below we demonstrate that loops implement finite quantifications
by showing how the specification of a loop is implemented, unsurprisingly,
using a loop.
A finite quantification can be defined axiomatically
by the empty-range rule and split-off term rules.
Together these form a recursive definition which can be phrased as a loop.
#+begin_parallel org
#+BEGIN_SRC c
@ axiom foldEmptyRange{L} @ axiom foldSplitOffTerm{L}
#+END_SRC
#+latex: \columnbreak
#+BEGIN_SRC c
𝑻 fold(int N, 𝑻* A) {
𝑻 total = identity(⊕);
for(int n = 0; n != N; n++)
total = total ⊕ A[n];
return total;
}
#+END_SRC
#+end_parallel
#+latex: \vspace{-0.5em}
This pseudo-code is reified by giving concrete values
for (𝑻, ⊕, identity) such as (int, +, 0) or (bool, ||, false).
Any monoid will do.
#+LATEX: \ifnum\cheatsheetcols=1 \newpage \else \fi
** Subsection Support
Ideally a cheat sheet is not too hierarchical and so a subsection, as in ** child,
is turned into a rule as follows.
*** A new child tree
Here is the first child's content.
*** Another child tree
Here is the sibling's content.
** spacing COMMENT vfill :myIgnore:
\vfill
** COMMENT Negative space :myIgnore:
#+latex: \vspace{-1em}
* COMMENT Emacs Java Repl
(use-package repl-driven-development)
;; Set “Cx Cj” to evaluate Java code in a background REPL.
(repl-driven-development [C-x C-j]
"jshell --enable-preview -R -ea" ;; enable assertions!
:prompt "jshell>")
// Select this Java snippet, then press “Cx Cj” to evaluate it
import javax.swing.*;
var frame = new JFrame(){{ setAlwaysOnTop(true); }};
JOptionPane.showMessageDialog(frame, "Super nice!");
/ REPL result values are shown as overlays:
2 + 4 / ⇒ 6
https://github.com/alhassy/repl-driven-development/blob/main/repl-driven-development.el#L31-L44
* Abstract :ignore:
:PROPERTIES:
:CUSTOM_ID: Abstract
:END:
#+begin_center
#+html: This is a quick reference of concepts in modern Java.
badge:PDF|colorful_cheat_sheet|success|https://alhassy.com/java-cheat-sheet.pdf|read-the-docs
# badge:license|GNU_3|informational|https://www.gnu.org/licenses/gpl-3.0.en.html|read-the-docs
tweet:https://alhassy.com/java-cheat-sheet
badge:|buy_me_a_coffee|gray|https://www.buymeacoffee.com/alhassy|buy-me-a-coffee
badge:contributions|welcome|green|https://github.com/alhassy/alhassy.github.io/issues
# badge:author|musa_al-hassy|purple|https://alhassy.github.io/|nintendo-3ds
# badge:Warning|Incomplete_DRAFT|red||codeigniter
#+end_center
Modern Java is a strongly-typed, eagery evaluated, case sensative, yet
whitespace insensative language. It uses hierarchies of classes/types
to structure data, but also has first-class support for
functional-style algebraic datatypes.
Java programs are made up of ‘classes’, classes contain methods, and methods contain commands. To just try out a
snippet of code, we can
+ Open a terminal and enter jshell; then enter:
#+begin_src java
1 + 2
import javax.swing.*;
JOptionPane.showMessageDialog(new JFrame(), "Hello, World!");
#+end_src
+ Alternatively, in IntelliJ, click Tools then Groovy Console to try things out!
+ Finally, VSCode allows arbitrary Java code to be sent to a jshell
in the background(!) and it echoes the result in a friendly way.
:MWE:
In order to run a java program, it must have a main method as an entry point.
#+begin_src java
public class LearnJava {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.printf("pi = %.5f", Math.PI); }
}
#+end_src
:End:
** Web reference :ignore:
#+macro: begin-ignore-html #+html: <!--
#+macro: end-ignore-html #+html: -->
#+latex: \vspace{-1em}
begin-ignore-html()
To be terse, lots of content is not shown in this PDF, but is shown in the HTML
version.
end-ignore-html()
* The Philosophy of Classes & Interfaces
Real life objects have properties and behaviour. For example, my cat
has the properties of name and age, and amongst its behaviours are
sleep and meow. However, an apple does not have such features.
The possible features of an object are understood when we classify
it; e.g., my cat is an animal, whereas an apple is food. In Java, a
set of features is known as a src_java[:exports code]{class} and
objects having those features are called “objects of that class”.
Just as int is the type of the value 12, we say a class is a
type of an object.
We tend to think in (disjoint, hierarchical) categories; for example,
in my library, a book can be found in one section, either “Sports” or
“History” or “Trees”. So where should books on the history of football
be located? Or books on the history of trees? My library places such
books under “Sports”, and “Tree” respecively, but then adds a
“historical” tag to them. Likewise, in Java, to say different
kinds of things have a feature in common, we “tag” them with an
src_java[:exports code]{interface}. (Real life tagging is a also known
as multi-class-ificiation.)
#+begin_box "Java's Main Organisational Mechanisms"
| | | With state | Without state |
|-------------------------+---+---------------------+----------------|
| Attributes & properties | | src(class) | src(record) |
| Partial implementations | | src(abstract class) | src(interface) |
#+end_box
** Here is a teaser of nearly all of these packaging mechanisms :details:
#+begin_src java
interface Hospitable {
String name();
default void greet() {
System.out.printf("%s says “Welcome!”", name());
}
}
class Person implements Hospitable {
String name;
int age;
public String name() { return name; }
}
Person me = new Person();
me.name = "Musa";
me.age = 31;
me.greet();
record Person2(String name, int age) implements Hospitable { }
Person2 me = new Person2("Musa", 31);
me.greet();
#+end_src
** “Interfaces are the types of classes” :details:
A module is
a bunch of utilities that can be defined from some shared set of parameters.
Those utilities can be thought of as an interface 𝑰.
Then a module is a function from parameters to an anonymous implementation of an interface.
However, functions that return implementations are essentially records/classes that implement
the interface; i.e.,
#+begin_src java
𝑰 R(params) { return new 𝑰() { 𝑰_𝑶𝑽𝑬𝑹𝑰𝑫𝑬𝑺 }; } ≈ record R(params) implements 𝑰 { 𝑰_𝑶𝑽𝑬𝑹𝑰𝑫𝑬𝑺 }; #+end_src
This equation justifies the phrase “interfaces are the types of records/classes”
since a record declaration (i.e., the right side of the “≈”)
can be converted to an (abstract) module (of type 𝑰) ---i.e., the left side of the “≈”.
** Algebraic Data Types :ignore:details:
Finally, suppose there's something you want to do and there are a number of
ways/configurations to get it done. You could write it as a method in
a src_java[:exports code]{class} with a bunch of if's to account for
all of those ways. Better would be to create an interface, then have
a bunch of classes that implement it: One class for each possible
implementation. Finally, if you know all configurations, you
can move those classes into the definition of the interface
and make it sealed: This is known as an algebraic data-type,
whose kill-feature is that you can use src_java[:exports code]{switch}
to pattern match on instances of the interface.
** ADT example :details_ADTs:
An example 3-level hierarchy that can be easily represented with ADTs
rather than a traditional class hierarchy.
#+BEGIN_SRC dot :file ../images/monsters-adt.png :exports results
digraph {
bgcolor="transparent"
Monster -> {Flying, Ground};
Flying -> {Griffin, Pegasus};
Ground -> {Ogre};
}
#+END_SRC
#+html: <center><image src="../images/monsters-adt.png" width="50%" height="50%" /> </center>
#+begin_src java
sealed interface Monster {
sealed interface Flying extends Monster { }
record Griffin() implements Flying { }
record Pegasus() implements Flying { }
sealed interface Ground extends Monster { }
record Ogre() implements Ground { }
}
#+end_src
Then we can actually use this new type as follows:
#+begin_src java
private static String glare(Monster m) {
return switch (m) {
case Monster.Griffin it -> "Roar";
case Monster.Pegasus it -> "HeeHaw";
case Monster.Ogre it -> "Grrr";
};
}
glare(new Monster.Flying.Griffin()); #+end_src
Or only look at the Flying sub-type:
#+begin_src java
private static int attackDamage(Monster.Flying f) {
return switch (f) {
case Monster.Flying.Griffin it -> 120;
case Monster.Flying.Pegasus it -> 60;
};
}
attackDamage(new Monster.Pegasus()); #+end_src
** COMMENT Mathematically, what does <code>class</code> “mean”? :details_CategoryTheory:
Mathematically, a programming language (i.e., a model of computation with types and programs) is represented by a
category ---see Calculating Functional Programs §1.4. In such a setting, a class denotes a pointed co-algebra $(𝒪, ℴ₀,
𝒸 : 𝒪 → 𝒯(𝒪))$: “classes as modules” is captured by 𝒪 (“the set of objects”), “classes as structure” is captured by the
co-algebra 𝒸, a “new object” is the point ℴ₀, and the functor 𝒯 is the ‘signature/type’ of the class (i.e., its
properties and methods).
* Reads :details:
+ “MOOC” Massive Open Online Course - University of Helsinki
- Useful for learning Java, Python, Haskell, JavaScript.
- I highly reccommend their “full stack” course on web development, with JS!
+ Effective Java, 3rd Edition by Joshua Bloch
+ Seriously Good Software Code that Works, Survives, and Wins
+ Functional Programming in Java Harnessing the Power of Java 8 Lambda Expressions
+ Java Generics and Collections Speed Up the Java Development Process
+ Java 8 Lambdas Pragmatic Functional Programming - Richard Warburton
** COMMENT https://hyperskill.org/join/dee0c003 :5_months_free:
By this link up to 5 months free
** COMMENT More Reads
https://www.youtube.com/watch?v=-JYLuv7mmxM
Excellent 6-part series by Abdul Bari
https://www.baeldung.com/java-8-streams
https://www.capitalone.com/tech/software-engineering/java-streams-explained-simple-example/
https://stackify.com/streams-guide-java-8/
https://livebook.manning.com/book/modern-java-in-action/chapter-5/
https://www.digitalocean.com/community/tutorials/java-8-stream
https://www.oracle.com/technical-resources/articles/java/ma14-java-se-8-streams.html
+ Leetcode is about algorithms, mooc about learning coding and to program.
- Java MOOC. It is a purely introductory course to programming (with Java).
- [Enjoyable!] Massive Open Online Course - Java University of Helsinki
oh my god i LOVE mooc. I only did the course to refresh my memory, but i learned so much more than i did in school.
I also finished it in four weeks. The course didnt burn me out which was surprising. I think its because the lessons were very clear and easy to understand.
probably the best beginner course ive ever taken
- The university of helsinki (the guys behind mooc.fi) has a web dev
with java course online for free, including exercises. It is only
available in finnish, though google translate does a passable job.
https://web-palvelinohjelmointi-21.mooc.fi/osa-1
+ Computer Science: An Interdisciplinary Approach
It’s a great textbook! You can use the web book site as a
supplement or just read from the book. The concepts are clearly
explained and there are a ton of useful exercises that are difficult
and certainly give you many “a ha” moments.
+ https://edabit.com/
+ Codingbat.com has easier questions, that is a good starter for leetcode IMO
CodingBat has really good exercises with multiple test cases (to
help you write unit tests and debug) from very basic to really
challenging, and all the way from booleans and substrings to
lambdas, streams and recursion.
+ [Free] Practice-it is, along with CodingBat, one of the best
websites for beginners to practice and consolidate the fundamentals
of Java. It has more than 600 exercises grouped by different
categories. In my case, it has helped me to strengthen the knowledge
acquired and to continue advancing with this wonderful programming
language.
https://practiceit.cs.washington.edu/
+ https://cscx.org/
Computer Science by Example (cscx.org) is a collection of short programming exercises.
+ Start with CodeWars. Select only level 8 problems and sort by most completed.
+ https://www.coursera.org/learn/algorithms-part1?action=enroll
+ https://www.coursera.org/learn/algorithms-part2
+ https://programmedlessons.org/Java9/index.html#part03
+ https://hyperskill.org/tracks
You can get 9 weeks free by registering with a new email address if you don't mind testing out of concepts you've already completed
Hyperskill is a fairly new resource from Jetbrains (the maker of IntelliJ)
It is based on learning projects, then having prerequisite lessons that need to be learned to successfully complete the project.
+ https://www.codility.com/
+ https://exercism.org/tracks/java
+ https://www.youtube.com/playlist?list=PLE7E8B7F4856C9B19
+ https://docs.oracle.com/javase/tutorial/index.html
I recomend these books:
Java Concurrency in Practice by Brian Goetz
Java Performance - In-Depth Advice for Tuning and Programming Java 8, 11, and Beyond
--------------------------------------------------------------------------------
+ https://eloquentjavascript.net/
This is a book about JavaScript, programming, and the wonders of the digital.
Many of the examples in this cheatsheet were taken from this excellent read!
+ https://exploringjs.com/index.html
Exploring JS: Free JavaScript books for programmers
---E.g., “JavaScript for impatient programmers”
+ https://www.w3schools.com/js/
This tutorial will teach you JavaScript from basic to advanced.
Other bite-sized lessions can be found at: https://masteringjs.io/fundamentals
+ https://learnxinyminutes.com/docs/javascript/
Take a whirlwind tour of your next favorite language. Community-driven!
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
The JavaScript reference serves as a repository of facts about the JavaScript
language. The entire language is described here in detail.
+ https://github.com/you-dont-need/You-Dont-Need-Loops
Avoid The One-off Problem, Infinite Loops, Statefulness and Hidden intent.
Head First Java: A Brain-Friendly Guide 3rd Edition
runestone academy - https://runestone.academy/ns/books/published/csawesome/index.html
This is what I’m using, it simplifies Java into bite size lessons and has immediate hands on practice with coding.
* newpage :ignore:
#+latex: \columnbreak
* COMMENT Objects
In the real world you see and use various objects, and each of them is
belongs to some kind such as toys, food, animals, electronics et
al. In Java, instead of saying what kind of objects, we say what class
of objects. In other words, each object belongs to a class. A class is
like a blueprint of an object. In this chapter you’ll get familiar
with classes - the main constructs of the Java language.
Objects provide ways to group several values into a single
value. Conceptually, this allows us to put a bunch of related things
in a bag and run around with the bag, instead of wrapping our arms
around all of the individual things and trying to hold on to them
separately. These “things” are called properties.
Values of the type object are arbitrary collections of properties. One way to
create an object is by using braces as an expression that lists properties as “name:value”
pairs.
1. Almost all JavaScript values have properties. The exceptions are null and
undefined. If you try to access a property on one of these nonvalues, you get
an error. Properties are accessed using value.prop, dot notation.
* COMMENT Operational vs Denotational Semantics
A programming language consists of two parts: A syntax to indicate how to write programs down,
and a semantics to indicate how to execute programs.
Semantics describes the processes a computer follows when executing a
program in a specific language. This can be shown by describing the
relationship between the input and output of a program (i.e., “axiomatic semantics”)
or how expressions are reduced (i.e., “operational semantics).
Compilers are concernd with “syntax errors” (i.e., invalid expressions);
humans are concerns with semantics. Syntax is determined at compile-time,
whereas semantics is deteremined at run-time: For example, x + 1 is
syntactically a number whenever x is a number, but semantically it may
denote a number, or an overflow error if x is already the largest representable number,
or it may just be x again as is the case in JavaScript (Infinity + 1 = Infinity~).
A similar argument applies to 1 / x.
Type annotations are a way to bring some semantics into the world of syntax.
There are 3 popular approachs to semantics, each useful for particular goals.
For example, operational semantics is helpful for implementing a programming language (in, say, Java or Prolog);
whereas axiomatic semantics is helpful for program verification;
and denotation semantics is helpful for program rewriting (in possibly different programming languages).
Operational Semantics: A type is defined by how its “introduction
rules” (i.e., how instances are created) and its “elimination rules”
(i.e., how instances are used) and how those rules combine together
(so called “computation rules”). There is no “meaning” here: Just how
new syntax is introduced, and how it is operationally executed/reduced
(in an idealised computer). This is presented as a “Type Theory” or a
“Transition System” (which is a machine named “⟶” whose execution rules
are directed by the programming syntax).
This approach encourages “smart
constructors”, i.e., “factory methods”, and exhaustive case analysis;
i.e., src_java[:exports code]{switch}.
Axiomatic Semantics: A type denotes some state, and methods/programs
are characterised by their effect on assertions about program
state. This approach encourages explicit pre-conditions and post-conditions; emphasizing proofs-of-correctness.
Denotational Semantics: A type is defined, characterised, by the
mathematical properties of its instances. That is to say, a type (and
its properties & methods) are considered to denote an object in some
category, namely the category theory denoting the programming language
under consideration. This is also known more generally as
“categorical, or functorial, semantics”, and may be presented as two
categories and a functor “⟦⟧: Syntax → Semantics”. This approach
encourages “compositionality, functoriality”: Working with a complex
structure can be done by working with its parts. The mathematical
properties of this approach allow us to rewrite programs: For example,
requiring type constructors to be functors means we need the law
x.map(f).map(g) = x.map(f⨾g) which, when read left-to-right, is
essentially an optimisation. Likewise, the (homo)morphisms of the
category essentially give us correctness-preserving rewrite rules
for the methods of a type. Simply put, we can start with a program ℰ
that clearly does something we want but is inefficient, then we can
optimise it by rewriting its semantics ⟦ℰ⟧ to, say, ⟦ℱ⟧ which is
clearly more efficient but it's not obvious that it accomplishes the
same goal: The semantic rewrite justifies using ℱ in-place of ℰ.
(Note that ℱ might be a program in a different language that happens to have the same
semantics; this is useful when porting code from one language to another in a correctness-preserving fashion.)
This approach encourages characterising types by their
relationships/methods, rather than by specific implementation matter.
For example, a type of pairs has a specific characterising property,
rather than explicitly two projection functions (e.g.,
a pair of 1-byte src_java[:exports code]{char}s can be encoded
with the 2-byte src_java[:exports code]{short} type).
It is intersting to note that while explicit presentations may differ,
the type theories of operational semantics correspond to the categories
of denotational semantics. In particular, the simply typed lambda calculus
can be treated as a syntax whose semantics is an arbitrary cartesian closed category.
“We may program with type theory, but our programs can have arbitrary non-standard semantics!”
* COMMENT Records
Like tuples, but better.
Good for defining immutable data carriers.
Records are a constrained kind of class, and as a class
it can have constructors and methods.
* Null :details_null:
There is a special value named src_java[:exports code]{null} that
denotes the absence of a meaningful value. Ironically, it is a value
of every type (excluding the primitive types). Here is a neat story
about null.
* TODO COMMENT mention optional alongside null
* Primitive Objects
For performance reasons, there are a handful of types whose values are created
by literals; i.e., “What you see is what you get”. (As such, primitives are a
basic building block which cannot be broken apart; whereas non-primitives (aka
references) are made-up from primitives and other references.) For example, to
create a value of src_java[:exports code]{int} we simply write 5.
There are no instance methods on literals; only a
handful of operator methods. For example, we cannot write 2.pow(3)
to compute 2³, but instead must write src_java[:exports code]{Math.pow(2, 3)}.
Finally, variables of primitive types have default values when not initialised
whereas object types default to src_java[:exports code]{null} ---note: null is a value of all object types, but not of primitive types.
#+latex: \begingroup\scriptsize
#+begin_parallel :bar t
#+begin_src java :exports code
// Declare a new object type
class Person { String name; }
Person obj; / ≈ null (OBJECT)
int prim; / ≈ 0 (PRIMITIVE)
/ Primitives are created as literals
prim = 1; / ≈ 1
/ Objects are created with “new”
obj = new Person(); ≈ a reference,
/ like: Person@66048bfd
/ Primitives are identified by
/ thier literal shape
assert prim == 1;
/ Objects are identified by
/ references to their memory
// locations (not syntax shape!)
assert obj != new Person();
/ Primitives copy values
int primCopy = prim; / ≈ 1
/ Objects copy references
Person objCopy = obj;
// ≈ a reference, like: Person@66048bfd
/ Changing primitive copy has
/ no impact on original
primCopy = 123;
assert prim == 1;
/ Changing object copy also
/ changes the original!
assert obj.name == null;
objCopy.name = "woah"; / Alter copy!
/ Original is altered!
assert obj.name.equals("woah");
#+end_src
# // (Notice we use .equals since String is an object type!)
#+end_parallel
#+latex: \endgroup
:Remark:
Having two references accessing the same object in memory can be dangerous,
since they can alter it unexpectedly. It can also be useful, since the users
of the references can essentially communicate with one another by using
the object as “shared message buffer”.
:End:
** Wrapper Types :details:
Java lets primitives shift back and forth from their literal representations
and the world of reference objects somewhat-harmoniously by automatically
“boxing” them up as objects when need be. This is done by having class
versions of every primitive type; e.g., the primitive src_java[:exports code]{int}
has the class version src_java[:exports code]{Integer}.
#+begin_src java
Integer x = 1; int y = new Integer(2); #+end_src
Primitives require much less memory!
An int requires 32-bits to represent, whereas an Integer requires 128-bits:
The object requires as much space as 4 primitives, in this case.
* Properties and methods have separate namespaces
begin-ignore-html
Properties and methods have separate namespaces ---latex:{\tiny “Java is a Lisp-2 Language”.}
end-ignore-html
:Like_Lisp:
+ → :: Use funcall or apply to call functions bound to variables.
+ → :: Refer to functions outside of function calls by using a sharp quote, #'.
:End:
Below we use the name plus1 in two different definitional roles.
Which one we want to refer to depends on whether we use "dot-notation" with or without parenthesis:
The parentheis indicate we want to use the method.
#+latex: \begingroup\scriptsize
#+begin_src java
class SameNameNoProblem {
public static int plus1(int x){ return x + 1; } public static String plus1 = "+1"; }
class ElseWhere {
String pretty = SameNameNoProblem.plus1;
Integer three = SameNameNoProblem.plus1(2);
}
#+end_src
#+latex: \endgroup
The consequence of different namespaces meta: i.e. of being Lisp-2 are
1. Use src_java[:exports code]{apply} to call functions bound to variables.
2. Refer to functions outside of function calls by using a double colon, ::.
#+latex: \vspace{-.03em}{\centerline{\tiny Let's discuss both of these now... }}
* COMMENT Functions
+ A return keyword without an expression after it will cause the
function to return undefined.
+ Functions that don’t have a return statement at all, similarly return
undefined.
+ One may also define functions using “arrow” notation: (x₀, …, xₙ) => ⋯.
- When there is only one parameter name, you can omit the parentheses around
the parameter list.
- If the body is a single expression, rather than a (multi-line) block in
braces, that expression will be returned from the function.
So, these two definitions of square do the same thing:
#+BEGIN_SRC js
const square1 = (x) => { return x * x; };
const square2 = x => x * x;
#+END_SRC
* Anonymous functions: (arg₁, …, argₙ) → bodyHere latex: {\color{white}.}
#+latex: {\color{white} . } \vspace{-1em}
#+begin_box Functions are formed with the “→” notation and used with “apply”
#+begin_src java
// define, then invoke later on
Function<Integer, Integer> f = x -> x * 2;
f.apply(3) / ⇒ 6
f(3) / invalid!
// define and immediately invoke
((Function<Integer, Integer>) x -> x * 2).apply(3);
// define from a method reference, using “::”
Function<Integer, Integer> f = SameNameNoProblem::plus1;
#+end_src
#+end_box
#+begin_box "Let's make a method that takes anonymous functions, and use it"
#+begin_src java
// Recursion with the ‘tri’angle numbers: tri(f, n) = Σⁿᵢ₌₀ f(i).
public static int tri(Function<Integer, Integer> f, int n) {
return n <= 0 ? 0 : f.apply(n) + tri(f, n - 1);
}
tri(x -> x / 2, 100); // ⇒ Σ¹⁰⁰ᵢ₌₀ i/2 = 2500
/ Using the standard “do nothing” library function
tri(Function.identity(), 100); / ⇒ Σ¹⁰⁰ᵢ₌₀ i = 5050
#+end_src
#+end_box
#+begin_box Exercise! Why does the following code work?
#+begin_src java
int tri = 100;
tri(Function.identity(), tri); // ⇒ 5050
Function<Integer, Integer> tri = x -> x;
tri(tri, 100); // ⇒ 5050
#+END_SRC
# Solution: Recall that methods and variables have different namespaces...
:Solution:
Contextual location determines dispatch: In the expression tri(tri,
100) the first tri must be method whereas the second tri must
be a variable (which happens to refer to a function).
That is, variables and methods have different namespaces.
:End:
#+end_box
#+latex: \room
In Java, everything is an object! (Ignoring primitives, which exist for the purposes of efficiency!)
As such, functions are also objects! Which means, they must have a type: Either some class (or some interface), but which
one? The arrow literal notation x -> e is a short-hand for an implementation of an interface with one abstract
method...
** COMMENT Function, UnaryOperator, Consumer, Predicate, Supplier
The phrase Function<Integer, Integer> is a bit of a mouthful to write each time,
so the standard library provides a terser equivalent:
* Lambdas are a shorthand for classes that implement functional interfaces
Let's take a more theoretical look at anonymous functions.
** Functional Interfaces :centerline:
A lambda expression is a (shorthand) implementation of the only abstract method
in a functional interface ——–which is an interface that has exactly one abstract
method, and possibly many default methods.
For example, the following interface is a functional interface: It has only one abstract method.
#+begin_src java
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) { ... }
static <T> Predicate<T> isEqual(T target) {...}
}
#+end_src
Optionally, to ensure that this is indeed a functional interface, i.e., it has
only one abstract method, we can place @FunctionalInterface above its
declaration. Then the complier will check our intention for us.
** The Type of a Lambda :centerline:
Anyhow, since a lambda is a shorthand implementation of an interface, this means
that what you can do with a lambda depenends on the interface it's impementing!
As such, when you see a lambda it's important to know it's type is not "just a function"!
This mean to run/apply/execute a lambda variable you need to remember that the variable
is technically an object implementing a specific functional interface, which has a single
named abstract method (which is implemented by the lambda) and so we need to invoke that
method on our lambda variable to actually run the lambda. For example,
#+begin_src java
Predicate<String> f = s -> s.length() == 3; boolean isLength3String = f.test("hola"); #+end_src
Since different lambdas may implement different interfaces, the actually method
to run the lambda will likely be different! Moreover, you can invoke any method
on the interface that the lambda is implementing. After-all, a lambda is an object; not just a function.
Moreover, Function has useful methods: Such as andThen for composing functions sequentially,
and Function.identity for the do-nothing function.
** Common Java Functional Types :centerline:
Anyhow, Java has ~40 functional interfaces, which are essentially useful variations around the following 4:
|---------------------+--------+--------------------------------------------------------------------|
| Class | runner | Description & example |
|---------------------+--------+--------------------------------------------------------------------|
| src(Supplier<T>) | get | Makes objects for us; e.g., src(() -> "Hello"!). |
| src(Consumer<T>) | accept | Does stuff with our objects, returning void; |
| | | e.g., src(s -> System.out.println(s)). |
| src(Predicate<T>) | test | Tests our object for some property, returning a boolean |
| | | e.g., src(s -> s.length() == 3) |
| src(Function<T, R>) | apply | Takes our object and gives us a new one; e.g., src(s -> s.length()) |
|---------------------+--------+--------------------------------------------------------------------|
For example, src_java[:exports code]{𝒞::new} is a supplier for the
class 𝒞, and the forEach method on iterables actually uses a consumer
lambda, and a supplier can be used to reuse streams (discussed below).
The remaining Java functional interfaces are variations on these 4
that are optimised for primitive types, or have different number of
inputs as functions. For example, UnaryOperator<T> is essentially
Function<T, T>, and BiFunction<A, B, C> is essentially
Function<A, Function<B, C>> ———not equivalent, but essentially the
same thing.
- As another example, Java has a TriConsumer which is the type of functions that have 3 inputs and no outputs
---since Tri means 3, as in tricycle.
** Eta Reduction: Writing Lambda Expressions as Method References :centerline:
Lambdas can sometimes be simplified by using method reference:
| Method type | | | | |
|-------------+---+-----------------------+---+------------------------------------|
| Static | | $(x,ys) → τ.f(x, ys)$ | ≈ | $τ::f$ |
| Instance | | $(x,ys) → x.f(ys)$ | ≈ | $τ::f$, where τ is the type of $x$ |
| Constructor | | args → new τ<A>(args) | ≈ | τ<A>::new |
For example, src_java[:exports code]{(sentence, word) -> sentence.indexOf(word)} is the same
as src_java[:exports code]{String::indexOf}. Likewise, src_java[:exports code]{(a, b) -> Integer.max(a,
b)} is just src_java[:exports code]{Integer::max}.
+ Note that a class name τ might be qualified; e.g., src_java[:exports code]{x ->
System.out.println(x)} is just src_java[:exports code]{System.out::println}.
* Variable Bindings
Let's declare some new names, and assert what we know about them.
#+BEGIN_center
src_java[:exports code]{Integer x, y = 1, z;}
#+latex: \vspace{-1em}
src_java[:exports code]{assert x = null && y = 1 && z = null;}
#+END_center
latex:\hspace{-1em}
τ x₀ = v₀, …, xₙ = vₙ; introduces 𝓃-new names xᵢ each having value vᵢ of type τ.
- The vᵢ are optional, defaulting to src_java[:exports code]{ 0, false,} '\000',
src_java[:exports code]{null } for numbers, booleans, characters, and
object types, respectively.
- Later we use xᵢ = wᵢ; to update the name xᵢ to refer to a new value
wᵢ.
#+html: <hr>
#+begin_parallel 2 :bar t
There are a variety of update statements:
Suppose $τ$ is the type of $x$ then,
#+latex: \vspace{.7em}
| Augment: x ⊕= y ≈ x = (τ)(x ⊕ y) |
| Increment: x++ ≈ x += 1) |
| Decrement: x-- ≈ x -= 1) |
#+columnbreak:
The operators -- and ++ can appear before or after a name:
Suppose $𝒮(x)$ is a statement mentioning the name $x$, then
#+latex: \vspace{.7em}
| 𝒮(x++) ≈ 𝒮(x); x += 1 |
| 𝒮(++x) ≈ x += 1; 𝒮(x) |
#+end_parallel
Since compound assignment is really an update with a /cast/,
there could be unexpected behaviour when $x$ and $y$ are not both
ints/floats.
:Example:
short a = 0; / 16-bit integer
int b = 123456; 32-bit integer
a = b; Error: Possible loss of converion
a += b; / Now: a == -7616 due to hidden cast!
Long story short, don't use compound assignment operators on byte, short and char types.
:End:
#+html: <hr>
- If we place the keyword src_java[:exports code]{final} before the type τ,
then the names are constant: They can appear only once on the right side of an ‘=’,
and any further occurrences (i.e., to change their values) crash the program.
src_java[:exports code]{ final int x = 1, y; y = 3; } is fine, but changing the
second y to an x fails.
:REPL:
{ final int x = 0; x = 4; }
Need the braces; see https://arbitrary-but-fixed.net/java/jshell/2018/01/17/jshell-final-toplevel-declarations.html
:End:
- We may use src_java[:exports code]{var x = v}, for only one
declaration, to avoid writing the name of the type τ (which may be
lengthy). Java then infers the type by inspecting the shape of
v.
- Chained assignments associate to the right:
| a += b /= 2 * ++c; | ≈ | a += (b /= (2 * ++c)); |
(The left side of an “=”, or “⊕=”, must a single name!)
:Example:
int a, b, c, d = 1, e, f; a += b *= c /= d += e = 2 * ++f;
List.of(a, b, c, d, e, f).equals(List.of(0, 0, 0, 3, 2, 1))
int a, b, c, d = 1, e, f; a += (b *= (c /= (d += (e = (2 * ++f)))));
List.of(a, b, c, d, e, f).equals(List.of(0, 0, 0, 3, 2, 1))
:End:
{class}
* Scope, Statements, and Control Flow :noexport_pdf:
#+begin_parallel 2
#+begin_src java
var x = 1;
{ / new local scope
var x = 200; / “shadows” top x
var y = 300;
assert x + y == 500;
}
/ y is not visible here
assert y == 20; / CRASH!
// The top-most x has not changed
assert x == 1;
#+END_SRC
#+latex: \columnbreak
⊙ Each binding has a scope, which is the part of the program in which
the binding is visible.
#+latex: \vspace{1em}
⊙ local bindings are defined within a block and can only be referenced in it.
#+latex: \vspace{1em}
⊙ Names within a block /shadow//hide bindings with the same name.
#+end_parallel
Besides the assignment statement, we also have the following statements:
+ Blocks: If Sᵢ are statements, then {S₀; …; Sₙ;} is a statement.
+ Conditionals: src_java[:exports code]{if (condition) S₁ else S₂}
+ The “for-each” syntax applies to iterable structures
---we will define our own later.
#+BEGIN_SRC java
for (var x : List.of(1, 2, 3))
System.out.printf("x ≈ %s\n", x);
#+END_SRC
+ While-Loops src_java[:exports code]{ while (condition) S } and for-loops
src_java[:exports code]{ for(init; cond; change) body }.
#+begin_src java
var i = 0; while (i < 10) System.out.println(Math.pow(2, i++));
≈
for(var i = 0; i < 10; i++) System.out.println(Math.pow(2, i));
#+end_src
{for(init; cond; change) body ≈ init;
# while(cond){body; change;}}
Exit the current loop with the src_java[:exports code]{break;}
statement. Similarly, the src_java[:exports code]{continue;}
statement jumps out of the body and continues with the next
iteration of the loop.
* src_java[:exports code]{switch} :noexport_pdf:
Dispatching on a value with switch
#+begin_parallel
⟦Switch Statement⟧
#+begin_src java
switch (x){
case v₁: S₁
⋮
case vₙ: Sₙ
default: Sₙ
}
#+end_src
#+columnbreak:
The src_java[:exports code]{switch} works as follows:
Find the first 𝒾 with x == vᵢ, then execute
{Sᵢ; ⋯; Sₘ;}, if there is no such 𝒾, execute the
default statement Sₙ. Where Sₘ is the first
statement after Sᵢ that ends with break;.
#+end_parallel
E.g., case v: S; case w: S′; break
means do S;S′ if we see v
but we do S′
when seeing both v and w.
#+begin_src java
switch (2){
case 0: System.out.println(0);
case 1: System.out.println(1);
case 2: System.out.println(2);
default: System.out.println(-1);
} #+end_src
#+html: <hr>
⟦Switch Expression⟧
If we want to perform case analysis without the fall-over behaviour, we use
arrows ‘→’ instead of colons ‘:’.
#+begin_src java
switch (2){
case 0 -> 0;
case 1 -> 1;
case 2 -> 2;
default -> -1;
} #+end_src
* Strings
Any pair of matching double-quotes will produce a string literal
---whereas single-quote around a single character produce a
src_java[:exports code]{char}acter value. For multi-line strings, use
triple quotes, """, to produce text blocks.
String interpolation can be done with String.format using %s
placeholders. For advanced interpolation, such as positional
placeholders, use MessageFormat.
#+BEGIN_SRC java
String.format("Half of 100 is %s", 100 / 2) #+END_SRC
+ s.repeat(𝓃) ≈ Get a new string by gluing 𝓃-copies of the string 𝓈.
+ s.toUpperCase() and s.toLowerCase() to change case.
+ Trim removes spaces, newlines, tabs, and other whitespace from the start and
end of a string.
E.g., src_java[:exports code]{" okay \n ".trim().equals("okay")}
+ s.length() is the number of characters in the string.
+ s.isEmpty() ≡ s.length() == 0
+ s.isBlank() ≡ s.trim().isEmpty()
+ String.valueOf(x) gets a string representation of anything x.
+ s.concat(t) glues together two strings into one longer string; i.e., s + t.
* Equality
+ In general, ‘==’ is used to check two primitives for equality, whereas
.equals is used to check if two objects are equal.
+ The equality operator ‘==’ means “two things are indistinguishable:
They evaluate to the same literal value, or refer to the same place in memory”.
+ As a method, .equals can be redefined to obtain a suitable notion
of equality between objects; e.g., “two people are the same if they
have the same name (regardless of anything else)”. If it's not
redefined, .equals behaves the same as ‘==’. In contrast, Java
does not support operator overloading and so ‘==’ cannot be
redefined.
+ For strings, ‘==’ and .equals behave differently:
src_java[:exports code]{new String("x") == new String("x")} is false, but
src_java[:exports code]{new String("x").equals(new String("x"))} is
true! The first checks that two things refer to the same place
in memory, the second checks that they have the same letters in the
same order.
- If we want this kind of “two objects are equal when they have the
same contents” behaviour, we can get it for free by using
src_java[:exports code]{record}s instead of src_java[:exports
code]{class}es.
** COMMENT Equality
References to the same object are equal, whereas different object literals
with the same properties are considered different.
#+BEGIN_SRC js
let a = {value: 10};
let b = a;
let c = {value: 10};
console.log(a == b); console.log(a == c);
a.value = 15;
console.log(b.value); console.log(c.value); #+END_SRC
Since a and b refer to the same object, changing one also changes the value of
the other. However, c only superficially looks the same.
We say different objects with the same properties are “deeply equal”.
#+BEGIN_SRC js
function deepEqual(x, y){
if (typeof x != typeof y) return false;
if (x && y && typeof x != 'object') return x === y; let props = Object.keys(x).concat(Object.keys(y));
for (let p of props) if (! deepEqual(x[p], y[p])) return false;
return true;
}
let obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, {here: 1, object: 2})); console.log(deepEqual(obj, {here: {is: "an"}, object: 2})); console.log(deepEqual(1, 0 + 1)); #+END_SRC
Because of a historical accident, typeof null produces "object".
* Arithmetic
In addition to the standard arithmetic operations, we have src_java[:exports
code]{Math.max(x, y)} that takes two numbers and gives the largest; likewise
src_java[:exports code]{Math.min(x, y)}. Other common functions include
src_java[:exports code]{Math.sqrt, Math.ceil, Math.round, Math.abs,} and
src_java[:exports code]{Math.random()} which returns a random number between 0
and 1. Also, use % for remainder after division; e.g., n % 10 is the right-most
digit of integer $n$, and src_java[:exports code]{n % 2 = 0} exactly when $n$ is
even, and d % 1 gives the decimal points of a floating point number $d$, and
finally: If d is the index of the current weekday (0..6), then d + 13 % 7 is the
weekday 13-days from today.
#+begin_parallel :bar t
#+latex: \begingroup\scriptsize
#+begin_src java
// Scientific notation: 𝓍e𝓎 ≈ 𝓍 × 10ʸ
assert 1.2e3 == 1.2 * Math.pow(10, 3)
#+end_src
#+begin_src java
// random integer x with 4 ≤ x < 99
var x = new Random().nextInt(4, 99);
#+end_src
#+latex:\endgroup
#+end_parallel
#+begin_box "Sum the digits of the integer $n = 31485$"
#+begin_src java
int n = 31485;
int sum = 0;
while (n % 10 != 0) { sum += n % 10; n /= 10; }
assert sum == 3 + 1 + 4 + 8 + 5;
#+end_src
--------------------------------------------------------------------------------
#+latex: \vspace{1em}
A more elegant, “functional style”, solution:
#+latex: \vspace{.3em}
#+begin_src java
String.valueOf(n).chars().map(c -> c - '0').sum();
#+end_src
# Neato.
# // Random number in range min..max
# Math.floor(Math.random() * (max - min) + min)
#+latex: \vspace{1em}
The chars() methods returns a stream of integers (Java
src_java[:exports code]{char}acters are really just integers).
Likewise, src_java[:exports code]{IntStream.range(0, 20)} makes a
sequence of numbers that we can then map over, then sum, min, max, average.
#+end_box
:Ordering_on_chars:
#+begin_src java
assert 'Z' < 'a' && 'a' < 'z';
#+end_src
:End:
* Collections and Streams
Collections are types that hold a bunch of similar data: Lists,
Sets, and Maps are the most popular. Streams are pipelines for
altering collections: Usually one has a collection, converts it to a
stream by invoking .stream(), then performs map and filter
methods, etc, then “collects” (i.e., runs the stream pipeline to get
an actual collection value back) the result.
#+html: <hr>
Lists are ordered collections, that care about multiplicity. Lists
are made with List.of(x₀, x₁, …, xₙ). Indexing, xs.get(𝒾), yields
the 𝒾-th element from the start; i.e., the number of items to skip;
whence xs.get(0) is the first element.
Sets are unordered collections, that ignore multiplicity. Sets are
made with Set.of(x₀, x₁, …, xₙ).
Maps are pairs of ‘keys’ along with ‘values’. Map<K, V> is
essentially the class of objects that have no methods but instead have
an arbitary number of properties (the ‘keys’ of type K), where each
property has a value of type V. Maps are made with Map.of(k₀, v₀,
…, k₁₀, v₁₀) by explicitly declaraing keys and their associated
values. The method ℳ.get(k) returns the value to which the
specified key k is mapped, or null if the map ℳ contains no
mapping for the key. Maps have an entrySet() method that gives a set
of key-value pairs, which can then be converted to a stream, if need
be.
#+html: <hr>
Other collection methods include, for a collection instance 𝒞:
+ src_java[:exports code]{𝒞.size()} is the number of elements in the collection
+ src_java[:exports code]{𝒞.isEmpty()} ≡ src_java[:exports code]{𝒞.size() == 0}
+ src_java[:exports code]{𝒞.contains(e)} ≡ src_java[:exports code]{𝒞.stream().filter(x -> x.equals(e)).count() > 0}
+ src_java[:exports code]{Collections.fill(ℒ, e)} ≅ src_java[:exports code]{ℒ.stream().map(_ -> e).toList()};
i.e., copy list ℒ but replace all elements with e.
+ src_java[:exports code]{Collections.frequency(𝒞, e)}
counts how many times e occurs in a collection.
+ src_java[:exports code]{Collections.max(𝒞)} is the largest value in a collection; likewise min.
+ src_java[:exports code]{Collections.nCopies(n, e)} is a list of $n$ copies of e.
#+html: <hr>
src_java[:exports code]{Stream<τ>} methods
+ src_java[:exports code]{Stream.of(x₀, ..., xₙ)} makes a stream of data, of type τ, ready to be acted on.
+ src_java[:exports code]{s.map(f)} changes the elements according to a function $f : τ → τ′$.
- src_java[:exports code]{s.flatMap(f)} transforms each element into a stream since $f : τ → Stream<τ′>$, then the resulting
stream-of-streams is flattened into a single sequential stream.
- As such, to merge a streams of streams just invoke .flatMap(s -> s).
+ src_java[:exports code]{s.filter(p)} keeps only the elements that satisfy property p
+ src_java[:exports code]{s.count()} is the number of elements in the stream
+ src_java[:exports code]{s.allMatch(p)} tests if all elements satisfy the predicate p
+ src_java[:exports code]{s.anyMatch(p)} tests if any element satisfies p
+ src_java[:exports code]{s.noneMatch(p)} ≡ src_java[:exports code]{s.allMatch(p.negate())}
+ src_java[:exports code]{s.distinct()} drops all duplicates
+ src_java[:exports code]{s.findFirst()} returns an src_java[:exports code]{Optional<τ>} denoting the first element, if any.
+ src_java[:exports code]{s.forEach(a)} to loop over the elements and perform action a.
- If you want to do some action, and get the stream s back for further use,
then use src_java[:exports code]{s.peek(a)}.
** TODO COMMENT Dictionries or maps
An object can also be used as a “key:value” dictionary: When we ‘look-up’ a key,
we find a particular value. E.g., with ages = {mark: 12, james: 23, larry: 42}
we use ages.mark to find Mark's age.
Similarly, objects can be used to simulate keyword arguments in function calls.
* DONE COMMENT Streams are just a lazy, declarative, (mostly side-effect-free), abstraction of design patterns manually implemented with procedural for-loops and if's
When someone sees the stream .map method, it's clear that we are
using the obvious explicit design pattern for transforming elements of
a data source. In contrast, using a for loop means that the entire
data source will be processed even if it's not all needed, and there
may be stateful mutation within the loop body.
--------------------------------------------------------------------------------
Collections are data, and Streams are how we operate on them at a high-level
rather ---than resorting to for loops and if's.
Collections are just containers of objects. There are a bunch of them with slightly different API's, depending on what you need. There is List, Set, Map, ...
Streams are for data transformation and processing. That's what the API is designed for. You can map, filter, reduce, ...
--------------------------------------------------------------------------------0
Streams are for incrementally processing some data source (could be a
collection, or it could be generated on the fly as you process it) and
either doing something on the result, or transforming it to some other
representation.
Think of it like a pipeline of operations being performed on some data
being fed in.
Stuff is accessed in a stream lazily (so only when you demand each
item), unless you use a terminal operation like .toList, .collect,
.reduce, .forEach, .distinct, .count, .iterator, etc. In the latter
case, the entire stream contents will usually get retrieved eagerly
and buffered before the next operation is run. The side effect of this
is that unless your stream contains/ends with a terminal operation,
nothing will be executed.
Streams are designed to let you focus on "what is being done" rather
than "how it is being done" (declarative rather than
imperitive). Doing this lets you write code in a functional style
which ideally reads more closely to how you would explain it as a
human.
--------------------------------------------------------------------------------
Stuff is accessed in a stream lazily (so only when you demand each
item), unless you use a terminal operation like .toList, .collect,
.reduce, .forEach, .distinct, .count, .iterator, etc. In the latter
case, the entire stream contents will usually get retrieved eagerly
and buffered before the next operation is run. The side effect of this
is that unless your stream contains/ends with a terminal operation,
nothing will be executed.
This means that streams can be infinite; e.g., see .generate or .iterate.
Since they are lazy (ie fancy “short circuiting”).
And can only be consumed once.
+ So a method with an argument typed Stream communicates more information
about how the argument is used: Namely, that the argument is used only once!
- C.f., “linear methods” and “linear logic and programming”.
- This use-once constraint is because a stream's data values need not exist
before they are accessed, nor be stored anywhere afterwards. The canonical
example here is a stream of random integers where each is generated upon access.
Such a stream cannot be reused unless we explicitly save the values somewhere.
* Generics
Java only lets us return a single value from a method, what if we want
to return a pair of values? Easy, let's declare record Pair(Object
first, Object second) { } and then return Pair. This solution has
the same problem as methods that just return Object: It communicates
essentially no information ---after all, everything is an object!---
and so requires dangerous casts to be useful, and the compiler wont
help me avoid type mistakes.
#+begin_src java
record Pair(Object first, Object second) { }
Pair myMethod() { return new Pair("1", "hello"); }
int num = (int) (myMethod().first()); #+end_src
It would be better if we could say “this method returns a pair of an integer and a string”, for example.
We can do just that with generics!
#+begin_src java
record Pair<A, B>(A first, B second) { }
Pair<Integer, String> myMethod() { return new Pair<>(1, "hello"); }
int num = myMethod().first();
#+end_src
This approach communicates to the compiler my intentions and so the compiler ensures I don't make any silly typos.
Such good communication also means no dangerous casts are required.
We can use the new type in three ways:
| Pair<A, B> | explicitly providing the types we want to use Pair with |
| Pair<> | letting Java infer, guess, the types for Pair by how we use it |
| Pair | defaulting the types to all be Object |
The final option is not recommended, since it looses type information. It's only allowed
since older versions of Java do not have type parameters and so, at run time, all type
parameters are ‘erased’. That is, type parameters only exist at compile time and so cannot
be inspected/observed at run-time.
* COMMENT Methods
#+latex: {\color{white}.}\vspace{-1em}
+ Warning! Arguments are evaluated before the function is executed.
+ Method definition:
#+BEGIN_SRC java
τ f(τ₁ x₁, …, τₙ xₙ) {
⋮
return e;
}
#+END_SRC
In your home, furniture must be in some room.
Likewise, in Java, methods must be part of some
src_java[:exports code]{class},
src_java[:exports code]{record}, or
src_java[:exports code]{interface}.
- A src_java[:exports code]{class} is a type consisting of some state and some methods.
- A src_java[:exports code]{record} is a "value class": It is like a class, but it has no private hidden state
and cannot be changed. It's like a number: What you see is what you get!
(It's essentially a fancy tuple, pair, or heterogenous-array. More on this later!)
- An src_java[:exports code]{interface} is a collection of method signatures: It is a bunch of method names,
that can be implemented by a class or a record. It may also have src_java[:exports code]{default} definitions
of methods. It is an abstraction with no state.
* COMMENT The this Keyword
:Hide:
Methods are nothing more than properties that hold function values. This is a
simple method:
#+BEGIN_SRC js
let rabbit = {};
rabbit.speak = function(line) {
console.log(`The rabbit says '${line}'`);
};
rabbit.speak("I'm alive."); #+END_SRC
:End:
Usually a method needs to do something with the object it was called on. When a
function is called as a method --- looked up as a property and immediately
called, as in object.method() —-- the binding called this in its body
automatically points at the object that it was called on.
#+BEGIN_SRC js
function speak(line) {
console.log(`The ${this.type} rabbit says '${line}'`);
}
let whiteRabbit = {type: "white", speak};
let hungryRabbit = {type: "hungry", speak};
whiteRabbit.speak("Hola!"); hungryRabbit.speak("Hey!") #+END_SRC
** COMMENT THIS keyword
The keyword this is useful when your code needs to refer to the instance of the object, where this code is running.
Notice that the this keyword allows us to refer to other parts of
this object literal.
* COMMENT Object-Oriented Programming / Inheritance
** Intro :myIgnore:
In English, prototype means a preliminary model of something from which
other forms are developed or copied. As such, a prototypical object
is an object denoting the original or typical form of something.
In addition to their properties, JavaScript objects also have prototype ---i.e.,
another object that is used as a source of additional properties. When an object
gets a request for a property that it does not have, its prototype will be
searched for the property, then the prototype’s prototype, and so on.
+ Object.getPrototypeOf(x) returns the prototype of an object x.
For example, arrays are derived from Array.prototype which is derived from
Object.prototype ---which is the great ancestral prototype, the entity behind
almost all object. Object.prototype provides a few methods that show up in all
objects, such as toString, which converts an object to a string representation.
+ We can use the Object.getOwnPropertyNames(x) to get all the property names
linked to object x.
It is occasionally useful to know whether an object was derived from a specific
class. For this, JavaScript provides a binary operator called instanceof.
Almost every object is an instance of Object.
+ 𝓍 instanceof 𝓎 ≈ Object.getPrototypeOf(𝓍) == 𝓎.prototype
#+BEGIN_SRC js
console.log(Object.getOwnPropertyNames(Object.prototype))
console.log( {} instanceof Object
, [] instanceof Array
, Math.max instanceof Function
, Math.max instanceof Object)
console.log(Object.getPrototypeOf(Object.prototype)); #+END_SRC
** Overriding Methods
(Overriding)
When you add a property to an object, whether it is present in the prototype or
not, the property is added to the object itself. If there was already a property
with the same name in the prototype, this property will no longer affect the
object, as it is now hidden behind the object’s own property.
#+latex: \vspace{-0.5em}
#+begin_parallel org
#+BEGIN_SRC js
Array.prototype.colour = 'purple'
let xs = [1, 2, 3]
console.log(xs.colour) #+END_SRC
#+latex: \columnbreak
#+BEGIN_SRC js
xs.colour = 'green'
console.log(xs.colour)
console.log(Array.prototype.colour)
#+END_SRC
#+end_parallel
#+latex: \vspace{-1em}
** Inheritance
With extends, the new class inherits properties and behavior from the old
class ---it is like Object.create(parentPrototype). The old, parent, class is
called the “super-class” and we refer to it using the super binding.
#+BEGIN_SRC js
class Person {
constructor(name) { this.name = name; }
speak() { console.log(`I am ${this.name}`); }
}
class Teacher extends Person {
constructor(name, topic) { super(name); this.topic = topic; }
speak() { super.speak(); console.log(`I teach ${this.topic}`); }
}
let bobby = new Person('Bob');
bobby.speak();
let bobert = new Teacher('Bob', 'Maths');
bobert.speak(); #+END_SRC
:Hide:
#+BEGIN_SRC js
console.log( bobert instanceof Person
, bobert instanceof Teacher
, bobby instanceof Teacher
, [1, 2] instanceof Array
)
#+END_SRC
:End:
** OOP Summary
So objects do more than just hold their own properties. They have prototypes,
which are other objects. They’ll act as if they have properties they don’t have
as long as their prototype has that property. Simple objects have
Object.prototype as their prototype.
The instanceof operator can, given an object and a constructor, tell you whether
that object is an instance of that constructor.
When implementing multiple classes that differ in only some details, it can be
helpful to write the new classes as subclasses of an existing class, inheriting
part of its behavior.
* COMMENT Class Extension & Overloading
In the real life, every person inherits some features from his or her parents. Likewise, it’s easier to create children
classes that will inherit some common behavior and attributes from a parent class, rather than creating each child class
from scratch every time and copy-pasting the common features.
#+begin_src java
class A { int age() { return 1; } }
class B extends A { int age() { return 2; } }
A a = new B();
a.age(); #+end_src
The actual implementation of age() is determined at run-time: a is an
A which has an age method; moreover, a is specialised kind of
A known as a B, which overrides the implementation of the age
method.
In general, when there are overloads, the most specific overload is used.
#+begin_src java
int height(A a) { return 10; }
int height(B b) { return 20; }
height(a) #+end_src
Note: Properties cannot be overriden, only methods can.
* COMMENT Streams
#+BEGIN_SRC java
class SameNameNoProblem0 {
public static int tri(Function<Integer, Integer> f, int n) {
return n <= 0 ? 0 : f.apply(n) + tri(f, n - 1);
}
public static Function<Integer, Integer> tri = x -> x;
int fiftyFifty = tri(tri, 100); }
#+END_SRC
* COMMENT Lists and List-Like Structures
+ Produce a syntactic, un-evaluated list, we use the single quote:
'(1 2 3).
+ Construction: (cons 'x₀ '(x₁ … xₖ)) → (x₀ x₁ … xₖ).
+ Head, or contents of the address part of the register:
(car '(x₀ x₁ … xₖ)) → x₀.
+ Tail, or contents of the decrement part of the register:
(cdr '(x₀ x₁ … xₖ)) → (x₁ … xₖ).
E.g., (cons 1 (cons "a" (cons 'nice nil))) ≈ (list 1 "a" 'nice) ≈ '(1 "a" nice).
#+latex: \room
Since variables refer to literals and functions have lambdas as literals, we
can produce forms that take functions as arguments. E.g., the standard mapcar
may be construed:
#+BEGIN_SRC emacs-lisp
(defun my-mapcar (f xs)
(if (null xs) xs
(cons (funcall f (car xs)) (my-mapcar f (cdr xs)))))
(my-mapcar (lambda (x) (* 2 x)) '(0 1 2 3 4 5)) (my-mapcar 'upcase '("a" "b" "cat")) #+END_SRC
Pairs: (x . y) ≈ (cons x y).
An association list, or alist, is a list formed of such pairs.
They're useful for any changeable collection of key-value pairs.
The assoc function takes a key and an alist and returns the first pair
having that key. In the end, alists are just lists.
:Try_it_out:
#+BEGIN_SRC emacs-lisp
(setq drinks '( (jasim . coffee) (mary . tea) (jasim . chai) ))
(assoc 'mary drinks) (assoc 'jasim drinks)
(push '(mary . cola) drinks)
(assoc 'mary drinks) #+END_SRC
:End:
#+latex: \room
(Rose) Trees in lisp are easily formed as lists of lists where each inner
list is of length 2:
The first symbol is the parent node and the second is the list of children.
#+latex: \room
Lists are formed by chains of cons cells, so getting and setting are very slow;
likewise for alists. If performance is desired, one uses arrays and hash tables,
respectively, instead. In particular, the performance of arrays and hash tables always
requires a constant amount of time whereas the performance of lists and alists grows in
proportion with their lengths.
However, the size of an array is fixed ---it cannot change and thus grow--- and hash
tables have a lookup cost as well as issues with "hash collisions". Their use is worth
it for large amounts of data, otherwise lists are the way to go.
#+latex: \room
An array is created like a list but using [only square brackets] with getter (aref arr index).
A hash table is created with (make-hash-table) with getter (gethash key table).
:Try_it_out:
#+BEGIN_SRC emacs-lisp
(setq x [0 1 2 nice])
(aref x 3)
(aset x 0 'woah)
(setq drinks (make-hash-table))
(setf (gethash 'mary drinks) 'tea)
(setf (gethash 'mary drinks) 'chai)
(gethash 'mary drinks) #+END_SRC
:End:
#+latex: \room
What if you look up a key and get nil, is there no value for that key or is the value
nil? gethash takes a final, optional, argument which is the value to return when the
key is not found; it is nil by default.
* COMMENT Records
If we want to keep a list of related properties in a list, then we have to remember
which position keeps track of which item and may write helper functions to keep track
of this. Instead we could use a structure.
:More:
A Lisp "Structure, record, object" represents objects with properties as in OOP.
Make a structure like this: (defstruct X (f1 d1) (f2 d2) ... (fn dn)), this creates a record type named X with slots/properties/fields fi having defaults di or nil if di is absent in which case we simply write fi rather than (fi di), moreover it gives the generic constructor (make-X :f1 val1 :f2 val2 ... :fn valn) where any of the fi is optional and assigned nil by default; projection functions X.fi are also provided automatically.
Printing and reading symmetry works as expected with structures and updates happen with setf as expected.
:End:
#+BEGIN_SRC elisp
(defstruct X "Record with fields/slots fᵢ having defaults dᵢ"
(f₀ d₀) ⋯ (fₖ dₖ))
(make-X :f₀ val₀ :f₁ val₁ ⋯ :fₖ valₖ)
(X-p (make-X)) (X-p 'nope)
(defstruct book
title (year 0))
(setq ladm (make-book :title "Logical Approach to Discrete Math" :year 1993))
(book-title ladm) (setf (book-title ladm) "LADM")
(book-title ladm) #+END_SRC
Advanced OOP constructs can be found within the CLOS, Common Lisp Object System;
which is also used as a research tool for studying OOP ideas.
* COMMENT Conditionals
+ Booleans: nil, the empty list (), is considered false, all else
is true.
- Note: nil ≈ () ≈ '() ≈ 'nil.
- (Deep structural) equality: (equal x y).
- Comparisons: As expected; e.g., (<= x y) denotes x ≤ y.
+ (if condition thenExpr optionalElseBlock)
- Note: (if x y) ≈ (if x y nil); \newline better: (when c thenBlock) ≈ (if c (progn thenBlock)).
- Note the else-clause is a ‘block’: Everything after the then-clause is considered to be part of it.
- (if xs ⋯) means “if xs is nonempty then ⋯” is akin to C style idioms on
linked lists.
#+begin_parallel org
#+BEGIN_SRC emacs-lisp
(cond
(test₀
actionBlock₀)
(test₁
actionBlock₁)
…
(t defaultActionBlock))
#+END_SRC
\columnbreak
#+BEGIN_SRC emacs-lisp
(defun go (x)
(pcase x
('bob 1972)
(`(,a ,_ ,c) (+ a c))
(otherwise "Shucks!")))
(go 'bob) (go '(1 2 3)) (go 'hallo) #+END_SRC
#+end_parallel
Avoid nested if-then-else clauses by using a cond statement --a (lazy) generalisation
of switch statements: It sequentially evaluates the expressions testᵢ and
performs only the action of the first true test; yielding nil when no tests are true.
Or use pattern matching; which even allows predicates in the case position ---C-h o ;-)
:Try_it_out:
#+BEGIN_SRC emacs-lisp
(cond
(t (message "first"))
((/ 2 0) (message "crash"))
)
#+END_SRC
:End:
#+latex: \room
Hint: If you write a predicate, think of what else you can return besides t; such as
a witness to why you're returning truth --all non-nil values denote true after all.
E.g., (member e xs) returns the sublist of xs that begins with e.
:Try_it_out:
#+BEGIN_SRC emacs-lisp
(member 1 '(2 1 3 5))
#+END_SRC
:End:
* COMMENT Loops
Let's sum the first 100 numbers in 3 ways.
#+begin_parallel org
#+BEGIN_SRC elisp
(let ((n 100) (i 0) (sum 0))
(while (<= i n)
(incf sum i) (incf i))
(message (format "sum: %s" sum)))
#+END_SRC
\columnbreak
| C | Elisp |
| x += y | (incf x y) |
| x -= y | (decf x y) |
y is optional, and is 1 by default.
#+end_parallel
#+BEGIN_SRC elisp
(let ((result 0) (n 100))
(dotimes (i (1+ n) result) (incf result i)))
(let ((result 0) (mylist (number-sequence 0 100)))
(dolist (e mylist result) (incf result e)))
#+END_SRC
In both loops, result is optional and defaults to nil.
It is the return value of the loop expression.
#+latex: \vspace{-1em}
| Example of Above Constructs |
#+latex: \vspace{-1em}
#+BEGIN_SRC emacs-lisp
(defun my/cool-function (N D)
"Sum the numbers 0..N that are not divisible by D"
(catch 'return
(when (< N 0) (throw 'return 0)) (let ((counter 0) (sum 0))
(catch 'break
(while 'true
(catch 'continue
(incf counter)
(cond ((equal counter N) (throw 'break sum ))
((zerop (% counter D)) (throw 'continue nil))
('otherwise (incf sum counter )) )))))))
(my/cool-function 100 3) (my/cool-function 100 5) (my/cool-function -100 7) #+END_SRC
The special loop construct provides immensely many options to form
nearly any kind of imperative loop. E.g., Python-style ‘downfrom’ for-loops
and Java do-while loops. I personally prefer functional programming, so wont
look into this much.
* COMMENT Exception Handling
We can attempt a dangerous clause and catch a possible exceptional case
--below we do not do so via nil-- for which we have an associated handler.
#+BEGIN_SRC elisp
(condition-case nil attemptClause (error recoveryBody))
(ignore-errors attemptBody)
≈ (condition-case nil (progn attemptBody) (error nil))
(ignore-errors (+ 1 "nope")) #+END_SRC
* COMMENT Types & Overloading
Since Lisp is dynamically typed, a variable can have any kind of data, possibly
different kinds if data at different times in running a program.
We can use type-of to get the type of a given value; suffixing that with p
gives the associated predicate; \newline e.g., function ↦ functionp.
:More:
The following predicates tell us what kind of data a variable
has: numberp, arrayp, characterp,
consp, functionp, hash-tablep, listp, stringp, and symbolp.
:End:
:Details:
Using these we can write functions that behave differently according to the types of
their arguments. However this sort of ad hoc polymorphism can be slow and difficult to
maintain when new types need to be considered. Instead, we could create overloaded
methods using the defmethod command: Lisp decides which one to use by considering the
types, hence the types of each declaration need to differ in at least one argument.
:End:
:Try_it_out:
#+BEGIN_SRC emacs-lisp
(type-of 3) (type-of "3") (type-of 'x) (type-of '(x . y)) (type-of nil) (type-of '(1 2 3)) (type-of [1 2 3]) #+END_SRC
:End:
#+BEGIN_SRC emacs-lisp
(defun sad-add (a b)
(if (and (numberp a) (numberp b))
(+ a b)
(format "%s + %s" a b))
)
(sad-add 2 3) (sad-add 'nice "3")
(cl-defmethod add ((a number) (b number)) (+ a b)) (cl-defmethod add ((a t) (b t)) (format "%s + %s" a b))
(add 2 3) (add 'nice "3") #+END_SRC
While list specific functions like list-length and mapcar may be more efficient than
generic functions, which require extra type checking, the generic ones are easier to
remember. The following generic functions work on lists, arrays, and strings:
+ find-if, gets first value satisfying a predicate.
+ count, finds how often an element appears in a sequence
+ position, finds the index of a given element.
+ some, check if any element satisfies a given predicate
+ every, check if every element satisfies the given predicate
+ reduce, takes a binary operation and a sequence and mimics a for-loop.
Use keyword :initial-value to specify the starting value, otherwise use head of
sequence.
+ sum, add all numbers; crash for strings.
+ length, subseq, sort.
:More:
+ map, like mapcar but works for any sequence with the added ability to transform
sequences to other types: Its first argument could be 'list even if we operate in a
string, so that the list is converted after the operation is mapped.
+ subseq, yields subsequence according to given indices.
+ sort, takes an ordering relation and sorts according to it.
:End:
dash is a modern list library for Emacs that uses Haskell-like names for list operations ;-)
Likewise, s is a useful Emacs string manipulation library.
In-fact, we can write Emacs extensions using Haskell directly.
* COMMENT This is how we do it ---Assertions
An assertion describes what the result of a computation is expected to look like
and throws an exception if those expectations are not met.
#+BEGIN_SRC js
const assert = require('assert');
assert.ok(!null)
console.log('Hello!');
#+END_SRC
#+RESULTS:
: Hello!
* COMMENT Misc experiments :SomeUsefulStuffHere:
** Clean up multiple if/else statements by using a Map
TODO: Take a look on Martin Fowler's book ''Refactoring", he talks about a technique called Replace Conditional With Polymorphism
#+begin_src java
var perform = new Utilities();
if (someCondition(1)) perform.a();
if (someCondition(2)) perform.b();
if (someCondition(3)) perform.c();
boolean someCondition(int i) {
return List.of(1, 3, 4).contains(i);
}
class Utilities {
void a() { System.out.println("A"); }
void b() { System.out.println("B"); }
void c() { System.out.println("C"); }
}
Map<Integer, Consumer<Utilities>> ifs =
Map.of(1, it -> it.a(),
2, it -> it.b(),
3, it -> it.c());
ifs.keySet().stream().filter(k -> someCondition(k)).forEach(k -> ifs.get(k).accept(perform))
#+end_src
** Lisp's apply operator in Java; i.e., JS's spread operator :Misc:
(See also: https://stackoverflow.com/questions/48351536/varargs-as-input-parameter-to-a-function-in-java-8)
- What are varargs behind the scenes? Arrays! https://stackoverflow.com/a/57290781
- How to write Lisp's apply operator in Java? i.e., JS's spread operator? https://stackoverflow.com/a/46388765
#+begin_src java
import java.lang.reflect.*;
class Test {
public static int go(int a, int b, int c) {
return a + b + c;
}
public static int go(int a, int b) {
return a + b;
}
public static int og(String a, Integer b) {
return 12;
}
public static void main () throws java.lang.Exception {
Method goM = Test.class.getMethod("go", Integer.TYPE, Integer.TYPE);
Object[] args = new Object[] {1, 2};
Object res = goM.invoke(null, args);
System.out.println(res);
}
}
@FunctionalInterface
public interface VarArgsBiFunction<S, T, R>{
R apply(S a, T... args);
}
VarArgsBiFunction<Class,Object,Object> spread = (clazzy, arguments) -> {
String fname = (String) arguments[0];
Object[] args = Arrays.stream(arguments).skip(1).toArray();
Class<? extends Object>[] types = Arrays.stream(args).map(x -> x.getClass()).toArray(Class[]::new);
try { Method f = clazzy.getMethod(fname, types);
return f.invoke(null, args);} catch(Exception e) { return null; }
};
spread.apply(Test.class, "og", "hello", 1)
#+end_src
** How to make a ‘fat’ jar file
Do you want to make a regular desktop GUI application? If so, in IntelliJ click File > New... > Project... And pick JavaFX and go from there. It even gives you a sort of Hello World window. You can just launch the app by clicking the green play button.
IntelliJ's new project wizard does a ton to make it easier to get started so you don't have to futz as much with IDE, JDK and build tool configuration. I like to let IntelliJ download and install the JDK too. It's just so much easier.
To build an executable, open the Maven pane and run package under "lifecycle". That creates your runnable jar in the target/ folder.
--------------------------------------------------------------------------------
None of the responses so far answered what you are asking. I will give you the terms you need to look up in order to do what you want to do. First you need to install the Java SDK on your computer. Next you can create a new project in intellij. Intellij manages the packages so you don't have to worry about that for the most part. If you plan on using third party libraries you will need to use Maven or Gradle to easily download and apply them. Once you have coded your project then you need to compile the project into a Jar file. A jar file is like a zip folder full of class files which are compiled Java files. To run you project you will use the Java command in the terminal with the jar name. If you want to double click on an icon to run the project you will need to create a "fat" jar instead which has Java bundled into it. Using these keywords you can look up tutorials on how to do each step. Good luck!
** Searlisation
Neato article: https://yfain.github.io/Java4Kids/#_serialization_turning_an_object_into_bytes
#+begin_quote
11.5. Serialization: Turning an Object Into Bytes
Imagine a building that, with a push of a button, can be turned into a
pile of construction materials. Load all these materials on the truck
and drive to a different city. On arrival push another button, and the
building is magically re-created in its original form. This is what
Java serialization is about, but instead of a building we’ll use a
Java object. By “clicking the serialize button” JVM turns an instance
of an object into a pile of bytes, and “clicking the deserialize
button” re-creates the object.
Why would you need such functionality? Say you are working on a board
game and want to be able to save the current state of the game so the
player can continue playing it tomorrow even if the computer will need
to be rebooted. The program needs to save the state of the game in a
file, and when the player launches the game again, the program should
load the saved state and recreate the situation on the board. Creating
a Java class with fields like player name, level, score, and lives can
be a good way to represent a state of the game.
#+end_quote
A Java object can be serialized if it implements Serializabe
interface. It’s a very simple interface to implement, as it doesn’t
declare any abstract methods. Just add implements Serializable to the
class declaration to make a class serializable.
#+begin_src java
record Winner(String name, int score) implements Serializable { }
var gameState = List.of(new Winner("You", 123), new Winner("Me", 456));
var gamePath = Paths.get("gamestate.ser");
new ObjectOutputStream(Files.newOutputStream(gamePath, StandardOpenOption.CREATE)).writeObject(gameState);
List<Winner> mySavedState = (List<Winner>) new ObjectInputStream(Files.newInputStream(gamePath)).readObject();
#+end_src
you’ll see that it creates a new file gamestate.ser. Open this file in
a text editor, and you’ll see some gibberish. Java serializes objects
in its internal format, which is not meant to be read by people.
** Reading URLs (including local files)
var url = "file:///Users/musa/blog/java-cheat-sheet.html";
var buffer = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
//
for(String line; (line = buffer.readLine()) != null;) System.out.println(line);
There are better ways to read local files, though.
** labels aka jump points
https://stackoverflow.com/questions/3821827/loop-in-java-code-what-is-this-and-why-does-it-compile
these are labels.
They should not even be taught to you. Labels are mostly a thing of the past (like line numbers in BASIC were).
Do yourself a favor and forget them as soon as you are over with that chapter/have done your test.
Basically what they do is define "jump points" to where the code execution is rerouted.
--------------------------------------------------------------------------------
these are essentially a limited form of 'goto' in Java.
There are very rare cases where the use of labels could allow you to write faster control-flow - but unless you're micro-optimising something, you really shouldn't use them. I wouldn't go as far as saying you shouldn't be taught about them, or that you should immediately forget them - you may encounter them in highly tuned, very specialised code (or in cases where people optimise when they shouldn't), but their use is exceptionally rare and justified use even more so.
You can short-circuit a block of code by naming it, then using break to “break out of it”:
N : {S₀; S₁; …; if(someCondition) break N; Sᵏ; Sᵏ⁺¹; … } ≈ S₀; S₁; ⋯; if(!someCondition) { Sᵏ; Sᵏ⁺¹; ⋯ }.
A fair number of those that know about labels, don't realise that they don't just apply to loops.
Both of these are valid Java (assuming I don't have a typo).
#+begin_src java
void m1(int x) {
X1: {
System.out.println(1);
X2: {
System.out.println(2);
if (x %2 == 0) break X1;
else break X2;
}
System.out.println(3);
}
System.out.println(4);
}
m1(3)
void m2(int x) {
X1: if (x > 5) {
System.out.println(1);
if (x < 10) break X1;
System.out.println(2);
}
else X2: {
System.out.println(3);
if (x > 0) break X2;
System.out.println(4);
}
}
#+end_src
** Subclasses
We can be more specific and create another Java class called
PlayStation4. It also belongs to the family of video games, but has
some properties that are specific to the model Play Station 4,
* COMMENT Making README.org
Evaluate the following source block with C-c C-c
to produce a README file.
#+NAME: make-readme
Note that the blurb macro is defined by the user, to provide a terse description of the project.
- Think the one-line statement at the top of a github repo page.
#+BEGIN_SRC emacs-lisp
(with-temp-buffer
(insert
"#+EXPORT_FILE_NAME: README.md
# HTML: <h1> Easily Making CheatSheets with Org-mode </h1>
#+OPTIONS: toc:nil d:nil
# Toc is displayed below at a strategic position.
{{{blurb}}}
:Hide:
This project is to contain a listing of common results in X Theory.
*The repo contains other articles I've written on X Theory;*
*which may be read in a blog-format at:*
https://alhassy.github.io/blog/categories/#Xtheory
:End:
*The listing sheet, as PDF, can be found
[[file:java-cheat-sheet.pdf][here]]*,
while below is an unruly html rendition
---there is also a
badge:beautiful|HTML_webpage|success|https://alhassy.com/java-cheat-sheet|java (•̀ᴗ•́)
# Markdown links: [title](target)
This reference sheet is built from a
[[https://github.com/alhassy/CheatSheet][CheatSheets with Org-mode]]
system.
#+TOC: headlines 2
#+INCLUDE: java-cheat-sheet.org
")
(let ((org-export-use-babel nil))
(org-mode)
(org-md-export-to-markdown)
(pop org-export-exclude-tags)
(add-to-list 'org-export-exclude-tags "TOC")
)
)
#+END_SRC
* COMMENT Making artifacts for the Github Repo :myIgnore: