Shop OBEX P1 Docs P2 Docs Learn Events
History of Parallax Microcontrollers and languages - Page 2 — Parallax Forums

History of Parallax Microcontrollers and languages

2

Comments

  • Invoking Microsoft as a character witness as to the quality of a software product is like calling Jeffrey Dahmer to attest to the quality of your food. They have never been embarrassed to release a product that only works most of the time. (Disclaimer: I have hated Microsoft since long before hating Microsoft was cool.)

    More generally, scripting and object-oriented languages are bad teaching languages because those very conveniences that make them so easy to use (when they work the way you expect) also hide the actual operation of the computer. This can reach almost comical proportions. One manufacturer I know used a lexer designed for a compiler in a BASIC interpreter in one of their products, and it was painfully slow. The C++ object orientation neatly hid from the top-level programmer that an innocent looking function call was eating 40,000 clock cycles every time it evaluated a keyword at runtime.

    I firmly believe you should not use convenience tools until you have some idea what they are doing under the hood, or you will make similarly stupid mistakes. One fortunate result of the way BASIC was implemented was that it forced you to edge your way into machine language and learn what was under the hood to do anything really useful. And this could be gradual, starting with simple functions tucked into a string and graduating to larger blocks of self-sufficient code. By the time you moved on to a language like C, you knew how it worked and where the overhead was likely to be found.
  • Heater.Heater. Posts: 21,230
    localroger,
    Disclaimer: I have hated Microsoft since long before hating Microsoft was cool.
    Discaimer: I never knew it was "cool" to hate Microsoft. I thought it was normal since this: https://en.wikipedia.org/wiki/Open_Letter_to_Hobbyists
    More generally, scripting and object-oriented languages are bad teaching languages because those very conveniences that make them so easy to use (when they work the way you expect) also hide the actual operation of the computer.
    So BASIC, being an interpreted "scripting" language is a bad teaching language for the reasons you give there.
    I firmly believe you should not use convenience tools until you have some idea what they are doing under the hood,...
    But, but, BASIC is exactly designed to be a convenience tool designed to introduce people to programming whilst hiding all the messy details of what goes on under the hood.

    When I was introduced to programming, using BASIC, as a teenager in 1972 there was no way we could know what goes on under the hood. Too much detail for our young minds. The important part was to get an idea of programming, you know: variables, operators, statements, importantly sequence, selection and iteration. As it happened we learned assembler in that same course, a year later. By then we were prepared for it.
    One fortunate result of the way BASIC was implemented was that it forced you to edge your way into machine language...
    Ah, I see now why we have different views. The BASIC I was weened on had no easy way to edge one into machine language. The BASIC we had and later assembler were totally different worlds. What you are describing is the situation a decade later when kids had 8 bit home computers with mutant BASICs that supported PEEK and POKE and even in line assembler.

    I'm old skool. If your BASIC does not need line numbers and has structured "if", "while", "do" etc constructs then it is not really BASIC at all. It's a child of ALGOL. Like C and Javascript and all the rest.





  • Heater. wrote: »

    I'm old skool. If your BASIC does not need line numbers... ... then it is not really BASIC at all.

    I swear to god your the only one who thinks this. Cobol, Fortran, Assembler, whatever, back then had line numbers, and have since gotten rid of them. I don't then have the nerve to declare they're not Cobol, Fortran, and Assembler any more.

    I encourage you to look at, say, PBasic. (this IS Parallax forum after all) No line numbers.
  • David BetzDavid Betz Posts: 14,511
    edited 2018-10-14 19:56
    Heater. wrote: »
    I'm old skool. If your BASIC does not need line numbers and has structured "if", "while", "do" etc constructs then it is not really BASIC at all. It's a child of ALGOL. Like C and Javascript and all the rest.
    I feel the same way. I don't understand the attraction of "modern" versions of BASIC over other more capable languages. What is the advantage of BASIC over Spin for example? I guess you don't have to understand objects to use BASIC and you don't have to write a main function. You can just write statements outside of any function definition for simple programs. Is that really that much of an advantage? Anyway, I guess it's what you like. Some people like languages with "basic" in the name even if they aren't much different than other structured languages. That's fine. Everyone has their preferences.
  • BASIC is not what would be considered a scripting language in the modern world, as it has strongly typed variables and lacks built-in interfaces to extended functions. As for what is or isn't BASIC, the necessary minimum is that it supports LET (or implied LET) assignment, FOR/NEXT, GOTO, IF/THEN, and something resembling PRINT. It uses a single equals sign as the equality operator and treats boolean conditions as numeric expressions, giving zero or nonzero for false and true respectively. It may or may not require line numbers for all lines on the editor, and may or may not support tags (generally colon terminated) instead of line numbers if it supports a page editor. It may support extra stuff like WHILE/WEND, DO/LOOP, and myriad machine specific extensions; by its nature BASIC is a very easy language to extend in a new implementation. Really modern versions may also support user defined types, but all the fields in such a type will be either a string or number.

    If it doesn't have GOTO, doesn't have FOR/NEXT, or uses something other than a single equals sign as the equality operator, or has weakly typed variables, it's not BASIC.

    And the Horror that is the J-script language begins with the fact that it has weakly typed variables, yet uses the BASIC syntax of overloading the + operator for both addition and string concatenation so that the compiler can't always be sure of what to do with that +. This is fundamentally broken. This may work fine with workarounds, it may work well in practice with those workarounds because of other less broken language features, but it is still fundamentally broken and should have been fixed rather than shipped that way, full stop. Our willingness to accept such Smile is the single biggest problem in the software industry.

  • localroger wrote: »
    If it doesn't have GOTO, doesn't have FOR/NEXT, or uses something other than a single equals sign as the equality operator, or has weakly typed variables, it's not BASIC.
    Hmmm... Maybe C is actually BASIC. It has "goto" and uses a single "=" for assignment. It also has "for" but not "next". Does it qualify?

  • David Betz wrote: »
    Heater. wrote: »
    I'm old skool. If your BASIC does not need line numbers and has structured "if", "while", "do" etc constructs then it is not really BASIC at all. It's a child of ALGOL. Like C and Javascript and all the rest.
    I feel the same way. I don't understand the attraction of "modern" versions of BASIC over other more capable languages. What is the advantage of BASIC over Spin for example?
    Well, since I'm in the process of implementing a compiler that handles both BASIC and Spin at the same time, I'm in a position to comment on this :). For me, the big advantage of BASIC over Spin is that BASIC variables have types associated with them. That helps to catch some kinds of programming errors (passing the wrong types to functions) and also lets us integrate floating point into the language. With BASIC we can know whether "x+y" is a floating point, fixed point, integer, or string operation. BASIC (at least the FreeBasic variant that fastspin BASIC is based on) also has function pointers built in to the language, which makes some kinds of programming much easier. (Dave Hein did implement a method pointer object for Spin, so Spin can do it, but it's more awkward there and there is no type checking.)

    Now, does BASIC have an advantage over C? Not really. I am thinking of implementing function closures in my BASIC (the way it already handles function pointers is practically a closure anyway) so I suppose that would allow for a little bit more functional style of programming than you can do in C.

    Eric
  • Heater.Heater. Posts: 21,230
    ersmith,
    I am thinking of implementing function closures in my BASIC
    Wow, closures in BASIC. That is one of the most radical ideas I have heard in years.

    I still think all this fussing over types in JS is overblown. The main thing is you have strings and numbers, in practice one does not get them mixed up very often. Being able to build strings from sub strings and numbers using "+" is very convenient. In practice such type errors show up immediately in ones unit testing. You are testing you code right? It's not like one had bytes, words, longs, floats, doubles, signed unsigned to deal with and get right all the time. Cough, C, cough, spin, etc.

    Perversely I'm all in favor of strict type checking in hardware description languages. Which is why I'm getting along much better using SpinalHDL than Verilog.

    I'm also in favor of strict, type, range and other validity checks on all data entering a system. No matter what language one is using.
  • ersmith wrote: »
    David Betz wrote: »
    Heater. wrote: »
    I'm old skool. If your BASIC does not need line numbers and has structured "if", "while", "do" etc constructs then it is not really BASIC at all. It's a child of ALGOL. Like C and Javascript and all the rest.
    I feel the same way. I don't understand the attraction of "modern" versions of BASIC over other more capable languages. What is the advantage of BASIC over Spin for example?
    Well, since I'm in the process of implementing a compiler that handles both BASIC and Spin at the same time, I'm in a position to comment on this :). For me, the big advantage of BASIC over Spin is that BASIC variables have types associated with them. That helps to catch some kinds of programming errors (passing the wrong types to functions) and also lets us integrate floating point into the language. With BASIC we can know whether "x+y" is a floating point, fixed point, integer, or string operation. BASIC (at least the FreeBasic variant that fastspin BASIC is based on) also has function pointers built in to the language, which makes some kinds of programming much easier. (Dave Hein did implement a method pointer object for Spin, so Spin can do it, but it's more awkward there and there is no type checking.)

    Now, does BASIC have an advantage over C? Not really. I am thinking of implementing function closures in my BASIC (the way it already handles function pointers is practically a closure anyway) so I suppose that would allow for a little bit more functional style of programming than you can do in C.

    Eric
    Full closures? Doesn't that mean you can end up having to dynamically allocate stack frames in case they are captured by a closure?

  • Heater.Heater. Posts: 21,230
    Is that how closures work? I have no idea, I assumed there was a stack as usual but somehow a closure took a snapshot of it, on the heap presumably.
  • Heater. wrote: »
    Is that how closures work? I have no idea, I assumed there was a stack as usual but somehow a closure took a snapshot of it, on the heap presumably.
    Yeah but if you just copy the variables into the closure then two functions that close over the same stack will have different copies of those variables. Shouldn't a change by one closure function be seen by the others?


  • ersmith wrote: »
    Well, since I'm in the process of implementing a compiler that handles both BASIC and Spin at the same time, I'm in a position to comment on this :). For me, the big advantage of BASIC over Spin is that BASIC variables have types associated with them.
    Good point. I've been having a problem with my C-like language because I made a decision early on to avoid explicit types. This led to strange syntax for accessing byte arrays since every variable is assumed to be a 32 bit integer.

  • Heater.Heater. Posts: 21,230
    David Betz,
    if you just copy the variables into the closure then two functions that close over the same stack will have different copies of those variables. Shouldn't a change by one closure function be seen by the others?
    Hmm...good question, I have no idea. Let's break out the trusty Javascript and see:
    let constructFuncs = (step) => {
        let funcs = {}
        let count = 0 
    
        funcs.print = () => {
            console.log(count)
        }
    
        funcs.step = () => {
            count += step
        }
        return funcs
    }
    
    let funcs = constructFuncs(1)
    setInterval (() => { 
        funcs.print()
        funcs.step()
    }, 100)
    
    Result:
    0
    1
    2
    3
    4
    5
    
    Seems you are right. There is one closure "snapshot", object, created and shared between the created functions. I guess it makes sense.


  • Heater.Heater. Posts: 21,230
    David Betz,
    This led to strange syntax for accessing byte arrays since every variable is assumed to be a 32 bit integer.
    JS solves this problem with typed arrays
    var buffer = new ArrayBuffer(16);
    var int8View = new Int8Array(buffer);
    for (var i = 0; i < int8View.length; i++) {
      console.log('Entry ' + i + ': ' + int8View[i]);
    }
    
    I have no idea if that would suite you language though.
  • David BetzDavid Betz Posts: 14,511
    edited 2018-10-15 15:42
    Heater. wrote: »
    David Betz,
    This led to strange syntax for accessing byte arrays since every variable is assumed to be a 32 bit integer.
    JS solves this problem with typed arrays
    var buffer = new ArrayBuffer(16);
    var int8View = new Int8Array(buffer);
    for (var i = 0; i < int8View.length; i++) {
      console.log('Entry ' + i + ': ' + int8View[i]);
    }
    
    I have no idea if that would suite you language though.
    I suppose I could do that but then I would have types in my language after all. JavaScript has an advantage since every data object has a type even though the language itself doesn't require you to declare it. My data is just unadorned 32 bit values. I don't have a type field to remember the type of a data object. Even an array is just a 32 bit offset into the data space where the array data starts. The same applies to functions. A function pointer or an object pointer is just a 32 bit integer. It would be easy for me to introduce the concept of static types. Maybe that's what I should do. It wouldn't slow down the language at all and it would get around many of these problems. Adding dynamic types is more of a problem though since it requires me to implement a heap and I've been trying to avoid that especially on P1.

  • Heater.Heater. Posts: 21,230
    Tricky.

    I'm my one and only attempt at building a simple minded compiler for a C/Pascal style language ages ago I only wanted unsigned bytes, words and longs. Not even arrays or strings. Damn I swear getting all that type checking and coercion etc right was 90% of the effort. Amazingly I did get it to generate assembler for x86 and Propeller. Testing that those types all played well together was another 90% of the work.
  • David Betz wrote: »
    ersmith wrote: »

    Now, does BASIC have an advantage over C? Not really. I am thinking of implementing function closures in my BASIC (the way it already handles function pointers is practically a closure anyway) so I suppose that would allow for a little bit more functional style of programming than you can do in C.
    Full closures? Doesn't that mean you can end up having to dynamically allocate stack frames in case they are captured by a closure?

    My original plan had been to do snapshots at the point of the function definition, but it sounds like most other languages have the functions share the stack frame so I can do that (it's actually easier, I think). Thanks for testing this, @"Heater."

    The stack frame would only be dynamically allocated if necessary, i.e. if the function is itself returning a function. But this is a bit speculative right now and getting ahead of things.
    Adding dynamic types is more of a problem though since it requires me to implement a heap and I've been trying to avoid that especially on P1.
    I ended up biting the bullet and implementing a garbage collected heap, and it really makes a lot of things easier even on P1. The heap size is bounded (by a user constant called HEAPSIZE) so the overall memory usages is still somewhat deterministic.
  • Do you do heap compaction to avoid fragmentation? Do you do reference counting or some sort of mark/sweep algorithm?
  • ersmithersmith Posts: 5,900
    edited 2018-10-15 16:02
    David Betz wrote: »
    Do you do heap compaction to avoid fragmentation?
    Only on free (all adjacent free blocks are coalesced). I didn't want to move things around in case there were pointers live, and I wanted to be able to re-use the garbage collector for languages like C where using handles instead of pointers isn't really practical.
    Do you do reference counting or some sort of mark/sweep algorithm?

    mark/sweep. It's a somewhat ugly conservative collector that looks at HUB memory and the current COG's memory to see if there are any references. Allocated blocks are marked with the COG that allocated them so we don't try to collect other COG's allocations (that part isn't really finished yet, I need to add some locking).
  • Conservative collectors always made me nervous but I guess it's a lot more efficient than trying to track down every heap pointer.
  • Heater.Heater. Posts: 21,230
    ersmith,
    ...it sounds like most other languages have the functions share the stack frame...
    Seems to be so. I might never have guessed correctly if I had been asked earlier.

    Just for fun I thought I'd try the same experiment on my latest new shinny YAFL around here, Scala. Three hours later I got the following (I know almost nothing about Scala so far):
    object ClosureDemo {
        class Funcs {
            var step = () => {}
            var print = () => {}
        }
    
        def constructFuncs (step:Int): Funcs = {
            var funcs = new Funcs
            var count = 0
            
            funcs.print = () => {
                 println(count)
            }
    
            funcs.step = () => {
                count += step
            }
    
            return funcs
        }
    
        def main(args: Array[String]) {
            var funcs = constructFuncs(1)
            for(x <- 1 to 10 ) {
                funcs.print()
                funcs.step()
            }
        }
    }
    
    With output:
    0
    1
    2
    3
    4
    5
    
    Again a shared closure.

    Amazingly if you strip away all the cruft Scala has for it's type system the code that does the work looks almost identical to Javascript.
  • Heater.Heater. Posts: 21,230
    edited 2018-10-15 21:35
    Another 3 hours later...

    ersmith may have guessed correctly about lambdas for C++.

    Being a masochist I thought I try and make a similar closure test in C++. C++ has lambdas and such goodies now a days. You really have to like mental pain to try this sort of thing in C++.

    Anyway, I cannot get it to work. Here is the C++ version I came up with:
    #include <iostream>
    #include <functional>
    
    using namespace std;
    
    class Funcs {
    public:
        function<void (void)> print;
        function<void (void)> step;
    };
    
    Funcs* constructFuncs(int stepSize) {
        Funcs *funcs = new Funcs;
        int count = 100; 
    
        funcs->print = [&count, stepSize] {        
            cout << count << endl;
        };
    
        funcs->step = [&count, stepSize] {
            count += stepSize;
        };
    
        for (int i = 0; i < 10; i++) {              //  <-----------This loop works here.
            funcs->print();
            funcs->step();
        }
    
        return funcs;
    }
    
    int main (int argc, char* argv[]) {
        Funcs* funcs = constructFuncs(10);
    
        for (int i = 0; i < 10; i++) {             //  <-----------Same loop fails here.
            funcs->print();
            funcs->step();
        }
        return 0;
    }
    
    Result:
    100
    110
    120
    130
    140
    150
    160
    170
    180
    190
    32767
    32767
    32767
    32767
    32767
    32767
    32767
    32767
    32767
    32767
    
    I suspect that the reason it does not work is because it works like ersmith suspected lambdas work, not how proper languages do it. The closure takes a snapshot of the variables and stuffs them into a struct. A new, different one at lambda creation point.

    Except, in order to get lamdas to share variables you have to capture by reference. Like our "&count" above. But now each lambda has a reference to something on the stack. It's only valid within the scope of that variable. Hence my last loop fails.

    Perhaps that is why C++ calls them "captures" and not "closures".

    Anyone see a way out of this and recreate in C++ what we have in JS and Scala above?
  • Heater.Heater. Posts: 21,230
    edited 2018-10-16 05:22
    I can make it work with a horrible hack. I create my own closure struct manually on the heap. Now it survives going out of scope and the second loop works. Except now I have two memory leaks instead of just one :)
    class Funcs {
    public:
        function<void (void)> print;
        function<void (void)> step;
    };
    
    struct Closure {
        int count;
        int stepSize;
    };
    
    Funcs* constructFuncs(int stepSize) {
        Funcs *funcs = new Funcs;
        Closure *closure = new Closure;
        closure->count = 100; 
        closure->stepSize = stepSize; 
    
        funcs->print = [closure] {        
            cout << closure->count << endl;
        };
    
        funcs->step = [closure] {
            closure->count += closure->stepSize;
        };
    
        for (int i = 0; i < 10; i++) {
            funcs->print();
            funcs->step();
        }
    
        return funcs;
    }
    
    int main (int argc, char* argv[]) {
        Funcs* funcs = constructFuncs(10);
    
        for (int i = 0; i < 10; i++) {
            funcs->print();
            funcs->step();
        }
        return 0;
    }
    
  • With C++'s object lifetime rules and the requirement that dynamic memory be managed manually, the only way to share a variable across multiple lambdas is to dynamically allocate it yourself.

    From a quick search on JavaScript and Scala (which is the extent of my knowledge of these languages) it appears that everything is allocated dynamically rather than on a stack and thus the variable captured by the closure remains alive as long as the closure does and thus can't get clobbered. This dynamic allocation of everything could explain why closures default to capturing be reference in these languages (if they even have the concept of capturing by value). References: JavaScript, Scala.

    Also, I've rewritten Heater's test, eliminating the memory leaks, and removing the unnecessary capture of the step size by print.
    #include <functional>
    #include <iostream>
    #include <memory>
    
    namespace {
        struct Functions {
            std::function<void ()> print;
            std::function<void ()> step;
        };
    }
    
    auto construct_functions( int step_size )
    {
        auto functions = std::make_unique<Functions>();
    
        auto count = std::make_shared<int>( 100 );
    
        functions->print = [ count ]()
        {
            std::cout << *count << '\n';
        };
    
        functions->step = [ count, step_size ]()
        {
            *count += step_size;
        };
    
        for ( auto i = 0; i < 10; ++i ) {
            functions->print();
            functions->step();
        } // for
    
        return functions;
    }
    
    int main()
    {
        auto functions = construct_functions( 10 );
    
        for ( auto i = 0; i < 10; ++i ) {
            functions->print();
            functions->step();
        } // for
    }
    

    Output:
    100
    110
    120
    130
    140
    150
    160
    170
    180
    190
    200
    210
    220
    230
    240
    250
    260
    270
    280
    290
    
  • potatoheadpotatohead Posts: 10,253
    edited 2018-10-16 03:37
    What is the advantage of BASIC over Spin for example? I guess you don't have to understand objects to use BASIC and you don't have to write a main function. You can just write statements outside of any function definition for simple programs. Is that really that much of an advantage?

    Yes!

    There is, and I do not currently understand how best to quantify it, but there is what one needs to know to attempt a program. And there is what can be quickly, reasonably inferred vs understanding other than what one sees at the console.

    8 bit basics were whittled down to some nubs, and a program listing conveyed what one needed to begin.

    I saw a program listing as a little kid in the 70's. I remember looking at it for a long time too. (And I am odd in this way in that I can tell you what I was taught, often why (where someone, or I asked or the teacher offered it), and in what order from K through 12. It just is there. Some fading now, but mostly still there, vivid.

    Anyway, I recall that day, what I mused over, and a chat with a friend.

    It was a guess my number type game. TRS-80.

    What are the line numbers? Oh, order. K got it.

    Print? That must show up somewhere. Input? Why is that not called ask? If, then, goto...

    There is shockingly little one needs to know.

    That friend and I wrote what we thought might be programs. Showed them around, and it turned out a neighbor saw our attempts, invited us over, and we typed them in.

    Got stuff wrong. Made changes with neighbors help, and then they worked, but did not do what we thought they might.

    After a brief time, we got the proeams we wanted, ran them, and learned a ton.

    And just that, line number, print, input, math, variables, if then, goto was enough!

    Super powerful to us nerds living in the woods, outside of an out of the way, small, hick town.

    We wrote more programs. Did not even have a computer.

    Yes, huge advantage.

    Today, we have a more robust information environment. Videos, cool stuff.

    I do not think people have to do it the way we did, but I also think why what we did was how it was too.

    SPIN actually is not bad. Back then, it would have been harder, need to know more stuff. But, today? SPIN is pretty lean. The basics of it do not take much and people can write surprising programs with only a portion of SPIN too.

    Heck, it is really lean, so is PASM.

    I have said this before, but I saw the P1 diagram with the COGS and ordered a Demo Board. When it showed up, I ran the graphics demo. Wrote some fun stuff later, wanted to change the video signal, and basically got going in a day.

    Nice.

    When someone approaches this stuff, it is super hard for us, being close to it like we are, to imagine what it is like, what people have to know, what they can guess at, deduce, infer.

    I still like BASIC. I do not use it for too much, though ersmith has made that a curious proposition... (nice work)

    I can turn on my model 100, knock out some programs easy. Before Excel, I did this all the time. I would use an 8 bitter (usually Apple 2), or a pocket PC, or the basic one found with MSDOS.

    Most of those were manufacturing oriented. I would learn something, then write a program, then validate it, then print or write it down. Ended up selling a bunch of programs to fund my first 386 PC. Basic. Lol

    To me, it was simple, executable documentation. Worked for me and or the computer. Spiffy!



  • Here is another advantage of BASIC like thinking:

    I end up away from this stuff at times. In fact, just leaving one of those times. (Perfect timing too)

    So much does not matter. How big it is. How fast it is. No. Does it work and work well? Check, next.

    Jumping back into BASIC is super easy. Jumping back into SPIN and PASM easy. C harder. (But not that hard, just highlighting where the dynamics are)

    Other things vary with my experience and need. Make less sense to talk about. And all of this is just me too. YMMV, right?

    Well, the point being lean environments totally make sense. Not everyone will take the software engineering career path. But, a whole lot, and I would argue a growing number of, people benefit by writing and reading software.

    That is what BASIC was for! Nailed it too.
  • Heater.Heater. Posts: 21,230
    David Betz,
    What is the advantage of BASIC over Spin for example? I guess you don't have to understand objects to use BASIC and you don't have to write a main function. You can just write statements outside of any function definition for simple programs. Is that really that much of an advantage?
    I'm with spud on this one.

    When you take a kid, or anyone, that has never programmed and perhaps has no idea what a program is and you want to introduce them to programming then it's best to have the minimum amount of cruft between the nothing that they know and them getting a result.

    Contrast everyone's first program in BASIC:

    10 PRINT "HELLO"

    vs a "hello world program" in C or Java etc.

    In the later cases you have to have your student ignore and not get blinded by include files, functions, parameters, return values, types, objects/classes. All kind of concepts that they are not ready for. In BASIC they just do the thing that is actually the point of the exercise, print a message.

    Of course it's easier to get our student started in Javascript, now he only has to type "HELLO". :)

    Like Spud I vividly recall my first experience of programming as a teenager in 1972, having never actually seen a computer before. The power of that 10 PRINT "HELLO" was awesomely inspiring. Within a few hours one has learned all there is to programming: variables, statements, sequence, selection and iteration.

    I believe millions of kids from the later 8 bit microcomputer generation felt the same thing.
    Anyway, I guess it's what you like.
    Perversely, having said all that, it was only a matter of a month or two that I started to get frustrated with BASIC and have never much wanted to use it since. You see by then I wanted to write an expression parser so that a user could input a formula. I had no idea how of course and BASIC was not the tool to use to experiment with that and find out.

    But BASIC had done it's job for me.
  • Heater.Heater. Posts: 21,230
    apcountryman,

    Wow, thank you for C++ version of the closure demo.

    I think you are spot on with your assessment of dynamic allocation of closures, in C++ you just have to do it yourself.

    I had just woken up with thoughts of using unique and shared pointers. It might have taken me all day to get it working though!

    What is the purpose of the namespace you have introduced around the Functions struct?

    It's interesting to look at the complexity of the solution in the languages we have here, in simple minded terms of lines of code and characters typed.
                        Lines       Characters      Compile time
    
    closure.js          16          130             0.2             
    
    closure.scala       24          337             1.7
    
    closure.cpp         35          610             0.8
    

    This really demonstrates why one would not want to do anything complicated in C++ unless one really had to. With all it's syntactic "line noise" it becomes impossible to make out the job it's supposed to be doing from the cruft.
  • It's interesting that most of the posts here that say how easy BASIC is to use relate to the old microcomputer BASICs. The newer structured BASICs aren't quite as easy and don't differ that much from other structured languages. There is no PRINT in BASIC Stamp pbasic for example. I really think that the fact that a language has the word "BASIC" in its name makes people think it will be easier to use and so they aren't as afraid of it as they are some other language. Anyway, I have some fond memories of BASIC and have even written a few BASIC interpreters for the Propeller. It's a fun language and can be useful. And Eric's new fastspin BASIC seems like it is going to be quite capable of doing serious P1 and P2 programming.
  • Heater,

    The use of the anonymous namespace restricts the visibility of its members to the current translation unit. construct_functions() should have been placed within it as well. Doing this is overkill for the example but it is a best practice.
Sign In or Register to comment.