Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Why can't we use + to concatenate strings?

adamohernadamohern Member, OS Professional Posts: 216 PRO
It took quite a while to figure out that tilde (~) is used for string concatenation in FS. I'm sure there's a good reason why you chose to use a special operator, but I wonder what that might be, and why tilde was chosen specifically? I've never encountered that in any other language.

Comments

  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    I guess the reason I find this so odd is contortions like this:

    id + ("splitPart"~i)

    You have to wrap the concatenation in parentheses or it fails. Logically speaking, if A + B works, and A + C works, I would expect for A + B + C to work.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,215
    I never liked + for string concatenation because it falsely implies commutativity.  I also wanted a totally distinct operator that would not be overloadable (and would therefore be usable for any type) and not possible to confuse with addition.

    id + ("splitPart"~i) is doing two different things: it's adding a level to the id hierarchy and that level is labeled by a concatenated string.  id + i + "splitPart" would work and add two levels to the hierarchy.

    It's not great that it's not consistent with other languages, but that was the tradeoff for an easy and unambiguous way to turn any value into a string.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    I suppose that makes sense. I like Python, so I'm just used to things being a bit simpler. This is fine.
  • traveler_hauptmantraveler_hauptman Member, OS Professional, Mentor, Developers Posts: 419 PRO
    Just to add an opinion to the mix: I did not struggle with the string cat once I figured it out(I used it with D for a while) but I do agree with @adamohern that it's more likely that users will be coming to FS from a language that uses +. At minimum you may want to sprinkle a few more mentions of it in the docs (code examples that use strings, the string type section).
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,215
    @traveler_hauptman
    You are right -- I forgot -- I did get the tilde operator from D (they have similar reasoning on this).
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    I think I'm beginning to unerstand what 'id + something' does, but if you're going to consider string concatenation as distinct from arithmetic addition, I'm surprised you felt the + sign was a good way to append the (array? map? whatever) to the id item.

    I just found the id declaration thing to be really confusing. It works, and I'm using them without a problem, but it's all very fuzzy.
  • traveler_hauptmantraveler_hauptman Member, OS Professional, Mentor, Developers Posts: 419 PRO
    I also assumed id + 'string' was simple string concatenation for a while. In fact, probably attempting to do a string concatenation and having it error is what caused me to look for the correct operator and then go read std for what the heck id was using + for.
  • adamohernadamohern Member, OS Professional Posts: 216 PRO
    Same here.
  • tom_augertom_auger Member Posts: 116 ✭✭
    I also assumed id + 'string' was simple string concatenation for a while. In fact, probably attempting to do a string concatenation and having it error is what caused me to look for the correct operator and then go read std for what the heck id was using + for.

    Would you happen to have a convenient link handy that explains what the heck id was using + for?  @ilya_baran
    mentioned something about an "id hierarchy" where I assumed what we were doing was simply assigning a unique id "string" that is composed of the id string passed in through the defineFeature() method concatenated to some arbitrary text. Upon reading more on for loops where it's best practice to append the index to the string literal using tilde, is where that nuance starts to rear its ugly head and google led me to this thread in the forums.
  • tom_augertom_auger Member Posts: 116 ✭✭
    I suppose this is probably as good as it gets in terms of understanding the way IDs are represented internally...
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,215
    @tom_auger
    That link is probably as good an explanation as we have.  You can also look in std itself (https://cad.onshape.com/documents/12312312345abcabcabcdeff/v/ea4cda9e1faa7aa24e82d28d/e/1ccf6e5321844da29ab72f2b)
    to see what exactly we do, but it doesn't tell you too much about why.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • MBartlett21MBartlett21 Member, OS Professional, Developers Posts: 2,050 ✭✭✭✭✭
    Just on an additional note:
    The string concatenation operator (~) converts any non-string value to a string (absolutely anything can be converted to a string by "" ~ value)
    mb - draftsman - also FS author: View FeatureScripts
    IR for AS/NZS 1100
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,646
    @MBartlett21
    That works but using `toString(value)` is somewhat more declarative if you are not concatenating onto something.

    -----------

    @tom_auger
    One thing that that description of ids does not mention is the power that comes from id hierarchy:
    fCuboid(context, id + "cuboids" + "A", {...});
    fCuboid(context, id + "cuboids" + "B", {...});
    qCreatedBy(id + "cuboids", EntityType.BODY); // This resolves to both cuboids
     
    Jake Rosenfeld - Modeling Team
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,215
    To clarify a bit more, toString(value) means something different than "" ~ value -- conversion to string for concatenation is entirely internal and will perfectly preserve maps etc.  toString can be (and is) overloaded for various types, so for instance ValueWithUnits will have a nicer representation.  toString is usually the right choice, but if you need to know the underlying representation "" ~ value is the way.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
Sign In or Register to comment.