func some() -> Bool {
return true;
}
func some() -> Int {
return 1;
}
let valBool: Bool = some()
let valInt: Int = some()
some() // this doesn't work: Ambiguous use of 'some'
Yeah… I never liked the OpenGL API since 3.0 and higher…
So I see what you mean. As I saw for short, you are designing higher level functions, not just exposing the C functions?
inline fun <reified T> getTexLevelParameter(target: TextureTarget, level: Int, name: TexLevelParameter): T
As I said, there are different functions but you want them unite into one function name. So you did it with generics?
On other side… there is the red book(?) which is teaching OpenGL with these C functions. How does your implementation fits in? Sorry I didn’t read your code, just some snippets…
Uh, why that? Things got pretty nice especially with the Direct State Access
Yeah, exactly.
Yeah, at the moment the only way I could find was to use inline reified methods.
This is basically a wrapper to reduce boiler plate code and make it less error prone as possible with inline enums, inferring automatically mandatory parameters, object-oriented design, etc etc
The logic behind remains always the same as you’d write vanilla opengl though
Uh, why that? Things got pretty nice especially with the Direct State Access
The control is of course nice, and it makes everything faster. But the design of these functions is not very pretty. For example all these query functions have a strange semantic.
I tried Vulkan and I rewrote the tutorial example in C++. The query functions in Vulkan seem very clean. The semantics are all over similar. Well I don’t like the C Style functions and I wrapped them in C++ functions.
Back to kotlin… I think, you cannot implement it better. Or you put an additional parameter. But that’s not really better.
object AsInt
object AsBool
fun f(p:AsInt):Int=0
fun f(p:AsBool):Boolean=false
...
@Test
fun foos() {
Assert.assertEquals( 0, f(AsInt) )
Assert.assertEquals( false, f(AsBool) )
}
I don’t know OpenGL, but reading this thread I have a few suggestions:
Instead of creating separate objects like asInt etc. just create an enum with these values and make function an extension of this enum.
Then instead of f(asInt) you can call asInt.f() or even Int.class.f() without defining enum.
Also in this case you don’t need to do “when”, but just implement type-specific function.
I just entered the same problem with some functions in an API where I wanted to use the labels as indicators of expected values although the Type of these values were the same.
eg:
fun function(length: Int) {}
fun function(height: Int) {}
We do that in Swift, on the basis of ObjC, SmallTalk…
So it clashes.
I change for another type
fun function(length: Int) {}
fun function(height: UInt) {}
But Int & UInt are seen as same.
As my problem was in constructors and not in methods, I didn’t have the opportunity to rename functions as
fun functionLength(l: Int) {}
fun functionHeight(h: Int) {}
So I had to adopt an ugly workaround
constructor(length: Int) {}
constructor(height: Int, discriminator: Unit = Unit) {}
to avoid the clash.
Why haven’t adopted label discrimination in polymorphism on Kotlin that own labels remain a total mystery to me.
PS: the discussed solution using generics to solve a so little semantic problem looks a bit out of dimension — even I do like to use them when it’s relevant.
And you just listed all and only languages in the world that do this But joking aside, there is no mystery here. We shouldn’t expect language X do something simply because language Y does this. Languages you mentioned have a different concept of “calling a function” than most of the languages, so they needed to design this differently.
Also, this is a different problem than in the beginning of this topic. Overloading by param names feels more “exotic” to me than by a return type.
Anyway, what should happen if we do: function(10)?
Languages that include labels for params doesn’t allow to call functions without param labels. Not like kotlin where labels are only param names and are optionals in the call.
If you want to avoid to ‘say’ the label, you use the elision.
func function(_ length: Int) {}
but you can have only one function(_ xxxx: Int) {} because it would be impossible to define which is targeted.
Swift hasn’t a different concept of “calling a function” than the most of existing language.
It just integrated the characteristics of discrimination by labels for polymorphism if they are present.
Yet I definitively don’t understand why kotlin didn’t adopt that, that is definitely a very modern approach, that so simplify writing and make reading so mandatory readable.
It’s so true that IDE like IntelliJ displays labels even though you didn’t put it.
And the reason lies on the basis of smalltalk that bring about the paradigme of “talks”.
fun add(length: Int) {}
fun add(height: Int) {}
fun add(length: Int, andHeight height: Int) {}
give a concise approach of param meanings, and readability.