The root function checks and traverse until it get the root element in the tree.
class NodeRoot(N: Int){
private val id: IntArray = IntArray(N)
init {
(0..N-1).forEach{ id[it] = it }
}
fun root(i: Int): Int {
var i = i
while (i != id[i]) i = id[i]
return i
}
}
To answer your question, here's how you can rewrite root to be functional:
tailrec fun root(i: Int): Int = if (i == id[i]) i else root(id[i])
The tailrec keyword lets the compiler know that it should compile this to a loop, which avoids allocations on the stack due to recursion.
However, I agree with glee8e: There may be better ways to express this.
You can also avoid the init block and just pass a lambda to IntArray to initialize each element:
private val id: IntArray = IntArray(N) { it }
Related
Im making this anonymus function, and i need it to call itself. Is there any way to do it? I tried the code below, which didnt work...
val example:Char = fun () : Char {
//Some code
if(condition) {
return this();
}
}
What should i replace 'this()' with?
Im pretty new to kotlin, so it would be really helpful with a response
You can't name anonymous functions (either with this syntax, or as a lambda) in Kotlin, and therefore you can't make them recursive either, because you have know way to reference themselves.
If you need recursion, you'll have to create a regular function, and call that:
fun helper() : Char {
if (condition) {
return helper();
}
...
}
val example = helper()
The good news is that you can basically create a regular, named function in any scope. They can be top level outside classes, class members, or just local functions nested within other functions. Wherever you can write down val example = ..., you can also create a function.
Calling an anonymous function sound complicated as there is no name to call it with :)
As I'm learning Kotlin myself at the moment, I tried something and came up with this, hope it helps:
import kotlin.test.Test
import kotlin.test.assertEquals
class StackOverflow51233329 {
#Test
fun test() {
var letter = 'A'
lateinit var example: () -> Char
example = {
letter++
if (letter >= 'C') letter else example()
}
assertEquals('C', example())
}
}
If you want to avoid using lateinit, you could use the Y combinator, which can be used to enable recursion when recursion is impossible directly. Declare this globally:
class RecursiveFunc<T, R>(val f: (RecursiveFunc<T, R>) -> (T) -> R)
fun <T, R> y(f: ((T) -> R) -> (T) -> R): (T) -> R {
val rec = RecursiveFunc<T, R> { r -> f { r.f(r)(it) } }
return rec.f(rec)
}
This code was taken from Rosetta Code. You use it like this:
val fac = y { f: ((Int) -> Int) ->
{ n: Int ->
if (n <= 1) 1 else n * f(n - 1)
}
}
println(fac(10))
f is the recursive function here, with a signature of (Int) -> Int. The rest of the function is pretty much the same as usual, but in lambda form. You can even use the usual function syntax if that's more familiar:
val fac = y { f: (Int) -> Int ->
fun(n: Int): Int {
return if (n <= 1) 1 else n * f(n - 1)
}
}
How would I make this function into a pure function (functional programming)?
fun validateOffer(offerValidateRequest: OfferValidateRequest, channelId: ChannelId, tenant: Tenant): OfferValidateRepresentation {
val errorsList = mutableListOf<OfferValidateErrorsRepresentation>()
val successList = mutableListOf<OfferValidateSuccessRepresentation>()
offerValidateRequest.offers.forEach {
val filterRequest = OfferGetRequest(it.id, it.type)
val catalogs = findCatalogsWithOffers(filterRequest, channelId, tenant)
val errorMessages = getOfferErrorMessages(it, catalogs, filterRequest)
if (errorMessages.isEmpty()) {
successList.add(OfferValidateSuccessRepresentation(it.id, it.type))
} else {
errorsList.add(OfferValidateErrorsRepresentation(it.id, it.type, errorMessages))
}
}
return OfferValidateRepresentation(errorsList, successList)
}
I'm not very comfortable with these iterations in the lists of errors and successes.
Actually your function is already pure. It has no side effects.
But you still could avoid the mutable lists by using map, partition and a pair destructuring declaration.
If I replace a for loop by functional operations, I try to use multiple maps, filters, flatMaps. The nice thing about this is, that between these operations the only shared data, is the collection you pass through.
val (successList, errorsList) = offerValidateRequest.offers.map {
val filterRequest = OfferGetRequest(it.id, it.type)
val catalogs = findCatalogsWithOffers(filterRequest, channelId, tenant)
val errorMessages = getOfferErrorMessages(it, catalogs, filterRequest)
Pair(it, errorMessages)
}.partition {
it.second.isEmpty()
}
return OfferValidateRepresentation(
errorsList.map { OfferValidateErrorsRepresentation(it.first.id, it.first.type, it.second.errorMessages) },
successList.map { OfferValidateSuccessRepresentation(it.first.id, it.first.type) }
)
I need pass returnValue to a method as argument passed by reference and adjust original var value when function id done. So using ReferenceArgumentHelper class.
What's wrong in code bellow when returnValue is unintentionally deleted (when it is a node, i.e. string) and valgrind detects it. callMethod("onFunctionExit" calls an Qore script method and I can see there correct returnValue value. I suspect it's deleted when exiting onFunctionExit when ReferenceArgumentHelper is destroyed. rah.getArg() references reference variable, so it should not be deleted in callMethod.
DLLLOCAL ThreadDebugEnum callMethod(const char* name, const ThreadDebugEnum defaultResult, QoreProgram *pgm, int paramCount, AbstractQoreNode** params, ExceptionSink* xsink) {
int rv;
QoreListNode* l = new QoreListNode();
qore_program_to_object_map_t::iterator i = qore_program_to_object_map.find(pgm);
if (i == qore_program_to_object_map.end()) {
return defaultResult;
}
i->second->ref();
l->push(i->second);
for (int i=0; i<paramCount; i++) {
if (params[i])
params[i]->ref();
l->push(params[i]);
}
rv = qo->intEvalMethod(name, l, xsink);
l->deref(xsink);
return (ThreadDebugEnum) rv;
}
DLLLOCAL virtual ThreadDebugEnum onFunctionExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, ExceptionSink* xsink) {
AbstractQoreNode* params[2];
params[0] = getLocation(blockStatement);
ReferenceArgumentHelper rah(returnValue.takeNode(), xsink); // grab node from returnValue and pass to helper
params[1] = rah.getArg(); // caller owns ref
ThreadDebugEnum rv = callMethod("onFunctionExit", DBG_SB_RUN, pgm, 2, params, xsink);
AbstractQoreNode* rc = rah.getOutputValue(); // caller owns ref
returnValue.assign(rc); // takes reference
// returnValue.ref();
}
return rv;
}
When looking deeply I did not get why compiler is happy with code in /lib/ReferenceArgumentHelper.cpp:
struct lvih_intern {
LocalVar lv;
ExceptionSink* xsink;
ReferenceNode* ref;
DLLLOCAL lvih_intern(AbstractQoreNode* val, ExceptionSink* xs) : lv("ref_arg_helper", 0), xsink(xs) {
printd(5, "ReferenceArgumentHelper::ReferenceArgumentHelper() instantiating %p (val: %p type: '%s') \n", &lv, val, val ? val->getTypeName() : "n/a");
lv.instantiate(val); <--------------
VarRefNode* vr = new VarRefNode(strdup("ref_arg_helper"), VT_LOCAL);
vr->ref.id = &lv;
ref = new ReferenceNode(vr, 0, vr, 0);
}
class LocalVar {
....
DLLLOCAL void instantiate(QoreValue nval) const {
What is behind conversion AbstractQoreNode* to QoreValue in method call? I did not find an overloaded operator or so. I'm looking what exactly happens with references.
** EDIT **
To make a long story short, ReferenceArgumentHelper was buggy; it hadn't been used in years and was not up to date. The class has been fixed which should fix your issue I hope.
Thank you for pointing this out, and let me know if you have any further problems with this or the fix to the affected code.
Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.
I have the following function to access a property's delegate. It uses Kotlin reflection to get a property's name and Java reflection to get the field.
fun Any.getDelegate<T>(prop: KProperty<T>): Any {
return javaClass.getDeclaredField("${prop.name}\$delegate").let {
it.setAccessible(true)
it.get(this)
}
}
The method is used like this:
val delegate = a.getDelegate(A::b)
However, I would prefer to use it like this:
val delegate = a.b.delegate
The problem with the code above is getting the property name of a.b and getting the instance a from a.b. From what I know about Kotlin, this is probably not possible, however I'd like to see if I can clean up my function at all.
To give a bigger picture of what I'm trying do here's my complete code. I want an observable delegate to which I can add and remove observers using the delegate reference and without creating addition variables.
fun Any.addObservable<T>(prop: KProperty<T>, observer: (T) -> Unit) {
getObservableProperty(prop).observers.add(observer)
}
fun Any.getObservableProperty<T>(prop: KProperty<T>): ObservableProperty<T> {
return getDelegate(prop) as ObservableProperty<T>
}
fun Any.getDelegate<T>(prop: KProperty<T>): Any {
return javaClass.getDeclaredField("${prop.name}\$delegate").let {
it.setAccessible(true)
it.get(this)
}
}
class ObservableProperty<T>(
initialValue: T,
initialObservers: Array<(T) -> Unit> = emptyArray()) : ReadWriteProperty<Any?, T> {
private var value = initialValue
public val observers: MutableSet<(T) -> Unit> = initialObservers.toHashSet()
public override fun get(thisRef: Any?, desc: PropertyMetadata): T {
return value
}
public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) {
this.value = value
observers.forEach { it(value) }
}
}
class A() {
var b by ObservableProperty(0)
}
fun main(args: Array<String>) {
val a = A()
a.addObservable(A::b) {
println("b is now $it")
}
a.b = 1
a.b = 2
a.b = 3
}
Edit:
I just realized that the function also isn't strict because the property delegate field name is referenced by KProperty name, which doesn't require a strong reference to the enclosing class. Here's an example to demonstrate the problem:
class A() {
var foo by ObservableProperty(0)
}
class B() {
var foo by ObservableProperty(0)
}
fun main(args: Array<String>) {
val a = A()
a.addObservable(B::foo) {
println("b is now $it")
}
a.foo = 1
a.foo = 2
a.foo = 3
}
This compiles and runs without error because A::foo and B::foo both result in a field string of "foo$delegate.
Right now reflection is all we can do to get to the delegate object. We are designing a language feature to have direct access to delegate instance, but it's long way to go.
This is how you get the name of a Kotlin Property (although only with an instance of the class). This part will be useful to anyone arriving at this question purely based off its title.
class Stuff(val thing: String)
val stuff = Stuff("cool stuff")
val thingFieldName = "${stuff.thing}\$delegate"
// value of thingFieldName is now "thing"
In terms of getting the delegate itself easier, they say you can now do this:
class Foo {
var bar: String by ReactiveProperty<String>()
}
val foo = Foo()
val bar = foo.bar
val barDelegate = ... // foo.bar$delegate
See ticket.