Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 15 16 [17] 18 19 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 815806 times)

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #240 on: January 09, 2012, 02:15:17 am »

He get's to exist in the time before combat is implemented. What is not to be happy about?

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #241 on: January 09, 2012, 02:54:55 am »

He get's to exist in the time before combat is implemented. What is not to be happy about?

The fact that he's probably homeless...not that the need for food, water, or shelter has been implemented either...he's sad because he's one of two people existing in the entire world and has no friends!

What are you eventual goals with this project?
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #242 on: January 09, 2012, 02:59:13 am »

Max, would you do something to humor me? Make a final boss fight where the boss's name is a reference to coffee.

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #243 on: January 09, 2012, 03:12:43 am »

What are you eventual goals with this project?
Goals are over rated.
But seriously? I go with more of a SCRUM methodology, but excelled to an extreme only possible for a one man project, in that new goals come in on an hourly basis. I do have sort of a long term vision though...
DF style damage, so no HP meter.
Over world map.
Towns, dungeons, rivers, forests.

I also have a really neat idea for magic. I mean seriously, this shit will be defining. It's all hush hush though.

Max, would you do something to humor me? Make a final boss fight where the boss's name is a reference to coffee.
Final?

Virex

  • Bay Watcher
  • Subjects interest attracted. Annalyses pending...
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #244 on: January 09, 2012, 03:18:31 am »

 
The better way to test your theory would be to implicitly construct a String, wait for any hidden instantiation to get garbage collected and then implicitly instantiate another one...wait, I know how to force the garbage collector to run...
Code: [Select]
String s1 = "foo";
System.out.println(Integer.toHexString(System.identityHashCode(s1)));
System.gc();
String s2 = "foo";
System.out.println(Integer.toHexString(System.identityHashCode(s2)));
Nope.
Code: [Select]
41ed8741
41ed8741

If it were constructing an anonymous constant or something, I'd imagine it would go away when the garbage collector is run.  In fact, it's unthinkable that something no longer being used wouldn't die when the garbage collector runs.  Otherwise it would have to spend the time to check all existing objects in memory for a match.  I would think that would be ridiculously inefficient.  Java isn't exactly known for being efficient, though.
Of course that doesn't work. Neither string literal actually exists at run-time, so the GC never gets to collect anything. Only the strings themselves exist at run-time. At least as far as I know, in a situation like this, the compiler can see the properties of the string ahead of time and will preallocate the string for you. But the Java compiler is a clever little bastard and it also knows that both strings are exactly the same. So it preallocates one of the string and makes the other point to it, but still keeps note that they are different.


In order for your test to work you would actually have to deallocate s1 and run the garbage collector, then check if the two values are the same.


Anyway, time for some tutorials:

Talking with a Lisp
Chapter 1: (Hello-Parens!)


The canonical start to any programming tutorial is a hello-world program. We'll do the same for Common Lisp, but you'll need some extra info to get on your way, so excuse me if I'm a bit talkative.

So how to get the bloody thing to run anyway?
Common Lisp isn't quite as popular as languages as Java or C. This means that support in most IDEs relies on third-party plug-ins, such as Dandelion for Eclipse. However, due to historical reasons, Slime and Emacs like each other very much. Emacs itself is written in a different Lisp dialect, more on that later. First, let's get things up and running.
I assume you're working on Windows. In that case, you can use Lisp Cabinet. This will set up a preconfigured Emacs with Common Lisp and some other useful plugins.
After loading up the net installer for lisp cabinet, you'll see a screen where you can select what components to install. First tick box is desktop shortcuts, which may be ticked if you prefer them. Then we've got Emacs. Here you can select Emacs 23 or Emacs 24. Emacs 24 is officially still in beta, but it has been for nearly a year now and it's pretty much completely stable. IT also comes with a few useful features that emacs 23 lacks, but most of those can be hacked in after the fact. I'll be using emacs 24, but feel free to chose whatever you like. You may also like the autocomplete plugin, so feel free to tick it.
Next tick box is called Common Lisp. Here we meet a little peculiarity of the Common Lisp world. There's not a single, unifying version of Common Lisp. Instead there are several environments. Compare it to C++, which has the GCC compiler and the Intel compiler among others. Standard, SBCL and Clozure CL will be selected. I'd suggest leaving things like this as any lisp environment does a fine job, both those two generally produce the fastest code (I prefer Clozue Cl for development work as it gives some more info when something breaks, but some libraries work on SBCL exclusively so that's why I generally advise getting them both).
If you want to follow the Clojure tutorials I'll write later, you may also want to tick the Clojure box. I won't mention Racket, which is a Scheme dialect, but feel free to explore it at your own leisure if you want to. If you're using Clojure as well. remember to avoid spaces in the path where you install Lisp Cabinet or things will break
Now, let the installer do it's magic, navigate to the path where you installed everything and fire up Lisp Cabinet.


You'll be greeted with a pretty Emacs window. If you ever used Emacs before, this may look a little different as Lisp Cabinet installs it's own color scheme. This can be changed, but that's outside of the scope of this book.

Is that all we're going to get?
Patience, my dear.
What we have here is just Emacs, but it's not Common Lisp yet. Common Lisp is similar to languages like Python in the sense that you always have a Common Lisp image running in the background. Any code, be it in the form of a script, a compiled program or code you type in for direct evaluation first goes through this image, which handles all the magic needed to get it to work.

So how to get such an image?

Emacs talks to a running image using Slime, the Superior Lisp Integration Mode for Emacs. Slime provides, among others, code evaluation, error handling and profiling options while autocompletion and parenthesis highlighting are also provided as a courtesy of Emacs and Lisp Cabinet.
To get a running Common Lisp image and be able to do anything, we simply tell Emacs to start Slime.
Hold the meta-key (called Alt on most keyboards) and press x. I'll refer to such a combination as M-x. Holding meta and pressing G would be M-g, holding control (marked crtl on most keyboards) and pressing X would be C-x et cetera. This is standard Emacs jargon, you'll find it in many other documents as well. (if you type something wrong, you can always hit C-g to quit the input)
Now after pressing M-x, you'll see a teal M-x appear in the lowest line of your screen. If you start to type, text will appear after it. Type in slime and hit enter. Blam! You'll see some code flashing past and will quickly be greeted by the following line:


Code: [Select]
; SLIME 2011-10-19
CL-USER>

So what is it we're looking at exactly?
This is the so-called REPL: The Read, Evaluate, Print Loop. Here we can type in code,which will be read and evaluated and the result will be printed back. Remember when I said Emacs talks to a running Common Lisp image? We can talk directly to the lisp image via the REPL.
So let's do some talking:

Code: [Select]

CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>

As you can see, typing in "Hello, World!" causes the REPL to respond with "Hello, World!". This is because "Hello, World!" is a string literal, which is read in and evaluates to itself. (On a side note, if you want to copy and paste stuff to and from Emacs, you might want to go to options and set 'Use CUA keys'. This makes C-c, C-v and C-x work as expected).

So ok, we've got our Common Lisp image to print "Hello, World!", but have we programmed anything? Well, we certainly haven't made any function calls or anything. So let's do that now. We'll call a function that writes "Hello, World!" to the output:


Code: [Select]

CL-USER> (format t "Hello, World!")
Hello, World!
NIL
CL-USER>

Whoa! What the hell? Why is that format t inside the parenthesis? And where did that nil come from?
When I said Common Lisp is a bit different from languages like C, I meant that in more ways then one. First of all, lisp uses so-called S-expresssions. I'll explain then further later on, for now you can remember that they have the following structure:
(<function name> <function argument 1> <function argument 2>.... <function argument n>)
It's essentially a list with in the first spot a function call (or a method or special operator, but we'll cover that later) and the rest arguments to the function call. So in this case, format was the function and t and "Hello, World!" it's arguments. In the case of format, the first value tells it where to print to, the second value is a format string, which is a kind of instruction string that tells it how to print something, and it takes as many further arguments as the format string can handle. So


Code: [Select]
CL-USER> (format t "~a" "Hello, World!")
Hello, World!
NIL


and


Code: [Select]
CL-USER> (format t "~a, ~a!" "Hello" "World")
Hello, World!
NIL
CL-USER>


also work, since the ~a tells format: Print out one of your input arguments. The book Practical Common Lisp (Freely available as a digital version) has a good, but by no means exhaustive chapter on the format function. I'll also cover it if there's popular demand for it.
So about that nil. Let me demonstrate what it is by altering the function call to format a bit again:


Code: [Select]
CL-USER> (format nil "~a, ~a!" "Hello" "World")
"Hello, World!"
CL-USER>


Now the nil vanished. The reason for this is that if the first argument to format is nil, then instead of printing the output to the standard output (as with t) or a stream (if that stream is the first argument to format), it just returns a string. That is, the string becomes the return value. In the previous cases nil was the return value, indicating that the function was in essence returning nothing of use. nil in Common Lisp is, among others, false, the empty list and the return value of functions that don't have a sensible return value. This is because every function call (and macro call and special operator call) has a return value.
(On a side note, there are other functions besides format that print to the REPL, such as print or prin1 but format is the most versatile, so I'll use that throughout the tutorials)


So now that we've got the REPL to print a string and we've called functions that write output to the REPL, the next canonical step is to make ourself a little function. We'll make a function that takes 1 argument and prints "Hello, <argument>":


Code: [Select]
CL-USER> (defun hello (input)
         (format t "Hello, ~a!" input))
HELLO
CL-USER> (hello "John")
Hello, John!
NIL
CL-USER>


As you can see defining functions is done with defun, which has the following structure:


Code: [Select]

(defun <function name> (<input argument 1> <input argument 2> .... <input argument n>)
    code)


(defun looks like a function call, but it's actually a macro. More on that later)
Also note that we don't have to specify the type of our input, as Common Lisp is dynamically typed. More on that, and the intricacies of defining and using functions later. Lastly, there's that nil again. We haven't specified any output, so where does it come from?
Well, in Common Lisp, you don't need to specify output. By default, the result of evaluating the last expression is used as the return value. An since (format t ...) returns nil, our function also returns nil. Had we used (format nil ...), the result would have been:


Code: [Select]
CL-USER> (defun hello (input)
         (format nil "Hello, ~a!" input))
HELLO
CL-USER> (hello "World!")
"Hello, World!!"


since now the format returns a string, which then gets returned by our own function.


For now we're going to make this into an actual program. The problem is that if we shut down our Common Lisp image, the functions we defined are gone. We don't want that, because that means we have to reprogram everything from scratch again.
While Common Lisp can be developed from the REPL, it's often easier to work with files and only test stuff on the REPL. So let's put our function in a file.
Put the following key combination in Emacs:
C-x f
This is the combination for "find file". This is the general mechanism used for finding existing and new files. Put in the full path of your file, for example c:\Tutorials\Lisp\Hello World.lisp (the .lisp extension is mandatory, else Emacs won't use syntax highlighting) and hit enter. An empty file will appear, but our REPL is gone. Let's fix that first.
Hit C-x  2 or C-x 3 to split the window horizontally or vertically respectively. Select the window where you want the REPL, hit C-b, type in slime-re and hit tab. This will autocomplete to slime-repl-ccl (or slime-repl-sbcl if you only installed that one, but if you have Clozure Common Lisp it should start with it by default) You now have an empty file and the REPL side-by-side. Copy


Code: [Select]

(defun hello (input)
         (format t "Hello, ~a!" input))


(hello "World")


to the file and safe it with C-x s. (if you put the file in a non-existent directory, you'll get an error. Just hit M-x and type make-directory and hit enter twice, then save it again.)
We now have the code in our file, so we can load it whenever we want. With a file open and Slime running, we can always hit C-c C-k to evaluate the whole file. If you do this now, you'll see "Hello, World!" printed to the REPL, as expected. Alternatively, at the REPL, you can hit , (that's the coma key) and type CD to activate change directory, change to where you stored the file then type (load "filename") and it'll do the same thing:


Code: [Select]
CL-USER> (load "Hello World.lisp")
Hello, World!!
#P"d:/Common Lisp/Tutorial/Lesson 1/Hello World.lisp"
CL-USER>


The return value in this case is a path containing the full name of the file you just loaded.


Just to prove that doing this loads the whole file into the running image, as opposed to just executing it, do the following:


Code: [Select]
CL-USER> (unintern 'hello)
T
CL-USER> (hello "World!")
; Evaluation aborted on #<CCL::UNDEFINED-FUNCTION-CALL #x187F30F6>.
CL-USER> (load "Hello World.lisp")
Hello, World!!
#P"d:/Common Lisp/Tutorial/Lesson 1/Hello World.lisp"
CL-USER> (hello "World")
Hello, World!
NIL
CL-USER>


The first call to hello will dump you into the error handler since we just removed the function with unintern. Just hit q to exit the error handler. The second call to hello will work, because loading a file makes all functions in that file available in the REPL.

One final note: it's also possible to save compiled code instead of code files, but the functions used to do that differ by lisp implementation. In Clozure Common Lisp it's save-application and in SBCL it's save-lisp-and-die. If these pages look like absolute word salad to you, don't despair, I'll handle most if what you need to know at some point. Also, as the name of the SBLC function already indicates, saving an image, as it's called, is going to corrupt the running image to a point where it can't keep on running, so it'll shut itself down once it's done saving.

This concludes the first chapter of my Common Lisp tutorial. Here's a quick recap:
  • Whenever you use Common Lisp, there's a Common Lisp image running in the background that processes the code
  • We use a REPL to talk to the image, I've used the Slime repl for Emacs in this tutorial. A REPL is a Read, Evaluate, Print Loop
  • Feeding a literal, such as a string or a number to the REPL will result in it printing that literal
  • Common Lisp uses S-expressions, which have the form (<function name> <input arguments>)
  • We can output things to the REPL using (format t format-string input-arguments): (format t "Hello, ~a" "World")
  • We can define our own functions using (defun <name> (<input arguments>) <code>)
  • The result of evaluating the last expression in a function serves as the return value for that function
  • We can save code in .lisp files and load the code with the load function or by hitting C-c C-k
« Last Edit: January 09, 2012, 10:42:14 am by Virex »
Logged

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #245 on: January 09, 2012, 10:23:21 am »

Rule of thumb, regardless of what it's casted as, Java is smart enough to usually realize what it really is (and call appropriate methods).  And how exactly would you imagine an object oriented language not having casting?

Ah good, that is what I suspected.

Well Ruby and Python I don't think have casting, but come to think of it they are typeless languages.  Java has actual types so I suppose it must have casting.
Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Shakerag

  • Bay Watcher
  • Just here for the schadenfreude.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #246 on: January 09, 2012, 11:14:47 am »

Hmm.  Coding a routine to scan text strings and filter them using another partial string that likely has wildcard characters (* = 0 or more, ? = any 1 character) is about as fun as I was expecting it to be.  That may or may not be sarcastic; I'm not 100% sure yet. 

I think I'm obsessing over making sure my algorithm is as efficient as possible when that potentially isn't as important as I'm thinking it is.  Because I'm just anal that way.

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #247 on: January 09, 2012, 11:18:58 am »

Hmm.  Coding a routine to scan text strings and filter them using another partial string that likely has wildcard characters (* = 0 or more, ? = any 1 character) is about as fun as I was expecting it to be.  That may or may not be sarcastic; I'm not 100% sure yet. 

I think I'm obsessing over making sure my algorithm is as efficient as possible when that potentially isn't as important as I'm thinking it is.  Because I'm just anal that way.

Yeah, I can imagine how that would be.  It doesn't sound too terrible, though.  What language are you working in again?
Logged

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #248 on: January 09, 2012, 11:26:51 am »

Hmm.  Coding a routine to scan text strings and filter them using another partial string that likely has wildcard characters (* = 0 or more, ? = any 1 character) is about as fun as I was expecting it to be.  That may or may not be sarcastic; I'm not 100% sure yet. 

I think I'm obsessing over making sure my algorithm is as efficient as possible when that potentially isn't as important as I'm thinking it is.  Because I'm just anal that way.

So what's your algorithm? I'm thinking of recursion.
Logged

GlyphGryph

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #249 on: January 09, 2012, 11:41:46 am »

Quote from: Levi
Ah good, that is what I suspected.

Well Ruby and Python I don't think have casting, but come to think of it they are typeless languages.  Java has actual types so I suppose it must have casting.

Ruby does have types - it is actually a Strongly Typed language and it actually has one of the strongest typing systems around (which some may see as a drawback, but oh well). Casting is actually a property of weakly typed languages. Java is somewhere in the middle, with both strong and weak elements - its typing system is definitely a lot more fluid than Ruby's though, and is quite a bit closer to typeless. Neither of them actually ARE typeless, but I have no idea for Python.

The real difference between their typing system is that Ruby has a dynamic typing system as opposed to Java's static typing system. It certainly doesn't imply the language is typeless, just that types work differently.
« Last Edit: January 09, 2012, 11:45:10 am by GlyphGryph »
Logged

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #250 on: January 09, 2012, 11:44:36 am »

Quote from: Levi
Ah good, that is what I suspected.

Well Ruby and Python I don't think have casting, but come to think of it they are typeless languages.  Java has actual types so I suppose it must have casting.

Ruby does not have casting, but it is actually a Strongly Typed language - it actually has one of the strongest typing systems around (which some may see as a drawback, but oh well). Casting is actually a property of weakly typed languages. Java is somewhere in the middle, with both strong and weak elements. Neither of them are typeless, but I have no idea for Python.

The real difference between their typing system is that Ruby has a dynamic typing system as opposed to Java's static typing system. It certainly doesn't imply the language is typeless, just that types work differently.

Trivia: All three are strongly typed languages.
Logged

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #251 on: January 09, 2012, 11:45:41 am »

I think I'm obsessing over making sure my algorithm is as efficient as possible when that potentially isn't as important as I'm thinking it is.  Because I'm just anal that way.
Now your a real programmer!
Seriously, I have seen people wrack their brains for weeks making things more efficient, and for what? Saving seven ticks. Seriously, that was it, they were so proud that after countless hours working with some insane maths, they save them self an impossibly small amount of time on an algorithm that isn't even extensively used.

Efficiency is nice, and you should aim for it when ever possible, but be reasonable.

GlyphGryph

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #252 on: January 09, 2012, 11:48:38 am »

Duck Typing just means it's dynamically typed - you can have a language that is both dynamically typed and strongly typed. Python and Java both have some weakly typed elements, and Python actually has some actual /typeless/ elements (having just gone to look it up, no personal experience with that one), but overall, yes, all three languages are predominantly strongly typed.

Anyways, this argument is always dumb, I just had a contention with the statement that Ruby was typeless, when it it isn't. The details don't really matter.
Logged

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #253 on: January 09, 2012, 11:50:40 am »

3:50 in the morning. Insomnia.
Not responsible for anything.

Anyway yea, realised my mistake.

EDIT:
I really with there was a language that had the 'mew' keyword instead of 'new', I keep making that spelling error and it would be awesome to be a thing.

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #254 on: January 09, 2012, 11:54:13 am »

3:50 in the morning. Insomnia.
Not responsible for anything.

Anyway yea, realised my mistake.

What's worse for coding?  Insomnia or drunkenness?
Logged
Pages: 1 ... 15 16 [17] 18 19 ... 795