#kotlin is basically a way to make your
1 messages ยท Page 1 of 1 (latest)
This is true
I have one single snippet to make my topic
fun Player.doSomething() {
}
nop
I mean easier to make hidden control flow, extra bugs, harder to read, and harder to figure out what is yours, what is API and what is STD lib
harder to read lol
aren't we declaring variables in Java like
String msg = "";
any jvm language > java
where is the groovy ๐
we don't talk about groovy
I'll have a look at the scala. Is it possible to make a spigot plugin wit it?
yep
same process as kotlin
make a scala project
add the scala runtime to the libraries thing
add the spigot dependency to the build.sbt
do I need to make a fatjar?
and you're mostly done
nope
if you're 1.17+ iirc you can use the libraries tag in plugin.yml
that way the plugin remains small
can I do it on kotlin too?
org.jetbrains.kotlin.jvm:1.7.0
right?
that's kotlin
but no
- org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin.version}
- org.jetbrains.kotlin:kotlin-test:${kotlin.version}
<kotlin.version>1.7.20-Beta</kotlin.version>
no need for test
does maven automatically replace those?
if you tell it to
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
add that
using gradle :/
gradle > maven
maven > gradle
that's the second wrong opinion :P
gradle is too good for scripting
I ain't using a kts bullshit fuckin maven cheap ripoff
then use groovy buildscript
hell no
๐
I think gradle has a bit of a learning curve, but being able to write code in the script make things a lot nicer
I mean most of this stuff is preference
I didn't originally, but now I can't go back
don't really understand this point
for example
if the type can be inferred, it usually will be
yes I was writing :p
fun myIntFunc() = 5
```Invalid, throws error, type is not defined
shouldn't do?
lol
why tf does it not work sometimes
bitch either work always, or tell me why you can't infer it
still learning scala
does scala have tons of methods like kotlin does?
basically it just puts the java stream API actually inside iterable classes
which you could also do your self because extension functions :)
can I do it on Java?
extension functions, no
kotlin pretty much removes the need for .stream() and makes writing lambdas a lot nicer
yes I just learned receiver lambdas and I'm still amazed
the kotlin docs are also amazing
๐
one thing that's really nice for spigot plugins is delegation
there's probably better examples but you can make a custom player class that extends Player and have it implement the methods from another implementation of the class
yes this is why oop is here :P
I mean it's not something you can do in java
it wouldn't be able to extend the player interface
you'd just have to keep a reference to the original Player object and pass that where you need a player reference
class MyPlayer(p: Player) : Player by p {
// No need to implement all of players methods, that's taken care of by ^^
fun myMethod() = TODO()
}
val player: Player = // however you obtain player
val myPlayer = MyPlayer(player)
// myPlayer.name, myPlayer.uuid all accessable as well as myPlayer.myMethod()
what does "by p" does here?
well the minecraft server has it's own implementation of the Player class: CraftPlayer
by you can't really extend CraftPlayer nicely
but if you extend Player, you usually would have to implement all of it's methods yourself (getName, getExp etc.)
by using by p (where p is the value passed in the constructor) you can 'delegate' the implementation of all those methods to an existing implementation (because p is actually a CraftPlayer its just been abstracted)
it's still kinda clunky to use for Players, which is why this isn't the best example, but I have used it in the past primarily in plugins
like if it needs getName it uses p's name right?
yes
cool
another nice thing is that you're not forced to use try / catch
reflection is actually really nice to do in kotlin
well in java if a method's description says it throws an error, you have to deal with that error
first example that comes to mind is opening files could throw a IOException
and I have to do sth like
try{
// Method
}catch(Exceptation ignored){}
yes
no need for the block in kotlin unless you think its necessary
I mean it's usually good practise but...
Can't be done in Scala, natively, however you can make a macro to do it for you
(which is still scala, there just isn't scala syntax for it)
same in scala
however Scala has a one up on that
you can either
try {
// code
} catch {
case e: YourException => doSomething
}
OR
Try(method()) match {
case Success(value) => something
case Failure(ex) => somethingElse
}
not exactly
the 2nd way is basically Optional but for exceptions
-> is used for other things iirc
I guess somewhat like rust's result
eh not quite
really?
Option/Optional is like Some or None
Try is Some or Err
and another one I forgot
so you could pass the result of the try function to another and it would eventually have to be unwrapped and dealt with?
yeah
basically
I guess that is useful
somewhere between java forcing you to always deal with the exception
yes that's what I mean
(also method() in this case is lambda, it's then run in it's own try-catch)
as functions are first-class citizens
equal to Try(() => method())
also, the scala compiler is smart
say you have
def func[T](list: List[T])(using accumulator: Accumulator[T])
if you define an accumulator for type T, you can either call func(list)(acc) or just func(list) as the compiler is smart enough to inject it
that's context-based parameters
so what's the point in the second pair of brackets here, and what is the using keyword doing?
by the sounds of it you have some basic knowledge of kotlin, I have never even seen scala code
this is scala*
I don't know the why of the second parameters, however using basically tells the compiler "I want you to search and tell me the best parameter for this"
you can omit using
I actually know more kt than Scala
yes, I'm aware, I'm just saying you have to remember when you are writing scala code that I have to try and understand based off knowledge of other languages
not as nice as kotlins ๐
eh
ah
I see
multiple params is to allow things like
def foo(ints: Int*)(ints2: Int*) = ints.sum * ints2.sum for example
is the asterisk here meaning varargs?
yeag
interesting
does scala has an equivalent of functions with receivers in kotlin? where you can change the scope inside the lambda function to another class?
wdym
it's quite hard to explain until you use them
in spigot sense you could have a function A which takes a function as an argument
but you can change the scope of the function you pass to A to another object
wdym
Int => Int, but pass the scope?
oh like
array.forEachIndexed { index, value ->
}
it's not something I've seen in another language before so I'll link the docs to explain it. It's quite handy sometimes
kk
give me an example really quick
I found val sum: Int.(Int) -> Int = { other -> plus(other) }
what does it do
ohhhhhhhhhhhh
i see
you add a function like that
well idk, haven't learnt much scala
you would use that like 12.sum(2) // 14
it's sort of like an extension function but obviously the type of sum (Int.(Int) -> Int) could be an argument to a function
class Item(private val material: Material, private val builder: ItemBuilder.() -> Unit) {
inner class ItemBuilder(val meta: ItemMeta) {
var name: String? = null
var lore: List<String> = emptyList()
}
is how I use it in my code
so then when you instantiate item, the lambda you pass at the end can access name and lore like they were properties of it's own class
Item(Material.STONE) {
name = "test"
lore = listOf("1", "2")
}
nice nice
then, with some more kotlin magic, you can create properties that don't actual hold a value, just a reference to a function that's run when they are requested. So then you could have an item manager class that doesn't actual hold any references to ItemStacks, just the underlying information it needs to create an ItemStack when it needs to
I'll learn more scala and tell you
they're gonna need some life altering feature to make me prefer it over kotlin at this point
wait
is scala not null safe?
@solar dirge
class NullSafe[A, B](val a: A) extends AnyVal {
def ?(f: A => B): B = if (a != null) f(a) else null.asInstanceOf[B]
}
extension (any: Any)
def ?(f: Any => Any) = new NullSafe[Any, Any](any) ? f
```I don't know if Scala has null safety, however I have implemented it like so
"heyo" ? { hey =>
println(s"${hey}")
null
} ? { hey =>
println(s"${hey}")
"pogger"
} ? { hey =>
println(s"${hey}")
""
}
```only `heyo` is printed
```scala
"heyo" ? { hey =>
println(s"${hey}")
"yo"
} ? { hey =>
println(s"${hey}")
"pogger"
} ? { hey =>
println(s"${hey}")
""
}
````heyo` then `yo` then `pogger` is printed
I can't use it like
val item = Item(Material.STONE) {
name = "test"
lore = listOf("1", "2")
}
right?
And sorry it looks like it's been 5 days :p
The full definition of the Item class is
context(PluginContext)
class Item(private val material: Material, private val builder: ItemBuilder.() -> Unit) {
inner class ItemBuilder(val meta: ItemMeta) {
var name: String? = null
var lore: List<String> = emptyList()
}
operator fun getValue(thisRef: Any?, property: KProperty<*>): ItemStack {
val item = ItemStack(material)
val itemBuilder = ItemBuilder(item.itemMeta!!).apply(builder)
item.itemMeta = itemBuilder.meta.apply {
itemId = property.name.camelToUnderscored()
setDisplayName(itemBuilder.name?.colored())
lore = itemBuilder.lore.map(String::colored)
}
return item
}
}
so you use it as a property delegate
val item by Item(Material.STONE) {
name = "test"
lore = listOf("1", "2")
}
and then when you use item it actually runs the getValue method and returns an ItemStack that's built at that time. Probably slower than just calling clone on an ItemStack but this comes with the upside of being easier to serialise and you don't have to hold an ItemStack in memory
@thorny hare
itemId is something specific to the plugin I initially made this for but it just makes a string tag in the items persistent data container with its id for comparison