Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
StringJoin with ToString
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  10 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
replicator...@gmail.com  
View profile  
 More options Apr 3 2009, 9:15 pm
Newsgroups: comp.soft-sys.math.mathematica
From: replicator...@gmail.com
Date: Sat, 4 Apr 2009 01:15:40 +0000 (UTC)
Local: Fri, Apr 3 2009 9:15 pm
Subject: StringJoin with ToString
It is quite interesting why StringJoin does not apply ToString to
those arguments which are non-string. I've overridden the built-in
StringJoin, to save a few unnecessary ToStrings by the standard method
(the context specifications are necessary for packaging):

Unprotect[System`StringJoin];
$UseNewStringJoin = True;
System`StringJoin[expr___] :=
  Block[{$UseNewStringJoin = False},
    StringJoin@(ToString /@ {expr})] /; TrueQ[$UseNewStringJoin];
Protect[$UseNewStringJoin];
Protect[System`StringJoin];

This seems to work (after loading the package) for any cases, e.g.:

In[2]:= StringJoin[1, 2, 3]

Out[2]= "123"

In[3]:= 4 <> 5 <> 6

Out[3]= "456"

but has a strange effect on messages:

In[5]:= Append[dummy, 2]

During evaluation of In[5]:= Append::normal: {Nonatomic expression
expected at position , {1},  in , {Append[dummy,2]}, .} >>

Out[5]= Append[dummy, 2]

that is: the message strings are displayed in a non-joined list
format.
The code below shows an other modified StringJoin, that gives the
exact same results (after initiating a fresh kernel):

Unprotect[System`StringJoin];
       System`StringJoin[expr___]:=Module[{str=""},
       Scan[(Print[#]; str=StringInsert[str,ToString[#],-1])&,{expr}];
       str
];
Protect[System`StringJoin];

Now I've inserted a Print[#]; inside the function to see what's
happening. This reveals some internal calculation that is done during
the evaluation of the erroneous call of Append[dummy, 2], which I
don't really understand (did not copy here for size constraints).
Apart from this strange sideeffect on messages (which seems to be
harmless), both functions work as expected. Does anyone have any idea
what is the exact cause of this behaviour and how to overcome it?

Thanks

Istvan Zachar


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
replicator...@gmail.com  
View profile  
 More options Apr 5 2009, 6:36 am
Newsgroups: comp.soft-sys.math.mathematica
From: replicator...@gmail.com
Date: Sun, 5 Apr 2009 10:36:06 +0000 (UTC)
Local: Sun, Apr 5 2009 6:36 am
Subject: StringJoin with ToString
It is quite interesting why StringJoin does not apply ToString to
those arguments which are non-string. I've overridden the built-in
StringJoin, to save a few unnecessary ToStrings by the standard method
(the context specifications are necessary for packaging):

Unprotect[System`StringJoin];
$UseNewStringJoin = True;
System`StringJoin[expr___] :=
  Block[{$UseNewStringJoin = False},
    StringJoin@(ToString /@ {expr})] /; TrueQ[$UseNewStringJoin];
Protect[$UseNewStringJoin];
Protect[System`StringJoin];

This seems to work (after loading the package) for any cases, e.g.:

In[2]:= StringJoin[1, 2, 3]

Out[2]= "123"

In[3]:= 4 <> 5 <> 6

Out[3]= "456"

but has a strange effect on messages:

In[5]:= Append[dummy, 2]

During evaluation of In[5]:= Append::normal: {Nonatomic expression
expected at position , {1},  in , {Append[dummy,2]}, .} >>

Out[5]= Append[dummy, 2]

that is: the message strings are displayed in a non-joined list
format.
The code below shows an other modified StringJoin, that gives the
exact same results (after initiating a fresh kernel):

Unprotect[System`StringJoin];
       System`StringJoin[expr___]:=Module[{str=""},
       Scan[(Print[#]; str=StringInsert[str,ToString[#],-1])&,{expr}];
       str
];
Protect[System`StringJoin];

Now I've inserted a Print[#]; inside the function to see what's
happening. This reveals some internal calculation that is done during
the evaluation of the erroneous call of Append[dummy, 2], which I
don't really understand (did not copy here for size constraints).
Apart from this strange sideeffect on messages (which seems to be
harmless), both functions work as expected. Does anyone have any idea
what is the exact cause of this behaviour and how to overcome it?

Thanks

Istvan Zachar


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Albert Retey  
View profile  
 More options Apr 5 2009, 6:39 am
Newsgroups: comp.soft-sys.math.mathematica
From: Albert Retey <a...@gmx-topmail.de>
Date: Sun, 5 Apr 2009 10:39:01 +0000 (UTC)
Local: Sun, Apr 5 2009 6:39 am
Subject: Re: StringJoin with ToString
H,
.

I think you would be much better off to leave the System functions as
they are and define a tostring or mytostring that behaves as you want. I
have no idea what causes the problems with messages that you see, but I
suspect that there are many more problems that eventually could arise
but you haven't yet discovered because you presumably only tried a very
limited part of Mathematica's full functionality. On the other hand it
is very easy to construct cases where your "improved" ToString behaves
different from the original and so will potentially cause troubles, here
is just one:

If[Head[Quiet[StringJoin[1,2,3]]] == StringJoin,
 Print["this was no string!"]]

hth,

albert


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
ADL  
View profile  
 More options Apr 5 2009, 6:40 am
Newsgroups: comp.soft-sys.math.mathematica
From: ADL <alberto.dilu...@tiscali.it>
Date: Sun, 5 Apr 2009 10:40:18 +0000 (UTC)
Local: Sun, Apr 5 2009 6:40 am
Subject: Re: StringJoin with ToString
With the following definitions, your idea appears to work (at least in
a few examples I tested):

ClearAll[toString];
toString[x_?NumericQ, format___] := ToString[x, format];
toString[x_[y__], format___] := x @@ (toString /@ {y});
toString[x_Symbol, format___] := ToString[x, format];
toString[x_, format___] := x;

Unprotect[System`StringJoin];
Unprotect[$UseNewStringJoin];
$UseNewStringJoin = True;
System`StringJoin[expr___] :=
  Block[{$UseNewStringJoin = False},
    StringJoin @@ (toString /@ {expr})] /; TrueQ[$UseNewStringJoin];
Protect[$UseNewStringJoin];
Protect[System`StringJoin];

The problem was the way ToString works, which is incompatible with
intermediate formatting functions. The definition of "toString" does
the job.

In[12]:= StringJoin[{1, 2, 3}] // InputForm

Out[12]//InputForm=
"123"

In[13]:= StringJoin[1, a, 3] // InputForm

Out[13]//InputForm=
"1a3"

In[17]:= StringJoin[1, "2", \[Pi]] // InputForm

Out[17]//InputForm=
"12Pi"

In[15]:= Append[dummy, 2]

During evaluation of In[15]:= Append::normal: Nonatomic expression
expected at position 1 in Append[dummy,2]. >>

Out[15]= Append[dummy,2]

ADL

On 4 Apr, 03:15, replicator...@gmail.com wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Bailey  
View profile  
 More options Apr 5 2009, 6:40 am
Newsgroups: comp.soft-sys.math.mathematica
From: David Bailey <d...@removedbailey.co.uk>
Date: Sun, 5 Apr 2009 10:40:29 +0000 (UTC)
Local: Sun, Apr 5 2009 6:40 am
Subject: Re: StringJoin with ToString

I would never routinely override built-in commands - even to extend
their functionality. There are lots of reasons for this, but not least
is the fact that code that uses this trick is very hard to read. Why not
simply write a function ExtendedStringJoin.

Part of Mathematica is written using other Mathematica functions - so
problems such as you report are not unexpected.

On the face of it, adding extra functionality to a built-in might not be
expected to cause problems, but it is easy to write code that would be
disrupted by your change:

ss = Quiet[2 <> 3];
Map[ToString[#^2] &, ss]

Who knows what sort of code lies inside Mathematica :)

David Bailey
http://www.dbaileyconsultancy.co.uk


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
replicator...@gmail.com  
View profile  
 More options Apr 8 2009, 2:48 am
Newsgroups: comp.soft-sys.math.mathematica
From: replicator...@gmail.com
Date: Wed, 8 Apr 2009 06:48:56 +0000 (UTC)
Local: Wed, Apr 8 2009 2:48 am
Subject: Re: StringJoin with ToString
Thanks AES,

with your extension the code works fine so far.
For those who warned me not to play with system symbols: I use this
modified StringJoin in a program where it can produce onyl two types
of string outputs: either one that is printed for verbosing (i.e. just
for me to check behaviour of the code) or a string that is used as a
path of some file to be saved.
In both situations any erroneous behaviour would be immediatley
recognized, since either the text printed would be garbled, or the
file/directory would not be created, thus I do not afraid using the
modified StringJoin in this "controlled" environment.

Istvan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
replicator...@gmail.com  
View profile  
 More options Apr 8 2009, 2:49 am
Newsgroups: comp.soft-sys.math.mathematica
From: replicator...@gmail.com
Date: Wed, 8 Apr 2009 06:49:07 +0000 (UTC)
Local: Wed, Apr 8 2009 2:49 am
Subject: Re: StringJoin with ToString
I was too hasty posting my reply:

First, I'm extremely sorry to mix up your name, ADL.
Second: this code of you does only half of the job: It can not convert
lists to strings verbatim,
that is toString[{1,2,3}] gives {"1","2","3"} instead of "{1,2,3}".
Which (as it seems to me) is exactly the problem causing the wrong
pinting of Messages. Still I wonder whether there is a reliable
solution to apply ToString to inputs of StringJoin without explicitely
writing it each time I call StringJoin.
If I use a different name (e.g. ExtendedStringJoin, as it was
suggested), I loose the effective shorthand version (<>), as it would
still use the original function. Is there a way to overwrite at least
the definitions of the infix operator?

Istvan

On Apr 5, 12:40 pm, ADL <alberto.dilu...@tiscali.it> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Bailey  
View profile  
 More options Apr 10 2009, 4:59 am
Newsgroups: comp.soft-sys.math.mathematica
From: David Bailey <d...@removedbailey.co.uk>
Date: Fri, 10 Apr 2009 08:59:33 +0000 (UTC)
Local: Fri, Apr 10 2009 4:59 am
Subject: Re: StringJoin with ToString

replicator...@gmail.com wrote:
> If I use a different name (e.g. ExtendedStringJoin, as it was
> suggested), I loose the effective shorthand version (<>), as it would
> still use the original function. Is there a way to overwrite at least
> the definitions of the infix operator?

You can't overwrite it (as far as I know), and in some ways that would
be as bad as redefining the actual function, but you can co-opt an
unused operator:

In[1]:= SetAttributes[CirclePlus, Flat];
SetAttributes[CirclePlus, OneIdentity];

In[3]:= CirclePlus[x___] := f[x]

In[4]:= a\[CirclePlus]b\[CirclePlus]c\[CirclePlus]d

Out[4]= f[a, b, c, d]

David Bailey
http://www.dbaileyconsultancy.co.uk


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
ADL  
View profile  
 More options Apr 11 2009, 3:56 am
Newsgroups: comp.soft-sys.math.mathematica
From: ADL <alberto.dilu...@tiscali.it>
Date: Sat, 11 Apr 2009 07:56:13 +0000 (UTC)
Local: Sat, Apr 11 2009 3:56 am
Subject: Re: StringJoin with ToString
Istvan, actually toString was not meant to replace ToString, but only
to support your StringJoin functionality in a "hidden" way.
Also, StringJoin[{1, 2, 3}] gives "123", so that only ToString[{1, 2,
3}] can return "{1,2,3}".

In any case, I would also support David Bailey's suggestion. When I
had to do similar things in the past, I used exactly CirclePlus, which
is also rather handy to type in the GUI: <Esc>c+<Esc>.

In the same category, you also find CircleMinus <Esc>c-<Esc>,
CircleDot <Esc>c.<Esc>, CircleTimes <Esc>c*<Esc> and perhaps some
more.

So you can avoid tampering with built-in functions and keep effective
shorthands. Unfortunately, only <> works also in the text interface,
but you might use NonCommutativeMultiply (**), if you do not already
use it for other reasons:

Unprotect[NonCommutativeMultiply];
NonCommutativeMultiply[expr___]:=StringJoin@@(toString/@{expr});
Protect[NonCommutativeMultiply];

1 ** "b" ** c // InputForm
"1bc"

ADL

On 8 Apr, 08:49, replicator...@gmail.com wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
replicator...@gmail.com  
View profile  
 More options Apr 14 2009, 6:12 am
Newsgroups: comp.soft-sys.math.mathematica
From: replicator...@gmail.com
Date: Tue, 14 Apr 2009 10:12:38 +0000 (UTC)
Local: Tues, Apr 14 2009 6:12 am
Subject: Re: StringJoin with ToString
Dear All,

I've considered your warnings, but - mainly because of my curiosity -
I continued to find a solution to the problem. Combining information
from here and my earlier tries, I've managed to come up with a stable
code that is quite short:

toString[expr_String] := expr;
toString[expr_] := ToString[expr];

Unprotect[System`StringJoin];
Attributes[System`StringJoin] = {};
System`StringJoin[expr___] := StringJoin[{expr}];
System`StringJoin[expr_List] := Module[{s = ""}, Scan[(s = StringInsert
[s, toString[#], -1]) &, expr]; s]
Protect[System`StringJoin];

Extensive testing shows that this works as expected (error messages
are returned unchanged, Import[file, "Lines"] works correctly, etc.).
Of course, there are effects, which must be considered, e.g. David's
example:

ss = Quiet[2 <> 3];
Map[ToString[#^2] &, ss]

this indeed would give 23 instead of 49, but that is definitely not
disrupting, since one who uses the new StringJoin *should be aware*
that it actually joins non-strings as well. I wouldn't consider it a
problem, just a point, where it must be kept in mind what the extended
StringJoin can do. To make my point clearer: no one would expect the
following

ss = Quiet[2\[CirclePlus]3];
Map[ToString[#^2] &, ss]

to result other than "4"\[CirclePlus]"9" IFF there is no assigned
meaning of CirclePlus. Although if one uses CirclePlus to actually do
something, then the result of the first line won't be the same as the
input: 2\[CirclePlus]3. As one would expect.

For the other problematic example of Albert (modified here a bit):

If[Head[Quiet[StringJoin[1, 2, 3]]] === StringJoin, Print["this was no
string!"], Print["string ok"]]

This should (in case of the new StringJoin) result "string ok", while
in case of the original StringJoin: "this was no string!". But the
former is exactly the functionality I would like to gain, namely to
get a string from StringJoin even in case of non-string input.

So, of course one must be cautios, but I wouldn't consider these cases
problematic.
Could anyone find any abnormal/unexpected behaviour of this new
function?

Thanks for your help,

Istvan


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »