Hi I'm trying to make the last line work: ```fun &...
# announcements
r
Hi I'm trying to make the last line work:
Copy code
fun <T>genattrs(vararg args: T): ArrayList<T> {
    val arrays = ArrayList<T>()
    arrays.addAll(args)
    return arrays
}
val f = ::<Int>genattrs // invalid syntax
s
@robinchew try
val f: (Array<out Int>) -> ArrayList<Int> = ::genattrs
💪 1
r
Thanks @enleur. Hey again @Shawn, looks like a simillar issue I had before.
s
those pesky function types lol
r
Hmmmm why Array instead of ArrayList
s
that’s what
vararg params: T
is sugar for,
Array<out T>
having a function type like
(vararg Int) -> ...
isn’t supported
not sure if it ever will but ¯\_(ツ)_/¯
r
man I would never have figured that
You work at jetbrains designing kotlin or something?
s
r
I guess I don't read docs
s
lol I’m just ribbing you, it’s no biggie
r
google, copy, paste programming
s
docs aren’t always that helpful until you’ve got a bit of familiarity with the thing documented, anyhow
r
Hmm i think im still getting issues
s
story of my life lol
r
The following:
Copy code
val attrs: (Array<out Int>) -> ArrayList<Int> = ::genattrs
Is not the same as:
Copy code
fun attrs(vararg args: Int): ArrayList<Int> {
    val arrays = ArrayList<Int>()
    arrays.addAll(args)
    return arrays
}
I will get the red squiggly underline, when trying to use
attrs(1,2,3)
s
well, I’m a little unclear as to what the error is exactly, but I feel like oughta point out that if the function needs to take one type and return another, the signature needs more than one type parameter
so if you’re trying to go from
Virtual...
to
Int
you need a function like
Copy code
fun <T, R> genAttrs(vararg args: T): ArrayList<R>
r
sorry i keep making mistakes
I meant to replace Virtual with Int
s
gotcha
I see what you mean
yeah, unfortunately you can’t really have vararg lambda params 😕
I’d bet money there’s a youtrack to vote for that concerns it
r
Even this has issues:
Copy code
fun attrs(vararg args: Int): ArrayList<Int> {
    val arrays = ArrayList<Int>()
    arrays.addAll(args)
    return arrays
}
apparently
varargs args: Int
is a
collection<Int>
type, which is not the same as
ArrayList<Int>
.
So I gotta do:
Copy code
fun attrs(vararg args: Int): ArrayList<Int> {
    val arrays = ArrayList<Int>()
    arrays.addAll(args as ArrayList<Int>)
    return arrays
}
s
ah, so, this is another Kotlin gotcha unfortunately
there are optimized arrays for primitive types (or maybe just the primitive numeric types? I oughta read up on that)
so instead of args presenting in the function as
Array<Int>
, it’s
IntArray
, which has a different inheritance hierarchy
r
right, so back to the
::genAttrs
problem. I guess this doesn't work?
s
if your goal is to take save a reference to a varargs fun such that you can use the reference to call it using varargs, then no, I don’t think it’ll work
r
Oh well. Is there an equivalent of
Copy code
arrayListOf(1,2,3)
but expecting 1 array argument instead, something like
Copy code
NewArrayList(arrayListOf(1, 2, 3))
s
Oh, are you just trying to make a deep copy of an existing arraylist?
or, rather, not a deep copy, but just a copy of an arraylist instead of just another reference
r
Actually I basically want to give
arrayListOf
an alternate name, so I can just do
a(1, 2, 3)
instead of
arrayListOf(1,2,3)
s
oh
r
Doing
a = ::arrayListOf
dont work
s
for that you’re just gonna have to define a new function I guess.
Copy code
fun <T> a(vararg args: T): ArrayList<T> = arrayListOf(*args)
I’d also suggest using a type higher up the chain than
ArrayList
if you can help it
List
if you can do with a read-only interface,
MutableList
if you need those add/remove methods
r
I thought
*
wasn't supported, which is like
...
right?
s
well
...
means a couple different things depending on the language lol, but
*
is definitely supported as the array spread operator
lets you pass in arrays where you need varargs
r
Damn the syntax is weird, a function declaration with
=
instead of
{}
s
lol, you don’t need the expression body syntax here, but I like it for one-liners
r
foreign, but good to know
s
cribbed from scala iirc
you can even omit the return type when you use expression bodies, but that’s bad juju for public API methods and instances where the return type is ambiguous or unintuitive
r
Now what about a short function for a data class?
s
going to need to be a bit more specific lol
r
Say I got:
Copy code
data class GlobalState(
    val age: Int = 0,
    val count: Int = 0,
    val selectedIndex: String = "invalid-key")
When instantiating that I just want to do
Copy code
GS(1, 1, "key")
Just renaming GlobalState is an obvious answer
s
I don’t really get your proclivity towards shortening names, but in this case you can just use a
typealias
Copy code
typealias GS = GlobalState
// elsewhere
val gs = GS(1, 1, "key")
r
Just providing choices
If you must know, I'm building an equivalent of this https://mithril.js.org/#dom-elements
s
didn’t you say you were coming from a Python background? aren’t you folks all about following the BDFL and there being only one way to do something? 😛
granted, Guido did abdicate a little while back, so I’m not sure where everyone stands on that one lol
r
Oh I got a JavaScript background too. I'm out of control.
s
wild lol
r
Copy code
m(::LinearLayout,
  attrs(
    size(400, WRAP),
    backgroundColorHex("#009999"),
    elevation(1f),
    margin(50)
  ),
  children(
    m(::TextView,
      arrayListOf(
        onCrup {movingView ->
          value.animation.setView(movingView.parent as LinearLayout)
        },
        size(WRAP, MATCH),
        weight(1f),
        layoutGravity(CENTER_VERTICAL),
        padding(5),
        text("${value.name} ${selectedTop} ${value.checked}"),
        backgroundColorHex("#000066"),
        onTouch {v, motionEvent ->
          val view = v.parent as LinearLayout
s
oof
this looks like something much better expressed using a DSL
r
No need to learn another language
s
no, I mean, like, you can use Kotlin to mimic a DSL
see kotlin/gradle build scripts or #C0BRKJ9K9 for example
or even the kotlinx.html example
you could build something that maybe more resembles this
Copy code
m(LinearLayout) {
  attrs {
    size(400, WRAP)
    backgroundColorHex ="#009999"
    elevation = 1f
    margin = 50
  }

  children {
    +TextView {
      onCrup { movingView ->
          value.animation.setView(movingView.parent as LinearLayout)
      }
      size(WRAP, MATCH)
      weight = 1f
      layoutGravity = CENTER_VERTICAL
      padding = 5
      text = "${value.name} ${selectedTop} ${value.checked}"
      backgroundColorHex = "#000066"
      onTouch { v, motionEvent ->
        view = v.parent as LinearLayout
      }
    }
  }
}
r
Thanks for that. At this point though, it's not worth adding more code just to get rid of those commas and brackets.