Skip to content

Commit

Permalink
merge master and new_text branches
Browse files Browse the repository at this point in the history
  • Loading branch information
nusco committed Nov 25, 2012
2 parents 2f2f59c + 3815723 commit 57890f5
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 95 deletions.
4 changes: 2 additions & 2 deletions resources/public/javascript/tryclojure.js
Expand Up @@ -166,8 +166,8 @@ var controller;

$(document).ready(function() {
controller = $("#console").console({
welcomeMessage:'Enter some Clojure code to be evaluated.',
promptLabel: 'Clojure> ',
welcomeMessage:'Give me some Clojure:',
promptLabel: '> ',
commandValidate: onValidate,
commandHandle: onHandle,
autofocus:true,
Expand Down
12 changes: 2 additions & 10 deletions resources/public/tutorial/page1.html
@@ -1,15 +1,7 @@
<p>
This tutorial isn't entirely complete yet. More fun content is to be written. Stay tuned.
I'll take you on a 5-minutes tour of Clojure, but feel free to experiment on your own along the road!
</p>

<p>
Above, you have your REPL. Please try the examples as we go along, and by all means experiment
with concepts independently. Should you refuse, you will promptly be IP banned from this
website, and a teddy bear will eat your candies. ctrl+v to paste and ctrl+c to copy like you
would normally expect, but you can't paste with your browser's right-click menu.
</p>

<p>
You can type 'next' to move forward, 'back' to go back to the previous step, and 'restart' to
restart the tutorial. Go ahead and type 'next' to begin
You can type <code>next</code> to skip forward, <code>back</code> to return to the previous step, and <code>restart</code> to get back to the beginning. Let's get started: type <code>next</code>.
</p>
35 changes: 20 additions & 15 deletions resources/public/tutorial/page10.html
@@ -1,30 +1,35 @@
<p>Awesome. Now you can call this function just like we called the old square function.</p>
<p>
Success! Now you can call this new <code>square</code> function just like you called the old <code>square</code> function.
</p>

<p>
Clojure has a great set of immutable and persistent data structures. Vectors, lists, maps, sets,
I get chills.
By now, you know that lists are quite important in Clojure.
But Clojure also has other data structures:
</p>

<p>
Vectors: <code class="expr">[1 2 3 4]</code><br/>
Maps: <code class="expr">{:foo "bar" 3 4}</code><br/>
Lists: <code class="expr">'(1 2 3 4)</code><br/>
Sets: <code class="expr">#{1 2 3 4}</code><br/>
Vectors and lists are sequential and ordered collections. You'll see vectors used much more than lists.
Maps are typical hash-maps - unordered collections indexed by keys. The keys can be any object. Here,
we've used a keyword, <code>:foo</code> as a key. Keywords make excellent keys. We also used a number.
Sets are mathematical sets.
</p>

<p>
Clojure's collections are one of the most imporant parts of Clojure. Being a functional language, Clojure
encourages immutability and as little state as possible. Therefore, instead of for loops mutating variables
and such, most of the time you'll see higher order functions doing transformations on immutable data and
returning new collections rather than ever modifying the old one.
Vectors and lists are sequential and ordered collections.
Sets are not ordered, and they cannot contain duplicate elements.
Maps are key-value collections, where the keys can be any object.
Here, we've used what Clojure calls a <em>keyword</em> (<code>:foo</code>) for one of the keys, and a number for the other key.
</p>

<p>
Now I'll tell you another thing that may surprise you: Clojure collections are <em>immutable</em> - they can never change.
When you do anything on a list, including adding and removing elements, you actually get a brand new list.
(Fortunately, Clojure is amazingly efficient at creating new lists).
In general, Clojure encourages you to have as little mutable state as possible.
For example, instead of "for" loops and other state-changing constructs, most of the time you'll see functions doing transformations on immutable data and returning new collections, without changing the old one.
</p>

<p>
A prime example of this is <code>map</code>. We can use map, a higher order function (which is a function
that takes functions as arguments or returns functions), to 'map' a function to every element of a sequence.
Let's use this to increment each number in a vector. Type <code class="expr">(map inc [1 2 3 4])</code> to continue.
A prime example of this is <code>map</code>. <code>map</code> is a <em>higher order function</em>, which means that it takes another function as an argument.
For example, you can ask <code>map</code> to increment each number in a vector by passing it the <code>inc</code> function, followed by the vector.
Try it for yourself: type <code class="expr">(map inc [1 2 3 4])</code> to continue.
</p>
13 changes: 8 additions & 5 deletions resources/public/tutorial/page11.html
@@ -1,8 +1,11 @@
<p>Excellent work.</p>
<p>Great job!</p>

<p>
Well, that's all there is right now. This tutorial is still a work in progress, and I'm working on more
steps. If anybody wants to contribute, you can find a link to the Github repository on the 'about' page.
Furthermore, if you're just a brand new Clojure developer looking for some learning experiences, check
out the 'links' page. You'll find links to some tutorials and such there.
We've only scratched the surface of Clojure and its mind-bending power.
This tutorial is still a work in progress, and I'm working on more steps.
Meanwhile, you can learn more about Clojure by visiting the 'links' page.
</p>

<p>
Welcome to your adventures in Clojure, and be prepared to be surprised and delighted every step of the way!
</p>
7 changes: 4 additions & 3 deletions resources/public/tutorial/page2.html
@@ -1,6 +1,7 @@
<p>
I bet you're curious to find out what Clojure code looks like, aren't you? Sure you are.
Well, I've give you a hint: it's made up of lists. Let's do some arithmetic.
The first thing you may notice about Clojure is that common operations look... strange.
</p>

<code class="expr">(+ 3 3)</code>
<p>
For example, try typing <code class="expr">(+ 3 3)</code> in the REPL.
</p>
13 changes: 7 additions & 6 deletions resources/public/tutorial/page3.html
@@ -1,12 +1,13 @@
<p>
Excellent work! There are other arithmetic functions.
That was a strange way to say "three plus three", wasn't it?
</p>
<code>*</code>
<code>-</code>
<code>/</code>

<p>
Try them out. Save <code>/</code> for last (don't worry, I have a reason!).
A Clojure program is made of <em>lists</em>.
<code class="expr">(+ 3 3)</code> is a list that contains an operator, and then the operands.
Try out the same concept with the <code>*</code> and <code>-</code> operators.
</p>

<p>Once you're finished playing around, try <code class="expr">(/ 10 3)</code>.</p>
<p>
Division might surprise you. When you're ready to move forward, try <code class="expr">(/ 10 3)</code>.
</p>
8 changes: 2 additions & 6 deletions resources/public/tutorial/page4.html
@@ -1,8 +1,4 @@
<p>
I bet that caught you by surprise, didn't it? Don't fear! Clojure simply has a built in Rational type.
We can prove that we've got a rational by running <code class="expr">(type (/ 10 3))</code>. Rationals are more
concise and precise than floating point numbers. However, we can force Clojure to do floating point
division by just making one of our numbers floating point.
Now, that was a bit surprising: Clojure has a built in Rational type.
You can still force Clojure to do floating point division by making one of the operands floating point: type <code class="expr">(/ 10 3.0)</code> to continue.
</p>

<p>Type <code class="expr">(/ 10 3.0)</code> to continue.</p>
9 changes: 2 additions & 7 deletions resources/public/tutorial/page5.html
@@ -1,11 +1,6 @@
<p>Awesome!</p>

<p>
Another neat thing about Clojure is that functions can take an arbitrary number of arguments.
Functions are allowed to specify a 'catch-all' to put an optional and arbitrary number of arguments
into. Because of this, a lot of Clojure's core functions have interesting capabilities. For example
the arithmetic functions we've already played with are not limited to two arguments! No sir, they can
take any number of arguments they wish.
Many Clojure functions can take an arbitrary number of arguments.
Try it out: type <code class="expr">(+ 1 2 3 4 5 6)</code> to continue.
</p>

<p>Try it out. Type <code class="expr">(+ 1 2 3 4 5 6)</code> to continue.</p>
9 changes: 5 additions & 4 deletions resources/public/tutorial/page6.html
@@ -1,7 +1,8 @@
<p>Alright, that's enough math. Let's do some fun stuff, like write functions.</p>

<p>
You can define functions in Clojure with <code>defn</code>
That's enough math. Let's do some fun stuff, like defining functions.
You can do that in Clojure with <code>defn</code>.
</p>

<p>Type <code class="expr">(defn square [x] (* x x))</code> to continue!</p>
<p>
Type <code class="expr">(defn square [x] (* x x))</code> to define a "square" function that takes a single number and squares it.
</p>
13 changes: 7 additions & 6 deletions resources/public/tutorial/page7.html
@@ -1,12 +1,13 @@
<p>Oh boy! We wrote our very own function! It's a lovely one, isn't it?</p>
<p>Congratulations - you just defined your first Clojure function. Many more will follow!</p>

<p>
Our <code>square</code> function takes a single argument -- a number -- and squares it.
<code>defn</code> takes the name of the function, then the list of arguments, and then the body of the function.
I told you that a Clojure program is made of lists, right?
The entire <code>defn</code> is a list, and the function body is also a list.
(Even the arguments are collected in a vector, which is similar to a list - we'll talk about vectors soon).
</p>

<p>
Take a look at how our defn form looks. First comes the name of the function, then the argument list
(which is a vector, and not an actual list), then the body of the function.
Oh, sorry for talking so long - you probably want to try out your brand new function!
Type <code class="expr">(square 10)</code>.
</p>

<p>But wait! We don't even know if our function works or not! Let's try it out. Type <code class="expr">(square 10)</code>.</p>
17 changes: 10 additions & 7 deletions resources/public/tutorial/page8.html
@@ -1,17 +1,20 @@
<p>Yay! It works!</p>

<p>
You know, Clojure is a functional programming language. As such, it has first-class and
anonymous functions. Let's write our square function as an anonymous function.
By now, you probably think that Clojure is very different from the programming languages you already know.
Indeed, it belongs to a different family than most popular languages' - the family of "functional" programming languages.
Like most functional languages, Clojure can define a function without even giving it a name:
</p>

<code class="expr">(fn [x] (* x x))</code>

<p>
If you run this in the REPL above (as you should), you'll note that some very weird and
cryptic thing is printed. Functions are just normal values like a number, a string, or
anything else. The cryptic thing is simply how they look when printed.
If you run this code, you'll see some cryptic output.
In Clojure, functions are just normal values like numbers or strings.
<code>fn</code> defines a function and then returns it.
What you're seeing is simply what a function looks like when you print it on the screen.
</p>

<p>
Our anonymous function isn't very useful if we don't call it. Let's do it. Type
<code class="expr">((fn [x] (* x x)) 10)</code>
But wait - an anonymous function isn't very useful if you can't call it. Try to define a new anonymous function and call it straight away: <code class="expr">((fn [x] (* x x)) 10)</code>.
</p>
16 changes: 10 additions & 6 deletions resources/public/tutorial/page9.html
@@ -1,12 +1,16 @@
<p>
Yay! Notice how we called our anonymous function? We just wrapped the function in parentheses,
placing it as the first element in this new list and passing it arguments just like we did earlier
with the arithmetic functions. Awesome, huh?
Let's see what you just did: you evaluated a list where the first element is the function itself, defined on the spot - and the other elements are the arguments that you pass to the function.
That's exactly the same syntax that you used earlier on to call functions like <code>square</code> or even <code>+</code>.
The only difference is that now you defined the function in the same place where you called it.
</p>

<p>
You may not know this, but <code>defn</code> is actually just a bit of sugar around <code>def</code>
and <code>fn</code> to create named functions. We can create named functions without <code>defn</code>
Remember <code>defn</code>?
Now I can tell you a secret: <code>defn</code> is actually just a bit of syntactic sugar around <code>def</code> and <code>fn</code>.
You've just seen <code>fn</code> at work: it defines a new function.
<code>def</code> binds the newly defined function to a name.
</p>

<p>Type <code class="expr">(def square (fn [x] (* x x)))</code> to continue.</p>
<p>
If you want, you can create a named functions without using <code>defn</code>: type <code class="expr">(def square (fn [x] (* x x)))</code> to continue.
</p>
36 changes: 18 additions & 18 deletions src/tryclojure/views/home.clj
Expand Up @@ -15,26 +15,28 @@

(defpartial about-html []
[:p.bottom
"Please note that this REPL is sandboxed, so you wont be able to do everything in it "
"that you would in a local unsandboxed REPL. Keep in mind that this site is designed for "
"beginners to try out Clojure and not necessarily as a general-purpose server-side REPL."]
"Welcome to Try Clojure - a quick tour of Clojure for absolute beginners."
]
[:p.bottom
"One quirk you might run into is that things you bind with def can sometimes disappear. "
"The sandbox wipes defs if you def too many things, so don't be surprised. Furthermore, "
"The sandbox will automatically be wiped after 15 minutes and if you evaluate more after that,"
"It'll be in an entirely new namespace/sandbox."]
"Here is our only disclaimer: this site is an introduction to Clojure, not a generic Clojure REPL. "
"You won't be able to do everything in it that you could do in your local interpreter. "
"Also, the interpreter deletes the data that you enter if you define too many things, or after 15 minutes."]
[:p.bottom
"TryClojure is written in Clojure and JavaScript (JQuery), powered by "
(link-to "https://github.com/flatland/clojail" "clojail")
" and Chris Done's "
(link-to "https://github.com/chrisdone/jquery-console" "jquery-console")]
[:p.bottom "Design by " (link-to "http://apgwoz.com" "Andrew Gwozdziewycz")])
"TryClojure is written in Clojure and JavaScript with "
(link-to "http://webnoir.org" "Noir") ", "
(link-to "https://github.com/flatland/clojail" "clojail") ", and Chris Done's "
(link-to "https://github.com/chrisdone/jquery-console" "jquery-console") ". "
" The design is by " (link-to "http://apgwoz.com" "Andrew Gwozdziewycz") "."
])

(defpartial home-html []
[:p.bottom
"Welcome to Try Clojure. See that little box up there? That's a Clojure repl. You can type "
"expressions and see their results right here in your browser. We also have a brief tutorial to "
"give you a taste of Clojure. Try it out by typing " [:code.expr "tutorial"] " in the console!"])
"Welcome to Clojure! "
"You can see a Clojure interpreter above - we call it a <em>REPL</em>."
]
[:p.bottom
"Type \"tutorial\" in the REPL to begin."
])

(defn root-html []
(html5
Expand Down Expand Up @@ -65,9 +67,7 @@
[:a#about.buttons.last "about"]]
[:div#changer (home-html)]]
[:div.footer
[:p.bottom "©2011-2012 Anthony Grimes and numerous contributors. Built with "
(link-to "http://webnoir.org" "Noir")
"."]]
[:p.bottom "©2011-2012 Anthony Grimes and numerous contributors."]]
(javascript-tag
"var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-27340918-1']);
Expand Down

0 comments on commit 57890f5

Please sign in to comment.