translate code blocks to Ludus, learn some things, take some notes

This commit is contained in:
Scott Richmond 2024-12-01 19:01:50 -05:00
parent 32cf547efb
commit 9890a6f0c2

View File

@ -120,7 +120,6 @@ Get a lot of it.
Be careful using this glue, though; it is very flammable. Be careful using this glue, though; it is very flammable.
Don't smoke and glue at the same time. Don't smoke and glue at the same time.
### Dialects ### Dialects
Unfortunately, there is not just one Logo. Unfortunately, there is not just one Logo.
While some Logos are more alike than others, most have quirks. While some Logos are more alike than others, most have quirks.
@ -196,7 +195,7 @@ Review the turtle reference commands: `FD`, `BK`, `PU`, `PD`, `RT` `LT`.
In the cartesian system, the destination is the important thing; in the turtle reference system, it's the trip. In the cartesian system, the destination is the important thing; in the turtle reference system, it's the trip.
### Making shapes ### Making shapes
Let's draw a simpel shape using turtle reference commands. Let's draw a simple shape using turtle reference commands.
Suppose you would like the turtle to draw a square box located at the center of the screen (usually the origin of the coordinate system). Suppose you would like the turtle to draw a square box located at the center of the screen (usually the origin of the coordinate system).
Here are the steps you would take: Here are the steps you would take:
@ -216,10 +215,10 @@ That's it.
The turtle has walked around the four sides of a size 50 box, arriving back to where it started. The turtle has walked around the four sides of a size 50 box, arriving back to where it started.
These prose commands would translate into Logo as: These prose commands would translate into Logo as:
1. `FD 50 RT 90` 1. `forward! (50); right! (0.25)`
2. `FD 50 RT 90` 2. `forward! (50); right! (0.25)`
3. `FD 50 RT 90` 3. `forward! (50); right! (0.25)`
4. `FD 50 RT 90` 4. `forward! (50); right! (0.25)`
The third and last step would be to type these commands on the keyboard. The third and last step would be to type these commands on the keyboard.
And here is what you will see. And here is what you will see.
@ -234,11 +233,13 @@ Review the `REPEAT` command; it is exactly what we need here.
Try it. Try it.
``` ```
CG repeat 4 {
REPEAT 4 [FD 50 RT 90] forward! (50)
right! (0.25)
}
``` ```
Notice that the line `REPEAT 4 [FD 50 RT 90]` is a kind of operational definition of what a square is: a square is four sides, four `FD` commands, with each side joined at right angles to the next, the `RT 90` commands. Notice that the line `repeat 4 { forward! (50); right! (0.25) }` is a kind of operational definition of what a square is: a square is four sides, four `FD` commands, with each side joined at right angles to the next, the `RT 90` commands.
That's tidy, but it's still a bore to type two lines each time you want a size 50 box on the screen. That's tidy, but it's still a bore to type two lines each time you want a size 50 box on the screen.
After all, you may want to draw 100 boxes. After all, you may want to draw 100 boxes.
@ -257,9 +258,12 @@ Let's get on with writing the necessary procedure.
Here it is: Here it is:
``` ```
TO BOX50 fn box50! () -> {
REPEAT 4 [FD 50 RT 90] repeat 4 {
END forward! (50)
right! (0.25)
}
}
``` ```
Logo will add `BOX50` to all its other commands. Logo will add `BOX50` to all its other commands.
@ -276,7 +280,14 @@ Keep track of what you are doing in your notebook so that you can reconstruct yo
Here is a simple command that wraps boxes around the screen: Here is a simple command that wraps boxes around the screen:
``` ```
REPEAT 25 [PD BOX50 PU RT 15 FD 60 LT 15] repeat 25 {
pendown! ()
box50! ()
penup! ()
right! (inv (24))
forward! (60)
left! (inv (24))
}
``` ```
### Wrapped boxes ### Wrapped boxes
@ -314,9 +325,12 @@ You can now draw boxes of any size from, say, 1 unit to 5000 units.
Use this example as a "pattern" for incorporating an argument into a procedure. Use this example as a "pattern" for incorporating an argument into a procedure.
``` ```
TO BOX :EDGE fn box! (edge) -> {
REPEAT 4 [FD :EDGE RT 90] repeat 4 {
END forward! (edge)
right! (0.25)
}
}
``` ```
### Putting a demonsuation procedure together ### Putting a demonsuation procedure together
@ -339,13 +353,22 @@ If you wish to show off with several designs, you could design specific Logo pro
Here is an example of such a demonstration procedure: Here is an example of such a demonstration procedure:
``` ```
TO DEMO & A demonstration procedure to show off a design
; A demonstration procedure to show off a design & produced from multiple boxes of different sizes.
; produced from multiple boxes of different sizes. fn demo () -> {
REPEAT 4 [BOX 100 BOX 98 BOX 96 BOX 75 BOX 40 repeat 4 {
BOX 35 BOX 30 RT 90] box! (100)
END box! (98)
box! (96)
box! (75)
box! (40)
box! (35)
box! (30)
right! (0.25)
}
}
``` ```
To see the pattern defined by `DEMO`, type it: To see the pattern defined by `DEMO`, type it:
{{Figure 4: Differently sized boxes. Top of p. 15.}} {{Figure 4: Differently sized boxes. Top of p. 15.}}
@ -399,9 +422,12 @@ Why not call the generalized procedure `NGON` for n-sided polygon?
Look again at the procedure BOX and decide what needs to be changed to turn `BOX` into `NGON`. Look again at the procedure BOX and decide what needs to be changed to turn `BOX` into `NGON`.
``` ```
TO BOX :EDGE fn box! (edge) -> {
REPEAT4 [FD :EDGE RT 90] repeat 4 {
END forward! (edge)
right! (0.25)
}
}
``` ```
You need to add a second argument `:N`. You need to add a second argument `:N`.
@ -423,13 +449,16 @@ Review the Logo notation to add, subtract, multiply, and divide.)
You are ready to write the new procedure NGON: You are ready to write the new procedure NGON:
``` ```
TO NGON :N :EDGE fn ngon! (n, edge) -> {
REPEAT :N [FD :EDGE RT 360/:N] repeat n {
END forward! (edge)
right! (inv (n))
}
}
``` ```
Try it out. Try it out.
Notice that when: N becomes large, the drawn figure becomes a circle (almost). Notice that when `:N` becomes large, the drawn figure becomes a circle (almost).
Carry out some clever visual experiments with `NGON`s. Carry out some clever visual experiments with `NGON`s.
### Some observations ### Some observations
@ -481,12 +510,12 @@ For a 90% shrinkage I would use `:GROWTH`=.9."
### A procedure to spin polygons ### A procedure to spin polygons
``` ```
TO SPINGON :N :EDGE :ANGLE :GROWTH fn spingon! (n, edge, angle, growth) -> {
NGON :N :EDGE ngon! (n, edge)
RT :ANGLE right! (angle)
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH spingon! (n, mult (edge, growth), angle, growth)
; Here is the recursion. & Here is the recursion
END }
``` ```
What is new here? What is new here?
@ -501,14 +530,17 @@ Will `SPINGON` ever stop? Try it out.
### Some spingons ### Some spingons
``` ```
SPINGON 30 2 10 1.02 95 spingon! (30, 2, inv (36), 1.02, 95)
``` ```
{{Figure 7: Snail-ish spingon. Top of p. 21.}} {{Figure 7: Snail-ish spingon. Top of p. 21.}}
``` ```
HOME CG REPEAT 3 [SPINGON 4 120 0 .95 50 RT 90] repeat! 3 {
SPINGON 4 120 0 .95 19 spingon! (4, 120, 0, 0.95, 50)
right! (0.25)
}
spingon! (40, 120, 0, 0.25, 19)
``` ```
{{Figure 8: Frame-ish spingons. Bottom of p. 21.}} {{Figure 8: Frame-ish spingons. Bottom of p. 21.}}
@ -524,15 +556,17 @@ Review the conditional commands in Logo.
Using the `IF` phrase, everything becomes very tidy. Using the `IF` phrase, everything becomes very tidy.
``` ```
TO SPINGON :N :EDGE :ANGLE :GROWTH :TIMES fn spingon! (n, edge, angle, growth, times) -> {
; Note the new argument above. & Note the new argument above.
IF :TIMES < 1 [STOP] if lt? (times, 1) then :stop
; This is the conditional stopper. & This is the conditional stopper.
NGON :N :EDGE else {
RT :ANGLE ngon! (n, edge)
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH (:TIMES-1) rt! (angle)
; Note the new argument above. spingon! (n, mult (edge, growth), angle, growth, dec (times))
END & Note the new argument above.
}
}
``` ```
### Boring logistics ### Boring logistics
@ -560,15 +594,17 @@ Here is an example from this chapter.
Notice the use of comments, too. Notice the use of comments, too.
``` ```
TO SPINGON :N :EDGE :ANGLE :GROWTH :TIMES fn spingon! (n, edge, angle, growth, times) -> {
; Note the new argument above. & Note the new argument above.
IF :TIMES < 1 [STOP] if lt? (times, 1) then :stop
; This is the conditional stopper. & This is the conditional stopper.
NGON :N :EDGE else {
RT: ANGLE ngon! (n, edge)
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH (:TIMES-1) rt! (angle)
; Note the new argument above. spingon! (n, mult (edge, growht), angle, growht, dec (times))
END & Note the new argument above.
}
}
``` ```
Third, the _body structuring_ rule. Third, the _body structuring_ rule.
@ -579,13 +615,15 @@ Here is an example.
Notice that the Logo material within the [repeat brackets] would have been difficult to read if the long statement had not been divided into several short lines. Notice that the Logo material within the [repeat brackets] would have been difficult to read if the long statement had not been divided into several short lines.
``` ```
TO SQUIGGLE :A :B :N fn squiggle! (a, b, n) -> {
REPEAT :N [ FD :A - repeat n {
RT 130 - forward! (a)
FD :A - rightt! (inv (3))
RT 50 - forward! (a)
BK :B ] right! (inv (6))
END back! (b)
}
}
``` ```
The symbol "`-`" indicates, of course, that the return key should not be used becausethe Logo statement continues. The symbol "`-`" indicates, of course, that the return key should not be used becausethe Logo statement continues.
@ -614,7 +652,7 @@ This is another way to ask yourself what information must be given to `CNGON` so
That means that the first line of the new procedure will look like this: That means that the first line of the new procedure will look like this:
``` ```
CNGON :N :RAD cngon! (n, rad)
``` ```
Second, imagine yourself as the turtle. Second, imagine yourself as the turtle.
@ -689,14 +727,19 @@ No more words are necessary.
Here it is. Here it is.
``` ```
TO CNGON :N :RAD fn cngon! (n, rad) -> {
PU FD :RAD penup! ()
RT (angle) PD forward! (rad)
NGON :N (edge) right! (::angle::)
LT (angle) pendown! ()
PU BK :RAD PD ngon! (n, ::edge::)
END left! (::angle::)
penup! ()
back! (rad)
pendown! ()
}
``` ```
The procedure is sketched. The procedure is sketched.
And we know what we know and what we don't. And we know what we know and what we don't.
The two amounts, (angle) and (edge), are still unknown. The two amounts, (angle) and (edge), are still unknown.
@ -719,31 +762,31 @@ The external angle is the turning angle used in `NGON`.
What about the internal angles, labeled b. What about the internal angles, labeled b.
We need some work here: We need some work here:
(1) c = 360/n, (1) c = 1/n,
(2) c + b = 180. (2) c + b = 1/2.
Putting these two equations together and solving for b gives Putting these two equations together and solving for b gives
(3) b=180*(n-2)/n. (3) b = 1/2 - 1/n.
We are now ready to handle the first problem: Find d in terms of n. We are now ready to handle the first problem: Find d in terms of n.
(4) d + b/2 = 180. (4) d + b/2 = 1/2.
Putting (3) and (4) together and solving for d gives Putting (3) and (4) together and solving for d gives
(5) d = 180 - 90*(n-2)/n <---**First problem solved**. (5) d = 1/4 + 1/2n <---**First problem solved**.
OK, now look at the second problem: Find e in terms of R and n. OK, now look at the second problem: Find e in terms of R and n.
(6) sin (a/2) = (e/2)/R, (6) sin (a/2) = (e/2)/R,
(7) a = 360/n. (7) a = 1/n.
Putting (7) and (6) togetherand solving for e gives Putting (7) and (6) togetherand solving for e gives
(8) e = 2\*R\*sin(180/n) <---**Second problem solved**. (8) e = 2\*R\*sin(1/2n) <---**Second problem solved**.
Review the following trig functions: sine, cosine, and tangent. Review the following trig functions: sine, cosine, and tangent.
What is ani arctangent? What is ani arctangent?
@ -754,34 +797,45 @@ Glue them on the inside cover of your notebook.
Here's how far we have gotten with `CNGON`: Here's how far we have gotten with `CNGON`:
``` ```
TO CNGON :N :RAD fn cngon! (n, rad) -> {
PU FD:RAD penup! ()
RT (angle) PD forward! (rad)
NGON :N (edge) right! (::angle::)
LT (angle) pendown! ()
PU BK :RAD PD ngon! (n, ::edge::)
END left! (::angle::)
penup! ()
back! (rad)
pendown! ()
}
``` ```
Now we can replace `(angle)` and `(edge)` with the needed expressions. Now we can replace `(angle)` and `(edge)` with the needed expressions.
Here is the finished `CNGON`: Here is the finished `CNGON`:
``` ```
TO CNGON :N :RAD fn cngon! (n, rad) -> {
PU FD :RAD let angle = sub (inv (2), inv (n))
RT 180 - (90*(:N-2)/:N) PD let edge = mult (2, rad, sin (inv (mult (2, n))))
NGON :N (2*:RAD*SIN (180/:N))
LT 180 - (90*(:N-2)/:N) penup! ()
PU BK :RAD PD forward! (rad)
END right! (angle)
pendown! ()
ngon! (n, edge)
left! (angle)
penup! ()
back! (rad)
pendown! ()
}
``` ```
### Lessons and tips ### Lessons and tips
When solving visual problems, like this CNGON thing, try to break the single big problem down into several smaller problems. When solving visual problems, like this `CNGON` thing, try to break the single big problem down into several smaller problems.
Solve each of the small problems in turn, and then plug the little solutions together to form one big solution. Solve each of the small problems in turn, and then plug the little solutions together to form one big solution.
#### Exercise 1.2 #### Exercise 1.2
Put together one or more DEMO procedures that make imaginative use of the ideas presented and reviewed in this chapter. Put together one or more `DEMO` procedures that make imaginative use of the ideas presented and reviewed in this chapter.
Modify every procedure in the chapter. Modify every procedure in the chapter.
Make them act more strangely. Make them act more strangely.
@ -825,3 +879,26 @@ Don't forget the following tricks:
research. research.
6. Translate the words into Logo commands. 6. Translate the words into Logo commands.
7. Test it out with realistic and totally outlandish argument values 7. Test it out with realistic and totally outlandish argument values
### Notes for adaptation
* Don't use abbreviations everywhere!
* Stopping recursion looks different.
- This will be different once we get actors and Ludus runs in a different thread. Is this a prerequisite?
* Math is harder, since we don't have familiar arithmetic operators.
* A few places there are arbitrary degrees; figure out how to make this friendlier.
- Throughout, replace degrees with turns.
* Consider a helper function, `double`, to simplify the math for `cngon!`.
* Procedure -> function, throughout.
* The canvas doesn't (currently) wrap, so the example of many squares with wrapping needs to be a bit different.
* Prepping the annotated SVGs will be a thing.
- Do we want hand-drawn stuff? Consider using the iPad.
* This we do not need here:
- Appeals to a manual
- The `-` character to continue a line
* Things we do need that are absent (in no particular order):
- `let` bindings
- M-expression math
- A discussion of turns instead of degrees
- A discussion of empty parens/function calls
- A discussion of bangs in names
- A discussion of question marks in names