Amen to that!I just wish that using * for string concatenation had been avoided...
It just is confusing for people coming from any other language that I know of (I would have expected *, if used on strings atall, to be a “repeat n times” operator, i.e. string * n gives my a new string with n copies..., or character * n might give me a string a length n all of that character.
I would like to have something like Lua’s convention of .., and also have it as syntactic sugar for the vcat operation.
It avoids confusion where * on an Array{UInt8} means multiply each element by n...+ also has that problem, so I wouldn’t like either the suggestion of using + (like JavaScript or Python) for string concatenation...
On Tuesday, April 21, 2015 at 10:45:04 AM UTC-5, Scott Jones wrote:Amen to that!I just wish that using * for string concatenation had been avoided...
It wouldn't free up any characters, though, to not use it, so it's somewhat different than the rest of this discussion.
It just is confusing for people coming from any other language that I know of (I would have expected *, if used on strings atall, to be a “repeat n times” operator, i.e. string * n gives my a new string with n copies..., or character * n might give me a string a length n all of that character.
That is more typical. There have been *long* prior arguments/discussions about this, which you can search the list for. I might be the sole remaining defender of Julia's decision here, but there are a couple things about it which I personally like. In particular, addition (+) is typically commutative, but string concatenation is not. Multiplication is in general not commutative, so there is some sense in selecting that operator. If you need it, repeated concatenation is the exponentiation operator, so the same logic to the more typical +/* progression applies.
I would like to have something like Lua’s convention of .., and also have it as syntactic sugar for the vcat operation.
It took me several readings to realize that the operator you were using wasn't the ellipsis token "..."; but yeah, concatenations are hard, and there's a long discussion of concatenation and related topics at https://github.com/JuliaLang/julia/issues/7128.
It avoids confusion where * on an Array{UInt8} means multiply each element by n...+ also has that problem, so I wouldn’t like either the suggestion of using + (like JavaScript or Python) for string concatenation...
..(a::AbstractString,b::AbstractString) = a * b
The discussing about array concatenation in issue 7128 is very interesting... personally, I found it *very* confusing that ; meant something special within [ ], and that spaces are also significant... (something I *really* hated [as the compiler guru] in the language I maintained previously [wasn't my choice, the language in question was designed by committee, committees of doctors, not software engineers, it actually was the third language to become an ANSI standard (after Fortran and Cobol!)])
I do hope that having spaces be significant goes away... I'd hoped never to have to deal with that again!
We tried being super-disciplined about using dotted operators to denote elementwise operations even when one argument was a scalar.
The experiment: https://github.com/JuliaLang/julia/issues/5807
The outcome: https://github.com/JuliaLang/julia/issues/6417
Thanks for all the feedback; I hope you find some of those discussions informative!
Patrick
I always thought multiplication *was* commutative, at least that was what I was taught at school, and it seems all the examples on Google searching "commutative operations"mention addition and multiplication as being commutative.I suppose there is some rarified realm popular with Julia's designers where that is not true... but, it is NOT what most anybody (including people who went to MIT) would expect!
On Tuesday, April 21, 2015 at 4:47:37 PM UTC-5, Scott Jones wrote:I always thought multiplication *was* commutative, at least that was what I was taught at school, and it seems all the examples on Google searching "commutative operations"mention addition and multiplication as being commutative.I suppose there is some rarified realm popular with Julia's designers where that is not true... but, it is NOT what most anybody (including people who went to MIT) would expect!
One such "rarified realm," as you put it, is linear algebra, which is an important use case for us. While we hope Julia to be suitable as a general-purpose language, a key part of its attraction for me is that it does math--in particular, linear algebra--well. And doing mathy things (quickly!) is very much a design goal; math-like objects exploit multimethods well. A quick look at our standard dependencies (BLAS? FFTW? SuiteSparse?) I think does a good job of showing where most of the developers' heads are at.
That sometimes means that we hit trades most other languages don't spend too much time on. An ongoing example of such a discussion regards "vectorizing" common functions--which is a common feature in the technical languages from which Julia draws a lot of inspiration. But unlike some of those languages, Julia distinguishes between array-typed things and scalar-typed things, and as the language (and its ecosystem) grows, needing to provide two implementations of every single-argument function starts to get repetitive, and there's a strong push towards requiring the use of the map(f, A) construct. This doesn't sit well with everyone.
Likewise string concatenation, matrix construction (the space sensitivity doesn't bother me as a MATLAB user whose needs primarily fall in the 2-or-fewer-array-dimensions cases, but what "," vs. ";" will do tends to confuse me), etc.
The ".." operator may get taken for a particular meaning related to getfield overloading (https://github.com/JuliaLang/julia/pull/5848), so that's something to watch out for.
Base is unlikely to get much bigger; it will probably get smaller over time in part to better support general-purpose programming without the baggage all this silly math carries with it. The plan is something along the lines of preparing a "standard distribution", and you can see a lot of packages currently owned by JuliaLang on GitHub which will likely become a part of that when it comes together. That way you can still get your batteries, but can remove batteries you don't need.
For Char*String/String*Char, see https://github.com/JuliaLang/julia/issues/1771 (though that devolves into concatenation operator discussion, rather unfortunately.) There's probably a good argument for trying to add those again...
One nice thing is that it's really not troublesome to take on, say, binary-coded decimal types as an external package. The same machinery (method specializations, `convert()`, and `promote_type()`) that powers the standard Julia numeric type hierarchy works just fine outside of Base.
Hoping this doesn't come off as a rant (I promise it's not!),
Patrick
"foo" "bar" # "foobar"foo "bar" # "$(foo)bar""foo" bar # "foo$bar"foo "" bar # "$foo$bar"
Here is a vote for just using + for string concatenation. No deep philosophical reason, it simply seems the choice of least unfamiliarity for the largest number of people. I think with + the topic of how string concatenation should be done would not come up again on this list. With any other choice, I’m sure this will resurface again and again and again :) I’ve read all the coherent arguments for other choices, but in this case I’m more convinced by “keep it familiar/simple for many people”.
Personally, I think it should be a new 2 character sequence, that does not currently have a meaning, in Julia or any major languages...C, C++, Java, JavaScript, Python, Ruby...
I'd personally lean toward ++ for string concatenation (and other sorts of lists, while we're at it); this is already the case in a few other languages, so there's already at least some precedent/inertia in that direction.
Changing to a new operator will result in both current Julia users and new ones having to look it up whereas keeping * means only new ones will have to find it and it will be much easier to find since it has gained lots of ground.
Yes, that seems reasonable – doing `v++w` would be equivalent to `[v;w]` for vectors at the very least.
I actually strongly agree with this. As ASCII characters have become
more precious, bitwise operators don't seem like a good use of them.
We could gain *three* more ASCII operators.
On Mon, Apr 20, 2015 at 3:34 AM, Milan Bouchet-Valat <nali...@club.fr> wrote:
> Le dimanche 19 avril 2015 à 14:25 -0700, David van Leeuwen a écrit :
>> Hello,
>>
>>
>> I've seen this discussed before, but wasn't able to find search terms
>> to continue the discussion...
> You're probably looking for this:
> https://github.com/JuliaLang/julia/issues/1974
>
>
> Regards
>
>> I'm wondering what the actual usage of `$` as bitwise exclusive or in
>> practice is (in current packages and other code), and whether it is
>> possible to change this to `^` (which is is currently defined as `x ^
>> y = x | !y`, which, to me, appears to be the logic for "y implies
>> x").
>>
>>
>> It would be really cool if x$y (without spaces) could be syntactic for
>> x[:y] which would be useful in DataFrames, but has also use cases in
>> Dicts.
>>
>>
>> Cheers,
>>
>>
>> ---david
>
>
>
Just a clarifying question: in dataframe$col, is col planned to be a
variable (that has a key that identifies the column) or a symbol (that
is interpreted as a key per se)?
In R it is the latter, dataframe$col is equivalent to
dataframe[["col"]]. If that's what is planned for Julia then I guess $
would need to be a macro.
@$ begin
df = DataFrame(mydata)
z = df$colname1
q = df$colname2
end
I'm with Scott... I think it's a bad idea to add $ as something specific to dataframes. What could be cool (and doesn't need to be in base!) is a macro that would handle the syntactic sugar for you:
@$ begin
df = DataFrame(mydata)
z = df$colname1
q = df$colname2
end
Base.(:$)(df::DataFrame, col::Symbol) = df[col]
This sort of stuff isn't crazy hard to make, it doesn't touch julia's parsing, it's opt-in, etc. You can't use $ as a macro name right now, but you get the point. Is this feasible?
@$ begin
df = DataFrame(mydata)
z = df$colname1
q = df$colname2
end
df = DataFrame(mydata)
z = df[:colname1]
q = df[:colname2
Because, strings do form a non-commutative monoid and in academic literature on strings and parsing, multiplication – usually written as juxtaposition – is used for string concatenation. Whether that's a pun or not is a bit fuzzy. Using addition – which implies commutativity, mathematically – for concatenation is definitely a pun, however.On Wed, Apr 22, 2015 at 4:29 PM, Scott Jones <scott.pa...@gmail.com> wrote:But then, why * in the first place?
Sent from my iPhone+ isn't happening – avoid operator punning is crucial in a multiple dispatch language.On Wed, Apr 22, 2015 at 4:02 PM, David Anthoff <ant...@berkeley.edu> wrote:Here is a vote for just using + for string concatenation. No deep philosophical reason, it simply seems the choice of least unfamiliarity for the largest number of people. I think with + the topic of how string concatenation should be done would not come up again on this list. With any other choice, I’m sure this will resurface again and again and again :) I’ve read all the coherent arguments for other choices, but in this case I’m more convinced by “keep it familiar/simple for many people”.
From: juli...@googlegroups.com [mailto:juli...@googlegroups.com] On Behalf Of Stefan Karpinski
Sent: Wednesday, April 22, 2015 12:51 PM
To: juli...@googlegroups.com
Subject: Re: [julia-dev] use of $ as xor versus syntactic sugar for DataFrames
I'd also be happy to get rid of * for string concatenation. We could use ++ for concatenation in general, a la Haskell. There's not really any need for an operator for repeated concatenation. There was once a branch that made string juxtaposition do string concatenation, so you could write
"foo" "bar" # "foobar"
foo "bar" # "$(foo)bar"
"foo" bar # "foo$bar"
foo "" bar # "$foo$bar"
On Tue, Apr 21, 2015 at 11:15 PM, Jeff Bezanson <jeff.b...@gmail.com> wrote:
I greatly prefer `string(a, b, c)` and `repeat` for concatenating and
repeating strings. Strings are, in fact, a monoid, and I think the use
of * and ^ is highly justifiable, but I'd be just as happy to see them
go.
I'd love to have a really good decimal type available in julia.
On Tue, Apr 21, 2015 at 8:49 PM, Scott Jones <scott.pa...@gmail.com> wrote:
> On Tuesday, April 21, 2015 at 6:57:37 PM UTC-4, Patrick O'Leary wrote:
>>
>> On Tuesday, April 21, 2015 at 4:47:37 PM UTC-5, Scott Jones wrote:
>>>
>>> I always thought multiplication *was* commutative, at least that was what
>>> I was taught at school, and it seems all the examples on Google searching
>>> "commutative operations"
>>> mention addition and multiplication as being commutative.
>>> I suppose there is some rarified realm popular with Julia's designers
>>> where that is not true... but, it is NOT what most anybody (including people
>>> who went to MIT) would expect!
>>
>> One such "rarified realm," as you put it, is linear algebra, which is an
>> important use case for us. While we hope Julia to be suitable as a
>> general-purpose language, a key part of its attraction for me is that it
>> does math--in particular, linear algebra--well. And doing mathy things
>> (quickly!) is very much a design goal; math-like objects exploit
>> multimethods well. A quick look at our standard dependencies (BLAS? FFTW?
>> SuiteSparse?) I think does a good job of showing where most of the
>> developers' heads are at.
>
>
> Well, after I posted that I remembered something about cases where
> multiplication wasn't commutative, from 18.06 (Linear Algebra at MIT) with
> Gilbert Strang, however,
> I think the designers of Julia should think a bit more about what would make
> sense to the general programmer population, especially when it comes to
> something that *isn't*
> a mathematical operation... (at least, if they'd like Julia to become more
> generally accepted outside of a niche, and without a lot of programmers
> throwing virtual tomatoes at the designers for some non-intuitive choices).
> I would posit that probably over 95% of "general" programmers would consider
> + for concatenation, and * for repetition, to make a lot more sense for
> string operations, if you have
> to be overloading math operators for strings...
> If you'd had * for repetition, and treated characters as 1 character strings
> where it makes sense, then you could have nice things like:
>
> 20' ' to make a string with 20 spaces, which would be consistent with 20n
> meaning 20*n...
>
> If you didn't like + because of commutivity, why not pick / for string
> concatenation, which everyone would agree is not commutative, unlike *,
> which most everybody *does* think
> is commutative (and would associate with have multiple copies of something
> [even the word multiply screams repetition!])
>
>> That sometimes means that we hit trades most other languages don't spend
>> too much time on. An ongoing example of such a discussion regards
>> "vectorizing" common functions--which is a common feature in the technical
>> languages from which Julia draws a lot of inspiration. But unlike some of
>> those languages, Julia distinguishes between array-typed things and
>> scalar-typed things, and as the language (and its ecosystem) grows, needing
>> to provide two implementations of every single-argument function starts to
>> get repetitive, and there's a strong push towards requiring the use of the
>> map(f, A) construct. This doesn't sit well with everyone.
>>
>> Likewise string concatenation, matrix construction (the space sensitivity
>> doesn't bother me as a MATLAB user whose needs primarily fall in the
>> 2-or-fewer-array-dimensions cases, but what "," vs. ";" will do tends to
>> confuse me), etc.
>>
>> The ".." operator may get taken for a particular meaning related to
>> getfield overloading (https://github.com/JuliaLang/julia/pull/5848), so
>> that's something to watch out for.
>>
>> Base is unlikely to get much bigger; it will probably get smaller over
>> time in part to better support general-purpose programming without the
>> baggage all this silly math carries with it. The plan is something along the
>> lines of preparing a "standard distribution", and you can see a lot of
>> packages currently owned by JuliaLang on GitHub which will likely become a
>> part of that when it comes together. That way you can still get your
>> batteries, but can remove batteries you don't need.
>
>
> Well, I didn't mean to imply that I thought the math was *silly* ;-) I used
> to love math too, but my life revolves around software architecture,
> language design, databases and performance issues instead these days...
>
> Yes, I'd prefer to see it get *much* smaller, and have a Julia-lite, with
> just essentials, a Julia-standard, and possibly a Julia-GPL (including stuff
> like sparsesuite, RMath, and FFTW)...
>
>> For Char*String/String*Char, see
>> https://github.com/JuliaLang/julia/issues/1771 (though that devolves into
>> concatenation operator discussion, rather unfortunately.) There's probably a
>> good argument for trying to add those again...
>>
>> One nice thing is that it's really not troublesome to take on, say,
>> binary-coded decimal types as an external package. The same machinery
>> (method specializations, `convert()`, and `promote_type()`) that powers the
>> standard Julia numeric type hierarchy works just fine outside of Base.
>
>
> Yes, and I plan on doing just that ;-)
>>
>>
>> Hoping this doesn't come off as a rant (I promise it's not!),
>>
>> Patrick
>
>
>
> No, no, and I hope my responses don't come off that way either!
> I enjoy debating these sorts of things (politely! ;-) )
>
>
> Scott
I actually strongly agree with this. As ASCII characters have become
more precious, bitwise operators don't seem like a good use of them.
We could gain *three* more ASCII operators.
I would strongly support ++ behaving like \oplus and ** behaving like \otimes but I would more strongly prefer going straight to the unicode characters themselves. For vectors, \oplus and \otimes are well defined. For linear algebra, the same is true - we can replace kron(), for instance with ** or \otimes. For multilinear algebra, I could make this fit into my work (github.com/andyferris/Tensors.jl). And string concatenation would be sorted out at the same time, using familiar laymen terms (some kind of "addition") that is also consistent with mathematical theory!
Making \oplus for string concatenation would probably also stop any discussions about + vs * since no one would ever suggest \oplus for string concatenation (I hope!) although + is found in other languages :)
I thought that Andy Ferris was saying that \oplus, not \otimes, made sense mathematically for concatenation,and also, that \oplus would make more sense to people used to + for concatenation.Julia is the only language that I've ever seen that used * for concatenation (I think I've seen it for repetition before in other languages, which makes sense, multply x times = repeat x times).I had already suggested \oplus on GitHub, some time ago.
Stefan and Jeff - surely the monoid in question is much more like a tensor sum \oplus (which is non-commutative) than a product? This is exactly vector concatenation, and from the mathematical point of view a string is a bit like a vector of characters, no?
On Monday, 28 September 2015 00:47:45 UTC+10, Andy Ferris wrote:Stefan and Jeff - surely the monoid in question is much more like a tensor sum \oplus (which is non-commutative) than a product? This is exactly vector concatenation, and from the mathematical point of view a string is a bit like a vector of characters, no?Multiplication isn't commutative for matrices, either, but we use regular multiplication for that. It just so happens that integer/float multiplication ends up being commutative. If Julia is going to use a different operator for non-commutative operations, then matrix operations will need new operators. Personally, I think multiplication-for-concatenation makes sense, mathematically, since juxtaposition is equivalent to multiplication in most places where it applies, and juxtaposition of strings makes sense.
Seems a bit silly to use a unicode operator when regular multiplication, addition, and exponentiation (as per floats) can't apply to strings, anyway.
Indeed, that is a legitimate concern! But how might we express concatenation of vectors of numbers? Use ++? Is it beneficial to think of a string as behaving like a vector of characters, or should we treat them completely differently?
we sometimes see the outer product symbol used for the direct sum!
But other notations could work nicely. A+>B, for instance, or A|<B.
* is very confusing to most people (even mathematicians from comments I've seen) when they first come to Julia, for the very simple reason that people associate addition with concatenation, and multiplication with repetition.
Proponents of alternative syntaxes are very vocal and hijack threads, so
people who could not care less about the whole thing, are OK with the
current syntax, or have other priorities, feel that they should
voice their own opinion (yes, I am doing this too).
Which is why I suggest displacing the bitwise operators. They shouldn't be too frequently used in scientific applications, so it's probably safe to move them to multi-ASCII operators, or unicode. Not only does it provide a nice operator for the DataFrames example, but it also frees up a few other operators for more frequent uses.