Coder Social home page Coder Social logo

funktionale's People

Contributors

benjaminearley avatar eddieringle avatar iainmcgin avatar jkpl avatar jw-s avatar loicdescotte avatar marioarias avatar marioariasc avatar mustafin avatar ramonaranda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

funktionale's Issues

Alternative currying

operator fun <P1, P2, R> Function2<P1, P2, R>.invoke(p1: P1) = 
  { p2: P2 -> this(p1, p2) }

operator fun <P1, P2, P3, R> Function3<P1, P2, P3, R>.invoke(p1: P1) = 
  { p2: P2, p3: P3 -> this(p1, p2, p3) }

operator fun <P1, P2, P3, P4, R> Function4<P1, P2, P3, P4, R>.invoke(p1: P1) = 
  { p2: P2, p3: P3, p4: P4 -> this(p1, p2, p3, p4) }

val foo: (Int, Int, Int) -> Int = { a, b, c -> a + b + c }

fun bar(a: Int, b: Int, c: Int) = a + b + c

fun main(args: Array<String>) {
    foo(1, 2, 3)
    foo(1)(2)(3)

    bar(1, 2, 3)
    (::bar)(1)(2)(3)
}

The Either type is unbiased

Hi!

I just wanted to clarify whether it was a design decision to make Either unbiased. As far as I remember, the only unbiased version of Either in the Scala world is ancient scala.util.Either and it's criticized by everyone left and right for exactly its unbiased nature.

Pretty much all alternatives including scala.util.Try, scalaz.\/ or cats.data.Xor are right-biased. In your wiki you are also pointing out that

Traditionally the Left represent an error and Right a correct return

So, why not make it right-biased by design and provide map and flatMap? It would make it even more useful.

Thank you for a great library!

Licensing

I'd like to use this library in an application of mine. Would you be willing to add an open source license like Apache or MIT to the project? I could create a pull request to do it if you'd like.

Improve Either

sealed class Either<out L : Any?, out R : Any?>(protected open val l: L?, protected open val r: R?) {

    class Left<out L : Any>(override val l: L) : Either<L, Nothing>(l, null) {
        override fun <T1 : Any, T2 : Any> map(ifLeft: ((L) -> T1)?, ifRight: ((Nothing) -> T2)?) = Left(ifLeft!!.invoke(l))
        override fun swap() = Right(l)
        override fun <T> case(left: ((L) -> T)?, right: ((Nothing) -> T)?) = left!!.invoke(l)
        override fun <C> case(left: C, right: C) = left
        override fun toString() = "Left: $l"
        override fun equals(other: Any?) = this === other || (other is Left<*> && l == other.l)
        override fun hashCode() = l.hashCode()
    }

    class Right<out R : Any>(override val r: R) : Either<Nothing, R>(null, r) {
        override fun <T1 : Any, T2 : Any> map(ifLeft: ((Nothing) -> T1)?, ifRight: ((R) -> T2)?) = Right(ifRight!!.invoke(r))
        override fun swap() = Left(r)
        override fun <T> case(left: ((Nothing) -> T)?, right: ((R) -> T)?) = right!!.invoke(r)
        override fun <C> case(left: C, right: C) = right
        override fun toString() = "Right: $r"
        override fun equals(other: Any?) = this === other || (other is Right<*> && r == other.r)
        override fun hashCode() = r.hashCode()
    }

    fun isLeft() = l !== null
    fun isRight() = r !== null
    fun left() = l!!
    fun right() = r!!
    abstract fun <C> case(left: C, right: C): C
    abstract fun <T> case(left: ((L) -> T)?, right: ((R) -> T)?): T
    abstract fun <T1 : Any, T2 : Any> map(ifLeft: ((L) -> T1)?, ifRight: ((R) -> T2)?): Either<T1, T2>
    abstract fun swap(): Either<R, L>
}

That's much easier to read and use

License is missing.

Absence of license raises the question whether I can use this library in my code.

Would you share the script to generate functions with multiple generic params?

In your talk you said you have a script to generate functions like this:

infix inline fun <P1, R> P1.pipe(t: (P1) -> R): R = t(this)

infix inline fun <P1, P2, R> P1.pipe2(crossinline t: (P1, P2) -> R): (P2) -> R = { p2 -> t(this, p2) }

infix inline fun <P1, P2, P3, R> P1.pipe3(crossinline t: (P1, P2, P3) -> R): (P2, P3) -> R = { p2, p3 -> t(this, p2, p3) }

Would you mind sharing it?

I want to automate the generation of functions like that.

Better support for coroutines

Functions like eitherTry and Try would also be useful when catching exceptions thrown by suspending functions. The current implementations don't support this. For example, I cannot to this:

fun main(args: Array<String>) = runBlocking {
    val a = async<String>(CommonPool) {
        throw Throwable()
    }

    val result = eitherTry {
        a.await()
    }
    println(result)
}

This fails to compile on a.await because we are not in a suspending block.

I see two potential solutions:

  • Add new functions (or change existing signatures) to support coroutines. E.g: eitherTry becomes suspend fun <T> eitherTry(body: suspend () -> T): Either<Throwable, T>
  • Simply mark these functions inline.

'partially(...)' for multiple arguments functions?

Can I transform function like
fun myProc(a:Int, b: String, c: Float)
to
fun myProc(c:Float)
in one step?

Right now I use code
myProc.partially1(1).partially1("")
, but maybe there are best solution?

Mapping EDSL for Either

I've been doing some experiments with Either myself and what I came up with has IMO a nice way of mapping either choice in a concise fashion, you might want to take a look at it and see if this is something for funktionale-either. It appears to be what Either is doing in fold but expanded by infix operations.

Relevant code starts here:
https://gist.github.com/lukashaertel/02b8dd4a5ad8c691bc783eb7b88fba9b#file-choice-kt-L37

And here's an example of how it's applied:

    // A method handling that choice type
    val f = { u: Choice<Number, String> ->
        // Map either side accordingly
        val d = u onLeft {
            it.toDouble() / 2
        } onRight {
            it.length.toDouble()
        }

        println(d)
    }

no license file

funKTionale has no license file.

What license is it released under?

Thanks!

Functions like Try.flatMap or fold swallow RuntimeExceptions

Functions like Try<T>.flatMap and Try<T>.fold swallow RuntimeExceptions, making it harder to find bugs.

For example, I tried to use a TODO(), but my application did not terminate:

fun main(args: Array<String>) {
    val result = Success("Test").flatMap<Unit> { TODO() }
    println(result)
}

Instead, the console prints

Failure(kotlin.NotImplementedError: An operation is not implemented.)

Either carrying like Rust

In Rust, the stdlib provides an Either like enum called Result. Functions that return Result can also carry values from other Result returning functions up the call stack. So if you're performing disk IO, where you'll be getting Result types as returns based off of whether there was an error opening a file, writing to disk etc. All this can be represented by a macro, or an operator.

fn i_return_a_result() -> Result<String, std::io::Error> {
    let i_returned_a_result: File = file_operation_that_returns_result()?;
    try!(write_to_file(i_returned_a_result));
    Ok("We did it!".to_string())
}

To those not familiar with Rust, let me explain.
The function declaration is similar to one you would find in Haskell or using FunKTionale using Either, with the difference being that the left side is the result, and the right side is the error, exception, or what have you. In the function body, there were 2 instances where I would have needed to deal with checking that there was a proper value in the result. When I get the file, and when I write (I didn't bind a variable in that case, because it's often used that functions return a Result with an empty left side, just indicating success).
In both cases, were there an error at any point¸ my function would have stopped executing, and the Error from their result would propogate up as the return value of my function, allowing it to be dealt with at the top.

Would this be at all possible in funcKTionale? Taking a Either returning function and collapsing it down to either give you the value of Right, or return from your function with the value of left?

Memoization thread safe?

I used memoization in Scala before and had issues when two different threads tried to call the memoized function. (The issue was that the memo used a non-thread safe "regular" HashMap and that caused it misbehave. However, I also tried creating a custom memo implementation using ConcurrentHashMap and I seem to recall that had performance issues).

The question---is the underlying memo implementation thread safe?

Rename second argument in Option.fold

The name of the second argument "f" like a not very good solution. I like to use named argument for fold calling and any more functions.
Of course, I can write:

 fold(isEmpty = {...}){value -> ...}

But I want to be able to write like this

 fold(isEmpty = {...},  some = {value -> ...})

Question regarding memoization of member functions

Hi Mario,

thank you very much for funKTionale!

I have a question regarding memoization of member functions. I'm used to Java and Groovy and a Kotlin Newbie.

Maybe you have some time and can give some insights on this...

I'd like to memoize the sum member function of this immutable data class (just a silly example)

package tryout

data class MyDataClass(val a: Int = 1,
                       val b: Int = 2) {

    fun sum(): Int {
        println("Calculating...")
        return a + b
    }
}

fun main(args: Array<String>) {
    val myData = MyDataClass()
    println(myData.sum())
    println(myData.sum())
    println(myData.sum())
}

In groovy I can do this using an annotation

package tryout

import groovy.transform.CompileStatic
import groovy.transform.Immutable
import groovy.transform.Memoized

@CompileStatic
@Immutable
class MyGroovyDataClass {

	int a, b

	@Memoized
	int sum() {
		println("Calculating...")
		a + b
	}

	static void main(String[] args) {
		def myData = new MyGroovyDataClass(1, 2)
		println(myData.sum())
		println(myData.sum())
		println(myData.sum())
	}
}

If I want to do this using funkTionale, then there is at the moment "only" this solution, right?

package tryout

import org.funktionale.memoization.memoize

data class MyMemoizedDataClassV1(val a: Int = 1,
                                 val b: Int = 2) {

    private val memoizedSum: (Int, Int) -> Int = { i: Int, j: Int ->
        println("Calculating...")
        i + j
    }.memoize()

    fun sum(): Int {
        return memoizedSum(a, b)
    }
}

fun main(args: Array<String>) {
    val myData = MyMemoizedDataClassV1()
    println(myData.sum())
    println(myData.sum())
    println(myData.sum())

    val myData2 = myData.copy(b = 99)
    println(myData2.sum())
    println(myData2.sum())
    println(myData2.sum())

    val myData3 = myData2.copy(a = 101)
    println(myData3.sum())
    println(myData3.sum())
    println(myData3.sum())
}

Or is there a "more direct" solution?

Thanks for your time & best regards,
Peti

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.