<@U3K70UN9H> what is the parser target? narses is...
# arrow
j
@xenomachina what is the parser target? narses is sort of a production system input format
x
I'm not sure what you mean by "parser target"
Are you familiar at all with parser combinators?
j
i see a lot of multiple arity support in kessel.
im not familiar with combinator as a formal term, but i've been using boost spirit for 15 years
my goal is to make the kotlin parser definition as close to bnf as possible such that you can more or less cut and paste ebnf into kotlin with some accomodations for the operator limitations
x
Kessel tries to make it relatively straightforward to translate bnf into Kotlin, though it doesn't use operator overloading.
By multiple arity support, you mean like the various
seq
methods, and the "SequenceNRule" classes?
j
iiuc @pakoito has suggested kessel as a means to make knarsese [more intuitive] through FP.
this is my combinator design to date... there's a tiny bit of rewindable token sequence code not shown which leverages the coroutines. if there are FP alternatives to the kotlin I'm using in those IO features, im trying to get my head around what's less awkward than the basic kotlin options which appear to be mostly takeIf() <elvis> pairs

https://files.slack.com/files-pri/T09229ZC6-FB9MUABPD/image.png

x
Sorry, I have to run right now, but I'll ping you again when I'm online.
In the meantime, there's a simple sample grammar under the "Parsing" heading here: https://github.com/xenomachina/kessel
I am back, at least for a bit
j
I don't recall seeing the arrow component of Kessel maybe I missed it
x
It only uses arrow a little bit at the moment. Mostly Either, Option and Validated.
j
right now i hav an idealistic dislike for kotlin promoting null safety, andTHEN disabling ternary expressions, and THEN promoting takeIf/TakeUnless when we complain about ternary expressions
x
if
expressions are the same as ternary expressions, just a bit more verbose 😁
j
i would at least prefer something like TakeIfNotUnit and takeIfUnit but I don't wish to pay down the technical debt for idealism
the reasons they omitted ternary were cited as a feature that was removed before 1.0
wtf, elvis but not ternary
x
What would TakeIfNotUnit do? Unit has only one value.
j
anyways, there is a win for technical debt imho by leveraging overloads. using null in kotlin is seemingly bad like using new in c++, but then they go and shit all over that with binary logic using null as false
at least if methods throw and return Unit, you could still say you're not bending the rules and your entire fucking type inference by peppring in nulls
if someone kind of FP library is supplying TakeIfNotNil, takeUnlessNil s/Nil/Unit, it's not a technical debt im paying with my toy codebase
x
I've never heard that null is "bad" in Kotlin. It's fine to have things that are nullable, it just isn't the default (unlike Java, where every reference type is nullable)
On your last point, are you suggesting using
Unit?
in place of
Boolean
?
j
I would say Unit/Void/Nil all look the same to me, with null being a like if hitler was thier grandfather, yes
and if the language is using elvis as a ternary, then yes, Unit makes a good one
i dont find null in kotlin to be particularly helpful considering how swiftly it will pollute an object hierarchy
it adds line-noise to my assignments
I am not particularly fond of !! and ?
x
Can you show me an example of how you'd use one of TakeIfNotNil, takeUnlessNil s/Nil/Unit?
I've rarely had to use !!. Mostly I use it in tests, where I'm fine with it throwing an exception (to indicate failure)
j
well, im writing a parser "combinator". i have rules. I want to publish using events typed as Any, for now. but the language allows some assingments and tests based on null. if I had elvis operator and takeIf/Unless etc., foreach etc. that used Unit, wherever null is specified, I could build a control system without specifying Any?, and adding specific cases where ? and !! are required for compilation
this matters in a MAJOR way for concurrent programming, where null checks are more than slightly inconvenient, suspend functions are also extremely unfriendly with regards to access and type
i still can in thoery write a library os Unit support to minimize a few usages of null, and substitute Unit, however iinm the best i can do is write a lot of "more verbose" if statements instead of leverage concise elvis syntax or ternary
oervlaoding elvis and ternary would be a benefit to expressive programming as well, but i pick my battles.
i would expect any library throwing around the term FP and "purity" in the README elevator pitch would make some inroads toward safer type system and operators than the ones that make a dual type hierarchy for nulls and ternary by null/elvis
x
Can you point me at some code where you're running into these issues of wanting a takeifunit?
If you're using
Any
and then checking to see if it's
Unit
to treat that case separately, I suspect that you would be better off using `Any?`and null as your sentinel, or possibly using
Option
.
i originally did have Any instead of Any?
i looked at the situation, and figured i would rather lean on elvis and takeIf and suffer the hit for now, with nullable types, than to write if(x=Unit) to determine a parse fialure
i would prefer Unit?doSomething():somethingElse() in a cold minute but i don't like the if statement overhead
and likewise takeIfUnit, if the language had operator support for making the almighty immutable Monad useful for something
but it doesn't, so I'm hoping a FP library carries the torch and runs with non-nullable type systems
i we're discussing engineering transparency in a language, then the decision to make an inflexible set of operators will lead to less transparent engineering opportunities. some languages have the ability to redefine the syntax. i went with the backtick symbols for a o minute but that's still not actually making an operator, infix or not.
the decision to have a dual typesystem with a "?" discriminator seems like an afterthought of reading about Rust, not like a well thought out plan. when im porting java libs to kotlin, particularly math and matrix libraries, this is a source of unending tedium with little gain
x
Are these libraries actually using null a lot?
j
these libraries are java, and so they tend to use default initialization and then go and inherit hierarchies that abandon the attribute and force the entire library to accept null after kotlin infers differently during conversion, so yes, by default, most java code makes use of null freuqnelty
x
Java code that does that is a pain to use even in Java. I don't know that there's much Kotlin can do to make bad libraries better.
j
at any rate, i'd love to know how arrow's FP can make my parser decisions more idiomatic than what kotlin provides out of the box. i've seen some interesting pixiedust around type-extensions and so forth to make the language do more with more consistency but iiinm most "FP" starts with a Monadic nil entity and many things can be infered such as 0, false,java.lang.Void from this Monad, and thereafter signaling could be accomplished if there were a feature to elevate this Monad above kotlin.lang.Nothing and below null
kotlin's core operators are not negotiable, there will never be an elvis for Nil, so it's a moot point, but i would love to see something clever that i overlooked
x
Have you looked at Option?
Its
None
sounds like your Nil. You can use flatMap to compose functions that return Options.
j
can you show me an example that is more virtuous than kotlin's elvis and take* methods?
i do want to get some familiarity with arrow if it is worth the gradle/maven jihad i see in the github issues
at this time i have a lot of uncomfortable
takeIf(op(token))?:throw
conditions
because... generateSequence uses null as a cardinal ending. forEach() uses null signalling. thereafter anytime i want sequence or foreach declaration i need a ? declaration somewhere to enable the kotlin signaling choices
so i'd rather use throw as a goto than pick a cardinality
x
What do you mean "generateSequence uses null as a cardinal ending"?
j
Copy code
/**
 * Returns a sequence defined by the starting value [seed] and the function [nextFunction],
 * which is invoked to calculate the next value based on the previous one on each iteration.
 *
 * The sequence produces values until it encounters first `null` value.
 * If [seed] is `null`, an empty sequence is produced.
 *
 * The sequence can be iterated multiple times, each time starting with [seed].
 *
 * @see kotlin.coroutines.experimental.buildSequence
 *
 * @sample samples.collections.Sequences.Building.generateSequenceWithSeed
 */
@kotlin.internal.LowPriorityInOverloadResolution
public fun <T : Any> generateSequence(seed: T?, nextFunction: (T) -> T?): Sequence<T> =
    if (seed == null)
        EmptySequence
    else
        GeneratorSequence({ seed }, nextFunction)
x
Ah, sorry. I got confused with buildSequence.
j
it just lacks consistency with null free programming. i love the idea, i just don't know where to go to find it, because kotlin makes convenience more important than a sense of "pure" safety
i guess if there were an FP operator overloaded "safe" library, that i didn't have to maintain for a toy parser, I would use that
^collections library
x
I have to head out now. In the meantime you might want to look and Option or possibly Validated. I think some of the issues you're running into might come from mixing Java-imperative style (eg: throwing exceptions) with functional style . They can be combined, but you kind of need to set up boundaries.
j
What would TakeIfNotUnit do? Unit has only one value.
return <T>/Unit on false/true condition
x
What is the return type?
j
The same as takeunless?:Unit
Sry on mobile
I would rather not use null for signalling or binary operators that introduce nulls like takeoff. I see option in arrow. The lack of maven support in the threads and doc's is giving me cause to pass for just dipping my feet in for one feature
x
So if T is String, what is the return type?
j
String
x
Unit is not a subtype of String
j
Are you familiar with kotlin takeunless?
x
Yes
j
What is string.takeunless<string>{}?
x
String?
j
null isn't either
the javadocs for Option say: Represents optional values.
Copy code
Instances of `Option` are either an instance of $some or the object $none
in summary, for this long thread, I would endorse the replacement of None with Unit in a kotlin functional library that had maven support on the basis of occam's razor
i suppose one could argue that someone may in fact be using Unit as an object for which there an option <Unit> or None, but Unit does not alter the program compilation like the use of null, which is where my discomfort steams from as i develop idiomatic libraries. I would love to see how a functional library such as Arrow, or similar with a critical mass of developers could introduce options (not reffering to Arrow.Option)to dissuade the use of null in all of the operators where Unit could suffice, such as for sequence termination, branch determination, and elvis
again, on the basis of occam's razor, if i don't have nullable types anywhere in my code I use fewer operators and experience fewer mandatory code changes for using null-friendly parts of kotlin libraries and operators
x
String? Is a disjunction of String and null
If you think of a type as a set of values, then String? Is the union of String and {null}
You can't do that with arbitrary types/values, though
There is no type which is a union of String and Unit
While you can't do it with arbitrary types, you can create a sealed class, which is essentially a union of its subclasses.
That's what Kotlin arrow-kt uses for Option, Either, and a bunch of other algebraic data types
I'm also not sure what you're referring to about maven support. Do you mean something other than having artifacts in maven central?
j
ahh right it occurred to me where your question was going. so takeIf?:Unit would need Nothing as type.
iiuc the arrow <team> commenting on recent issues doesn't like maven, there are issues brought out by maven users and comments by devs and apparently kapt is a gradle construct
x
kapt is a Kotlin compiler thing, not a gradle thing
That said, I use gradle, not maven, so I have no idea how well it does or does not work with maven
I don't think arrow requires actually using kapt yourself unless you are planning on building it yourself, or using their annotation processors
you don't need any of that to just use Option, Either, etc.
j
as a maven user with very marginal interest in figuring out where the use of a library differs from gradle support, and seeing comments to the effect that ... maven's not supported, i didn't study too hard
x
The kapt page at http://kotlinlang.org/docs/reference/kapt.html suggests that kapt does work with maven, with a sufficiently large blob of XML in your build file.
j
i just reached a point with my idiomatic grammar parser construction to poke my head up and see if there's an FP library that clicks with me on the level of reducing my code's kolmogorov complexity
x
They've also split up arrow into fairly small modules. Just arrow-core and maybe arrow-data should get you enough to try out Option, etc. I'm pretty sure you won't need any kapt.