#kotlin is basically a way to make your

1 messages ยท Page 1 of 1 (latest)

somber glade
#

This is true

#

I have one single snippet to make my topic

#
fun Player.doSomething() {

}
thorny hare
#

What do you mean by worse?

#

Shorter?

somber glade
#

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

thorny hare
#

harder to read lol

somber glade
#

Yes

#

it is harder to read

#

also due to having to specify a type a lot of times

thorny hare
#

aren't we declaring variables in Java like

String msg = "";
somber glade
#

I forgot to include another msg

#

sorry

#

I also added: scala is better

thorny hare
#

any jvm language > java

somber glade
#

yes

#

but ranking

#

scala > kt > clojure

thorny hare
#

where is the groovy ๐Ÿ˜„

somber glade
#

we don't talk about groovy

thorny hare
#

I'll have a look at the scala. Is it possible to make a spigot plugin wit it?

somber glade
#

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

thorny hare
#

do I need to make a fatjar?

somber glade
#

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

thorny hare
#

can I do it on kotlin too?

somber glade
#

yep

#

you can also use scala, kotlin and java together

thorny hare
somber glade
#

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

solar dirge
#

does maven automatically replace those?

somber glade
#

if you tell it to

#
<build>
<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
</build>
#

add that

thorny hare
#

using gradle :/

solar dirge
#

gradle > maven

somber glade
#

maven > gradle

solar dirge
#

that's the second wrong opinion :P

thorny hare
#

gradle is too good for scripting

somber glade
#

I ain't using a kts bullshit fuckin maven cheap ripoff

solar dirge
#

then use groovy buildscript

somber glade
#

hell no

thorny hare
solar dirge
#

I think gradle has a bit of a learning curve, but being able to write code in the script make things a lot nicer

somber glade
#

I have used gradle as well

#

I don't really like it

solar dirge
#

I mean most of this stuff is preference

#

I didn't originally, but now I can't go back

solar dirge
somber glade
#

for example

solar dirge
#

if the type can be inferred, it usually will be

somber glade
#
def myIntFunc() = 5
#

that's scala

solar dirge
#
fun myIntFunc() = 5
#

is valid kotlin

thorny hare
#

yes I was writing :p

somber glade
#
fun myIntFunc() = 5
```Invalid, throws error, type is not defined
solar dirge
#

shouldn't do?

somber glade
#

eeeeeeeeeeeeeeee

#

now it doesn't

solar dirge
#

lol

somber glade
#

why tf does it not work sometimes

#

bitch either work always, or tell me why you can't infer it

solar dirge
#

what's functional programming like in scala?

#

one of the things I like about kotlin

somber glade
#

still learning scala

thorny hare
#

does scala have tons of methods like kotlin does?

solar dirge
#

basically it just puts the java stream API actually inside iterable classes

#

which you could also do your self because extension functions :)

thorny hare
solar dirge
#

extension functions, no

#

kotlin pretty much removes the need for .stream() and makes writing lambdas a lot nicer

thorny hare
#

yes I just learned receiver lambdas and I'm still amazed

solar dirge
#

the kotlin docs are also amazing

somber glade
#

i gtg

#

i'll tell more tmr

#

cya

solar dirge
#

๐Ÿ‘‹

#

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

thorny hare
solar dirge
#

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()
thorny hare
#

what does "by p" does here?

solar dirge
#

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

thorny hare
#

like if it needs getName it uses p's name right?

solar dirge
#

yes

thorny hare
#

cool

solar dirge
#

another nice thing is that you're not forced to use try / catch

#

reflection is actually really nice to do in kotlin

solar dirge
#

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

thorny hare
#

and I have to do sth like

try{
  // Method
}catch(Exceptation ignored){}
solar dirge
#

yes

#

no need for the block in kotlin unless you think its necessary

#

I mean it's usually good practise but...

somber glade
#

(which is still scala, there just isn't scala syntax for it)

somber glade
#

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
}
solar dirge
#

scala uses equals arrows for lambda ๐Ÿ‘€

#

JS stink

solar dirge
#

whats the use case for the second way

#

is it just an alternative way of writing?

somber glade
#

the 2nd way is basically Optional but for exceptions

somber glade
solar dirge
#

I guess somewhat like rust's result

somber glade
#

eh not quite

solar dirge
#

really?

somber glade
#

Option/Optional is like Some or None
Try is Some or Err

and another one I forgot

solar dirge
#

so you could pass the result of the try function to another and it would eventually have to be unwrapped and dealt with?

solar dirge
#

I guess that is useful

#

somewhere between java forcing you to always deal with the exception

somber glade
#

scala doesn't

#

you don't need to catch, or declare throw

solar dirge
#

yes that's what I mean

somber glade
#

(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

solar dirge
#

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

somber glade
#

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

somber glade
solar dirge
#

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

somber glade
#

yeah

#

trying to explain

#

there is some info

solar dirge
#

not as nice as kotlins ๐Ÿ˜ƒ

somber glade
#

eh

#

ah

#

I see

#

multiple params is to allow things like

#

def foo(ints: Int*)(ints2: Int*) = ints.sum * ints2.sum for example

solar dirge
#

is the asterisk here meaning varargs?

somber glade
#

yeag

solar dirge
#

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?

somber glade
#

wdym

solar dirge
#

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

somber glade
#

ohhhhhhhhhhh

#

yeah

#

that's basically rule #1 of scala

solar dirge
#

but you can change the scope of the function you pass to A to another object

somber glade
#

wdym

#

Int => Int, but pass the scope?

#

oh like

#
array.forEachIndexed { index, value -> 

}
solar dirge
#

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

somber glade
#

kk

somber glade
#

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

solar dirge
#

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

somber glade
#

ah ye

#

idk

#

I need to study more

solar dirge
#
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")
}
somber glade
#

nice nice

solar dirge
#

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

somber glade
#

I'll learn more scala and tell you

solar dirge
#

they're gonna need some life altering feature to make me prefer it over kotlin at this point

#

wait

#

is scala not null safe?

somber glade
#

again

#

I still need to leanr

somber glade
#

@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
thorny hare
#

And sorry it looks like it's been 5 days :p

solar dirge
#

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