From: bh@anarres.CS.Berkeley.EDU (Brian Harvey)
Newsgroups: comp.archives
Subject: [comp.lang.logo] Berkeley Logo version 2.7 available
Followup-To: comp.lang.logo
Date: 26 Sep 1992 11:57:45 GMT
Organization: University of California, Berkeley
Distribution: world
NNTP-Posting-Host: soda.berkeley.edu
X-Original-Newsgroups: comp.lang.logo
X-Original-Date: 21 Sep 1992 18:43:23 GMT

Archive-name: auto/comp.lang.logo/Berkeley-Logo-version-2-7-available

A new alpha test release (version 2.7) of Berkeley Logo is now
available by anonymous FTP.  I've done most of the major development
that I'd intended, and I hope this is the last alpha test release.
From here on, I just want to fix bugs.  (But someday there will
probably be an extended-memory version for 386-and-up machines, when
I get a compiler that knows about that.)

The new version fixes bugs that were reported to me in version 2.6,
and also implements user-defined macros, a new feature that I'll describe
at the end of this message.  The DOS version does splitscreen graphics
much better than before, thanks to George Mills.

I am thinking about two incompatible changes in the first official Beta
release, and I'd be interested in people's opinions.  First, more often
than not I want case-independent comparison of words, so I want Logo to
start up with CASEIGNOREDP set to TRUE.  Second, there are now a bunch of
graphics-related primitives that are defined for all machines but really
only work on one of them.  (For example, FILL only works on the PC, while
SETPENSIZE only works on the Mac.)  My instinct is to just remove all of
these, because I never use that sort of thing and I'm more interested in
guaranteeing portable Logo programs than in getting the fanciest possible
graphics.  And they're likely to be the first things to break as hardware
and operating systems change over time.  Does anyone else use these?

FTP to anarres.cs.berkeley.edu and get any of the following files:

pub/ucblogo.tar.Z	Unix sources and documentation
pub/ucblogo.zip		PC version, PKZIP form, including executable BL.EXE
pub/ucblogo.sit.hqx	Mac version, StuffIt/BinHex form, w/ executable Logo
pub/usermanual		Just the documentation file.
pub/csls.tar.Z		Logo programs from _Computer Science Logo Style_

You're on your own for the unpacking software.

Advantages of Berkeley Logo:

	* It's free.

	* It comes with source files (in C).

	* Logo programs are completely compatible among Unix, PC, and Mac.

Disadvantages of Berkeley Logo:

	* It's pretty slow.

	* It doesn't do anything fancy about graphics.  (One turtle.)

	* The DOS version runs out of memory easily.

If you don't have FTP access, but can read a 3.5-inch disk, send me
$2.50 to cover costs and tell me whether you want the Mac or the PC
version (or send $5.00 for both) and I'll send you a disk.

				Brian Harvey
				2634 Virginia St
				Berkeley, CA  94709



MACROS
======

.MACRO procname :input1 :input2 ...				(special form)
.DEFMACRO procname text
MACROP name

	A macro is a special kind of procedure whose output is evaluated
	as Logo instructions in the context of the macro's caller.
	.MACRO is exactly like TO except that the new procedure becomes
	a macro; .DEFMACRO is exactly like DEFINE with the same exception.
	MACROP returns TRUE if its input is the name of a macro.

	Macros are useful for inventing new control structures comparable
	to REPEAT, IF, and so on.  Such control structures can almost, but
	not quite, be duplicated by ordinary Logo procedures.  For example,
	here is an ordinary procedure version of REPEAT:

		to my.repeat :num :instructions
		if :num=0 [stop]
		run :instructions
		my.repeat :num-1 :instructions
		end

	This version works fine for most purposes, e.g.,

		my.repeat 5 [print "hello]

	But it doesn't work if the instructions to be carried out include
	OUTPUT, STOP, or LOCAL.  For example, consider this procedure:

		to example
		print [Guess my secret word.  You get three guesses.]
		repeat 3 [type "|?? | ~
			  if readword = "secret [pr "Right! stop]]
		print [Sorry, the word was "secret"!]
		end

	This procedure works as written, but if MY.REPEAT is used instead
	of REPEAT, it won't work because the STOP will stop MY.REPEAT
	instead of stopping EXAMPLE as desired.

	The solution is to make MY.REPEAT a macro.  Instead of actually
	carrying out the computation, a macro must return a list containing
	Logo instructions.  The contents of that list are evaluated as if
	they appeared in place of the call to the macro.  Here's a macro
	version of REPEAT:

		.macro my.repeat :num :instructions
		if :num=0 [output []]
		output sentence :instructions ~
				(list "my.repeat :num-1 :instructions)
		end

	Every macro is an operation -- it must always output something.
	Even in the base case, MY.REPEAT outputs an empty instruction
	list.  To show how MY.REPEAT works, let's take the example

		my.repeat 5 [print "hello]

	For this example, MY.REPEAT will output the instruction list

		[print "hello my.repeat 4 [print "hello]]

	Logo then executes these instructions in place of the original
	invocation of MY.REPEAT; this prints "hello" once and invokes
	another repetition.

	The macro-defining commands have names starting with a dot because
	macros are an advanced feature of Logo; it's easy to get in trouble
	by defining a macro that doesn't terminate, or by failing to
	construct the instruction list properly.

	Lisp users should note that Logo macros are NOT special forms.
	That is, the inputs to the macro are evaluated normally, as they
	would be for any other Logo procedure.  It's only the output from
	the macro that's handled unusually.

	Here's another example:

		.macro localmake :name :value
		output (list ("local		~
			      word "" :name	~
			      apply		~
			      "make		~
			      (list :name :value))
		end

	It's used this way:

		to try
		localmake "garply "hello
		print :garply
		end

	LOCALMAKE outputs the list

		[local "garply apply "make [garply hello]]

	The reason for the use of APPLY is to avoid having to decide
	whether or not the second input to MAKE requires a quotation
	mark before it.  (In this case it would -- MAKE "GARPLY "HELLO --
	but the quotation mark would be wrong if the value were a list.)

	It's often convenient to use the ` function to construct the
	instruction list:

		.macro localmake :name :value
		op `[local ,[word "" :name] apply "make [,[:name] ,[:value]]]
		end