Skip to content

Instantly share code, notes, and snippets.

@bantonsson
Created October 14, 2011 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bantonsson/1286624 to your computer and use it in GitHub Desktop.
Save bantonsson/1286624 to your computer and use it in GitHub Desktop.
The Kojo Presentation that Phil Bagwell presented at Scala LiftOff London 2011
// Click the Run button in the toolbar above to start the story
//
// =================================================================
//
// The source for the story is provided below
val pageStyle = "color:#1e1e1e; margin:15px;font-size:large"
val centerStyle = "text-align:center;"
val headerStyle = "text-align:center;font-size:110%;color:maroon;"
val codeStyle = "font-size:90%;"
val smallNoteStyle = "color:gray;font-size:95%;"
val sublistStyle = "margin-left:60px;"
showVerboseOutput()
def pgHeader(hdr: String) =
<p style={headerStyle}>
{new xml.Unparsed(hdr)}
<hr/>
</p>
def para (pl:List[String])= for(i <- pl) yield { <p> {i} </p>}
def bullet (pl:List[String])= for(i <- pl) yield { <ul> <li> {i} </li> </ul> }
def title(t:String)= <center> <h1> {t} </h1> </center>
def ipara(pl:List[String])= for(i <- pl) yield Para(<p> {i} </p>)
def ibullet(pl:List[String])= for(i <- pl) yield Para(<ul> <li> {i} </li> </ul>)
def ititle(ti:String)=List(Para( {pgHeader(ti)}))
def icode(cd:String)=List(Para(<p> <pre style={codeStyle}> </pre> </p>, code = {
stSetScript("clearOutput\n" + cd)}))
def icode(cdid:String,pr:String)=List(Para(
<p> {pr} <pre style={codeStyle}> </pre> </p>,
code = { clearOutput;clear;stSetScript(cdEx(cdid))})
)
def goto(px:Int)=if((px<story.pages.length)&&(px>0))story.goto(px,0)
var pages = new collection.mutable.ListBuffer[StoryPage]
var pg: StoryPage = _
var header: xml.Node = _
def link(page: String) = "http://localpage/%s" format(page)
val homeLink = <div style={smallNoteStyle+centerStyle}><a href={link("home#7")}>Start Page</a></div>
// All Code examples in this list
// The examples are preformatted and will display as quoted
var cdEx=Map[String,String]()
def addEx(ex:(String,String))= cdEx=cdEx+ex
addEx("0"->"")
addEx("1g1"->
""" clear
forward(100)
right(120)
forward(100)
right(120)
forward(100)
right(120)
""")
pg= Page("",
body =
<body style={pageStyle}>
{title("A Short Peek at Scala")}
{ bullet(List(
"""Some basic Scala syntax and Concepts"""
,"""Examples of simple DSL for drawing and parsing"""
,"""This is KOJO Created by Lalit Pant, volunteer Math teacher at Himjyoti School for under-privileged girls in Dehradun, India"""
,"Kojo is a little Logo like but based on the Scala language"
))}
</body>
)
pages += pg
addEx("2g0"->"""val msg1 = "hello"
var msg_Block=4.2
var ** = "two asterix"
** = "ask"
""" )
addEx("2g0a"->"""msg1 = "bye" """)
addEx("2g1"->"""println(if (msg1.contains('a')) msg1 else "no a")""")
addEx("2g2"->"""val xa=3;val yb=4
println(if(xa>yb)xa else yb)""")
addEx("2g3"->"""println({val x1 = 2; println(x1); x1 * x1 })""")
addEx("2g4"->"""val time,index:Int=1
var myl:List[List[Int]]= List(List(1,2,3),List(7,6,5,4))""")
addEx("2g5"->"""var vortex=(1).+(2)""")
addEx("2g6"->"""vortex=1 + 2""")
addEx("2g7"->"""// GCD
var gx=36;var gy=16
while(gx!=0){
val t=gx
gx=gy % gx
gy=t
}""")
addEx("2g8"->""" for(i <- 1 to 5){println(i)}
for(i <- 1 to 5 ; j <- 1 until 3){println(i,j)}
for(c <- "abcdef")println(c)
""")
addEx("2g9"->"""def myfoo=println("hello") // returns unit
def mysqr(x:Int)=x*x // simple expression return type inferred
def mymax(x:Int,y:Int)={ if(x>y) x else y}
def gcd(x:Int,y:Int):Int=if(y == 0) x else gcd(y, x % y)
""")
addEx("2g10"->"""val anonmax= (x:Int,y:Int)=>{if (x>y) x else y}
val anongrt= (x:Int,y:Int)=>x > y
""")
addEx("2g11"->"""val nums=List(1,5,3,6,2,8,4,7)
println(nums.sortWith((x,y)=> x > y))
println(nums.sortWith(_ > _)) // _ is a short hand, or place holder
println(nums.sortWith(anongrt)) // functions are just like any other value
println(gcd(96,128))
""")
addEx("2g12","""val s="The quick brown fox jumps over the lazy dog"
println(s.split(' ').reverse.mkString(" "))
""")
addEx("2g12a","""val n = List(19,2,5,1,99,4,8,12,16,3)
println(n.filter(_ % 2 == 1).map(_ / 2)) // only odd divided by two
println(n.foldLeft(0)(_ + _)) // sum all the items
val trans = Map("yes"->"oui","no"->"non","big"->"grand","book"->"livre","a"->"un")
println(trans("yes"))
println("a big book".split(' ').map(trans(_)).mkString(" "))
""")
addEx("2g13"->"""//draw P
def P(joe: Turtle){
joe.setPenColor(blue); joe.penDown
joe.forward(35) ; joe.turn(-90)
joe.forward(18) ; joe.turn(-90)
joe.forward(18) ; joe.turn(-90)
joe.forward(18) ; joe.turn(140)
joe.penUp()
joe.forward(25) ; joe.turn(40)
joe.forward(10) ; joe.turn(90)
}
clear()
invisible()
P(newTurtle(0,0))
""")
addEx("2g14"->"""implicit def TurtleToNTurtle(t:Turtle)=new NTurtle(t)
class NTurtle(val t:net.kogics.kojo.core.Turtle){
var sl=20
def tr(d:Double):NTurtle={t.turn(d);this}
def fw(d:Int):NTurtle={t.forward(d);this}
def fill(c:java.awt.Color)={t.setFillColor(c);this}
def pen(c:java.awt.Color)={t.setPenColor(c);this}
def pen(i:Int):NTurtle={if(i==1)t.penDown else t.penUp;this}
// tr = turn right, fw=forward, pen= pencolor, fill=fillcolor
def P = pen(blue) pen(1) fw 35 tr -90 fw 18 tr -90 fw
18 tr -90 fw 18 tr 140 pen 0 fw 25 tr 40 fw 10 tr 90
def U = pen(1) fw 35 tr -180 fw 35 tr 90 fw 20 tr 90 fw
35 tr 180 fw 35 tr 90 pen(0) fw 10 tr 90
def Z = pen(red) pen(1) tr -30 fw 40 tr 120 fw 20 tr
180 fw 20 tr -120 fw 40 tr 120 fw 20 pen(0) fw 10 tr 90
def L = pen(green) pen(1) fw 35 tr -180 fw 35 tr 90 fw
20 pen(0) fw 10 tr 90
def E = pen(1) fw 35 tr -90 fw 20 tr 180 fw 20 tr 90 fw 17 tr
90 fw 15 tr 180 fw 15 tr 90 fw 18 tr 90 fw 20 pen(0) fw 10 tr 90
}
clear()
invisible()
newTurtle(0,0).P.U.Z.Z.L.E
""")
addEx("2g15"->"""// Parse "23+((14.2+2*13)*30)"
class MPar extends AParser{
// EBNF
// ~ and, | or, ~~ optional, ~* repeated optional
def digit = ("1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"|"0") ~> "digit"
def inum = digit ~*(digit) ~> "Int"
def finum = digit ~*(digit)
def fnum = finum ~ "." ~~(finum) ~> "Float"
def binOp = ("+"|"-"|"/"|"*") ~> "Op"
def expr:Pres = ( fnum | inum | "(" ~ expr ~ ")" ) ~*
(binOp ~ expr) ~> "Expression"
def parse(s:String)= {sin = s; expr}
}
class AParser{
var sin:String=_
var p=0
implicit def strToPres(str:String):Pres={
val ps=p
val slen=str.length
val ok=if(p+slen>sin.length)false
else sin.startsWith(str,p)
p += (if(ok) slen else 0)
new Pres(ps,ok)
}
// inner class to support EBNF clauses
class Pres (ps:Int,var ok:Boolean){
def ~(rh: =>Pres):Pres={if(ok)ok=rh.ok;this}
def |(rh: =>Pres):Pres={
if(ok)this else {
p=ps
rh
}
}
def ~~(rh: =>Pres)=if(ok){rh;this} else this
def ~*(rh: =>Pres)={
if(ok){
var isok=true
do{
val psr=p
isok=rh.ok
if(!isok)p=psr
}while(isok)
}
this
}
def ~> (s: String) = {if(ok){println("at " + ps + " is " + s + " " + sin.substring(ps,p))};this}
}
}
clear
(new MPar).parse("23+((14.2+2*13)*30)")
""")
addEx("2g16"->"""def tree(distance: Double) {
if (distance > 4) {
setPenThickness(distance/7)
setPenColor(color(distance.toInt, Math.abs(255-distance*3).toInt, 125))
forward(distance)
right(25)
tree(distance*0.8-2)
left(45)
tree(distance-10)
right(20)
back(distance)
}
}
clear()
invisible()
setAnimationDelay(60)
penUp()
back(200)
penDown()
tree(90)
""")
pg = IncrPage(
name = "home",
style=pageStyle,
body =ititle("Basic Syntax")++
icode("1g1","Kojo has Turtle graphics, Scala has functions with parameters just like many languages. For functions with no parameters () not needed.")++
icode("2g16","Here is a 'binary' tree, a recursive function, Kojo can be fun and a nice way for 'kids' to play with Scala.")++
icode("2g0","Identifiers are alpha numeric or symbols like * / + - : = ! < > & ^ | Obscure use of symbols not recommended! 'var' mutable, 'val' immutable, notice types inferred, explicit type definitions mostly not needed")++
icode("2g0a","Cannot re-assign to a val, immutable")++
icode("2g1","Only expressions, everything returns a value. 'if' for example returns a value.")++
icode("2g2","Semi-colon only needed for seperating expressions on same line or where ambiguous. ; rarely needed")++
icode("2g3","{ } enclose code blocks. Code blocks result in a value too, the value of the last expression evaluated. Code blocks can be passed as arguments to functions")++
icode("2g4","Type definitions follow the identifier and sub-types are enclosed in []")++
icode("2g5","Everything is an object so should really write")++
icode("2g6","But Scala allows the . and () to be omitted so you can write")++
icode("2g7","'while' gives a familiar flow control")++
icode("2g8","'for' familiar but more powerful")++
icode("2g9","Function, methods and procedures Functions return values, methods have objects, procedures return (unit)")++
icode("2g10","Functions are objects, they can be assigned to variables too.")++
icode("2g11","Can pass functions as arguments to other functions, functions can be anonymous too. They have no name. The underscore _ can be used as a shorthand for a place holder. Saves thinking up names and keystrokes.")++
icode("2g12","Reddit 'Stupid Interview Question', 'Please reverse the word order in a string'. - Luckily Scala has a powerful collections library")++
icode("2g12a","Collections like lists, vectors, hashmaps, strings, arrays, are very powerfull. They provide many useful methods to do commonly required operations on the entire collection, For concurrency immutable collections have tremendous advantage. Side effect free")++
icode("2g13","Task to have the Turtle draw 'Puzzle'. Could create function for each letter. But it is going to be verbose!")++
icode("2g14","Use 'implicit' to create mini DSL to describe letters. Implicit means that the compiler will apply the implicit conversion if the resulting object has the required method. A very powerful technique.")++
icode("2g15","Now a DSL to parse arithmetic expressions like 23+((14.2+2*13)*30). ")
)
pages += pg
pg= Page("",
body =
<body style={pageStyle}>
{title("A Peek at Scala")}
{ bullet(List(
"""Very similar constructs to Java/C++"""
,"""Syntax Sugaring and functional style give expressiveness """
,"""Immutable data structures for Multi-Thread"""
))}
</body>
)
pages += pg
pg= Page("",
body =
<body style={pageStyle}>
{title("A Peek at Scala")}
{ bullet(List(
"""That's all folks"""
))}
</body>
)
pages += pg
val story = Story(pages: _*)
stClear()
stPlayStory(story)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment