Shop OBEX P1 Docs P2 Docs Learn Events
New Spin - Page 19 — Parallax Forums

New Spin

1161719212236

Comments

  • I think the basic problem of spin is not to be able to pass a function as a argument, except on starting a new spin cog. There you can do it, and even pass parameters to the used/started method.

    if you could write:

    hexOut(ser.tx(char),value) instead of implementing hex in the object 'ser'

    things would get way easier to reuse.

    It would also allow to use the same output redirected to different devices by just changing the pointer to the output function.

    so something like

    currentoutput := addressOf(ser.tx(char))

    hexout(currentoutput,value)

    should work also. Or something alike to that

    Also in current syntax you can access functions/methods of a object thru

    ser.tx(whatever) and can access constants thru ser#baudrate.

    a nice addition would be ser@label to get the runtime address of any dat or var label inside the current instance of the 'ser' object, whatever 'ser' might be.

    I also think that the @,@@ and @@@ dilemma should be fixed so that a

    @label (or ser@label)

    always returns the real memory address, independent of used in code or in a dat section or in what instance of what sub object.

    Enjoy!

    Mike
  • cgraceycgracey Posts: 14,133
    Thanks, Mike. That all makes sense.
  • Chip,

    If you have two instances of a given object, one instance can't access the members of the other instance without some extra accessor functions added. It's mostly important for objects that are implementing math things like vectors and matrices. Where you want to do operations on multiple vectors/matrices together or like a vector matrix transform operation. You need access to the data elements of both (or more) instances. If your data is simple (like an array of the same type) then you can make a single accessor function and make it work, but it's kind of ugly syntax in usage cases, especially for math operations. If your data is not a simple array, then you need to use multiple accessor functions and that gets even more ugly. That's where I think structures could help.

    I think that if there was a mechanism for accessing the VARs of an object similarly to how we can use constants now with the obj#con syntax, then it helps make the syntax less ugly and gets rid of needing accessor functions.

    To really clean up the syntax for math like stuff it would require operator overloading, which I think we should NOT do in Spin. Just having a clean built in way to access VARs of an object instance would go a long way.
  • cgracey wrote: »
    One good thing about Prop2 is that bytes, words, and longs can sit in hub memory at any offsets, unlike in Prop1. This means there's no more need to segregate groups of longs, words, and bytes in VAR memory. That was done in Spin1 to avoid interstitial gaps between differently-sized variables.

    So, structures are not only welcome, but more practical than before.

    Yeah, I understand that, and am really glad the Prop2 has this new ability. I'm really looking forward to it all.
  • cgraceycgracey Posts: 14,133
    edited 2017-02-27 04:38
    Roy Eltham wrote: »
    Chip,

    If you have two instances of a given object, one instance can't access the members of the other instance without some extra accessor functions added...

    You are talking about accessing VAR elements of and from different instances, right, or just the methods which access them?

    You can make instance arrays, already, you know.
  • cgraceycgracey Posts: 14,133
    I keep imagining visualization stuff. There should be a visual for the object tree, which animates when executing, showing VAR states, method usage, and cogs. The more views one gets of his program, the better he'll understand what it's doing and how the resources are being used.
  • In my PropISAM project, I simulated structs by defining offsets in a object just using constants. So I could use it in any subObject without problems

    so object 'person' had

    index = 0
    firstname = 4
    lastname = 24
    ...

    in the code I used
    xxx := long[baseAdressOfReccord][person#firstname]

    to access it.

    quite readable in source.

    structs are basically just offsets of base addresses.

    Enjoy!

    Mike
  • Chip,
    Yes, accessing VAR elements to/from different instances. I know about arrays of objects, yes, I had to fix several bugs in OpenSpin due to them. :)
  • cgracey wrote: »
    I'm not entirely understanding the object limitations of Spin1, like Jason Dorie was talking about. Could someone explain what's needed, relative to what Spin1 already has? I want to understand this.

    The example I gave related to the Elev8 project is this: I have an object called Prefs that I use to store global user preferences, read and write them to/from eeprom, and send/receive them over the serial connection. Any global user preference that needs to persist and be editable is managed by this object. Having a single object that managed its data in DAT space would mostly work in Spin - I could include the object in the various places it's used, and use the functions to read/write the DAT data and it would work.

    In C++ I can create as many of these as I want, and pass them around. I generally only have one global one, with the single exception of when I'm reading one from somewhere, and don't want to overwrite the current one until I know the new one is correct (verified via checksum). In C++ this is trivial to manage - I pass a named object around as a pointer (or a reference, which is like a pointer, but has more restrictions).

    In Spin, the only way to instantiate an object of a given type is like this:
      ObjName : "Filename.spin"
    

    So, you're including the code, and creating a local object all at once, and you can only use it from there.

    What I want to be able to do is more like this:
      TypeName : "Filename.spin"
    
    pub DoSomething( TypeName : myObject ) | x, y
      x := myObject.GetValue()
      x *= 5
      myObject.SetValue( x )
    

    There's no way to do anything like that in Spin that I know of (at least that's intuitive or easy). You can't create a data structure and pass it around, referencing members by name in multiple objects, and you can't create an object (like an I2C object, or FDS) and pass that around to other things, call methods on it, etc. You can only *declare* it in your Spin code, and by declaring it you're essentially also creating it. Unless it uses all DAT members, in which case there's only ever one of them, which is also restrictive in some cases, but for different reasons.

    Does that make sense? I'm hoping that gets it across - I have other examples, but I think this illustrates it fairly well. I can point you at a couple places in the Elev8 code where C/C++ made certain things quite a bit simpler than their Spin counterparts.
  • JasonDorie,
    Makes sense to me. And that's an additional thing besides accessing VARs of an object from another object. I think we need both.
  • MJBMJB Posts: 1,235
    Heater. wrote: »
    Ah yes the great Bret Victor. You mean like this famous demo:



    Notice how he is always working in source text there. Even if the output is very graphical.

    Notice how functions can individually be updated on the fly to change program behavior.

    Notice how it's all done in Javascript.

    It's not clear to me how this can be done in Spin or traditional micro-controller languages.

    It can of course be done with the Espruino JS engine on an STM32 MCU.



    If I follow his main idea in the video,
    then I think a major breakthrough for SPIN is not adding some little syntactic/sematic aspects as discussed here
    a real break trough will be adding a REPL (Read Eval Print Loop i.e. have the interpreter exposed to the user and not just used internally for compactness reasons,
    so users can interactively explore things like we can do in FORTH, LISP, some BASIC interpreters, MATLAB, LOGO (this is what I used many times to teach young and older kids some programming) ...
    This gives debugging, introspection, or just plain PLAYING

    If I can I always prefer REPL based systems for my engineering type projects over the classical EDIT/COMPILE/RUN/ERROR start again cycles.

    This is one reason I like TACHYON so much - it's the only real powerful REPL I know of for the Propeller.



  • Just an FYI, CSPIN has implemented structs using Spin for several years. Of course, the syntax uses C syntax since that's what it is converting. This is converted into Spin source by using the struct starting address along with a byte offset. The element is accessed using the BYTE, WORD or LONG keyword depending on the size of the element.
  • Heater.Heater. Posts: 21,230
    edited 2017-02-27 13:06
    That is why I love the Espruino Javascript engine. One can interactively enter code, get it running from interval timers or whatever events in responds to, then interact with it as it runs. Add more code, run expressions, call functions, rewrite functions, change values of variables etc. All on the fly.

    Is the Spin language even suitable for such a REPL? In Spin one cannot just write a one line expression like you can in BASIC, JS, Python, etc. It has to be wrapped in a PUB or PRI which is in turn wrapped in an object. Similarly there are no free standing functions. This all makes Spin some what less fun for playing with in a REPL.

    I guess Spinx (spelling?)is the closest we have to interactive Spin on the Propeller.

    On the other hand the compile, program, run turn around time with Spin is fast enough I have not felt the need for further interaction with a REPL. Especially when testing out new objects on their own.



  • Here is how CSPIN handles structs. The following C source
    struct TestS
    {
        int x;
        unsigned short y;
        char z;
    } a;
    
    void testsub(void)
    {
        a.z = a.x + a.y;
    }
    
    is converted to
    CON
    ' struct TestS
    x = 0
    y = 4
    z = 6
    
    VAR
      long a[2]
    
    PUB testsub
      byte[@a + z] := long[@a + x] + word[@a + y]
    
  • Roy Eltham wrote: »
    For Spin2, I will be very sad if it doesn't have structures. It's a fundamental thing that is missing.

    It makes stuff that would be a complete mess without them, very clean and simple with them.

    Isn't a structure just an object with no methods (only variables)? it seems like we don't need to add a new feature to Spin, just extend the existing feature (objects).

  • I just realized that most of what is being proposed in this thread has been proposed for P1 for many years. It's interesting that these suggestion where rejected and/or ignored for so many years, but now everyone is excited about getting them into Spin for P2.
  • Heater.Heater. Posts: 21,230
    Are you sure it's the same people doing the proposing and rejecting? Did they swap places?

    I can imagine some people changing their minds because the P2 is such a different machine, vastly bigger memory, HUB exec, etc. There must be things that were not so necessary within the confines of the P1 memory and performance and the resulting small scale of programs there.
  • Heater. wrote: »
    Are you sure it's the same people doing the proposing and rejecting? Did they swap places?

    I can imagine some people changing their minds because the P2 is such a different machine, vastly bigger memory, HUB exec, etc. There must be things that were not so necessary within the confines of the P1 memory and performance and the resulting small scale of programs there.
    I'm not sure what bigger memory has to do with structures. It seems like P1 could have benefited from them all along. Same goes with object references.

  • Heater.Heater. Posts: 21,230
    Perhaps not structures and object references specifically.

    Bigger memory means bigger programs which means more "programming in the large" as they like to say. Languages like C++, Ada, etc have a ton of features to make programming in the large by large teams easier. Which aren't really much use for a lone programmer creating little programs.

    I have no objection to the structure and object reference ideas. As long as the syntax and semantics of Spin don't get over complicated and uglyfied. We already have C++ for that :)

  • Roy has already suggested how structures could be defined in a manner similar to how things are currently done in Spin and both of us pointed out a logical extension of pointer dereferencing that should work for structure and object references.
  • Here's another approach that may be worth considering:

    Define just the bytecode interpreter. In other words, define the core bytecode operations, independent of the HLL. This is similar in concept to the CLR and JVM (and others). This can be (mostly) done without consideration for whether it's end-user friendly or not (e.g. ternary operators vs multiline if/else blocks).

    This allows:
    * A separation of the discussion about core requirements (func pointers, structured operations, etc.) and representation of high-level concepts (classes, structures, operator syntax, etc.) in the HLL.
    * Conversations about Spin changes to be framed within the context of whether the bytecode interpreter can support it.
    * Other languages can be written/ported to output the bytecode, potentially allowing interoperability between those languages.
  • Heater. wrote: »
    Are you sure it's the same people doing the proposing and rejecting? Did they swap places?

    I can imagine some people changing their minds because the P2 is such a different machine, vastly bigger memory, HUB exec, etc. There must be things that were not so necessary within the confines of the P1 memory and performance and the resulting small scale of programs there.
    Heater, it probably does depend on who's proposing the ideas. I have proposed some of the ideas myself, and they've been shot down. But then others can propose the same idea later on and it gains acceptance.

    Ultimately, it is Parallax that either accepts proposals or rejects them. And most often it comes down to Chip. So yes, Chip has swapped places on a few of the features we're talking about.

    I don't think the capabilities of the P2 has much to do with method pointers, integrating floating point, supporting structures or adding a ternary operator.

  • Dave Hein wrote: »
    Just an FYI, CSPIN has implemented structs using Spin for several years. Of course, the syntax uses C syntax since that's what it is converting. This is converted into Spin source by using the struct starting address along with a byte offset. The element is accessed using the BYTE, WORD or LONG keyword depending on the size of the element.

    My issue with anything like this is that Spin itself has certain patterns inherent to it that are faster than others - like accessing the first 16 variables in an object are faster, for example. Things like this, doing an end-run around those limits, are likely to end up costing performance. Add C's optimizer (Spin doesn't have one) and I'd just stick to C. I'm making assumptions here, but it'd be worth timing to see how the generated Spin stacked up to CMM in size and speed. CMM code has surprised me.

    If Chip is bent on supporting Spin first and C/C++ second, I'd like to see it get some of the things that C/C++ does that Spin stumbles on.
  • Perhaps those limits will be different this time.

    Byte code is planned, and a good size optimal option. Compiled is planned too, and a good speed optimal option.

    People will also have the option to use PASM directly, not just on a whole COG basis.

    Seems to me, optimization in the compile to PASM option can marginalize most of those concerns.
  • Heater.Heater. Posts: 21,230
    JasonDorie,
    If Chip is bent on supporting Spin first and C/C++ second,
    Perhaps it's not a question of Chip deciding on "Spin first, C/C++ second".

    I should not speak for Chip but get the feeling that Chip is not much into C/C++. Chip will do Spin because that's his thing.

    Meanwhile C/C++ support is either down to some GCC experts enthusiastic enough to target the P2. Or Parallax is going to have to hire someone.
    I'd like to see it get some of the things that C/C++ does that Spin stumbles on.
    Me to.

    But not if it means making a pigs ear out of the Spin syntax/semantics like C++.








  • If an optimized Spin to PASM path is planned that would take care of most of my concerns until a C++ is available.
  • JasonDorie wrote: »
    If an optimized Spin to PASM path is planned that would take care of most of my concerns until a C++ is available.

    fastspin already provides an optimized Spin to PASM path for P1 (and it supported a version of P2 last year, although that's bit rotted now). I don't know what Parallax's plans are, but if Spin2 is not too different from Spin1 then I (or anyone with sufficient motivation) could update fastspin to support it. If Spin2 gets wildly different then that'll be harder, of course.
  • Keep in mind that inline PASM in Spin will be hubexec execution mode. It can't really be anything else given the context. So it won't be full speed PASM as with COG/LUT execution (primarily with branches). Also, since starting hubexec incurs a delay to prime the fifo, short inline pasm will have a higher percentage of overhead cost.

    Having the compiler produce PASM from Spin will also have a lot of hubexec in it unless the entire Spin program can fit into one COGs local memory. Also, not sure how "optimized" this will be, writing an optimizing compiler for Spin to PASM is a giant task beyond just getting it to output PASM.

    As for SPin first, C/C++ second, that will be the case in the near term, but I suspect that by the time we have actual chips in hand, we will have Spin, C/C++, Forth, Basic, and perhaps some others at least in some workable state. There is a fairly long time between being "done" with the verilog/design and having the final chips ready for sale.
  • jmgjmg Posts: 15,140
    Seairth wrote: »
    Here's another approach that may be worth considering:

    Define just the bytecode interpreter. In other words, define the core bytecode operations, independent of the HLL. This is similar in concept to the CLR and JVM (and others). This can be (mostly) done without consideration for whether it's end-user friendly or not (e.g. ternary operators vs multiline if/else blocks).

    This allows:
    * A separation of the discussion about core requirements (func pointers, structured operations, etc.) and representation of high-level concepts (classes, structures, operator syntax, etc.) in the HLL.
    * Conversations about Spin changes to be framed within the context of whether the bytecode interpreter can support it.
    * Other languages can be written/ported to output the bytecode, potentially allowing interoperability between those languages.
    Yes, I've suggested this Byte-Code (or Word-code) centric approach before, but it gets lost in the 'new feature' chatter.
    Tachyon exists already on P2, and Peter changed there to a word-code.
    I've not seen yet, numbers on how the recent opcode changes improved Tachyon.
    (or if that means TF2 word choice is still the correct one?)
    A focus on code-engine (which I think should also include external memory fetch for XIP, from QuadSPIx2 or HyperRAM) means the silicon can be debugged - the higher level syntactic sugar can come along later.

    There is also WebAssembly, and they look to have some good ideas around documenting byte-codes.

  • Roy Eltham wrote: »
    Keep in mind that inline PASM in Spin will be hubexec execution mode. It can't really be anything else given the context. So it won't be full speed PASM as with COG/LUT execution (primarily with branches). Also, since starting hubexec incurs a delay to prime the fifo, short inline pasm will have a higher percentage of overhead cost.

    Having the compiler produce PASM from Spin will also have a lot of hubexec in it unless the entire Spin program can fit into one COGs local memory. Also, not sure how "optimized" this will be, writing an optimizing compiler for Spin to PASM is a giant task beyond just getting it to output PASM.

    I get that full speed PASM isn't possible with hub exec, but I assume it's going to be as fast as LMM on the P1, and that'd be enough. P1 is in this weird space where LMM has amazing performance, but is hobbled by limited RAM, while CMM & Spin are memory conserving but the performance is orders of magnitude slower, and you can't mix the two.

    If P2's tools support compilation to LMM/hubexec code, and it has enough RAM for large-ish programs, it'll be fine even if it's Spin. I don't care as much about the syntax of the language as I do about the feature set. GCC already has a great optimizer and dead code elimination. Catching up to that in a brand new Spin compiler is going to take a bunch of work, but if the idea is to provide Spin for beginners and an initial offering while GCC is ramped up for P2 then I'm on board.
Sign In or Register to comment.