Jump to content
IGNORED

Any interest in Atari LOGO examples?


Recommended Posts

I've recently picked up an Atari 800 with an Atari Logo cartridge. (Also Basic and Mac/65). Atari Logo is probably my second favorite Atari language next to Action!

 

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.

 

Anyway, now I have Atari Logo back, I want to recreate some of these challenges in Atari Logo. Most of them should convert pretty easily. But for some, I relied on a feature in FMS Logo that Atari Logo doesn't have, being able to have higher-level functions that can take functions as inputs (i.e. in Java, they're Lambda calls like MAP, FILTER, REDUCE... Atari Logo doesn't have these). The one that I hope will convert over is the one I wrote that solves mazes. Because I created a bit-map turtle on windows (default is a dumb triangle shape) to look like the Atari Logo turtles. (That's actually the only one I did that uses any turtle graphics.)

 

I am going to convert them to amuse myself, but wondered if anyone else would be interested in seeing some Atari Logo program examples as I finish them.

 

Dave

  • Like 8
  • Thanks 4
Link to comment
Share on other sites

14 hours ago, DocSavage2001 said:

I've recently picked up an Atari 800 with an Atari Logo cartridge. (Also Basic and Mac/65). Atari Logo is probably my second favorite Atari language next to Action!

 

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.

 

Anyway, now I have Atari Logo back, I want to recreate some of these challenges in Atari Logo. Most of them should convert pretty easily. But for some, I relied on a feature in FMS Logo that Atari Logo doesn't have, being able to have higher-level functions that can take functions as inputs (i.e. in Java, they're Lambda calls like MAP, FILTER, REDUCE... Atari Logo doesn't have these). The one that I hope will convert over is the one I wrote that solves mazes. Because I created a bit-map turtle on windows (default is a dumb triangle shape) to look like the Atari Logo turtles. (That's actually the only one I did that uses any turtle graphics.)

 

I am going to convert them to amuse myself, but wondered if anyone else would be interested in seeing some Atari Logo program examples as I finish them.

 

Dave

I'd be interested.  Logo, FMSLogo for modern Windows machines, is my language to quickly mock up an idea to test out.

 

Anyone looking for a version of Logo for a modern Windows machine can find it here: http://fmslogo.sourceforge.net/

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

On 9/19/2020 at 9:54 PM, DocSavage2001 said:

I am going to convert them to amuse myself, but wondered if anyone else would be interested in seeing some Atari Logo program examples as I finish them.

 

Dave

 

Yes, please!!  I would enjoy seeing them!!

 

Edited by irich2
  • Like 2
Link to comment
Share on other sites

EXAMPLE #1: Recursion

One of the things Logo has that Action! or Basic don't have is the ability to do recursion. Where a procedure/function/routine can call itself with it's own locally scoped variables.

 

One of the things recursion is really good at is drawing fractals. It's hard to make out in the image here (because of the resolution on the Atari pixels), but each little branch of this tree below is a smaller version of the branch it's on. This procedure draws a pretty detailed picture of a tree in small enough code that I can send it to the Twitter bot later when I get it off the Atari.

 

To run it, type it in and give it some number. I think I used 75? for this one? Don't use a value less than 10 though or it will be a VERY boring tree!

 

Atari Logo Tree 2.jpg

Atari Logo Tree.jpg

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

Example #2 - More Recursion

 

This is a famous problem easily solved recursively. It's a game called Tower of Hanoi. You have three rods and on one of the rods are five rings, each a different size, stacked from the bottom to the top in decreasing size (smallest on top). The puzzle is to move all five rings from the rod they are on to a different rod and have them end up in the same order (biggest on bottom, smallest on top). You move one ring at a time and the rule is you can never move a ring such that a bigger ring is put on top of a smaller ring.

 

Recursion works well for problems (like this one) where the solution can be expressed as smaller units of the same problem. For example, if you need to move five rings from rod 1 to rod 2, if you knew how to move the top 4 rings to rod 3, then you do that, move ring 5 to rod 2 and move the four rings on top of rod 2 using the same way you moved them to rod 3. So, if you know how to solve the problem for four rings, you know how to solve it for five. Likewise, if you know how to solve it for 3 rings, you know how to solve it for four and so on. Eventually, you only need to know what to do with one and two rings and you can solve all the rest.

 

Here's the code in Logo along with an example of solving it for 3 rings (so it will all show on the screen). Note that Atari Logo is not built for speed, so if you try something like solving for 10 rings, go grab some lunch!

 

Atari Logo Hanoi.jpg

Atari Logo Hanoi 2.jpg

  • Like 5
Link to comment
Share on other sites

EXAMPLE #3 - even more recursion and extensibility

 

My original intent was to convert programs I had written in FMS (for Microsoft) Logo (a free Logo you can download and use!) back to Atari Logo. I had written them for some lunchtime coding challenges when I wanted to show off that Logo wasn't just turtle graphics (though I did do one of those too). But I'm finding the problem in doing that is that I used some features of FMS Logo that aren't in Atari Logo. At least not as Atari Logo Primitives. Especially the use of the higher order functions like MAP, FILTER, REDUCE. I used those a lot.

 

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.

 

The first challenge I did at work was to write a whole POS (Point of Sale) system for a carnival where the main program only had three global pieces of data that changed. Stock in the store, stock in the warehouse, a record of the day's receipts. Everything else was just inputs to functions. Because the program has so few variables, you never have to worry about some other function/method/procedure somewhere else modifying your data without you knowing about it. Hence, less errors/bugs (or side effects as they like to call them).

 

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.

 

MAP lets you take a function and a list of inputs and apply that function to every member of the list, spitting out a new list with the outputs of the function applied to the old list.

 

FILTER lets you take a predicate function (a function with a single input that equates to either TRUE or FALSE) and a list of inputs and it applies the predicate to every member of the input list and spits out a new list with only the members of the input list who evaluate TRUE for the predicate function.

 

REDUCE lets you take a function that takes multiple outputs and outputs a single value and run that function over a list of inputs so that in the end, you reduce the list of inputs to a single value.

 

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.

 

By the way, here's a not so secret about FMS Logo. MAP, FILTER, REDUCE are NOT built in to FMS Logo as primitives either. They only exist because someone wrote them in FMS Logo and stuck them in a directory called Logolib and it gets loaded when you boot up FMS Logo. You could go into the LogoLib and change them if you wanted. The reason they LOOK like primitives in FMS Logo is because FMS Logo has a procedure called BURY which hides user defined procedures so they don't show up when you LIST or SAVE your workspace. My current plan is to try to create a Logolib for Atari Logo and figure out a way to create a new SAVE procedure for Atari Logo that will only save the non Logolib procedures in your workspace. That's on the to-do list.

 

Anyway, if you want to start your own Logolib with MAP and REDUCE, you can save these procedures, along with the QUOTED and LISTED procedures that MAP and REDUCE use. That's a total of four procedures to start. No variables. :)

 

The examples:

For REDUCE, I used the Primitive SUM to add all the numbers in the list together to come up with a single value. I also created a user defined procedure called MAX which outputs the larger of two values, over the whole list, it picks out the biggest value.

 

For MAP, I used the Primitive FIRST which takes the first character of each word in a list and outputs a new list with those first letters. I also created a simple user defined procedure that takes a number and doubles it and MAP applies that to every member in the list.

 

Long post I know... But hey, MAP and REDUCE for Atari Logo.

 

Dave

 

LogoReduceExample.jpg

LogoReduce.jpg

LogoMapExample.jpg

LogoMap.jpg

Edited by DocSavage2001
proper attributions
  • Like 4
  • Thanks 2
Link to comment
Share on other sites

3 hours ago, DocSavage2001 said:

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.

Quote

Functional programming is all about side effects, what the customer pays for are side effects.

Now I am expecting some custom monads in the Logo :D 

Edited by zbyti
monads
  • Like 1
Link to comment
Share on other sites

On 9/28/2020 at 12:14 AM, DocSavage2001 said:

FILTER lets you take a predicate function (a function with a single input that equates to either TRUE or FALSE) and a list of inputs and it applies the predicate to every member of the input list and spits out a new list with only the members of the input list who evaluate TRUE for the predicate function.

So I finished up FILTER for Atari Logo. Unlike MAP and REDUCE which I got from Logoworks book (with some modifications), this one is all mine. :)

 

One thing that is important to remember with these higher order functions is that you want to pass the function as input NOT the evaluation of the function. What that means is:
 

SHOW FILTER "VOWELP "ELEPHANT  is right and

SHOW FILTER VOWELP "ELEPHANT is wrong.

 

If Logo sees VOWELP, it will try to evaluate that word, but if it sees "VOWELP, then it knows that it is dealing with the THING that VOWELP is, and not to evaluate it. In other words, you could also write it the right was as:

 

SHOW FILTER THING VOWELP "ELEPHANT  where THING says "Take the thing that VOWELP represents" (in this case a function).

 

 

LogoFilterExample.jpg

LogoFilter.jpg

  • Like 2
Link to comment
Share on other sites

Still adding to my LOGOLIB for Atari LOGO of features from FMS Logo (Windows) that I used a lot but don't have in Atari LOGO.

 

ITEM outputs the index-th item of a list or word (both shown below). If the index exceeds the length of the list or word, it outputs an empty list.

 

I don't really *NEED* a DIFF function, I COULD just use ITEM :INDEX - 1 in ITEM, but I prefer the format function input1 (input 2 ...) to maintain functional programming consistency. Atari LOGO does support infix functions for mathematical and logical symbols, but it confuses me when trying to parse some lines if there is a mix of infix and postfix function calls. So I will use EQUALP instead of =, SUM instead of +, and now DIFF instead of -. It's funny that Atari LOGO includes SUM, PRODUCT, REMAINDER and SQRT, but not DIFFERENCE, QUOTIENT.

LogoItem.jpg

Edited by DocSavage2001
cover index > length
  • Like 4
Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Oh, I thought this thread was about logos on the Atari computers and systems (game and corporation logos, for example), not the programming language.

 

I guess the fully capitalized "LOGO" threw me off - had it written as "Logo", I might've realized we're taking about a name of something (like the programming language).

 

In any case, I always wondered about that 'Lucasfilm Games' logo of the old, and wanted to see what it might look like if Atari 8-bit computers could've used similar colors, but in higher resolution, so I created a 'mock-up' (or Monkup, if you want)-version of it.

 

Lucasfilm-Games-Logo.png

 

P.S. Sorry, this has nothing to do with the Logo language, admins, feel free to delete this post.

  • Like 1
  • Haha 2
Link to comment
Share on other sites

4 hours ago, Monk said:

Oh, I thought this thread was about logos on the Atari computers and systems (game and corporation logos, for example), not the programming language.

 

I guess the fully capitalized "LOGO" threw me off - had it written as "Logo", I might've realized we're taking about a name of something (like the programming language).

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! :)

 

Dave

  • Haha 1
Link to comment
Share on other sites

Well, THANK YOU #FujiNet, now I can attach LOGO program listings as PDFs instead of having to take screen shots of my procedures. :)

 

Tonight, I've finished off my Atari LOGO library of useful procedures that are not already built into the primitives of the language. Most of these are procedures I used heavily in FMS Logo on Windows so I could translate some of those FSM Logo programs I wrote into Atari LOGO. I added two more since last time, but the attached PDF has all the current procedures in my "utility" library. The two I added:

SETITEM :INDEX :LIST :VALUE

The corollary to ITEM :INDEX :LIST - Instead of returning the INDEXth item in a list, it replaces the INDEXth item of a list with VALUE. These routines in Atari LOGO are actually 'cleaner' than they are in FMS Logo because FMS Logo doesn't support ITEM or SETITEM on lists only arrays (which Atari LOGO doesn't have). So, in FMS Logo, when I wanted to use ITEM or SETITEM on a list, I would have to convert the list into an array, then use ITEM/SETITEM and then convert the array back into a list. These procedures just work directly on lists without conversion.

SAVE.CLEAN :FILENAME

The problem with using a library of utility procedures in Atari LOGO is that when you write your own programs, if you save them, Atari LOGO will save the entire workspace including all the utility procedures along with your program. FMS Logo gets around this because in FMS Logo, you can 'bury' utility library procedures so they aren't seen as part of the workspace, even though they are there.

 

So, I created this procedure so you can do a clean SAVE of your Atari LOGO programs WITHOUT any of the utility procedures getting saved along with your program. I do this by erasing all the utility procedures and then doing a SAVE. Note that a) SAVE.CLEAN can even erase itself and it will still work and b) that ";" is actually a procedure name, not a formatting command or a comment.

 

Now that the library of things I need (and you will probably find them useful too if you do much LOGO stuff), I can start doing an actual program that does something! Coming up...

 

Dave

LogoLib.pdf

  • Like 5
Link to comment
Share on other sites

Turns out I did need to add something more to my Logo Library of things I needed to take from FMS Logo on Windows.

 

FMS Logo has comparison procedures called LESSP and GREATERP (The P at the end of these procedures stands for 'predicate', meaning these are functions whose output will [usually] equate to TRUE or FALSE). Atari LOGO doesn't have either of these but DOES have the corresponding 'infix' comparisons < and >.

 

But it turns out there is an issue with using these in Atari LOGO to try to do the same things that LESSP and GREATERP do in FMS Logo. That's because Atari LOGO < and > will only take numbers (or objects that are numbers) and will not evaluate the inputs if they are functions/procedures. So...

PR SUM 3 1 < DIFF 7 -2
< DOES NOT LIKE SUM 3 1 AS INPUT

Even using other 'infix' operations do not work:

PR 3+1 < 7-5
< DOES NOT LIKE 3+1 AS INPUT

BUT... you CAN do this... (which I did)

TO LESSP :A :B
OUTPUT :A < :B
END
              
PR LESSP SUM 3 1 DIFF 7 2
TRUE
             

The reason THAT works is that BEFORE evaluation LESSP, Atari LOGO looks at how many inputs LESSP wants and sees 2, then it will evaluate SUM 3 1 as the first input and DIFF 7 2 as the second input BEFORE executing the LESSP function. So I had to add LESSP and GREATERP to my updated Logo Library, which I've attached here again, both as a PDF and as a file on an .ATR.

 

Note that this Logo Library adds MAP, REDUCE, FILTER (higher order functions), LESSP, GREATERP, ITEM, SETITEM, DIFF, a SAVE.CLEAN utility procedure and this entire library still prints out on a single page and no procedure is more than 3 lines long. Such is the beauty of recursion! :)

 

I've also attached a small project I did for one of our lunch time competitions at work. It deals two hands of cards, makes sure no cards are duplicated in either hand, figures out the best poker hand possible from the dealt hand and compares the two hands to see who won. (or if they are equal.)

 

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.

 

The actual hands that are dealt, their poker equivalents, and some helper objects that cut down on the logic needed to figure out the poker hands, these were all locally defined in the FMS Logo version. For the Atari version, before the program ends, I call a procedure called CLEANUP that erases all these 'local' objects so you won't save them along with your workspace.

 

This program has a few more procedures that ARE over three lines long, but if you look at them closely, they all share one common denominator. They do their work in a sequential fashion instead of using recursion. 

 

If you want to play around with it, I've attached the PDF for both the LogoLib and the Poker program. If you take the disk image, make sure to load BOTH files to your LOGO workspace. You can execute the program by typing POKER. If you change or add something to the POKER program, be sure to use SAVE.CLEAN not the built-in SAVE.

 

NOTE this program is slow. The Atari LOGO implementation CAN do the higher order functions but it wasn't built for it. So it can chug along at times. But the point of this exercise wasn't to write commercial quality code, just to show off the 40 year old Atari LOGO can do some major recursive tricks, which makes it one of the few Atari native languages that can do that. Just remember to RECYCLE often to reclaim NODES. (You can see free NODES left by doing a PR NODES.)

 

Dave

 

Poker.jpg

LOGODISK.ATR LOGOLIB.pdf POKER.pdf

Edited by DocSavage2001
formatting
  • Like 2
  • Confused 1
Link to comment
Share on other sites

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.

 

The odds of a naturally occurring Royal Flush are just shy of 650,000 to 1. But I don't have to run my program 650,000 times hoping to hit that condition. Right from the workspace, I can just do...

PR POKERHAND [AC JC 10C KC QC]
royal flush

PR POKERHAND [KS 10S AS QS JS]
royal flush

PR POKERHAND [KS 10S AD JS QS]
straight

PR POKERHAND [KS JS 9S QS 10S]
straight flush

Dave

  • Like 5
Link to comment
Share on other sites

  • 2 years later...
On 9/27/2020 at 10:14 PM, DocSavage2001 said:

EXAMPLE #3 - even more recursion and extensibility

 

My original intent was to convert programs I had written in FMS (for Microsoft) Logo (a free Logo you can download and use!) back to Atari Logo. I had written them for some lunchtime coding challenges when I wanted to show off that Logo wasn't just turtle graphics (though I did do one of those too). But I'm finding the problem in doing that is that I used some features of FMS Logo that aren't in Atari Logo. At least not as Atari Logo Primitives. Especially the use of the higher order functions like MAP, FILTER, REDUCE. I used those a lot.

 

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.

 

The first challenge I did at work was to write a whole POS (Point of Sale) system for a carnival where the main program only had three global pieces of data that changed. Stock in the store, stock in the warehouse, a record of the day's receipts. Everything else was just inputs to functions. Because the program has so few variables, you never have to worry about some other function/method/procedure somewhere else modifying your data without you knowing about it. Hence, less errors/bugs (or side effects as they like to call them).

 

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.

 

MAP lets you take a function and a list of inputs and apply that function to every member of the list, spitting out a new list with the outputs of the function applied to the old list.

 

FILTER lets you take a predicate function (a function with a single input that equates to either TRUE or FALSE) and a list of inputs and it applies the predicate to every member of the input list and spits out a new list with only the members of the input list who evaluate TRUE for the predicate function.

 

REDUCE lets you take a function that takes multiple outputs and outputs a single value and run that function over a list of inputs so that in the end, you reduce the list of inputs to a single value.

 

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.

 

By the way, here's a not so secret about FMS Logo. MAP, FILTER, REDUCE are NOT built in to FMS Logo as primitives either. They only exist because someone wrote them in FMS Logo and stuck them in a directory called Logolib and it gets loaded when you boot up FMS Logo. You could go into the LogoLib and change them if you wanted. The reason they LOOK like primitives in FMS Logo is because FMS Logo has a procedure called BURY which hides user defined procedures so they don't show up when you LIST or SAVE your workspace. My current plan is to try to create a Logolib for Atari Logo and figure out a way to create a new SAVE procedure for Atari Logo that will only save the non Logolib procedures in your workspace. That's on the to-do list.

 

Anyway, if you want to start your own Logolib with MAP and REDUCE, you can save these procedures, along with the QUOTED and LISTED procedures that MAP and REDUCE use. That's a total of four procedures to start. No variables. :)

 

The examples:

For REDUCE, I used the Primitive SUM to add all the numbers in the list together to come up with a single value. I also created a user defined procedure called MAX which outputs the larger of two values, over the whole list, it picks out the biggest value.

 

For MAP, I used the Primitive FIRST which takes the first character of each word in a list and outputs a new list with those first letters. I also created a simple user defined procedure that takes a number and doubles it and MAP applies that to every member in the list.

 

Long post I know... But hey, MAP and REDUCE for Atari Logo.

 

Dave

 

LogoReduceExample.jpg

LogoReduce.jpg

LogoMapExample.jpg

LogoMap.jpg

Interesting stuff! I stumbled across LOGO in an effort to troll some functional programming purist ivory tower types. I came up with an implementation of FORTRAN's DO loop in LOGO, with the original evil F66 semantics. Some support functions and the experience turned out to be applicable to my own take on MAP, FILTER, and REDUCE. However, how do I get pasteable plain text out of LOGO on the Altirra emulator? SAVE "P: can't open P:, probably because I have no idea how to set up the 850, and while saving and loading from .CAS files has been the most convenient for me so far, I suppose I'd need to whip up something to extract text from .CAS. Or figure out the "Host device." Halp!

Link to comment
Share on other sites

15 hours ago, yetanothertroll said:

However, how do I get pasteable plain text out of LOGO on the Altirra emulator?

In Altirra, Click "View" and select Printer Output (or press "ALT" - 8 ), will open a window below the emulator screen, you can

divert all printer output here.

 

Once you have some output, you can use the mouse the select what text you need, then press "CTRL"-C to copy

the text and "CTRL"-V to paste it, right click in the printer window to clear the text.

 

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, TGB1718 said:

In Altirra, Click "View" and select Printer Output (or press "ALT" - 8 ), will open a window below the emulator screen, you can

divert all printer output here.

 

Once you have some output, you can use the mouse the select what text you need, then press "CTRL"-C to copy

the text and "CTRL"-V to paste it, right click in the printer window to clear the text.

 

Thanks. I tried that in Altirra 4.01 and still got errors from LOGO's SAVE "P: . I worked around it by saving my workspace to cassette then throwing together a program in X11-Basic to extract plain text from the .CAS file:

#!/usr/bin/xbasic
Program CASDump

 Clr CASFile$, TXTFile$
 
 FileSelect "Select input CAS file", "./*", "in.cas", CASFile$
 FileSelect "Select output text file", "./*", "out.txt", TXTFile$
 
 Print "'"; CASFile$; "'"
 Print "'"; TXTFile$; "'"
 
 ! Stop
 
 Open "I", #1, CASFile$
 Open "A", #2, TXTFile$
 
 Print #2
 Print #2, "*************************"
 Print #2, Date$; " "; Time$; " "; CASFile$
 Print #2, "*************************"
 
 
 While Not EOF(#1)
 
  CType$ = Space$(4)
  Clr CLen%, CAux%, CData$
  
  BGet #1, VarPtr(CType$), 4
  BGet #1, VarPtr(CLen%), 2
  BGet #1, VarPtr(CAux%), 2
  
  Print CType$, CLen%, CAux%
  
  If CLen%
   CData$ = Space$(CLen%)
   BGet #1, VarPtr(CData$), CLen%
   
   Print Left$(CData$, 2), 
   Print Asc(Mid$(CData$, 3, 1)) And 255,
   Print Asc(Right$(CData$, 1)) And 255
   
   ! Print "'"; Mid$(CData$, 4, CLen% - 4); "'    "
   
   Print "'";
   
   For i% = 4 To CLen% - 1
    j% = Asc(Mid$(CData$, i%, 1)) And 255
    If j% = 155
     Print "\"; "n";
     Print #2
    Else If (j% < 32) Or (j% > 126)
     Print "\"; j%; ";";
     Print #2, "\"; j%; ";";
    Else
     Print Mid$(CData$, i%, 1);
     Print #2, Mid$(CData$, i%, 1);
    EndIf
   Next i%
   
   Print "'"
   
   
  EndIf
  
 WEnd
 
 Print #2
 Print #2
 Print #2, "*************************"
 
 Close #1
 Close #2
 
 Print "OK"
End

So far it works with LOGO workspaces. I haven't tried it yet with BASIC programs or other program output sent to the cassette.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...