[Info-vax] BASIC (was Re: 64-bit)
Arne Vajhøj
arne at vajhoej.dk
Fri Jan 12 14:56:15 EST 2024
On 1/12/2024 12:40 AM, Dave Froble wrote:
> On 1/11/2024 2:42 PM, Dan Cross wrote:
>> In article <unpa1b$3316l$2 at dont-email.me>,
>> Dave Froble <davef at tsoft-inc.com> wrote:
>>> On 1/10/2024 9:28 PM, bill wrote:
>>>> On 1/10/2024 7:02 PM, Arne Vajhøj wrote:
>>>>> The world has evolved.
>>>>
>>>> Exactly. BASIC also evolved, but better languages have passed it by.
>>>
>>> I confess to curiosity. In what ways has other languages passed by
>>> Basic?
>>
>> Usually the answer to this is going to be some combination of
>> better abstraction facilities, better safety properties, more
>> capable and ergonomic libraries, etc.
>
> Which then asks the question, are such really better? Perhaps some of
> that is more opinion than fact.
It is not so much Basic vs other languages but a 70's/80's language
vs a modern languages.
But yes progress has been made.
>> VSI BASIC appears to have a few useful things like static type
>> definitions, functions, etc, and it frees the programmer from
>> _having_ to specify e.g. line numbers. But it doesn't seem to
>> have a lot of support for other abstraction facilities like
>> modules, classes, or anything of that nature.
>
> What amuses me about that is that when people talk about "classes", I
> don't have a clue what they are talking about. Perhaps I do, if the
> case is new names for old concepts. That is something I didn't like
> about Microsoft, they seemed to like re-naming concepts.
Think of classes as record definition with both data and subs/functions.
Bundling the subs/functions with the data they are working on usually
give cleaner code and you have the ability to restrict access to data
to the subs/functions within the class.
Let me produce an example in VMS Basic and VB.NET.
$ type datarec.bas
option type = explicit
record datarec
string created = 20
integer counted
end record
$ type vms.bas
program main
%include "datarec.bas"
declare integer nrec
declare datarec alld(1 to 1000)
external datarec function init_datarec(integer)
external sub dump(integer, datarec dim())
print "VMS Basic"
nrec = 0
nrec = nrec + 1
alld(nrec) = init_datarec(37)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_datarec(32)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_datarec(19)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_datarec(50)
call dump(nrec, alld())
end program
!
function datarec init_datarec(integer c)
%include "datarec.bas"
external sub lib$date_time(string by desc)
declare datarec res
call lib$date_time(res::created)
res::counted = c
init_datarec = res
end function
!
sub dump(integer nrec, datarec lstd())
%include "datarec.bas"
declare integer i
external string function tostring(datarec)
for i = 1 to nrec
print tostring(lstd(i))
next i
end sub
!
function string tostring(datarec d)
%include "datarec.bas"
tostring = "[" + d::created + ": " + str$(d::counted) + "]"
end function
$ bas vms
$ link vms
$ run vms
VMS Basic
[12-JAN-2024 15:38:18: 37]
[12-JAN-2024 15:38:19: 32]
[12-JAN-2024 15:38:20: 19]
[12-JAN-2024 15:38:21: 50]
vs
Imports System
Imports System.Collections.Generic
Imports System.Threading
Namespace Modern
Public Class Data
Public Property Created() As DateTime
Public Property Counted() As Integer
Public Sub New(c As Integer)
Created = DateTime.Now
Counted = c
End Sub
Public Overrides Function ToString() As String
Return String.Format("[{0}: {1}]", Created, Counted)
End Function
End Class
Public Class Program
Public Shared Sub Dump(lstd As List(Of Data))
For Each d As Data In lstd
Console.WriteLine(d)
Next
End Sub
Public Shared Sub Main(args As String())
Console.WriteLine("VB.NET")
Dim alld As New List(Of Data)()
alld.Add(New Data(37))
Thread.Sleep(1000)
alld.Add(New Data(32))
Thread.Sleep(1000)
alld.Add(New Data(19))
Thread.Sleep(1000)
alld.Add(New Data(50))
Dump(alld)
Console.ReadKey()
End Sub
End Class
End Namespace
VB.NET
[1/12/2024 2:44:53 PM: 37]
[1/12/2024 2:44:54 PM: 32]
[1/12/2024 2:44:55 PM: 19]
[1/12/2024 2:44:56 PM: 50]
And if we spice it up by extending the data structure:
$ type datarec.bas
option type = explicit
record datarec
string created = 20
integer counted
end record
$ type extdatarec.bas
%include "datarec.bas"
record extdatarec
datarec main
integer verified
end record
declare integer constant VERIFIED = 1
declare integer constant NOT_VERIFIED = 2
$ type vms2.bas
program main
%include "extdatarec.bas"
declare integer nrec
declare extdatarec alld(1 to 1000)
external extdatarec function init_extdatarec(integer, integer)
external sub dump(integer, extdatarec dim())
print "VMS Basic"
nrec = 0
nrec = nrec + 1
alld(nrec) = init_extdatarec(37, VERIFIED)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_extdatarec(32, VERIFIED)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_extdatarec(19, VERIFIED)
sleep(1)
nrec = nrec + 1
alld(nrec) = init_extdatarec(50, NOT_VERIFIED)
call dump(nrec, alld())
end program
!
function extdatarec init_extdatarec(integer c, integer v)
%include "extdatarec.bas"
declare extdatarec res
external datarec function init_datarec(integer)
res::main = init_datarec(c)
res::verified = v
init_extdatarec = res
end function
!
function datarec init_datarec(integer c)
%include "datarec.bas"
external sub lib$date_time(string by desc)
declare datarec res
call lib$date_time(res::created)
res::counted = c
init_datarec = res
end function
!
sub dump(integer nrec, extdatarec lstd())
%include "extdatarec.bas"
declare integer i
external string function tostring(extdatarec)
for i = 1 to nrec
print tostring(lstd(i))
next i
end sub
!
function string tostring(extdatarec d)
%include "extdatarec.bas"
declare string VERTEXT(VERIFIED to NOT_VERIFIED)
VERTEXT(VERIFIED) = "Verified"
VERTEXT(NOT_VERIFIED) = "Not verified"
tostring = "[" + d::main::created + ": " + str$(d::main::counted) + " ("
+ VERTEXT(d::verified) + ")]"
end function
$ bas vms2
$ link vms2
$ run vms2
VMS Basic
[12-JAN-2024 15:42:38: 37 (Verified)]
[12-JAN-2024 15:42:39: 32 (Verified)]
[12-JAN-2024 15:42:40: 19 (Verified)]
[12-JAN-2024 15:42:41: 50 (Not verified)]
vs
Imports System
Imports System.Collections.Generic
Imports System.Threading
Namespace Modern2
Public Class Data
Public Property Created() As DateTime
Public Property Counted() As Integer
Public Sub New(c As Integer)
Created = DateTime.Now
Counted = c
End Sub
Public Overrides Function ToString() As String
Return String.Format("[{0}: {1}]", Created, Counted)
End Function
End Class
Public Class ExtData
Inherits Data
Public Property Verified() As Boolean
Public Sub New(c As Integer, v As Boolean)
MyBase.New(c)
Verified = v
End Sub
Public Overrides Function ToString() As String
Return String.Format("[{0}: {1} ({2})]", Created, Counted,
If(Verified, "Verified", "Not verified"))
End Function
End Class
Public Class Program
Public Shared Sub Dump(lstd As List(Of Data))
For Each d As Data In lstd
Console.WriteLine(d)
Next
End Sub
Public Shared Sub Main(args As String())
Console.WriteLine("VB.NET")
Dim alld As New List(Of Data)()
alld.Add(New ExtData(37, True))
Thread.Sleep(1000)
alld.Add(New ExtData(32, True))
Thread.Sleep(1000)
alld.Add(New ExtData(19, True))
Thread.Sleep(1000)
alld.Add(New ExtData(50, False))
Dump(alld)
Console.ReadKey()
End Sub
End Class
End Namespace
VB.NET
[1/12/2024 2:49:04 PM: 37 (Verified)]
[1/12/2024 2:49:05 PM: 32 (Verified)]
[1/12/2024 2:49:07 PM: 19 (Verified)]
[1/12/2024 2:49:08 PM: 50 (Not verified)]
Besides using objected oriented programming the VB.NET code also
used some generic programming. The List(Of Data) thing.
An illustrative example of how it works:
Imports System
Namespace Gen
Public Class Pair(Of T As IComparable(Of T))
Public Property FirstValue() As T
Public Property SecondValue() As T
Public Sub New(first As T, second As T)
FirstValue = first
SecondValue = second
End Sub
Public Sub Swap()
Dim temp As T = FirstValue
FirstValue = SecondValue
SecondValue = temp
End Sub
Public Function Max() As T
If FirstValue.CompareTo(SecondValue) > 0 Then
Return FirstValue
Else
Return SecondValue
End If
End Function
Public Overrides Function ToString() As String
Return String.Format("({0},{1})", FirstValue, SecondValue)
End Function
End Class
Public Class Program
Public Shared Sub Main(args As String())
Dim ip As New Pair(Of Integer)(123, 456)
Console.WriteLine(ip)
Console.WriteLine(ip.Max())
ip.Swap()
Console.WriteLine(ip)
Console.WriteLine(ip.Max())
Dim sp As New Pair(Of String)("ABC", "DEF")
Console.WriteLine(sp)
Console.WriteLine(sp.Max())
sp.Swap()
Console.WriteLine(sp)
Console.WriteLine(sp.Max())
Console.ReadKey()
End Sub
End Class
End Namespace
>> I
>> don't see any support for higher-order functions,
>
> Not sure what that means ...
>
>> lambdas,
>
> Not sure what that means ...
>
>> or
>> closures;
>
> Not sure what that means ...
>
>> no currying of functions.
>
> Not sure what that means ...
Functional programming is another big area.
I don't think the typical business application need
much of the advanced stuff, but some things can be
done conveniently.
A slightly modified version of the last VB.NET example
with an appetizer:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Namespace Modern3
Public Class Data
Public Property Created() As DateTime
Public Property Counted() As Integer
Public Sub New(c As Integer)
Created = DateTime.Now
Counted = c
End Sub
Public Overrides Function ToString() As String
Return String.Format("[{0}: {1}]", Created, Counted)
End Function
End Class
Public Class ExtData
Inherits Data
Public Property Verified() As Boolean
Public Sub New(c As Integer, v As Boolean)
MyBase.New(c)
Verified = v
End Sub
Public Overrides Function ToString() As String
Return String.Format("[{0}: {1} ({2})]", Created, Counted,
If(Verified, "Verified", "Not verified"))
End Function
End Class
Public Class Program
Public Shared Sub Dump(lbl As String, lstd As IEnumerable(Of Data))
Console.WriteLine(lbl)
For Each d As Data In lstd
Console.WriteLine(d)
Next
End Sub
Public Shared Sub Main(args As String())
Console.WriteLine("VB.NET")
Dim alld As New List(Of ExtData)()
alld.Add(New ExtData(37, True))
Thread.Sleep(1000)
alld.Add(New ExtData(32, True))
Thread.Sleep(1000)
alld.Add(New ExtData(19, True))
Thread.Sleep(1000)
alld.Add(New ExtData(50, False))
Dump("All:", alld)
Dump("Counted < 30:", alld.Where(Function(d) d.Counted < 30))
Dump("Verified = false:", alld.Where(Function(d) Not
d.Verified))
Console.ReadKey()
End Sub
End Class
End Namespace
VB.NET
All:
[1/12/2024 2:54:36 PM: 37 (Verified)]
[1/12/2024 2:54:37 PM: 32 (Verified)]
[1/12/2024 2:54:38 PM: 19 (Verified)]
[1/12/2024 2:54:39 PM: 50 (Not verified)]
Counted < 30:
[1/12/2024 2:54:38 PM: 19 (Verified)]
Verified = false:
[1/12/2024 2:54:39 PM: 50 (Not verified)]
The point is the function passed to the Where method that
allows for great flexibility in filtering data.
Arne
More information about the Info-vax
mailing list