The Logo Notebook
Part IX: SmartLOGO Can Do It Also

By Ron H. Mitchell



Last article (issue 6.1), I gave you an assignment. If you
recall, we were saying that LOGO has no means of picking out
characters within a string. There is a LOGO primitive to
determine the first element of a LOGO list (FIRST), and there is
another primitive that will give you the last element of the list
(LAST). We even have primitives that will pick out everything but
the first element (BUTFIRST) or the last element (BUTLAST).

It would seem that if we want to pick out elements of a LOGO list
in between the first and the last, we're on our own. Your
assignment was to write a LOGO procedure that would perform the
task. How did you make out?

Here's mine. It may not be the only answer, but it does work.

Procedure to simulate Smartbasic's MID$ command in LOGO

TO MID :X :Y :Z
MAKE "J 0
MAKE "TEMP []
MAKE "OUT []
DO.IT
END

TO DO.IT
IF :J < :Z [MAKE "A :Y + :J
MAKE "TEMP ITEM :A :X MAKE
"OUT SENTENCE :OUT :TEMP MAKE
"J :J+1 DO.IT] [PR :OUT]
END

All of which is sufficient to generate several paragraphs of
explanation.

Note that there is not just one procedure here but two. The
procedure MID initializes 3 variables and then transfers control
to the procedure DO.IT. But we're getting ahead of ourselves.

The Smartbasic enthusiasts will know that the command
MID$(X$,y,z) requires three inputs to do its job. The first is
the string to be considered (here referred to as X$) followed by
the position in the string at which to begin counting (y) and the
number of characters in the string to count (z). If you told
Smartbasic to:

PRINT MID$("MITCHELL",2,4)

the interpreter would reply:

ITCH

My procedure in LOGO will do the same thing. The syntax is:

MID "MITCHELL" 2 4

Obviously, if you try this without entering the procedures MID
and DO.IT as you see them above, you'll get a protest from LOGO:

I DON'T KNOW HOW TO MID

With the procedures entered, the reply will be the same as
Smartbasic gave you.

DO.IT consists of two parts. Recall the syntax for the
conditional IF:

IF [INSTRUCTIONLIST] [INSTRUCTIONLIST]

or

IF condition [true then do something] [false do something else]

In this case the condition is :J < :Z

:Z is obtained from the user as an input when the procedure MID
is invoked, and :J, a counter, increments by 1 each time DO.IT is
called. So all J is doing is counting the number of characters in
the string processed so far.

As long as :J is smaller than the maximum number of characters to
be counted, the procedure DO.IT will call itself. This is known
as recursion.

As long as :J is smaller than the maximum number of characters to
be counted, the variable "A is given a value equal to the value
of :Y - an input given by the user - plus the value of :J - the
number of characters that have already been counted. A temporary
variable "TEMP is then assigned the value of the character in the
string pointed to by :A . We then set up another variable "OUT to
hold the accumulated value of the string obtained so far. Each
time DO.IT is called, it adds to "OUT the value of "TEMP thereby
combining the desired elements of the string. This process of
concatenation is accomplished using the LOGO primitive SENTENCE.

MAKE "OUT SENTENCE :OUT :TEMP

adds each new character to the previous ones

Finally, after :Y repetitions of DO.IT :J is equal to :Z, the
procedure terminates and the condition is false. DO.IT branches
to the 'not true' instruction list which is simply to print the
variable "OUT.

MID "MITCHELL" 5 4

Clear as mud?

Back to Top