In the past couple years at work, my company has held some lunch-time programming competitions, where people get some kind of challenge and can program it in any language they want, and them demo it during lunch. (You know, back when people actually went into the office and sat in rooms together. ). As soon as they said "any language you want", I knew I had to do my challenges in Logo. Since almost everyone else was doing OOP languages like Java, I thought it would be fun to demonstrate how to solve some of these problems using functional programming instead. Since I didn't have an Atari, I wrote them all in FMS Logo, a free Logo for Windows.
BASIC and Pascal are procedural languages, a sequence of instructions. Java and C++ are Object Oriented Languages. Logo is a Functional Programming language. Not a pure functional programming language but at it's heart, that's what it is. One of the features of functional programming is that data should be immutable (i.e. data never changes). That means no variables. Variables as in data that varies. In practice, I've found this really hard to do, especially in Logo, but you CAN really get away with hardly using any variables if you write good functional procedures. Neither of the examples I've posted so far have a single variable. They have things that LOOK like variables (:size, :rings, etc) but those are INPUTS to functions, not variables. They never change their value over the life of the function they are in. With recursion, I spin off new versions of the function with new inputs, but the original inputs in ANY of those functions never changes. :SIZE stays 75 for the whole time the initial procedure is running. :RINGS in the original procedure never changes from 5, just kicks off new versions of itself with other inputs.
Logo doesn't have any built in flow controls like FOR EACH or WHILE DO or DO UNTIL. All of these depend on some variable changing to end the loop. Instead, functional programming languages like Logo use recursion as their flow control. There's a stopping condition based on input. If it doesn't stop, then it does some stuff and then calls itself with some new input. The order of those three things can change depending on what problem you're solving but that's the gist of it. You can write a brand new recursive looping function every time unique to your problem, but there are some general problems that follow a pattern that would be nice if you had a function that took OTHER functions as input (and their inputs) and write the recursion part only once instead of for every new function you came up with. That's where higher order functions (or lambdas in Java and Python) like MAP, FILTER and REDUCE come into play.
One of the other great features of functional programming languages is their extensibility. I can use existing procedures to build new procedures and Atari Logo will recognize them as being equal stature as the primitive built in procedures. So even though Atari Logo does not have MAP, FILTER and REDUCE, I can still (hopefully) create them on my own using the one higher order primitive function built into Atari Logo called RUN. RUN takes a list of inputs and treats those inputs as instructions to execute rather than raw data. I have coded the Atari Logo versions of MAP and REDUCE and have included examples below. I got the code for the MAP and REDUCE procedures from Logoworks, a great book. I modified MAP slightly so it will work with a Word or a List for the function. You can see that MAP and REDUCE work on both user created functions I made OR Atari Logo primitive functions. I'm still working on FILTER.
Logo is a Functional Programming language. Not a pure functional programming language but at it's heart, that's what it is. One of the features of functional programming is that data should be immutable (i.e. data never changes). That means no variables. Variables as in data that varies.
Ironically, the reason I used "LOGO" was specifically to identify I was talking about the programming language because that's how Atari referred to it, in all upper case. (Though they weren't always consistent about that.) I would have used "logo", all lower case to talk about graphical type logos. But no worries, the Lucasfilm logos are cool too!
There was another difference here between FMS Logo and Atari LOGO. FMS Logo allows you to define locally scoped objects/things, that will go away when the procedure they were defined in stops executing. All names/things/objects in Atari LOGO are global. All will be available globally scoped, so you have to be a bit careful using them compared to other functional programming languages. This program uses three TRUE pieces of global data, but these are JUST data. They are defined as part of the workspace and never are changed when the program runs. These are the listing of the four suits of cards, the 13 ranks of cards and a ranked list of poker hands from the best (a royal flush) to having nothing.
Ahhh, one other thing I forgot to mention about one of the great things with functional programming languages is that because they are comprised of a bunch of individual working pieces called procedures that can be all run on their own, it is easy to test your code.
I remember being exposed to Logo way back in high school. All I recall about Logo is the turtle graphics, and the primitive digital Etch-a-Sketch drawings you could create with it. What I didn't realize is that Logo is "an easier to read adaptation of the Lisp language.. [with] significant facilities for handling lists, files, I/O, and recursion", at least if the Wikipedia entry on Logo is to be believed.
Although I was eternally fascinated with programming, Logo held no interest for me. It seemed like a toy language, only useful for silly little graphical tricks and stunts with the turtle. But apparently there was a real language lurking underneath all that turtle graphics stuff. Brian Harvey is a Berkeley professor who not only co-wrote Berkeley Lisp, but authored three books that, amazingly, teach the whole of computer science using nothing but Logo.
If you're already familiar with programming, it's important to understand how Processing differs from other development environments and languages. The Processing project encourages a style of work that builds code quickly, understanding that either the code will be used as a quick sketch or that ideas are being tested before developing a final project. This could be misconstrued as software engineering heresy. Perhaps we're not far from "hacking", but this is more appropriate for the roles in which Processing is used. Why force students or casual programmers to learn about graphics contexts, threading, and event handling methods before they can show something on the screen that interacts with the mouse? The same goes for advanced developers: why should they always need to start with the same two pages of code whenever they begin a project?In another scenario, if you're doing scientific visualization, the ability to try things out quickly is a far higher priority than sophisticated code structure. Usually you don't know what the outcome will be, so you might build something one week to try an initial hypothesis and build something new the next week based on what was learned in the first week.
df19127ead