How to concatenate strings ?


    Mar 22 2006 | 12:02 pm
    Hi everybody, i'm a newbie in max and i'm already facing a problem :(
    I need to concatenate strings (symbols if you prefer) from 2 diferent lists and them send them over OSC to other applications (e.g. Eyesweb).
    For instance i've got a message box with [UUID00 UUID01 UUID02...UUIDnn] and another message box with [TLM-LUIS TLM-JOSE TLM-XPTO ...] my gold is to join these elements into a third list like [UUID00TLM-LUIS UUID01TLM-JOSE ...] and then send them over by OSC
    Can anyone help me out ? plzzzz :)
    Regards
    Nonon

    • Mar 22 2006 | 12:30 pm
      you can use sprintf
    • Mar 22 2006 | 12:41 pm
      Jasch has also made a lib for such things
      www.jasch.ch/dl/default.htm
      another good thing to do is to read the manual,
      and search in the forum if your question has
      not been asked thousands of times...
      or you'll soon learn what RTFM and STFW mean ;-)
      cheers
      vg
    • Mar 22 2006 | 12:44 pm
      On 22-Mar-2006, at 13:02, Nuno wrote:
      > For instance i've got a message box with [UUID00 UUID01
      > UUID02...UUIDnn] and another message box with [TLM-LUIS TLM-JOSE
      > TLM-XPTO ...] my gold is to join these elements into a third list
      > like [UUID00TLM-LUIS UUID01TLM-JOSE ...] and then send them over by
      > OSC
      Look at zl (partic [zl iter]) and sprintf.
    • Mar 22 2006 | 12:58 pm
      On 22 Mar 2006, at 12:02, Nuno wrote:
      > I need to concatenate strings (symbols if you prefer) from 2
      > diferent lists and them send them over OSC to other applications
      > (e.g. Eyesweb).
      As others have already hinted, [sprintf %s%s] will do what you want.
      However, if you're going to have arbitrary combinations of symbols,
      every combination symbol is going to go into Max's symbol hash table
      - forever. This may or may not affect performance.
      -- N.
      nick rothwell -- composition, systems, performance -- http://
      www.cassiel.com
    • Mar 22 2006 | 4:17 pm
      Tnx to you all :)
      I did searched the forum with "concatenate strings" keywords and didn't found nothing...but since my net acess is so lousy i'm not sure of anything...as for the manual, i've got a printed version and stinks, no sprintf, i've started to read the pdf latest (and complete) version.
      I've checked the sprintf and i'm sure it will do fine , as for the jasch lib, well, tnxs again for the tip: it's a very cool one and i'm downloading it right now...
      Best Regards
      Nonon
    • Mar 22 2006 | 11:07 pm
      On Mar 22, 2006, at 7:58 AM, Nick Rothwell wrote:
      > As others have already hinted, [sprintf %s%s] will do what you want.
      >
      > However, if you're going to have arbitrary combinations of symbols,
      > every combination symbol is going to go into Max's symbol hash
      > table - forever. This may or may not affect performance.
      What's the rationale here for Max's implementation of symbols? This
      doesn't make much sense to me.
      - John
    • Mar 22 2006 | 11:14 pm
      On 22 Mar 2006, at 23:07, John Nowak wrote:
      > What's the rationale here for Max's implementation of symbols? This
      > doesn't make much sense to me.
      You mean, the rationale for permanently hashing them?
      Fast lookup and comparison. Max uses symbols for ... well,
      everything, really.
      -- N.
      nick rothwell -- composition, systems, performance -- http://
      www.cassiel.com
    • Mar 23 2006 | 10:27 am
      Further unto: string comparison is slow. Comparing pointer addresses
      is fast. We can be talking as much as factor 100 here. More typically
      maybe factor 20 or so, but that's still a big difference.
      Furthermore, in the late 1980s this had to run on 68000s and 68020s
      at 8 MHz.
      Miller's implementation of symbols was puredead brilliant. Still is.
      The downside to this strategy (that the hash table grows and grows
      and grows and grows and grows and grows and...) is negligible in a
      world of +512MB RAM.
      -- P
      -------------- http://www.bek.no/~pcastine/Litter/ -------------
      Peter Castine | +--> Litter Power & Litter Bundle for Jitter
      |....................................................
      p@castine.de | iCE: Sequencing, Recording, and Interface Building
      pcastine@gmx.net | for Max/MSP
      pcastine@bek.no | http://www.dspaudio.com/ Extremely cool
      4-15@kagi.com |....................................................
      | home|chez nous|wir|i nostri http://www.castine.de/
    • Mar 23 2006 | 12:34 pm
      On 23 Mar 2006, at 10:27, Peter Castine wrote:
      > The downside to this strategy (that the hash table grows and grows
      > and grows and grows and grows and grows and...) is negligible in a
      > world of +512MB RAM.
      Sure, but these days people are talking about Max/MSP for
      installation works which run for months at a time. (Mine clocked in
      five weeks of 24/7 operation, but that's modest these days.) If the
      code is generating several distinct symbols a second (say, by
      symbolising a string representation of date and time) that adds up
      to ... erm ... lots. (And I don't know what computational complexity
      we're looking at here - O(log N)? - but with a gazillion symbols that
      must degrade somewhat.) So, it's a bad thing to do, and I always have
      faint alarm bells going off whenever I see something that's
      potentially synthesising dynamic symbols.
      It might be nice to have some kind of built-in Max function to report
      symbol table size and stats (bucket sizes and the like).
      -- N.
      nick rothwell -- composition, systems, performance -- http://
      www.cassiel.com
    • Mar 23 2006 | 1:37 pm
      On 23-Mar-2006, at 13:34, Nick Rothwell wrote:
      > Sure, but these days people are talking about Max/MSP for
      > installation works which run for months at a time.
      Point taken. Assuming you're *not* auto-rebooting once a day (which a
      lot of installations do for many reasons).
      Also, if the vocabulary is sufficiently limited, auto-generated
      symbols will start repeating before memory becomes an issue. Nuno's
      example:
      >> For instance i've got a message box with [UUID00 UUID01
      >> UUID02...UUIDnn] and another message box with [TLM-LUIS TLM-JOSE
      >> TLM-XPTO ...]
      >
      could, mathematically, generate up to 45 million different symbols,
      which would fill up an awful lot of RAM. But if the TLM-LUIS etc. are
      limited to a couple of hundred names, then symbol table growth will
      be tractable.
      This all depends very much on the concrete application.
      > It might be nice to have some kind of built-in Max function to
      > report symbol table size and stats (bucket sizes and the like).
      Or if Max time-stamped symbol usage and would start flushing unused
      symbols at some point.
      Or if it were possible to have a non-symbolized string data type.
      There was a 3rd party add-in a while back that did this; JScript and
      Java will also allow you to munge strings without stuffing the symbol
      table.
      J/JS are probably the most reliable options today for avoiding symbol
      table explosion. If and when it's an issue.
      You're right that people should think about what they're doing if
      they're going to auto-generate symbols, but in a lot of cases it
      doesn't rate more than blue or yellow HLS status.
      -- P.
      -------------- http://www.bek.no/~pcastine/Litter/ -------------
      Peter Castine | +--> Litter Power & Litter Bundle for Jitter
      |....................................................
      p@castine.de | iCE: Sequencing, Recording, and Interface Building
      pcastine@gmx.net | for Max/MSP
      pcastine@bek.no | http://www.dspaudio.com/ Extremely cool
      4-15@kagi.com |....................................................
      | home|chez nous|wir|i nostri http://www.castine.de/
    • Mar 23 2006 | 5:25 pm
      I was more talking about the permanent aspect. Obviously string
      comparisons for everything would be dog slow (which is part of the
      reason we have ports in the first place rather than prepending
      commands to everything I'd assume). I'd think after the current
      branch was done (i.e. after sprintf is done sending to everything),
      we'd be able to kick the symbol out of the hash table, no? I'm not
      trying to be snarky here -- I'm genuinely curious as I'm implementing
      a similar system myself. I've opted instead to do *everything* via
      ports, which works fine as it is a text-based language, and it is
      very fast (every "port" is just a function pointer that takes the
      current "object" and the received data as arguments). Obviously using
      so many "ports" is not possible with the GUI paradigm, and hence we
      have the current system.
      Can anyone explain why we can't manage the hash table at all?
      - John
    • Mar 23 2006 | 8:06 pm
      On Mar 23, 2006, at 9:25 AM, John Nowak wrote:
      >
      > Can anyone explain why we can't manage the hash table at all?
      symbols need to live for the life of the application since they are
      matched by pointer comparison (i.e. fast). The pointer must remain
      the same since there is no way of determining when there are no
      longer any references to said symbols. One could imagine a system
      which uses reference counting to "attach to" or "release" a symbol,
      though it would require a complete max overhaul (and all supporting
      objects) to do so. Not likely in the near future.
      If you want to use strings (i.e. *not* symbols), you can accomplish
      this in a number of ways--e.g. lists of integers or single letter
      symbols (which would only take up a handful of symbol table slots),
      or jitter matrices.
      -Joshua
    • Mar 24 2006 | 9:44 am
      This thread is interesting and important, as it shows something I was
      never aware of...
      Joshua Kit Clayton wrote:
      > If you want to use strings (i.e. *not* symbols), you can accomplish
      > this in a number of ways--e.g. lists of integers or single letter
      > symbols (which would only take up a handful of symbol table slots), or
      > jitter matrices.
      One essential information is missing for me: where does this hashing
      happen and which are the objects which actually do it.
      There are these lftoa and atolf objects from the pluggo installers which
      could translate strings into numbers. But if the symbol is already in
      the table it wouldn't help...
      One way to control the hash table eventually would be to exchange a
      symbol with another one. (Not for newbies, keep it somewhere hidden in
      the docs.) If you know that the symbol isn't used elswhere anymore you
      might want to exchange it instead of creating a new entry in the table.
      A nice opportunity to create almost untrackable bugs... ;-)
      For real world applications outside of installations its probably not
      important.
      Stefan
      --
      [][] [][][] [][] [][][]
      [][][][][][][][][][][][][][][]
      Stefan Tiedje
      Klanggestalter
      Electronic Composition
      &
      Improvisation
      /~~~~~
      \ /|() ()|
      ))))) )| | |( \
      /// _/)/ )))))
      ___/ ///
      -------------------------x----
      --_____-----------|-----------
      --(_|_ ----|-----|-----()----
      -- _|_)----|-----()-----------
      ----------()------------x-----
      14, Av. Pr. Franklin Roosevelt,
      94320 Thiais, France
      Phone at CCMIX +33-1-57 42 91 09
    • Mar 24 2006 | 10:29 am
      On 24 Mar 2006, at 09:44, Stefan Tiedje wrote:
      > One essential information is missing for me: where does this
      > hashing happen and which are the objects which actually do it.
      A hash entry is created (or, if it exists, retreived) by any external
      object, or part of Max/MSP proper, which makes a kernel call to gensym
      () - in other words, it happens all over.
      Re: symbol exchange: the point of hash tables is that they use hash
      values, designed to produce as few collisions as possible; it's not
      possible to exchange a symbol in-place in the table. Or am I
      misunderstanding your suggestion?
      -- N.
      nick rothwell -- composition, systems, performance -- http://
      www.cassiel.com
    • Mar 24 2006 | 11:52 am
      On 24-Mar-2006, at 10:44, Stefan Tiedje wrote:
      > One way to control the hash table eventually would be to exchange a
      > symbol with another one. (Not for newbies, keep it somewhere hidden
      > in the docs.) If you know that the symbol isn't used elswhere
      > anymore you might want to exchange it instead of creating a new
      > entry in the table.
      An interesting idea that, at its core, breaks almost all of the
      object-orientation of Max.
      Once an object passes a symbol out of an outlet, it can never "know
      that it isn't used elsewhere anymore". To do that, your object would
      have to what objects are attached and how each and every object
      (including 3rd party, yet-to-be-developed objects!) that receives the
      symbol handles it. Maybe someone is storing your object's symbols in
      a coll. If you destroy the hash table entry, that coll will go BOOM!
      and take Max down with it.
      An object can, realistically, only gauge the lifespan of a character
      string that it uses internally. In this case, there is probably no
      need to turn the string into a symbol.
      Add to this the details of hash table management--hash tables do not
      generally get smaller just because a couple of entries have been
      deleted--the idea is probably inpracticable at several levels.
      Of course, I don't know the innards of how Max manages its particular
      hash tables, so I may be going out on a limb with the above. But it
      seems a pretty stable limb.
      -- Peter
      -------------- http://www.bek.no/~pcastine/Litter/ -------------
      Peter Castine +--> Litter Power & Litter Bundle for Jitter
      iCE: Sequencing, Recording & |home | chez nous|
      Interface Building for |bei uns | i nostri|
      Max/MSP Extremely cool http://www.castine.de
    • Mar 25 2006 | 11:32 am
      Nick Rothwell wrote:
      > A hash entry is created (or, if it exists, retreived) by any external
      > object, or part of Max/MSP proper, which makes a kernel call to gensym
      > () - in other words, it happens all over.
      The question then would be, where does it not happen. If an external has
      a method "anything" does it happen? or does it happen if it has a method
      for "symbol"? When I send a message from a message box or from sprintf,
      is it already in the table? Or do I have a chance to convert it with
      atolf...
      > Re: symbol exchange: the point of hash tables is that they use hash
      > values, designed to produce as few collisions as possible; it's not
      > possible to exchange a symbol in-place in the table. Or am I
      > misunderstanding your suggestion?
      Yes that was the suggestion. Well, I am happy with Millers "puredead
      brilliant" way of doing it as Peter explained. No real world problem here...
      Stefan
      --
      [][] [][][] [][] [][][]
      [][][][][][][][][][][][][][][]
      Stefan Tiedje
      Klanggestalter
      Electronic Composition
      &
      Improvisation
      /~~~~~
      \ /|() ()|
      ))))) )| | |( \
      /// _/)/ )))))
      ___/ ///
      -------------------------x----
      --_____-----------|-----------
      --(_|_ ----|-----|-----()----
      -- _|_)----|-----()-----------
      ----------()------------x-----
      14, Av. Pr. Franklin Roosevelt,
      94320 Thiais, France
      Phone at CCMIX +33-1-57 42 91 09
    • Mar 25 2006 | 11:55 am
      It happens everytime the kernel or an object calls gensym(), which, if
      you do a Find in any of the available source code for Max objects,
      happens frequently.
      In effect, every message you send to the inlet of a Max object, or type
      into a box is, at some point, converted to a symbol.
      jb
    • Mar 26 2006 | 11:48 am
      Jeremy Bernstein wrote:
      > In effect, every message you send to the inlet of a Max object, or type
      > into a box is, at some point, converted to a symbol.
      In short terms, even if I send something to atolf it will be converted
      because its going to its inlet. Aka no issue for patchers, only for
      source coders eventually.
      Stefan
      --
      [][] [][][] [][] [][][]
      [][][][][][][][][][][][][][][]
      Stefan Tiedje
      Klanggestalter
      Electronic Composition
      &
      Improvisation
      /~~~~~
      \ /|() ()|
      ))))) )| | |( \
      /// _/)/ )))))
      ___/ ///
      -------------------------x----
      --_____-----------|-----------
      --(_|_ ----|-----|-----()----
      -- _|_)----|-----()-----------
      ----------()------------x-----
      14, Av. Pr. Franklin Roosevelt,
      94320 Thiais, France
      Phone at CCMIX +33-1-57 42 91 09
    • Mar 26 2006 | 11:57 am
      Yes. I wouldn't worry too much about the symbol table.
      jb