@@ -55,6 +55,11 @@ and evaluate their results:
5555- : bool = false
5656}
5757
58+ When the REPL is given an expression, it is evaluated to a value. In
59+ the case of OCaml, it prints both the value and its type. OCaml is
60+ able to determine the type of the value @emph{before} evaluating the
61+ expression, thanks to its static type system.
62+
5863Note that the @tt{;;} is not part of the expression syntax, but is a
5964terminator token, signalling to the REPL that the expression is
6065complete and ready to be evaluated.
@@ -75,6 +80,10 @@ and booleans. OCaml uses a @tt{#} prompt, while Racket uses @tt{>},
7580but these differences are immaterial. The languages are essentially
7681the same so far.
7782
83+ Racket doesn't print the type because it does not have a static type
84+ system like OCaml's and it has no way of predicting the type of value
85+ an expression will produce before it's evaluated.
86+
7887
7988@section{Basic operations}
8089
@@ -113,7 +122,7 @@ Languages, like people, descend from their ancestors and inherit some
113122of their properties. In the case of notation, Racket inherits the
114123Lisp (and Scheme) notation for programs. It takes a bit of getting
115124used to, but once aclimated, the notation should feel lightweight and
116- consistent; there is verry little to memorize when it comes to syntax.
125+ consistent; there is very little to memorize when it comes to syntax.
117126
118127So in Racket, we would write:
119128
@@ -136,6 +145,100 @@ Here the parens are indicating a function application. The
136145i.e. @racket[1 ]. Of course, @racket[1 ] isn't a function and can't be
137146applied, hence the error.
138147
148+ @section{Numbers}
149+
150+ Integers in OCaml and Racket look pretty similar, but the two
151+ languages have differing approaches to numbers overall. In OCaml, the
152+ @tt{int} type can represent only fixed bit-width integers. Hence
153+ there is a maximal (and minimal) integer. The variables @tt{max_int}
154+ and @tt{min_int} are bound to these values, respectively:
155+
156+ @ocaml-repl{
157+ # max_int;;
158+ - : int = 4611686018427387903
159+ # min_int;;
160+ - : int = -4611686018427387904
161+ }
162+
163+ What happens when you do something like add 1 to @tt{max_int}? Mess
164+ around and find out.
165+
166+ In Racket, integers behave like the integers you learned about in math
167+ class. There's no largest or smallest one:
168+
169+ @ex[
170+ (add1 4611686018427387903 )
171+ ]
172+
173+ In principle, you can represent arbitrarily large (or small) integers.
174+ In practice, you are bounded by the amount of memory available that
175+ can be used to represent those integers.
176+
177+ Another difference is that in OCaml, integers are disjoint from
178+ floating point numbers. They have different literal syntaxes,
179+ different types, and different operations. If you want to add a
180+ floating point number and an integer together, you'll have to
181+ explicitly convert one of them.
182+
183+ @ocaml-repl{
184+ # 1 +. 3.14 ;;
185+ Error: This expression has type int but an expression was expected of type
186+ float
187+ # (float_of_int 1 ) +. 3.14 ;;
188+ - : float = 4.14000000000000057
189+ }
190+
191+ In Racket, operations work on different kinds of numbers and can be
192+ used without conversions:
193+
194+ @ex[
195+ (+ 1 3.14 )
196+ ]
197+
198+ Moreover, Racket has certain kinds of numbers that are not supported
199+ (without using libraries) in OCaml. For example, you can write
200+ @racket[2/3 ] to mean the rational number two-thirds in Racket:
201+
202+ @ex[
203+ 2/3
204+ ]
205+
206+ It's worth noting that while this may look like division, it's not: we
207+ are writing the literal number @racket[2/3 ]. The division operator,
208+ like every other operation, would have to be written using prefix
209+ notation with parentheses:
210+
211+ @ex[
212+ (/ 2 3 )
213+ ]
214+
215+ But notice that division produces exact rational results, not a
216+ floating point approximation as in OCaml:
217+
218+ @ocaml-repl{
219+ # 2. /. 3. ;;
220+ - : float = 0.66666666666666663
221+ }
222+
223+ It's also possible to use complex numbers in Racket. The
224+ @racket[sqrt] operation computes the square root of its argument:
225+
226+ @ex[
227+ (sqrt 16 )
228+ (sqrt 25 )
229+ ]
230+
231+ But when given a negative number, it computes a complex result:
232+
233+ @ex[
234+ (sqrt -1 )
235+ (sqrt -100 )
236+ ]
237+
238+ Mostly we will be sticking to using integers and will not taking
239+ advantage of the advanced numeric system of Racket, but it's worth
240+ knowing it's there.
241+
139242
140243@section{Functions}
141244
@@ -365,7 +468,10 @@ second component is a list (either the empty list or another
365468pair whose second component is a list, etc.).
366469
367470You can make pairs out of any kind of element and you can
368- make lists out of any kind of elements. We can precisely
471+ make lists out of any kind of elements.
472+
473+ @;{
474+ We can precisely
369475define these sets as:
370476
371477@#reader scribble/comment-reader
@@ -389,6 +495,7 @@ Or, to give more useful parameterized definitions:
389495;; type (Pairof A B) =
390496;; | (cons A B)
391497)
498+ }
392499
393500The functions @racket[first] and @racket[rest] operate on
394501non-empty @emph{lists}, producing the first element of the
@@ -510,10 +617,11 @@ We can do the same in Racket:
510617]
511618
512619
513- @section{Datatypes }
620+ @section{Structures }
514621
515- OCaml has the ability to declare new datatypes. For example,
516- we can define type for binary trees of numbers:
622+ OCaml has the ability to declare new datatypes using records and
623+ variants. For example, we can define type for binary trees of
624+ integers:
517625
518626@ocaml-repl{
519627# type bt =
@@ -590,8 +698,8 @@ val bt_height : bt -> int = <fun>
590698- : int = 2
591699}
592700
593- We do something very similar in Racket using @emph{
594- structures}. A structure type is like a (single) variant of
701+ We do something very similar in Racket using @emph{structures}.
702+ A structure type is like a (single) variant of
595703a data type in OCaml: it's a way of combining several things
596704into one new kind of value.
597705
@@ -612,18 +720,18 @@ constructor takes 3 arguments.
612720(node 3 (node 2 (leaf) (leaf)) (leaf))
613721]
614722
723+ With these structure definitions in place , we can represent binary
724+ trees of integers just as in OCaml, and functions that process binary
725+ trees look very similar:
726+
727+ @;{
615728There is no type system in Racket, but we can conceptually still
616729define what we mean in a comment. Just like in OCaml, we can use
617730pattern matching to discriminate and deconstruct:
731+ }
618732
619733@ex[
620- (code:comment "type Bt = (leaf) | (node Integer Bt Bt) " )
621- (define (bt-empty? bt)
622- (match bt
623- [(leaf) #t ]
624- [(node _ _ _ ) #f ]))
625- (bt-empty? (leaf))
626- (bt-empty? (node 5 (leaf) (leaf)))
734+ ;(code:comment "type Bt = (leaf) | (node Integer Bt Bt)")
627735(define (bt-height bt)
628736 (match bt
629737 [(leaf) 0 ]
@@ -633,7 +741,17 @@ pattern matching to discriminate and deconstruct:
633741(bt-height (leaf))
634742(bt-height (node 4 (node 2 (leaf) (leaf)) (leaf)))
635743]
636-
744+
745+ One thing to note here is that in OCaml, the @tt{Node} and @tt{Leaf}
746+ constructors are part of the @tt{bt} type. You can't construct a node
747+ that doesn't conform to the @tt{bt} type definition and you can't
748+ re-use these constructors in the definition of some other type.
749+
750+ This isn't the case in Racket. Structures, like pairs and lists, can
751+ contain any kind of value. So while it doesn't conform to our idea of
752+ what a binary tree is: @racket[(node #t "fred " 9 )] is a value in
753+ Racket.
754+
637755@section{Symbols}
638756
639757One of the built-in datatypes we will use often in Racket is
@@ -670,12 +788,13 @@ to have not been used so far each time you call it:
670788]
671789
672790
791+ @;{
673792They can be used to define ``enum'' like datatypes:
674793
675794@ex[
676795(code:comment "type Flintstone = 'fred | 'wilma | 'pebbles " )
677796]
678-
797+ }
679798
680799You can use pattern matching to match symbols:
681800
@@ -761,14 +880,10 @@ Functions operating on such trees could be defined as:
761880]
762881}
763882
764- @section{Quote, quasiquote , and unquote }
883+ @section{Quote}
765884
766885One of the distinguishing features of languages in the Lisp family
767- (such as Scheme and Racket) is the @racket[quote ] operator and its
768- closely related cousins @racket[quasiquote ], @racket[unquote ], and
769- @racket[unquote-splicing ].
770-
771- Let's start with @racket[quote ].
886+ (such as Scheme and Racket) is the @racket[quote ] form.
772887
773888The ``tick'' character @racket['d ] is used as a shorthand for
774889@racket[(code:quote d)].
@@ -827,6 +942,7 @@ The kind of things you can construct with the @racket[quote] form are
827942often called @bold{s-expressions}, short for @bold{symbolic
828943expressions}.
829944
945+ @;{
830946We can give a type definition for s-expressions:
831947
832948@#reader scribble/comment-reader
@@ -838,6 +954,7 @@ We can give a type definition for s-expressions:
838954;; | Symbol
839955;; | (Listof S-Expr)
840956)
957+ }
841958
842959The reason for this name is because anything you can write
843960down as an expression, you can write down inside a
@@ -857,7 +974,7 @@ We will be using (subsets of) s-expressions extensively as our data
857974representation of AST and IR expressions, so it's important to gain a
858975level of fluency with them now.
859976
860-
977+ @ ;{
861978Once you understand @racket[quote ], moving on to @racket[quasiquote ],
862979@racket[unquote ], and @racket[unquote-splicing ] are pretty
863980straight-forward.
@@ -909,7 +1026,9 @@ equivalent to @racket[(list '+ 1 3 4)], or
9091026
9101027If the expression inside the @racket[unquote-splicing ]
9111028produces something other than a pair, an error is signalled.
1029+ }
9121030
1031+ @;{
9131032@section{Poetry of s-expressions}
9141033
9151034The use of structures lets us program in a style very
@@ -1009,6 +1128,12 @@ Moreover, we can embrace quasiquotation at the type-level and write:
10091128@ex[
10101129(code:comment "type Bt = `leaf | `(node ,Integer ,Bt ,Bt) " )
10111130]
1131+ }
1132+
1133+ @;section{Thinking about types}
1134+
1135+
1136+
10121137
10131138@section{Testing, modules, submodules}
10141139
0 commit comments