The Birth of BASIC.

General discussion for topics related to the FreeBASIC project or its community.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: The Birth of BASIC.

Post by dodicat »

marcov
The creator of C, freebasic's hero, said this about pascal, remember?
viewtopic.php?f=3&t=14526&p=148526&hili ... 2A#p148526
Has Pascal now evolved beyond this?
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: The Birth of BASIC.

Post by marcov »

dodicat wrote:marcov
The creator of C, freebasic's hero, said this about pascal, remember?
viewtopic.php?f=3&t=14526&p=148526&hili ... 2A#p148526
Has Pascal now evolved beyond this?
(I had a very large reply but lost it because of a forum timeout)

Most of them were already addressed by Modula2 1978, which absorbed into the Pascal language standard and the proposals for the next one, and appeared into e.g. Turbo Pascal mid eighties to early nineties, before the first ISO C standard even arrived.

It seems this article was a writeup of experiences mostly about UCSD, which was a bytecode interpreter, and therefore somewhat limited, but highly portable.

Anyway reading it after 1985 is IMHO a waste of time, and it would probably have been already forgotten by then, if not for the author's name, and some misplaced hero worshipping.
Linuxbob
Posts: 60
Joined: Sep 01, 2010 1:03
Location: Ohio, USA

Re: The Birth of BASIC.

Post by Linuxbob »

Tourist Trap wrote:

I would rather think it was lack of structured programming. Basic was later heavily modified for structured programming (e.g. sub's with parameters like QB got instead of just gosub <linenr>), and removed the need for goto/gosub in most common scenario.
[/quote]

IMHO, the worst impediments to the original BASIC was the lack of SUB/FUNCTION calls with parameters combined with a lack of variable scope: every variable was global by default so managing variables and variable names was sometimes a nightmare when writing programs that weren't trivial and had a lot of GOSUB calls. Funtionally, the GOTOs/GOSUBs are still in there...we just don't need to see them.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: The Birth of BASIC.

Post by jj2007 »

Linuxbob wrote:IMHO, the worst impediments to the original BASIC was the lack of SUB/FUNCTION calls with parameters combined with a lack of variable scope: every variable was global by default
Over 30 years ago, GfaBasic on the Atari had all that, including local variables, user-defined types etc; compiling took milliseconds, and the resulting executables were at least as fast as equivalent C programs. It is a mystery to me how that "Basic is not a proper programming language" urban legend survived all these years.
Linuxbob
Posts: 60
Joined: Sep 01, 2010 1:03
Location: Ohio, USA

Re: The Birth of BASIC.

Post by Linuxbob »

jj2007 wrote:It is a mystery to me how that "Basic is not a proper programming language" urban legend survived all these years.
In my experience, a lot of it comes from programmer snobbery: "there is only one way to do programming, and BASIC isn't it because it's a toy language." Spaghetti code was always a favorite fault to cite. Yes, a poorly written BASIC program will likely be a mess, but a well thought out BASIC program with appropriate comments and formatting (such as indenting FOR loops) can be very easy to follow and efficient to boot.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: The Birth of BASIC.

Post by jj2007 »

Linuxbob wrote:a well thought out BASIC program with appropriate comments and formatting (such as indenting FOR loops) can be very easy to follow and efficient to boot.
1986:

Code: Select all

    For I%=39 To 600 Step 112
      Line I%,0,I%,399
      Line I%+81,0,I%+81,399
    Next I%
    Do
      @Wait_nh
      I%=Max(1,(My%+16)/32)
      Td$="01."+Mid$(Str$(I%+100),2)+Mid$(Date$,6)
      @Get_wt(True,Td$)
      D%=Max(1,(Mx%/16)-1.5-D%)
      Td$=Mid$(Str$(D%+100),2)+Mid$(Td$,3)
      Exit If Mk%=2 Or Con!
      @Get_wt(True,Td$)
      Clr N%
      @Ba_g(0,0,639,192,0)
      Print "H";Ci$;
      While N%<=Term_max%
        Pt$=Term_f$(N%)
        Inc N%
        X!=Upper$(Left$(Pt$,2))=Upper$(Wt$)
        If Left$(Pt$,5)=Left$(Td$,5) Or X!
          Print Left$(Cn$+" "+Wt$,Len(Cn$)+3 And Not X!)'Pt$;"K";Ci$;Crlf$;"K";
        Endif
      Wend
      @Wm
      @Ba_p
    Loop
The editor took care of the indenting, and of the mixed case: typing upper$ would produce Upper$ etc. Note the suffixes: int32%, int16&, bool!, string$. The ampersand means @Gosub(args). Thirtysomething years later, I would write this 15,000+ lines program quite differently, with proper comments etc, but at the time this dialect (Gfa, ported to Windows some years later) did not even allow you to write unstructured code.
Linuxbob
Posts: 60
Joined: Sep 01, 2010 1:03
Location: Ohio, USA

Re: The Birth of BASIC.

Post by Linuxbob »

That's an excellent example. This is something I wrote in the mid 80's for a TRS-80 Model 4 using one of the BASIC compilers. Not quite as structured as yours, but not spaghetti either.

Code: Select all

'DOLLAR POKER REPEATABILITY CALCULATOR
'FOR PRO-ENHCOMP ON TRS-80 MODEL 4
'PURPOSE: THIS PROGRAM WILL RUN A SERIES OF RANDOM 8 DIGIT NUMBERS
'AND EVALUATE EACH SEQUENCE FOR THE BEST 5 CARD POKER HAND
'(I.E. PAIR, FULL HOUSE, STRAIGHT, ETC.) TO DETERMINE THE RELATIVE
'PROBABILITY OF EACH HAND.

CLS: DEFINT A-Z
DIM DIGIT(8), TEMP(8), RESULT#(11)

PRINT "Dollar Poker Calculator": PRINT
PRINT "This program will calculate the occurrences of different"
PRINT "dollar poker hands.": PRINT
INPUT "How many hands shall I run"; HANDS#
PRINT: PRINT "Initializing..."
'------------------------------------------------------------
'INITIALIZE EVERYTHING
RANDOM(CINT(HANDS))
RUNS# = 0
CLS
PRINT "Dollar Poker Calculator": PRINT
PRINT "Number of hands to run: "; HANDS#
PRINT "Running hand:": PRINT
PRINT "Eight of a kind:" 
PRINT "Seven of a kind:"
PRINT "  Six of a kind:"
PRINT " Five of a kind:"
PRINT " Four of a kind:"
PRINT "       Straight:"
PRINT "     Full House:"
PRINT "Three of a kind:"
PRINT "      Two pairs:"
PRINT "       One Pair:"
PRINT "        Nothing:"
'------------------------------------------------------------
'TOP OF THE PROCESSING LOOP
"LOOPER"
INC RUNS#: PRINT @254, RUNS#
IF RUNS# = HANDS# THEN GOTO "SUMMARY"
'CREATE A HAND
FOR I = 0 TO 7
  DIGIT(I) = RND(10) - 1
NEXT I
'------------------------------------------------------------
'FIVE CARD STRAIGHT
'OKAY TO CHECK A STRAIGHT HERE BECAUSE IF THERE IS A STRAIGHT,
'THERE CANNOT BE AN 8 THROUGH 4 OF A KIND OR A FULL HOUSE.
'SORT THE ARRAY IN ASCENDING ORDER (ENHCOMP SORT)
SCLEAR: KEY DIGIT(0): SORT 8
'ONLY NEED TO TEST STARTING WITH THE FIRST FOUR DIGITS 0-3
I = 0: J = 1  
"STRAIGHTLOOP"
FOR K = I TO I + 5
  IF TEMP(K+1)<>TEMP(K)+1 THEN J = 0
NEXT K
IF (J = 0) AND (I < 4)
  'NO STRAIGHT FOUND AND NOT DONE LOOKING
  INC I
  GOTO "STRAIGHTLOOP"
ENDIF
IF J = 1
  'STRAIGHT FOUND
  RESULT#(5) = RESULT#(5) + 1: PRINT @820, RESULT#(5)
  GOTO "LOOPER"
ENDIF
'-----------------------------------------------------------
'EIGHT OF A KIND
J = 1
FOR I = 1 TO 7
  IF DIGIT(0) = DIGIT(I) THEN INC J
NEXT I
IF J = 8
  'EIGHT OF A KIND FOUND
  INC RESULT#(0): PRINT @420, RESULT#(0)
  GOTO "LOOPER"
ENDIF
'-----------------------------------------------------------
'SEVEN OF A KIND
'THERE MUST BE A MATCH WITH THE FIRST OR SECOND DIGIT
J = 1
FOR I = 1 TO 7
  IF DIGIT(0) = DIGIT(I) THEN INC J
NEXT I
IF J = 7 THEN
  'FOUND SIX MATCHING THE FIRST DIGIT
  INC RESULT#(1): PRINT @5OO, RESULT#(1)
  GOTO "LOOPER"
ENDIF
'NOW CHECK AGAINST SECOND DIGIT
J = 1
FOR I = 2 TO 7
  IF DIGIT(1) = DIGIT(I) THEN INC J
NEXT I
IF J = 7
  INC RESULT#(1): PRINT @500, RESULT#(1)
  GOTO "LOOPER"
ENDIF
'------------------------------------------------------------
'SIX OF A KIND
'THERE MUST BE A MATCH WITH ONE OF THE FIRST THREE DIGITS
'CHECK AGAINST THE FIRST DIGIT
J = 1
FOR I = 1 TO 7
  IF DIGIT(0) = DIGIT(I) THEN INC J
NEXT I
IF J = 6
  INC RESULT#(2): PRINT @580, RESULT#(2)
  GOTO "LOOPER"
ENDIF
'NOW THE SECOND DIGIT
J = 1
FOR I = 2 TO 7
  IF DIGIT(1) = DIGIT(I) THEN INC J
NEXT I
IF J = 6
  INC RESULT#(2): PRINT @580, RESULT(2)
  GOTO "LOOPER"
ENDIF
'NOW THE THIRD DIGIT
J = 1
FOR I = 3 TO 7
  IF DIGIT(2) = DIGIT(I) THEN INC J
NEXT I
IF J = 6
  INC RESULT#(2): PRINT @580, SIX#
  GOTO "LOOPER"
ENDIF
'------------------------------------------------------------
'FIVE OF A KIND
'THERE MUST BE A MATCH WITH ONE OF THE FIRST FOUR DIGITS
FOR K = 0 TO 3
  J = 1
  FOR I = K + 1 TO 7
    IF DIGIT(K) = DIGIT(I) THEN INC J
  NEXT I
  IF J = 5
    INC RESULT#(3): PRINT @660, RESULT#(3)
    GOTO "LOOPER"
  ENDIF
NEXT K
'------------------------------------------------------------
'FOUR OF A KIND
'THERE MUST BE A MATCH WITH ONE OF THE FIRST FIVE DIGITS
FOR K = 0 TO 4
  J = 1
  FOR I = K + 1 TO 7
    IF DIGIT(K) = DIGIT(I) THEN INC J
  NEXT I
  IF J = 4
    INC RESULT#(4): PRINT @740, RESULT#(4)
    GOTO "LOOPER"
  ENDIF
NEXT K
'------------------------------------------------------------
'THREE OF A KIND AND FULL HOUSE
'CREATE A TEMPORARY ARRAY TO WORK ON
FOR I = 0 TO 7
  TEMP(I) = DIGIT(I)
NEXT I
'SORT THE ARRAY IN ASCENDING ORDER (ENHCOMP SORT)
SCLEAR: KEY TEMP(0): SORT 8
'FIRST LOOK FOR A SET OF THREE
J = 0  
FOR K = 0 TO 5
  IF TEMP(K+1) = TEMP(K) THEN INC J
  IF TEMP(K+2) = TEMP(K) THEN INC J
  IF J = 2
    'DESTROY THESE FOR THE NEXT PART
    TEMP(K) = 10 * TEMP(K)
    TEMP(K+1) = 11 * TEMP(K)
    TEMP(K+2) = 12 * TEMP(K+2)
  ENDIF
NEXT K
IF (J < 2)
  'THERE IS NOT AT LEAST ONE THREE OF A KIND
  GOTO "TWOPAIR"
ENDIF
'NOW LOOK FOR A PAIR
J = 0
FOR K = 1 TO 6
  IF TEMP(K) = TEMP(K+1) THEN INC J
NEXT K
IF J
  INC RESULT#(6): PRINT @820, RESULT#(6)
  GOTO "LOOPER"
ENDIF
'IF HERE, NO PAIR WAS FOUND, BUT THERE WAS A THREE OF A KIND
INC RESULT#(7): PRINT @900, RESULT#(7)
GOTO "LOOPER"
'-------------------------------------------------------------------
'ONE PAIR AND TWO PAIRS
"TWOPAIR"
'CREATE A TEMPORARY ARRAY TO WORK ON
FOR I = 0 TO 7
  TEMP(I) = DIGIT(I)
NEXT I
'SORT THE ARRAY IN ASCENDING ORDER (ENHCOMP SORT)
SCLEAR: KEY TEMP(0): SORT 8
'RUN FOR FIRST PAIR
I = 0: J = 0
'LOOK FOR FIRST PAIR
REPEAT
  IF TEMP(I) = TEMP(I+1)
    TEMP(I) = TEMP(I) * 10
    TEMP(I+1) = TEMP(I+1) * 11
    INC J
  ENDIF
  INC I
UNTIL (I = 7) OR (J = 1)
IF J = O THEN GOTO "NOTHING"
'LOOK FOR SECOND PAIR
I = 0
REPEAT
  IF TEMP(I) = TEMP(I+1) THEN INC J
  INC I
UNTIL (I = 7) OR (J = 2)
IF (J = 2)
  'TWO PAIRS FOUND
  INC RESULT#(8): PRINT @980, RESULT#(8)
  GOTO "LOOPER"
ELSE
  'ONE PAIR FOUND
  INC RESULT#(9): PRINT @1060, RESULT#(9)
  GOTO "LOOPER"
ENDIF
'-------------------------------------------------------------------
"NOTHING"
INC RESULT#(10): PRINT @1140, RESULT#(10)
GOTO "LOOPER"
'-------------------------------------------------------------------
"SUMMARY"
'CALCULATE AND DISPLAY PERCENTAGES
FOR I = 0 TO 10
  RATE# = (RESULT#(I) / HANDS#) * 100
  PRINT @(420 + (I * 80)), USING "##.##"; RATE#; "%"
NEXT I
PRINT: PRINT
PRINT "Press any key to continue...";
WINKEY$
END
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: The Birth of BASIC.

Post by lizard »

Nice to think for the beginning. In this Video you see at 25;06 the commodore +4 with the black case and the cursor keys like arrows which was my first machine in 1986. It has the CBM Basic V 3.5 built in on ROM so that was immediately ready when switching on.

This version was far advanced to V 2.0 from C64. It had an graphics mode and some features even missing today in FreeBASIC, like sound and vol commands:

https://www.c64-wiki.com/wiki/BASIC#Ove ... 5_Commands

You could plug in your TV and so there was a fantastic view and sound. These days it was a sensation!
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: The Birth of BASIC.

Post by leopardpm »

I think the graphics also had a sprite system built-in... not sure if this was the c-64 or the vic-20 though...maybe both. I remember I was always jealous of sprites with my poor apple II...

Edit: it was the c-64 with sprites... the vic-20 did not
Last edited by leopardpm on Jan 15, 2019 15:55, edited 1 time in total.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: The Birth of BASIC.

Post by lizard »

But Commodore made the mistake not to continue their their success line with a C1024 and so forth. Instead they bought Amiga and this was the beginning of the end.

Edit: typo
Last edited by lizard on Jan 15, 2019 16:02, edited 2 times in total.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: The Birth of BASIC.

Post by lizard »

leopardpm wrote:I think the graphics also had a sprite system built-in..
Right, for that there were the GSHAPE - SSHAPE commands, afaik.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: The Birth of BASIC.

Post by leopardpm »

it is a continual annoyance to me that FB does not directly handle sprites(and animation)/PNGs/sound, though I think I understand the reasoning....

sorry, this is just complaining and I don't need to do that...
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: The Birth of BASIC.

Post by marcov »

leopardpm wrote: Edit: it was the c-64 with sprites... the vic-20 did not
But the C-64 didn't have support for anything video or audio related in its Basic. (though there were ROM cartridges like Simon's Basic that did)
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: The Birth of BASIC.

Post by lizard »

leopardpm wrote:it is a continual annoyance to me that FB does not directly handle sprites(and animation)/PNGs/sound, though I think I understand the reasoning....

sorry, this is just complaining and I don't need to do that...
Yes, FB is OK like it is at the moment. But if we think of the things which could be added first i remember a discussion we had some time ago, wehre i have developed the following:
While it maybe would not be senseful to add a native GUI to the core at the moment, loading and handling of multimedia files would be a good thing.

In order to integrate these functions smoothly into the core of FB with respect for the original philosophy and syntax of Basic this could happen with only a few commands like

result = LOAD( [ <buffer>, ]< filename> , <type> [ , <param> ] )

in usual manner like at the other commands, here type would describe the type of file like:

sound:
TYPE_WAV
TYPE_MP3
TYPE_OGG
...

graphics:
TYPE_BMP
TYPE_PNG
TYPE_GIF
...

text:
TYPE_TXT
...

others:
TYPE_USER ' User defined
TYPE_ANY ' Any of the known, recognized by extension

Param would be optional further parameters. After loading data could be used depending on its type with commands like PLAY for soundfiles, SOUND and SPEAK for effects, waveforms and speechsynthesis like Angros47 mentioned.

Graphics can be smoothly integrated in the existing graphics system which ist already good now, BTW.
However, would be nice to have a sound command.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: The Birth of BASIC.

Post by leopardpm »

lizard wrote:But if we think of the things which could be added first i remember a discussion we had some time ago, wehre i have developed the following:
I like it! a general 'load' command which also has the ability to load user-defined 'types' - the 'type' is just a filter that the data is run through to unpack it into the buffer
Post Reply