Left and right division for strings

6 posts were split to a new topic: Case-insensitive prefix/suffix stripping

Please donā€™t do this. Strings arenā€™t numbers, and itā€™s completely senseless to apply mathematical rules for something that just isnā€™t math. Itā€™s already confusing enough that we have * for concatenation instead of the more obvious +, justified by the mathematical concept of commutativity.

Thereā€™s an argument about semantics, but honestly, itā€™d just be weird and confusing to see people do arithmetic on strings. In practice, people wonā€™t be awed that we managed to impose an algebraic structure over strings, theyā€™d just be annoyed that Julia appears to behave in a weakly typed manner.

Else, Iā€™m going to have to retaliate and implement String-specific concepts for numbers: :smiling_imp: Surely we should have:

julia> reverse(123)
321

julia> replace(123, 2=>3)
133

And of course we should have uppercase(xā‚‚) === x2, which by commutativity should be 2x. We could implement this with metaprogramming!

Edit: Whoops this was not meant as a reply to you, Valentin, but just as a post in this topic!

6 Likes

Strings were a concept in mathematics before they were a type in computer programs. Take a look at Kleene Algebras for more of the theory, which is applicable in all sorts of ways to the task of computer programming with strings.

Mathematics is not defined in terms of numbers. Thatā€™s arithmetic.

3 Likes
julia> occursin(5, 123456)
true

julia> split(123.456, ".")
2-element Vector{Int64}:
 123
 456

julia> startswith(pi, 3)
true

julia> contains(pi, strip(pi, "."))
LoadError: OutOfMemoryError()
in expression starting at REPL

Edit: could be a fun package for inclusion in JuliaWTF Ā· GitHub

2 Likes

All good, I agree with you wholeheartedly :slight_smile:

1 Like

Sorry, maybe Iā€™m missing something, but why is + more obvious here?

2 Likes

I know youā€™re joking but I think that example is a useful hook for discussing the bigger idea. Regarding reverse(::Number), there is no sense in which a number can be reversed by reversing the order of its digits, since (among other reasons) the value of a digit-reversed number depends on the base of its representation. For example reverse_digits(0b10) == 0b01 == 1 whereas reverse_digits(2) == 2.

Strings really are mathematical objects, analyzed extensively in the study of formal languages and their operations. If we define * as the binary operation on a monoid ā€“ notably a much more precise and well defined concept than Base.Number ā€“ it makes total sense that * would be provided for the (String, append) monoid instance.

Imho the better way to oppose this proposal is to take the mathematics more seriously, not less. Namely, this proposal does not include a good response to this problem:

I think it is good for Julia to lean into generic algebraic interfaces for functions, rather than coasting on general ā€œa matrix is kinda like a numberā€ vibes, so we can specify strict interfaces that are computer-checkable for all instances.

This policy would be both liberating, since any type matching the contract can define methods for a generic function, and restricting, since a type that only mostly conforms to the contract must not define a method for such a generic function.

3 Likes