What was the rationale to not just allow any arbit...
# language-proposals
b
What was the rationale to not just allow any arbitrary operator? For instance, at work in Swift, I came up with
+?
to append a new element to the end of an array only if that new element is not null.
k
That's exactly the mess they wanted to avoid ☺️.
3
b
I don't see why it's any more of a mess than a top-level
infix fun
. I don't think "alphanumeric" is less messy than "mathematical".
To be honest I think
lsh
is the least-intuitive way to shift the bits in an integer to the left.
<<
and
shiftBitsLeft
are both better, but
lsh
sits at the crossroads of "what does that mean?" and "what was that operator again?"
t
one is typically readable english, the other is huh?
ironically it is this same sort of argument that has kept things like annotations out of swift yet you can override seemingly arbitrary operators
k
I agree with the
shl
vs
<<
thing, but only because they're already established operators.
I like what we have now in Kotlin: there's no way to be confused about what any of the operators mean.
t
lsh
or
shl
? 😆
j
In C++ you can overload a comma. So yeah let's stay as far away from that as possible.
8
b
@jw hey now don't go accusing me of advocating
#define
😛
k
@trevjones Made me look it up, it's definitely
shl
.
b
I think for my code I'll just define my own
infix fun shiftBitsLeft
🙂
j
I think the fundamental difference is that at least with infix you're encouraged to use proper names.
k
Good luck using that for more than a couple lines of bit-level operations.
j
it's not that bad. it's actually encourages you to write other higher-level functions which represent your intent rather than repeating the operations each time.
👍 4
b
@karelpeeters Thanks! I rarely even have more than a couple lines of it in an app or library anyway
j
(e.g.,
inline fun Int.isBitSet(bit: Int) = ...
or whatever you want)
b
I am a huge fan of higher-level functions whenever possible :3
r
I'm of the opinion this could have been enabled through either some compiler extension or special imports without cluttering most code bases. Defining custom operators is important por DSLs and Kotlin already allows you to do it with backsticks. I know they have been abused greatly in other langs but still is the user's choice when using a library. In Kategory we could have benefited from
>>=
for aliases to
flatMap
and others which are common in most FP langs used by the community.
💯 1
c
Another operator overloading bogey man, straight from central casting.. lol.
e
if I could (i.e skillz), I'd seriously fork kotlin and implement that
👍 1
b
Great point with the `s, @raulraja
t
The thing is that you end up with hundreds of weird operators like in haskell and nobody knows what they do. Sure there is a system to it, but still. With normal infix functions at least you have a hint what they do when skimming over the code
Then again, haskell is notorious for having horribly unreadable libraries, even if they are normal functions. Who the hell is supposed to know what fst and snd are
2
k
You can just al easily read the source of a custom operator though.
b
Yeah no matter what happens, the IDE should let you see its declaration with ctrl+click or middle-click or a right-click menu option or whatever
k
ctrl+b
☺️
As it is right now.
p
@benleggiero not trying to be nitpicking, but that is not true anymore the moment you don't have an ide at hand (viewing code on github, or in crucible comes to mind). Also even if you have an ide, every investigation saved by a propperly named infix saves a couple of seconds(minutes?😀 )
💯 1
e
I always wonder if forbidding a feature to avoid abuse is really the right way
1
p
Damn. Did not want to post outside of thread. Sry
b
@pixelbumper IIRC IDE features are being built into the Kotlin compiler, so this could go in with them. Also, and again, it's hard to name these operators using alphanumerics in a way that conveys the same meaning as standard symbols without being very verbose. Again, compare
shiftingBitsRightInsertingZeroes
,
exclusiveOr
,
concatenateUnlessNull
to
>>>
,
^
, and
+?
👍 2
g
xor
as name for exclusive or is probably even more common than
^
p
@elect it depends. If in doubt I would be cautios, as putting a feature in the language is easy, compared to removing it when you realize its abuse hurt the language. But yeah you are right it is a fine line @benleggiero granted (although you could argue that
shrInsertingZeroes
would be more consistent with the current set of instructions). But as @jw already suggested it could encourage developers to write less convolutedly long one liners and split it into functions/more lines. At the end of the day we could probably live with either approaches though
e
@pixelbumper true, but what I'd really like at least is to have at least operators such as
&
on primitives. There is a reason why most of major languages out there today have that.. cmon Anyway, as I said, I'm convinced it's not a matter of
if
, but
when
K
b
@gildor Perhaps that's correct. Perhaps it's actually
, especially for people coming from more pure math. Why not define all three and
inline
them to the same bytecode so everyone can use Kotlin in a way they find comfortable and intuitive? @pixelbumper Like I said above, allowing people to define their own
inline
custom operators as aliases to ones they find more confusing is a key to making people really comfortable using a new language, without bloating the compiled code.
g
bloated language syntax much worse than bloated compiled code imho
b
@gildor Then GolfScript is the language for you 🙂
g
I don’t have strong opinion about bitwise operators, I fine now with infix but & ^ >> is fine for me too.
b
I think there's a good balance to be struck between terseness and explicitness. Kotlin is there for so many things, which is why i'm surprised they made this choice.
g
@benleggiero not so radical. operator + function is enough for everyone I think. To be honest infix functions is enough for me too, just because I use them very rarely
p
@benleggiero yeah there is some truth to that, then again I kind of got burnt by operator overloading in the past which is why I am a bit reluctant.
e
how, @pixelbumper
g
There are many reasons I think. I suppose that one of them that infix functions just easy to implement and bitwise operators looked not so important in most cases
but language evolves, especially if we are talking about kotlin-native
b
P.S. I tried writing an
Copy code
inline fun Int.`<<`(bitCount: Int)
but it wouldn't compile claiming
Name contains illegal characters: <
j
c++ allows the abuse of operator overloading, and the abuse of templates, and in a certain evolution of the compiler technology, the C++ templates and operators that were allowed could enable significant expressive improvements which have since become the std committee baseline (Boost C++).
the abuse potential of operators still exists in c++ but the general outcome is that NO, abuse did not kill the language or make it any less pleasant for everyday problem solving, when used sparingly
👍 2
c backwards compatibility did more to kill c++ through enabling opinionated yayhoo's who say things like "I don't want to learn that stuff". templates and operator overloading freedoms were fringe pursuits but had very powerful results when the potential was utilized.
the template math libraries outperformed c language options and were only possible through closed loop metaprogramming constructions. it was a good 10 years until LTO caught up with c++ templates for static optimizations that could peek through structs of pointers
without the available operator overloading, the benefits of the template metaprogramming would have been harder to gain.
👍 2
c
the operator overloading thing is always presented as an absurdity of possibility, no one ever presents actual cases, you can abuse lots of things in languages… this is the best explanation of why these low bore canards live on: https://en.wikipedia.org/wiki/Narcissism_of_small_differences
b
For me, it's more that I think Swift is the best language for me that I've ever used, and when I see Kotlin being so similar in so many ways and available on so many more platforms, I want to switch to it entirely. I am then saddened when I find out that Swift features I'm used to are absent, so I want to help find a way for them to fit in.
👍 1
r
@codeslubber good one 👍
👍 1
In Scala they were criticized because they were present in Scalaz, Dispatch and other libs and some people complained about readability when the real issue is that they were not familiar with the slang in those niches but any library that introduces custom operators usually provides another function that does the same in plain english for the best of both worlds. I'd like to have something similar in kotlin:
Copy code
@alias(">>=")
fun flatMap ...
I'd even settle for a compromise if to define one you had to provide an alternative representation if the real concern is readability or usage semantics.
🤔 1
k
That doesn't really help in a shared codebase, in fact that makes it even worse. Then everyone has to remember both the operator and the function name.
👆 1
👍 1
c
as I have said many times @benleggiero I totally agree with you, Swift is still my favorite.. and K deserves a lot of credit for that.. I do not like ‘we cannot let users have this feature’ arguments in general though, no matter the language…
👍 4
b
I think there's a nice middle ground of "You want this feature, eh? Well here's a feature that lets you accomplish what you're trying to do in a much better-suited way". That's kinda what Kotlin, Swift, et al are founded on.
👍 2
r
@benleggiero That would be ideal but Kotlin does not allow that. Swift and Scala allow you to use any symbols or unicode in definitions but in Kotlin everything has to be in `
ident
` which does not seem to me like a real way to have your custom operators / identifiers.
😞 1
j
the strong case for operator overloading is made by boost::spirit, to minimize EBNF impedence for compilable c++ code grammar definitions without a preprocessor. this made the case for template metaprogramming, and for whatever its worth, a succinct json library used in blockchain clients as a real-world value. the same author more or less devised a near lisp dialect as compilable c++ in templates which form the event lambdas of the spirit parrser library. turing complete templates/macros in kotlin would create options that jvm languages lack with generics at present. but permissive operator overloading would be "good enough" for most things http://www.boost.org/doc/libs/1_64_0/libs/spirit/classic/doc/introduction.html