Racket Introduction

by "Blag" - Senior Developer Evangelist

Return to Geeky Thursday

What is Racket?


Racket is multi-paradigm, functional, procedural, modular, object-oriented, logical, reflexive and meta programming language.


It used to be called PLT-Scheme and comes from the Lisp family.


It's Open Source...


It's like nothing you have seen before...

Unless of course...you have seen Lisp or Clojure -;)

How to install Racket?


Racket can be downloaded from here Racket

It's available for Windows, Linux and Mac.

All versions come with DrRacket...an awesome IDE for Racket.

Who uses Racket?


  • Mostly used for education.
  • Clojure is based on Racket (Scheme, Lisp).
  • MIT -> For teaching programming (Now using Python).
  • Square USA -> For the Final Fantasy movie, Real-time CG Content Production.
  • Naughty Dog -> (Uncharted, Crash Bandicoot) as scripting language.

Starting out...


Simply open up your DrRacket....


On the bottom right choose "Determine Language from Source", then "Choose Language"

Choose the first option...


Comments


We have a couple of ways to commnent our code...


				
;This is a commented line...


#|This is a multi-line comment

where can have multiple lines...

and all lines will be commented|#
				

Parentheses


Parentheses are crucial in Racket code...


Everything needs to be wrap up in parenthesis...


This might make the code look weird...but that's how it is -:)


Operations


In Racket, the operator comes first and the parameters follow...


				
(+ 1 2)

3


(expt 2 3)

8


(quotient 7 3)

2


(remainder 7 3)

1
				

Variables


Variables will get a type depending on the value they hold...


				
(define myInteger 5)

myInteger

5


(define myString "Hello Racket!")

myString

"Hello Racket!"
				

We can change the value of variable using set!.


				
(define myInteger 5)

myInteger

5


(set! myInteger 10)

myInteger

10
				

We can define more than one variable at the same time.


				
(define-values (myFirstInt mysecondInt) 
               
               (values 10 20))


myFirstInt

10


mySecondInt

20		
				

String are a fix-sized character arrays


				
(define myString (string-append "Hello " "Racket!"))

myString

"Hello Racket!"


(string-length myString)

13


(substring myString 6 12)

Racket


(define otherString (string-copy myString))

otherString

"Hello Racket!"	
				

Lists


Lists are the most common and used variable type in Racket.


Lists comes with some nice built-in functions...


				
(define myList (list 1 2 3))

myList

'(1 2 3)



(define myStrList '("A", "B", "C"))

myStrList

'("A" , "B" ,"C")
				

We can use "cons" to add values to the beginning of the list...

				
(set! myList (cons 0 myList))

myList

'(0 1 2 3)
				

However, to add values to the end of a list we need to use something else...

				
(set! myList (append myList (cons 4 null)))

myList

'(0 1 2 3 4)
				

Why are we using (cons 4 null)? Can't we just add it?

				
(set! myList (append myList 5))

myList

'(0 1 2 3 4 . 5)
				

Lists must end with a null termination...either "null" or "'()"

Othewise is going to be added as a pair...but...we can do this...

				
(define myList (append '(1 2) '(3 4)))

myList

'(1 2 3 4)
				
				
(length myList)

4



(first myList)

1



(last myList)

'( 2 3 4)



(list-ref myList 2)

3



(list-tail myList 2)

'(3 4)
				

Functions


Function are very important...that's true for every programming language...


Creating functions is not much different from creating a variable...

				
(define (myFunction) (print "Hello Racket!")

(myFunction)

"Hello Racket!"


(define (HelloFunction name) 

        (string-append "Hello " name))

(HelloFunction "Blag")

"Hello Blag"
				

Lambdas


Lambdas allows us to create anonymous functions...


				
((lambda () (print "Hello Racket!")))

"Hello Racket!"



(map (lambda (x) (* x 2)) myList)

'(2 4 6 8)



(define myLambda (lambda () (print "Hello Racket!")))

(myLambda)

"Hello Racket!"
				

Fibonacci list sequence


Finally...we're going to make our first application...


Name your file "Fibonacci.rkt"


				
#lang racket

(define (showFib num)

  (fib num 0 1))




(define (fib num a b)

  ( cond [(and (> a 0) (> num 1)) 

          (append (cons (+ a b) '()) 

                  (fib (sub1 num) (+ a b) a))]

         [(= a 0) 

          (append (append (cons a (cons b '())) 

                          (cons (+ a b) '())) 

                  (fib(sub1 num)(+ a b) b))]

         [(= 1 num) (append '())]))
				

When we run it we're going to see...


Wanna try a big number?


Racket can handle it...last number will be...1046 digits long...

Making an LCD Number App


This is my favorite application of all time...


Name your file "LED_Numbers.rkt"


				
#lang racket

(define (showLED num)

  (display(get_led(toList num) 0 num)))



(define (toList num)

         (map (lambda (elem) 

                (first (cons (make-string 1 elem) 
                
                              '()))) 

              (string->list(number->string num))))
				
				
(define (get_led x n num)


  (cond [(> (length x) 0)

  
         (string-append (list-ref (hash-ref 
         

		leds (string->number(first x))) n) 
			

			 (get_led (rest x) n num))]

         
        [(and (= (length x) 0) (< n 2)) 

        
         (string-append "" "\n" (get_led (toList num) 
         
         
                                (add1 n) num))]

         
        [(and (= (length x) 0) (= n 2))

        
         (string-append "" "\n")]))         
				
				
(define leds (hash '0 (list " _  " "| | " "|_| ") 

                   '1 (list "  " "| " "| ")

                   '2 (list " _  " " _| " "|_  ") 
                   
                   '3 (list "_  " "_| " "_| ")
                   
                   '4 (list "    " "|_| " "  | ") 
                   
                   '5 (list " _  " "|_  " " _| ")
                   
                   '6 (list " _  " "|_  " "|_| ") 
                   
                   '7 (list "_   " " |  " " |  ")
                   
                   '8 (list " _  " "|_| " "|_| ") 
                   
                   '9 (list " _  " "|_| " " _| ")))
				

When we run it we're going to see...


Random Names


This App will generate 100,000 random names using two 16 elements arrays


We will measure the runtime


Name your file "Random_Names.rkt"


				
#lang racket

(require math/array)


(define names (array #["Anne" "Gigi" "Blag" "Juergen" 


                       "Marek" "Ingo" "Lars" "Julia" 
                       
                       
                       "Danielle" "Rocky" "Julien"
                       
                       
                       "Uwe" "Myles" "Mike" "Steven" 
                       
                       
                       "Fanny"]))
				
				
(define last_names (array #["Hardy" "Read" "Tejada" 


                            "Schmerder" "Kowalkiewicz" 

                            
                            "Sauerzapf" "Karg" 

                            
                            "Satsuta" "Keene" 

                            
                            "Ongkowidjojo" "Vayssiere" 

                            
                            "Kylau" "Fenlon" "Flynn" 

                            
                            "Taylor" "Tan"]))
				
				
(define (show_names)

  (for/list ([i (build-list 100000 values)])

    (generate_names)))



(define (generate_names)

    (append (cons (array-ref names 
    
                  (vector(random 16))) '())

            (cons (array-ref last_names 
                  
                  (vector(random 16))) '())))			
			

When we run it we're going to see...


Time is measured in milliseconds...so that's about 49 seconds...

Not the fastest kid in town...

Decimal to Romans


This App will create a Roman Numeral based on a decimal number


This will include some nice commands...


Name your file "Decimal_to_Roman.rkt"


				
#lang racket

(define (showRomans num)

  (get_roman num 0))



(define Romans (hash 1000 "M" 900 "CM" 500 "D" 

                     400 "CD" 100 "C" 90 "XC" 

                     50 "L" 40 "XL" 10 "X"

                     9 "IX" 5 "V" 4 "IV" 1 "I"))
                     

                     
(define SortKeys (sort(hash-keys Romans)>))                     
				
				
(define (get_roman num ctr)

  (let ([roman (list-ref SortKeys ctr)])

  (cond [(>= num roman) (string-append 

                         (hash-ref Romans roman) 

                         (get_roman (- num roman) 
                         
                         ctr))]

        [(and (< num roman) (> num 0)) 
        
              (get_roman num (add1 ctr))]

        [(<= num 0) (string-append "")])))
				

When we run it we're going to see...


Counting Letters


In this example we're going to read a file and count how many time a letter appears...


Call your file "countletters.rkt" (all in lowercase).


Create a file called "readme.txt" with the following text...


"This is a text file that we're going to read it using Racket"


				
#lang racket

(require 2htdp/batch-io) ;for read-lines



(define (contents)

  (list-ref (read-lines "readme.txt") 0))



(define (toList line)

         (sort (map (lambda (elem) 

                      (first (cons 
                      
                             (make-string 1 elem) 
                             
                             '()))) 

                    (string->list line)) string<?))
				
				
(define (counter line)

  (let ((keys (make-hash)))

  (map (lambda (elem) (if (hash-has-key? keys elem)

                        (hash-update! keys elem add1)

                        (hash-set! keys elem 1))) 
                        
                        line )

    (hash-map keys (lambda (k v) (list v k)))))

    
    
(define (countLetters)

  (counter(toList(contents))))    
				

When we run it we're going to see...


Structs


Structs allows us to group different kind of data together.


With Structs we can create new types of data....


In this example we're going to store and retrieve bands and their albums


Call your file "structs.rkt" (all in lowercase).

				
#lang racket

(struct MusicCD (id# band album))



(define Music '())



(define (addCD band album)

  (set! Music (append Music 
              
              (cons(MusicCD add1 band album) '()))))



(define (showAlbums)

  (map(lambda(album) (MusicCD-album album)) Music))



(define (showBands)

  (map(lambda(band) (MusicCD-band band)) Music))
				

When we run it we're going to see...


That's it for now...


I hope you had some fun...


Contact Information


Blag --> blag@blagarts.com

@Blag on Twitter

Go back home...