Shop OBEX P1 Docs P2 Docs Learn Events
On the Uniqueness of Spin — Parallax Forums

On the Uniqueness of Spin

SRLMSRLM Posts: 5,045
edited 2008-10-17 20:57 in Propeller 1
I'm in the process of learning the Spin Language, and some things have struck me as odd. Mostly, it's the weird formatting that was choosen and the odd operators that are used, such as <#=, |, :, dira/outa, :=, ~, ~~, >>=. Also, the almost complete lack of closure operators (like {},[noparse]/noparse, and ()) is very confusing, especially for the fact that some things have them (like waitcnt) and others don't (like methods). From a background in traditional computer language (Java), I find the Spin syntax to be very different. Any reason why Parallax choose such? I read somewhere that the language was custom built, but why deviate so far from the norm?

Comments

  • PraxisPraxis Posts: 333
    edited 2008-10-15 20:01
    ouch! you will get some bites from that post[noparse]:)[/noparse]
  • CarlosFandangoCarlosFandango Posts: 67
    edited 2008-10-15 20:16
    Well, I've coded in so many different languages I've lost count, and it seems to me they all have their own idiosyncracies (especially the renegades from the sixties such as FORTRAN. But I'm a renegade from the sixties as well!). After using spin for a while, I find that it's quite good at relating high to low level code in many ways. The one thing that I find irritating if anything is the need to switch access methods when passing an address to a function; one minute you are saying array[noparse][[/noparse]index] and the next byte[noparse][[/noparse]array+ptr] or something like that. But bearing in mind that it's an address and not a variable token as such, even that kind of makes sense.

    Anyway, it's quite easy to understand and totally **FREE**, so what's to complain about?!
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-15 20:23
    My observations: Spin has its roots more in Pascal than in C or Java and the operators reflect that. The Spin interpreter is constrained to fit in 492 long words, mostly instructions with a few words of data, so that affects which operators could be added, yet give pretty much complete access to the underlying hardware. Indenting for statement scope has been used before, mostly in scripting languages.

    Be careful of the term "traditional computer language". Java is relatively recent as these things go. C and Pascal are the roots of current programming languages in that their development goes back to the '60s and '70s and they're still in widespread use today. Smalltalk is not in widespread use, but is still used significantly, has current, very sophisticated implementations on a variety of platforms and is the primary example of object oriented languages.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-10-15 20:44
    Hello SRLM,

    I had some problems at the beginning coming from pascal/delphi
    I was used to type ";" at the end of each line of code. But I learned quick to leave it out.

    The reasons are simply effectiveness and readability !

    It is simply faster to indent two columms instead of taking two hands to type charcters like "{" "}"
    whereever it is possible to leave out things without making it unclear what is meant characters are leaved out

    Methods HAVE brackets if the have parameters. If they don't have parameters why wasting time to type "()" ???

    Using indenting instead of opening/closing brackets forces everybody to format the code in a standardized and readable stile

    I have never seen any other computer-language that is so effective to write

    best regards

    Stefan
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-15 21:37
    Indented code
      takes up
        less vertical
        space
    
    Braced code {
      takes up {
        more vertical
        space
      }
    }
    
    
    


    More code on the screen at once == more efficient debugging.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • mirrormirror Posts: 322
    edited 2008-10-15 21:49
    Phil, it depends on how wide you're willing to go:
    (replace this text with your code)Indented code
      takes up
        less vertical
        space
    
    Braced code {takes up {less vertical; space }}
    

    It's interesting to note that even in the quirky example·presented, the braced code is still not as wide as the indented code.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-15 22:22
    Comparing apples to apples, with equivalent readability, I stand by my assertion. One-liners can be handy, though, if they're simple enough, viz:

    do {a := time()} until (a > time0)
    
    
    


    In a long program, these opportunites are more the exception than the rule, however.
    mirror said...
    It's interesting to note that even in the quirky example presented, the braced code is still not as wide as the indented code.
    Well, yeah, if you going to add fluff like "(replace this text with your code)" to it to make it wider! smile.gif

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • Cluso99Cluso99 Posts: 18,069
    edited 2008-10-16 07:12
    @Carlos: Now I understand your avatar smile.gif
    I learnt Fortran in 1970.

    Took a little to get used to no endif's etc, but I always liked indented code anyway.

    With the new compilers on the scene, it should be possible to persuade the writers for options (it has already been discussed). But, I don't take anything away from Chip for creating such marvellous stuff. :-)


    Post Edited (Cluso99) : 10/16/2008 7:18:39 AM GMT
  • cgraceycgracey Posts: 14,140
    edited 2008-10-16 09:49
    Phil Pilgrim (PhiPi) said...
    mirror said...
    It's interesting to note that even in the quirky example presented, the braced code is still not as wide as the indented code.
    Well, yeah, if you going to add fluff like "(replace this text with your code)" to it to make it wider! smile.gif

    -Phil

    One way to improve relative object density is to use longer label names in Spin.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • RaymanRayman Posts: 14,593
    edited 2008-10-16 10:40
    Huh?
  • Cluso99Cluso99 Posts: 18,069
    edited 2008-10-16 10:49
    While you're here Chip...

    I think it would be initially initially to teach indented spin to beginners than using the endif's etc. I believe it is more readable. For those of us who are used to the endif type language, it's probably harder for us. Can't have it both ways without a compiler option. What are your thoughts?

    As for the mathematics of ==, =< etc... Some of the time I just have to check but this is probably isn't helped by the fact I have done more VB that C, and far more various assemblers than anything.

    (tougue in cheek) - anyway why are you here - you should be finishing our PropII (remember, no rest for the wicked·nono.gif· )

    For the record: checked out the Xmos assembler briefly - I don't like the assembler shakehead.gif· The Prop's is so easy and regular - a couple of minor traps but the new compilers are addressing most of these with warnings.

    Post Edited (Cluso99) : 10/16/2008 10:57:58 AM GMT
  • heaterheater Posts: 3,370
    edited 2008-10-16 11:14
    Java - traditional, whos the new kid on the block? [noparse]:)[/noparse]

    Java does not even run on traditional computers.

    I have a lot of personal biases regarding programming languages, as do many people I guess, things like formatting, funny looking operators, operator precedence, lazy evaluation, type checking, etc etc. But in general I think spin pretty much hits the mark for it's intended use and audience.

    Together with the Propeller Tool and the way the Prop works it's very easy for the novice to get something working quickly without having to learn a lot of junk about header files, linkers, locators, libraries and so on. At the same time being powerful enough to handle some serious tasks unlike old Basic dialects.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • hippyhippy Posts: 1,981
    edited 2008-10-16 12:22
    What I particularly like about Spin from a programming language designer's perspective is that it is possible to logically explain why everything is as it is given the basic principles the language is built upon. The language holds together as a whole, it is completely rational so, for me, stands up there amongst other well designed languages.

    I don't like =< and => as comparisons but I can understand why they are as they are, although I'd personally have sacrificed purity and consistency of design elsewhere to allow <= and >=.

    The one major thing I think Chip missed out on, and I don't know why, is the ability to support nested methods and variables.

    Some of the tokens for operators are a little bizarre ( || and ^^ ) and strike me as desperation or forced choice as available symbols ran out, but still logically explainable, although why named "and", "or" and "not" rather than multi-symbol tokens ( &&, || etc ) does show some inconsistency.

    The most annoying issue I find is that a method parameter name cannot be the same as a VAR variable name. To me that's a compiler design flaw, implementation error or bug in handling name scope not necessarily a language design failure ( although it could be ).

    I don't like the way objects have been implemented in Spin; they are not objects in the sense of OOP and in terms of code encapsulation they are too restrictive. Having no #include and the lack of callbacks and function pointers presents major difficulties in source code division and encapsulation.

    As to "why deviate from the norm" I think that's three fold; because one can, because there is the freedom to try to do things better than other languages do, and because it better suits a target processor architecture. For Spin there is a very clear relationship between the language, the bytecode and the interpreter. It is hard to tell what drove what but it is a pretty solid and impressive combination.
  • cgraceycgracey Posts: 14,140
    edited 2008-10-16 17:07
    hippy said...
    ...The one major thing I think Chip missed out on, and I don't know why, is the ability to support nested methods and variables.

    I'm not sure what you mean by nested methods, though I·assume 'nested variables' means VAR name reuse within PUBs/PRIs.

    The most annoying issue I find is that a method parameter name cannot be the same as a VAR variable name. To me that's a compiler design flaw, implementation error or bug in handling name scope not necessarily a language design failure ( although it could be ).
    You mean if you declare 'i' at the VAR level, you can't declare a new 'i' within a PUB/PRI, right? I figured this would just introduce scope ambiguities, so it wasn't allowed. Can you show an example of where this would be beneficial? I probably have a blind spot that needs fixing.

    I don't like the way objects have been implemented in Spin; they are not objects in the sense of OOP and in terms of code encapsulation they are too restrictive. Having no #include and the lack of callbacks and function pointers presents major difficulties in source code division and encapsulation.
    Understood. This will be addressed in the next version of Spin.
    By the way, the comment about·higher object density (relative to source) was meant to be humorous. Sorry.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.

    Post Edited (Chip Gracey (Parallax)) : 10/16/2008 5:12:49 PM GMT
  • cgraceycgracey Posts: 14,140
    edited 2008-10-16 17:17
    Cluso99 said...
    While you're here Chip...

    I think it would be initially initially to teach indented spin to beginners than using the endif's etc. I believe it is more readable. For those of us who are used to the endif type language, it's probably harder for us. Can't have it both ways without a compiler option. What are your thoughts?
    A compiler option to use 'end' constructs? Mmmmmm... I don't feel good about that. I prefer one simple way, myself. Anyone making a compiler could do it however they want, of course.

    As for the mathematics of ==, =< etc... Some of the time I just have to check but this is probably isn't helped by the fact I have done more VB that C, and far more various assemblers than anything.

    (tougue in cheek) - anyway why are you here - you should be finishing our PropII (remember, no rest for the wicked·nono.gif· )
    Yes, I thought I'd come see what is going on here. I've been working on·some texture-mapping pixel-lighting/blending·instructions. All video·on the new chip will be 5:5:5 RGB with hardware YIQ conversion for PAL/NTSC. So,·a consistent color scheme with·good pixel processing for all video formats. The video is almost all done.·Just the counters to enhance after that.

    For the record: checked out the Xmos assembler briefly - I don't like the assembler shakehead.gif· The Prop's is so easy and regular - a couple of minor traps but the new compilers are addressing most of these with warnings.
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • hippyhippy Posts: 1,981
    edited 2008-10-16 18:05
    Chip Gracey (Parallax) said...
    hippy said...
    ...The one major thing I think Chip missed out on, and I don't know why, is the ability to support nested methods and variables.
    I'm not sure what you mean by nested methods, though I assume 'nested variables' means VAR name reuse within PUBs/PRIs.

    Nested methods as with Pascal's Procedures, a contrived example ...

    PRI PrintCharacterToTvTwice( c )
      PRI Print( c )
        tv.Out( c )
      Print( c )
      Print( c )
      return
    
    PRI PrintCharacterToPrinterTwice( c )
      PRI Print( c )
        lineprinter.Out( c )
      Print( c )
      Print( c )
      return
    
    
    



    So each Print would only be in scope and callable for the method it is defined within. Nested variables would be VAR specific to the method but unnecessary as that's what | and a local variables list gives.
    Chip Gracey (Parallax) said...
    hippy said...
    The most annoying issue I find is that a method parameter name cannot be the same as a VAR variable name. To me that's a compiler design flaw, implementation error or bug in handling name scope not necessarily a language design failure ( although it could be ).
    You mean if you declare 'i' at the VAR level, you can't declare a new 'i' within a PUB/PRI, right? I figured this would just introduce scope ambiguities, so it wasn't allowed. Can you show an example of where this would be beneficial? I probably have a blind spot that needs fixing.

    Is there any ambiguity ? I'd say simple scope rules apply as per Pascal. The case I was thinking of ...

    VAR
      byte ch
    PUB Main
      repeat ch from 'A' to 'Z'
        Print( ch )
    PRI Print( ch )
      tv.Out( ch )
    
    
    



    Within "Print", references to 'ch' would be the local parameter not the global variable. In both cases 'ch' is meaningful to me as 'holds a character' even though one is global, the other is local.

    Particular times I've run into a problem is in cutting and pasting from one program or object to another and finding a conflict which wouldn't occur if this was allowed. The awkward thing is it's no good just changing the parameter name or local variable, every use of the variable has to be identified or it wrongly then refers to the global variable of the same name.
  • Dennis FerronDennis Ferron Posts: 480
    edited 2008-10-16 20:08
    Spin objects do have a good side to them - IMO they're the best way to implement objects on a limited RAM system. For instance, coming from the PC programming world you'd think the fact that you can't create Spin objects dynamically and that whatever you have at program outset is all the objects you'll ever have would be a bad thing, while in fact it's really the only sane way to deal with the limited amount of memory. I think a good apples-to-apples comparison of Java to Spin is the implementation of Java for the Lego RCX Brick (embedded processor, 32K RAM... lots of similarities). In Java on the RCX, they didn't have room for a garbage collector & the overhead of tracking objects for garbage collection, so everything you create just stays resident. You end up changing your programming technique to one very much like what Spin supports directly.

    Spin definitely lies on its own waaaay out there evolutionary branch, like a platypus compared to regular mammals. (Chip, can we make the platypus be the mascot for Spin?) However, its design philosophy is consistent within itself even as much as it is different than other languages, and it does a few things remarkably well:

    1. It packs a lot into a little screen real estate without being "dense". (Yes in C-like languages you can put all the curly brace {} junk on one line to shrink it vertically, but even if it doesn't end up wide horizontally it's still dense in terms of how many symbols get packed in that space. Spin manages to be *compact* without being *dense*.)

    2. It integrates very well with assembly.

    3. It's good for table driven algorithms. For instance, I can express a table in a DAT section in very compact form, and access it directly in Spin.

    4. Uses memory efficiently.

    5. Allows you to easily combine components written by other people.

    Basically what I think Spin is, is that Parallax took all these years of experience making Basic Stamps and distilled exactly what it is that you want to do with a microcontroller, and wrote a language that makes it easy to do those things, even if the language breaks with mainstream PC language influences. Note, however, that there's some undefinable "feel" to the language that will feel familiar if you've been using Basic Stamp PBasic a long time. So it's not like there is no history at all to it.
  • heaterheater Posts: 3,370
    edited 2008-10-16 20:44
    Hippy: I've always wondered about nested procedures (they were introduced with ALGOL) what use are they? How much more complicated do they make a compiler? Are they worth it?

    In all my years of programming in many languages and in many application domains I've never felt the need for a nested procedure and never come across any code that uses them.

    Is there some compelling reason to have them that I have missed all these years?

    In an object oriented language were we can have "private" methods can we live without nested procedures?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • SRLMSRLM Posts: 5,045
    edited 2008-10-16 20:50
    The main points seem to be that

    1) Spin is more effecient in screen space without extra operators
    2) Spin is optimized for uC use


    Topic 1) Screen space is a valuable commodity, true, but why should we have to sacrifice readability for visibility? If the code is easy to understand, and uses english terms (not >#=) then there is no real need to save screen space. You understand everything that is happening simplyby reading the phrase out loud. I'm not saying that the Spin operators don't have an English equivalent, it's just that they are less intuitive. As for {}, [noparse]/noparse, and (): these you often have a choice of spacing them wherever your want, and lend sense of finality to the end of a code block. With indenation, you may simply cut and paste something wrongly, and it's a little too far over. In addition, the compiler can easily tell you when you've left out a closing brace, and a good IDE can highlight them for you. But how does it know if you've indented the correct bits of code? That's a logical error, and not a syntax. The more logical errors that can be converted to syntax errors, the easier it is to debug.

    Topic 2) Although some things are required for the uC, why can't a compiler optimize? It can cut out the variable names and replace them with the pointers needed. To me, that seems to be the purpose of the compiler: to do all the little housekeeping tasks so that programmers can focus on the higher level problems. These tasks should include optimization of memory and run time speed.


    Perhaps I should not have used "traditional programming languages." Instead I probably should have said "Popular" programming languages. Often, it's nice to break from the crowd, but when you use a language, certain things are expected. udn't just things rearrange like feel is best and hope understand ppl it.

    Anyway, I don't have any hard feelings against the Propeller, more, it's a new student from a older (popular?) language coming to terms with Spin.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-16 22:35
    SRLM said...
    n addition, the compiler can easily tell you when you've left out a closing brace, and a good IDE can highlight them for you.
    The Propeller tool does the same highlighting for indentation and doesn't need to warn about closing braces, because there aren't any. That's an advantage, not a disadvantage.
    SRLM said...
    But how does it know if you've indented the correct bits of code?
    How does a C compiler know if you've put a closing brace in the right spot? Same diff.

    Learning a new computer language has many parallels to learning a foreign natural language. There are similarities to what you already know, as well as differences. The differences don't make the foreign language "wrong". After all, native speakers of a "foreign" language may consider English odd, for similar reasons. With any language, once you gain fluency, the weirdness apparent upon first exposure disappears. This is as much true of Spin as it is of any othger language. Expanding one's comfort zone is just part of the learning process.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-16 22:55
    I'm not sure if it's clear what the advantage is for nested methods. In my experience, the primary advantage is that it flows naturally from algorithms that "need" internal methods when the algorithms themselves are expressed as methods (procedures or functions). Once you have two levels, it makes sense to generalize. It would be rare, but not impossible or unreasonable to occasionally have three levels.

    The advantage for having different name spaces for local variables, even constants (like in Pascal) or methods is primarily (as hippy implied) that code is sometimes lifted from other sources and may have variables (usually simple ones like single letters) that accidentally match other identifiers in the program (even global ones). By having local namespaces, there's a formal solution for this potential ambiguity. If you also include nested methods, this makes even more sense since the outer method is its "own world" and anything inside it can't conflict with the rest of the program (unless you forget to declare a local variable and mistakenly reference a global one).

    If #include is implemented, this local naming and nested method declarations becomes even more important. One might argue that some of this should be done with objects, but, for some simple cases, particularly where global constants and variables are used, using an object would create more complexity than a simple #include of one or more methods, possibly with internal method, even constant declarations (like Pascal).
  • RaymanRayman Posts: 14,593
    edited 2008-10-16 23:49
    Instead of nested methods, it'd be better to be able to call functions by reference... If you could make a word variable a pointer to whichever version of "print" you want, e.g., and then call it.
  • hippyhippy Posts: 1,981
    edited 2008-10-17 01:46
    Nested methods aren't an absolute necessity but just nice to have at times, often it's more about code readability than anything else.

    One advantage is for what could be called inline-objects ( in the Spin sense of objects ).

    Mike perhaps captures it best in terms of "namespace", what I called "scope". Each being its "own world" is a good way of viewing it.

    I think it's another of those things which people either see a need for or don't, are familiar with the idea or not. I learned programming with Pascal before C came along so this concept of nesting and scope is second nature to me. I can also live without it, and have done in most other languages I've used.
  • heaterheater Posts: 3,370
    edited 2008-10-17 06:36
    Well I can imagine wanting to factor out some code sequence into a method so as to make the original method containing the sequence easier to read. And that if that resulting method is totally useless anywhere else then it need only be in the scope of the original method i.e. nested. Especially if it is called more than once.

    Still I've never seen this done in working code, only in language tutorials and examples. Chip has got along just fine without ever hearing of them. Many languages, notably C, C++ seem to have dropped nested methods on purpose.

    Given an object oriented language is it not sufficient to use private methods instead of nested?. At least the scope of the method is contained to the class now. Even in good old C one can get much of this scoping using just static functions.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • hippyhippy Posts: 1,981
    edited 2008-10-17 11:13
    @ heater : I think the lack of working code examples with nested routines comes down to commonly used languages not having that ability.

    Had C not become dominant but the Algol, Pascal, Modula, Ada, Delphi family taken dominance I think they'd be more commonly seen. Interesting to note that GCC can support nested methods for C.

    I can understand why they were dropped; it complicates the compiler and the interpreter or run-time, particularly as code has to deal with where variables local to the method which wraps it are on the stack as that varies on which method call route takes execution into a particular nested routine.
  • rjo_rjo_ Posts: 1,825
    edited 2008-10-17 13:29
    Great thread... you guys even got Chip to take a break.

    One of the virtues of the current object structure is that you can understand it by looking at a single example... without any comments. You don't have to read anything... it is immediately obvious. This means that you can understand a lot about an application, without any study...

    This encourages the inquiring mind to look at Spin... it is like a welcome sign.

    I hate full blown oop structures because they requires me to remember and understand relationships between objects... which places demands on me that I simply don't like... some brains take to it like a duck to water... not mine.

    Spin objects all look the same to me... they all get called top down, I just need to remember "what is on top of what." And if I forget this... I just need to figure it out again... which takes a few seconds.

    Indentation... there are so many bracketed and hyphenated languages around and so many repeat structures syntaxes that it is hard to keep them straight... if you have to flip flop between different languages... Spins indentation is an absolute joy.... you just have to remember the syntax for 1 line... your program flow changes when you change the indentation... what could be easier?

    I constantly sit too far back from my monitor... the advantages of indentation over brackets becomes immediately obvious, when you can just barely see what you are looking at[noparse]:)[/noparse]

    when it comes to operators... I agree that there is a bit of a learning curve that is uncomfortable... operators are so ingrained in every language that we use them almost without thinking about them... it is where I habitually screw up my code... until I wake up and think about what I am doing. If I haven't programmed in a week or two, I still find myself using the cheat sheets from time to time.
  • heaterheater Posts: 3,370
    edited 2008-10-17 13:49
    @ Hippy: Good point.

    Given the lack of an urgent reason to have nested procedures I don't think Chip should lose any sleep over them. Especially if they are going to over complicate the compiler.

    After all this time I didn't know GCC could support nested procedures in C. Perhaps it's because GCC also is used as the back end for numerous other languages e.g. ADA. Time for some experiments.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • PyrotomPyrotom Posts: 84
    edited 2008-10-17 20:57
    As another renegade from the 60's (first programming language was CORC), I can say that nested procedures are really needed for languages that can dynamically allocate objects, such as Java. With the static allocation of objects in Spin, the usefulness of nested procedures becomes much more limited. I miss the ability pass a reference to an object as a parameter much more!
Sign In or Register to comment.